From 98435fb4649367c182e35aea8c89ce7a4cf8d4d3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 11 Sep 2014 18:15:06 +0200 Subject: [PATCH 0001/1198] 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 dee7825f05e0e558020fabe2e536e2b5d4df8050 Mon Sep 17 00:00:00 2001 From: Alexandre Morignot Date: Tue, 10 Feb 2015 16:37:41 +0100 Subject: [PATCH 0002/1198] 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 eb20a6c846373bbfba4cd80e6aef017b56409047 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 22 Sep 2016 04:27:35 +0200 Subject: [PATCH 0003/1198] Merge pull request #548 from ailin-nemui/buf-fix sync buf.pl --- scripts/buf.pl | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/scripts/buf.pl b/scripts/buf.pl index da50e821..6d907f12 100644 --- a/scripts/buf.pl +++ b/scripts/buf.pl @@ -5,7 +5,7 @@ use Irssi qw(command signal_add signal_add_first active_win settings_get_str settings_get_bool channels windows settings_add_str settings_add_bool get_irssi_dir window_find_refnum signal_stop); -$VERSION = '2.13'; +$VERSION = '2.20'; %IRSSI = ( authors => 'Juerd', contact => 'juerd@juerd.nl', @@ -13,10 +13,8 @@ $VERSION = '2.13'; description => 'Saves the buffer for /upgrade, so that no information is lost', license => 'Public Domain', url => 'http://juerd.nl/irssi/', - changed => 'Mon May 13 19:41 CET 2002', - changes => 'Severe formatting bug removed * oops, I ' . - 'exposed Irssi to ircII foolishness * sorry ' . - '** removed logging stuff (this is a fix)', + changed => 'Thu Sep 22 01:37 CEST 2016', + changes => 'Fixed file permissions (leaked everything via filesystem)', note1 => 'This script HAS TO BE in your scripts/autorun!', note2 => 'Perl support must be static or in startup', ); @@ -39,9 +37,15 @@ use Data::Dumper; my %suppress; +sub _filename { sprintf '%s/scrollbuffer', get_irssi_dir } + sub upgrade { - open BUF, q{>}, sprintf('%s/scrollbuffer', get_irssi_dir) or die $!; - print BUF join("\0", map $_->{server}->{address} . $_->{name}, channels), "\n"; + my $fn = _filename; + my $old_umask = umask 0077; + open my $fh, q{>}, $fn or die "open $fn: $!"; + umask $old_umask; + + print $fh join("\0", map $_->{server}->{address} . $_->{name}, channels), "\n"; for my $window (windows) { next unless defined $window; next if $window->{name} eq 'status'; @@ -57,36 +61,39 @@ sub upgrade { redo if defined $line; } } - printf BUF "%s:%s\n%s", $window->{refnum}, $lines, $buf; + printf $fh "%s:%s\n%s", $window->{refnum}, $lines, $buf; } - close BUF; + close $fh; unlink sprintf("%s/sessionconfig", get_irssi_dir); command 'layout save'; command 'save'; } sub restore { - open BUF, q{<}, sprintf('%s/scrollbuffer', get_irssi_dir) or die $!; - my @suppress = split /\0/, ; + my $fn = _filename; + open my $fh, q{<}, $fn or die "open $fn: $!"; + unlink $fn or warn "unlink $fn: $!"; + + my @suppress = split /\0/, readline $fh; if (settings_get_bool 'upgrade_suppress_join') { chomp $suppress[-1]; @suppress{@suppress} = (2) x @suppress; } active_win->command('^window scroll off'); - while (my $bla = ){ + while (my $bla = readline $fh){ chomp $bla; my ($refnum, $lines) = split /:/, $bla; next unless $lines; my $window = window_find_refnum $refnum; unless (defined $window){ - for 1..$lines; + readline $fh for 1..$lines; next; } my $view = $window->view; $view->remove_all_lines(); $view->redraw(); my $buf = ''; - $buf .= for 1..$lines; + $buf .= readline $fh for 1..$lines; my $sep = settings_get_str 'upgrade_separator'; $sep .= "\n" if $sep ne ''; $window->gui_printtext_after(undef, MSGLEVEL_CLIENTNOTICE, "$buf\cO$sep"); @@ -119,3 +126,10 @@ signal_add 'event join' => 'suppress'; unless (-f sprintf('%s/scripts/autorun/buf.pl', get_irssi_dir)) { Irssi::print('PUT THIS SCRIPT IN ~/.irssi/scripts/autorun/ BEFORE /UPGRADING!!'); } + +# Remove any left-over file. If 'session' doesn't exist (created by irssi +# during /UPGRADE), neither should our file. +unless (-e sprintf('%s/session', get_irssi_dir)) { + my $fn = _filename; + unlink $fn or warn "unlink $fn: $!" if -e $fn; +} From 91c9e871c78e203aed834edd1e1f558680a6ccfa Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 12 Jul 2016 13:59:46 +0200 Subject: [PATCH 0004/1198] Add an option to stop the connection when SASL fails. --- src/fe-common/irc/fe-sasl.c | 17 +++++++++++++++++ src/irc/core/irc-servers.h | 1 + src/irc/core/sasl.c | 7 +++++++ 3 files changed, 25 insertions(+) diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index 331b38b0..dfbfc84a 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -23,6 +23,9 @@ #include "signals.h" #include "levels.h" +#include "irc-servers.h" +#include "settings.h" + #include "printtext.h" static void sig_sasl_success(IRC_SERVER_REC *server) @@ -35,14 +38,28 @@ static void sig_sasl_failure(IRC_SERVER_REC *server, const char *reason) printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_SASL_ERROR, reason); } +static void sig_cap_end(IRC_SERVER_REC *server) +{ + /* The negotiation has now been terminated, if we didn't manage to + * authenticate successfully with the server just disconnect. */ + if (server->sasl_success == FALSE && + settings_get_bool("sasl_disconnect_on_failure")) + server_disconnect(SERVER(server)); + +} + void fe_sasl_init(void) { + settings_add_bool("server", "sasl_disconnect_on_failure", TRUE); + signal_add("server sasl success", (SIGNAL_FUNC) sig_sasl_success); signal_add("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); + signal_add_first("server cap end", (SIGNAL_FUNC) sig_cap_end); } void fe_sasl_deinit(void) { signal_remove("server sasl success", (SIGNAL_FUNC) sig_sasl_success); signal_remove("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); + signal_remove("server cap end", (SIGNAL_FUNC) sig_cap_end); } diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index bb100f86..09f3f81d 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -68,6 +68,7 @@ struct _IRC_SERVER_REC { unsigned int motd_got:1; /* We've received MOTD */ unsigned int isupport_sent:1; /* Server has sent us an isupport reply */ unsigned int cap_complete:1; /* We've done the initial CAP negotiation */ + unsigned int sasl_success:1; /* Did we authenticate successfully ? */ int max_kicks_in_cmd; /* max. number of people to kick with one /KICK command */ int max_modes_in_cmd; /* max. number of mode changes in one /MODE command */ diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index a1c16cdd..1021bea4 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -48,6 +48,7 @@ static gboolean sasl_timeout(IRC_SERVER_REC *server) cap_finish_negotiation(server); server->sasl_timeout = 0; + server->sasl_success = FALSE; signal_emit("server sasl failure", 2, server, "The authentication timed out"); @@ -84,6 +85,8 @@ static void sasl_fail(IRC_SERVER_REC *server, const char *data, const char *from params = event_get_params(data, 2, NULL, &error); + server->sasl_success = FALSE; + signal_emit("server sasl failure", 2, server, error); /* Terminate the negotiation */ @@ -99,6 +102,8 @@ static void sasl_already(IRC_SERVER_REC *server, const char *data, const char *f server->sasl_timeout = 0; } + server->sasl_success = TRUE; + signal_emit("server sasl success", 1, server); /* We're already authenticated, do nothing */ @@ -112,6 +117,8 @@ static void sasl_success(IRC_SERVER_REC *server, const char *data, const char *f server->sasl_timeout = 0; } + server->sasl_success = TRUE; + signal_emit("server sasl success", 1, server); /* The authentication succeeded, time to finish the CAP negotiation */ From 4ccffd85ffd06325687546f78b78e3e7fce575c5 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 20 Oct 2016 21:41:36 +0200 Subject: [PATCH 0005/1198] Expose 'sasl_success' to the perl side. --- src/fe-common/irc/fe-sasl.c | 2 +- src/perl/irc/Irc.xs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index dfbfc84a..4c86f850 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -42,7 +42,7 @@ static void sig_cap_end(IRC_SERVER_REC *server) { /* The negotiation has now been terminated, if we didn't manage to * authenticate successfully with the server just disconnect. */ - if (server->sasl_success == FALSE && + if (!server->sasl_success && settings_get_bool("sasl_disconnect_on_failure")) server_disconnect(SERVER(server)); diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 8b3b0c45..41690010 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -32,6 +32,7 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server) (void) hv_store(hv, "isupport_sent", 13, newSViv(server->isupport_sent), 0); (void) hv_store(hv, "cap_complete", 12, newSViv(server->cap_complete), 0); + (void) hv_store(hv, "sasl_success", 12, newSViv(server->sasl_success), 0); av = newAV(); for (tmp = server->cap_supported; tmp != NULL; tmp = tmp->next) From 560283ba4e4d355daa32dc970021845260d2dca9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Dec 2016 21:07:56 +0100 Subject: [PATCH 0006/1198] g_sequence backing for window list --- configure.ac | 2 +- src/fe-common/core/fe-windows.c | 204 ++++++++++++++++++++++---------- 2 files changed, 145 insertions(+), 61 deletions(-) diff --git a/configure.ac b/configure.ac index bf87f5aa..464f6288 100644 --- a/configure.ac +++ b/configure.ac @@ -237,7 +237,7 @@ for try in 1 2; do echo "*** trying without -lgmodule" glib_modules= fi - AM_PATH_GLIB_2_0(2.16.0,,, $glib_modules) + AM_PATH_GLIB_2_0(2.28.0,,, $glib_modules) if test "$GLIB_LIBS"; then if test $glib_modules = gmodule; then AC_DEFINE(HAVE_GMODULE) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 46c1593b..ff45f141 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -35,6 +35,7 @@ GSList *windows; /* first in the list is the active window, next is the last active, etc. */ +GSequence *windows_seq; WINDOW_REC *active_win; static int daytag; @@ -44,21 +45,23 @@ static int daycheck; /* 0 = don't check, 1 = time is 00:00, check, static int window_get_new_refnum(void) { WINDOW_REC *win; - GSList *tmp; + GSequenceIter *iter, *end; int refnum; refnum = 1; - tmp = windows; - while (tmp != NULL) { - win = tmp->data; + for (iter = g_sequence_get_begin_iter(windows_seq), + end = g_sequence_get_end_iter(windows_seq); + + iter != end; + + refnum++, + iter = g_sequence_iter_next(iter)) { + + win = g_sequence_get(iter); if (refnum != win->refnum) { - tmp = tmp->next; - continue; + return refnum; } - - refnum++; - tmp = windows; } return refnum; @@ -73,6 +76,7 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) rec->level = settings_get_level("window_default_level"); windows = g_slist_prepend(windows, rec); + g_sequence_insert_sorted(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic)); if (item != NULL) window_item_add(rec, item, automatic); @@ -84,6 +88,25 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) return rec; } +static void window_set_refnum0(WINDOW_REC *window, int refnum) +{ + int old_refnum; + + g_return_if_fail(window != NULL); + g_return_if_fail(refnum >= 1); + if (window->refnum == refnum) return; + + old_refnum = window->refnum; + window->refnum = refnum; + signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum)); +} + +static int window_refnum_lookup(WINDOW_REC *window, void *refnum_p) +{ + int refnum = GPOINTER_TO_INT(refnum_p); + return window->refnum == refnum ? 0 : window->refnum < refnum ? -1 : 1; +} + /* removed_refnum was removed from the windows list, pack the windows so there won't be any holes. If there is any holes after removed_refnum, leave the windows behind it alone. */ @@ -91,23 +114,34 @@ static void windows_pack(int removed_refnum) { WINDOW_REC *window; int refnum; + GSequenceIter *iter, *end; - for (refnum = removed_refnum+1;; refnum++) { - window = window_find_refnum(refnum); - if (window == NULL || window->sticky_refnum) + refnum = removed_refnum+1; + end = g_sequence_get_end_iter(windows_seq); + iter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + if (iter == NULL) iter = end; + + for (; iter != end; refnum++, iter = g_sequence_iter_next(iter)) { + window = g_sequence_get(iter); + + if (window == NULL || window->sticky_refnum || window->refnum != refnum) break; - window_set_refnum(window, refnum-1); + window_set_refnum0(window, refnum-1); + g_sequence_sort_changed(iter, (GCompareDataFunc)window_refnum_cmp, NULL); } } void window_destroy(WINDOW_REC *window) { + GSequenceIter *iter; g_return_if_fail(window != NULL); if (window->destroying) return; window->destroying = TRUE; windows = g_slist_remove(windows, window); + iter = g_sequence_lookup(windows_seq, window, (GCompareDataFunc)window_refnum_cmp, NULL); + if (iter != NULL) g_sequence_remove(iter); if (active_win == window) { active_win = NULL; /* it's corrupted */ @@ -189,26 +223,32 @@ void window_change_server(WINDOW_REC *window, void *server) void window_set_refnum(WINDOW_REC *window, int refnum) { - GSList *tmp; + GSequenceIter *oiter, *witer; int old_refnum; g_return_if_fail(window != NULL); g_return_if_fail(refnum >= 1); if (window->refnum == refnum) return; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + oiter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + witer = g_sequence_lookup(windows_seq, GINT_TO_POINTER(window->refnum), (GCompareDataFunc)window_refnum_lookup, NULL); - if (rec->refnum == refnum) { - rec->refnum = window->refnum; - signal_emit("window refnum changed", 2, rec, GINT_TO_POINTER(refnum)); - break; - } + if (oiter != NULL) { + WINDOW_REC *rec = g_sequence_get(oiter); + + rec->refnum = window->refnum; + signal_emit("window refnum changed", 2, rec, GINT_TO_POINTER(refnum)); } old_refnum = window->refnum; window->refnum = refnum; signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum)); + + if (witer != NULL && oiter != NULL) { + g_sequence_swap(oiter, witer); + } else { + g_sequence_sort_changed(witer, (GCompareDataFunc)window_refnum_cmp, NULL); + } } void window_set_name(WINDOW_REC *window, const char *name) @@ -346,13 +386,13 @@ WINDOW_REC *window_find_closest(void *server, const char *name, int level) WINDOW_REC *window_find_refnum(int refnum) { - GSList *tmp; + GSequenceIter *iter; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + iter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + if (iter != NULL) { + WINDOW_REC *rec = g_sequence_get(iter); - if (rec->refnum == refnum) - return rec; + return rec; } return NULL; @@ -400,71 +440,112 @@ WINDOW_REC *window_find_item(SERVER_REC *server, const char *name) int window_refnum_prev(int refnum, int wrap) { - GSList *tmp; - int prev, max; + GSequenceIter *iter, *end; - max = prev = -1; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + iter = g_sequence_search(windows_seq, GINT_TO_POINTER(refnum-1), (GCompareDataFunc)window_refnum_lookup, NULL); + end = g_sequence_get_end_iter(windows_seq); - if (rec->refnum < refnum && (prev == -1 || rec->refnum > prev)) - prev = rec->refnum; - if (wrap && (max == -1 || rec->refnum > max)) - max = rec->refnum; + if (iter != NULL) { + WINDOW_REC *rec; + if (iter != end) { + rec = g_sequence_get(iter); + + if (rec->refnum < refnum) + return rec->refnum; + } + + iter = g_sequence_iter_prev(iter); + rec = g_sequence_get(iter); + + if (rec->refnum < refnum) + return rec->refnum; } - return prev != -1 ? prev : max; + if (wrap) { + WINDOW_REC *rec; + iter = g_sequence_iter_prev(end); + if (iter != end) { + rec = g_sequence_get(iter); + + return rec->refnum; + } + } + + return -1; } int window_refnum_next(int refnum, int wrap) { - GSList *tmp; - int min, next; + GSequenceIter *iter, *end; - min = next = -1; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + iter = g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + end = g_sequence_get_end_iter(windows_seq); - if (rec->refnum > refnum && (next == -1 || rec->refnum < next)) - next = rec->refnum; - if (wrap && (min == -1 || rec->refnum < min)) - min = rec->refnum; + if (iter != NULL && iter != end) { + WINDOW_REC *rec = g_sequence_get(iter); + + if (rec->refnum > refnum) + return rec->refnum; + + iter = g_sequence_iter_next(iter); + if (iter != end) { + rec = g_sequence_get(iter); + + if (rec->refnum > refnum) + return rec->refnum; + } } - return next != -1 ? next : min; + if (wrap) { + WINDOW_REC *rec; + iter = g_sequence_get_begin_iter(windows_seq); + if (iter != end) { + rec = g_sequence_get(iter); + + return rec->refnum; + } + } + + return -1; } int windows_refnum_last(void) { - GSList *tmp; - int max; + GSequenceIter *end, *iter; + WINDOW_REC *rec; - max = -1; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + end = g_sequence_get_end_iter(windows_seq); + iter = g_sequence_iter_prev(end); + if (iter != end) { + rec = g_sequence_get(iter); - if (rec->refnum > max) - max = rec->refnum; + return rec->refnum; } - return max; + return -1; } int window_refnum_cmp(WINDOW_REC *w1, WINDOW_REC *w2) { - return w1->refnum < w2->refnum ? -1 : 1; + return w1 == w2 ? 0 : w1->refnum < w2->refnum ? -1 : 1; } GSList *windows_get_sorted(void) { - GSList *tmp, *sorted; + GSequenceIter *iter, *begin; + GSList *sorted; sorted = NULL; - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + for (iter = g_sequence_get_end_iter(windows_seq), + begin = g_sequence_get_begin_iter(windows_seq); - sorted = g_slist_insert_sorted(sorted, rec, (GCompareFunc) - window_refnum_cmp); + iter != begin; + + ) { + iter = g_sequence_iter_prev(iter); + WINDOW_REC *rec = g_sequence_get(iter); + + sorted = g_slist_prepend(sorted, rec); } return sorted; @@ -709,6 +790,7 @@ static void read_settings(void) void windows_init(void) { active_win = NULL; + windows_seq = g_sequence_new(NULL); daycheck = 0; daytag = -1; settings_add_bool("lookandfeel", "window_auto_change", FALSE); settings_add_bool("lookandfeel", "windows_auto_renumber", TRUE); @@ -733,4 +815,6 @@ void windows_deinit(void) signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + g_sequence_free(windows_seq); + windows_seq = NULL; } From 365097319f2bf57d7d01c2c4c912fca124fbedf9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Dec 2016 03:04:01 +0100 Subject: [PATCH 0007/1198] manually redraw the activity list on expose only might speed up /foreach query /unquery --- src/fe-text/statusbar-items.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 0db4f63a..de4499b4 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -143,16 +143,34 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) static void item_act(SBAR_ITEM_REC *item, int get_size_only) { char *actlist; + int max_size; - actlist = get_activity_list(item->bar->parent_window, TRUE, TRUE); - if (actlist == NULL) { - if (get_size_only) + if (get_size_only) { + if (activity_list == NULL) item->min_size = item->max_size = 0; + /* Skip activity calculation on regular trigger, only + set dirty */ return; } - statusbar_item_default_handler(item, get_size_only, + actlist = get_activity_list(item->bar->parent_window, TRUE, TRUE); + if (actlist == NULL) { + return; + } + + max_size = item->max_size; + statusbar_item_default_handler(item, TRUE, NULL, actlist, FALSE); + statusbar_item_default_handler(item, FALSE, + NULL, actlist, FALSE); + if (max_size != item->max_size) { + /* Due to above hack of skipping the calculation, we + need to manually trigger the redraw process now or + we won't see the item */ + item->bar->dirty = item->dirty = TRUE; + statusbar_redraw(item->bar, TRUE); + statusbar_redraw_dirty(); + } g_free_not_null(actlist); } From 59242cb595716bf34966ee71aca81e0c9a2a5284 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Dec 2016 16:59:38 +0100 Subject: [PATCH 0008/1198] add assertion to statusbar_read_group fix #564 --- src/fe-text/statusbar-config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index a47a709e..48f4aa61 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -194,6 +194,8 @@ static void statusbar_read_group(CONFIG_NODE *node) STATUSBAR_GROUP_REC *group; GSList *tmp; + g_return_if_fail(is_node_list(node)); + group = statusbar_group_find(node->key); if (group == NULL) { group = statusbar_group_create(node->key); From 7b856d628bfd6c775dfaee2138a3542ee13b1960 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Dec 2016 18:01:26 +0100 Subject: [PATCH 0009/1198] check for end of string in ansi 48 --- src/fe-common/core/formats.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index a58d839a..a789c0e3 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -956,6 +956,7 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, str++; for (num2 = 0; i_isdigit(*str); str++) num2 = num2*10 + (*str-'0'); + if (*str == '\0') return start; switch (num2) { case 2: @@ -973,6 +974,8 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, for (; i_isdigit(*str); str++) num2 = (num2&~0xff) | (((num2&0xff) * 10 + (*str-'0'))&0xff); + + if (*str == '\0') return start; } if (i == -1) break; @@ -1001,6 +1004,7 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, str++; for (num2 = 0; i_isdigit(*str); str++) num2 = num2*10 + (*str-'0'); + if (*str == '\0') return start; if (num == 38) { flags &= ~GUI_PRINT_FLAG_COLOR_24_FG; From 0d6add02cf1a1e0dc3905a482d259a8851b4939c Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 15 Dec 2016 15:22:30 +0100 Subject: [PATCH 0010/1198] Process the nick changes in queries before the PRIVMSG is handled. Otherwise we end up with the message in the status window since the frontend knows jack shit about the casemapping option when it tries to find the associated window for the query. --- src/fe-common/irc/fe-irc-queries.c | 7 +++++++ src/irc/core/irc-queries.c | 16 ---------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/fe-common/irc/fe-irc-queries.c b/src/fe-common/irc/fe-irc-queries.c index b2faefbc..c928a94a 100644 --- a/src/fe-common/irc/fe-irc-queries.c +++ b/src/fe-common/irc/fe-irc-queries.c @@ -78,6 +78,13 @@ static void event_privmsg(SERVER_REC *server, const char *data, if (!server_has_nick(server, query->name)) query_change_nick(query, nick); } + } else { + /* process the changes to the query structure now, before the + * privmsg is dispatched. */ + if (g_strcmp0(query->name, nick) != 0) + query_change_nick(query, nick); + if (address != NULL && g_strcmp0(query->address, address) != 0) + query_change_address(query, address); } } diff --git a/src/irc/core/irc-queries.c b/src/irc/core/irc-queries.c index 12861744..b611e621 100644 --- a/src/irc/core/irc-queries.c +++ b/src/irc/core/irc-queries.c @@ -79,20 +79,6 @@ static void check_query_changes(IRC_SERVER_REC *server, const char *nick, } } -static void event_privmsg(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *address) -{ - char *params, *target, *msg; - - g_return_if_fail(data != NULL); - if (nick == NULL) - return; - - params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); - check_query_changes(server, nick, address, target); - g_free(params); -} - static void ctcp_action(IRC_SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) @@ -117,14 +103,12 @@ static void event_nick(SERVER_REC *server, const char *data, void irc_queries_init(void) { - signal_add_last("event privmsg", (SIGNAL_FUNC) event_privmsg); signal_add_last("ctcp action", (SIGNAL_FUNC) ctcp_action); signal_add("event nick", (SIGNAL_FUNC) event_nick); } void irc_queries_deinit(void) { - signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); signal_remove("ctcp action", (SIGNAL_FUNC) ctcp_action); signal_remove("event nick", (SIGNAL_FUNC) event_nick); } From 7a7f6abc168b571a0db4fa65c760fe6e46edf199 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 15 Dec 2016 22:41:57 +0100 Subject: [PATCH 0011/1198] Prevent a UaF by calling server_disconnect in a signal handler. --- src/fe-common/irc/fe-sasl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index 4c86f850..6cba1887 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -43,8 +43,15 @@ static void sig_cap_end(IRC_SERVER_REC *server) /* The negotiation has now been terminated, if we didn't manage to * authenticate successfully with the server just disconnect. */ if (!server->sasl_success && - settings_get_bool("sasl_disconnect_on_failure")) - server_disconnect(SERVER(server)); + settings_get_bool("sasl_disconnect_on_failure")) { + /* We can't use server_disconnect() here because we'd end up + * freeing the 'server' object and be guilty of a slew of UaF. */ + server->connection_lost = TRUE; + /* By setting connection_lost we make sure the communication is + * halted and when the control goes back to irc_parse_incoming + * the server object is safely destroyed. */ + signal_stop(); + } } From a39e210ea8e0b0cdccb37eae212d1ade8c036ae2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 18 Dec 2016 15:46:48 +0100 Subject: [PATCH 0012/1198] Minor cleanup in the highlighting signal. --- src/fe-common/core/hilight-text.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 4691a708..46b416e6 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -379,34 +379,29 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, char *middle; int pos, color_pos, color_len; - tmp = g_string_new(NULL); - /* start of the line */ pos = strip_real_length(text, hilight_start, NULL, NULL); - g_string_append(tmp, text); - g_string_truncate(tmp, pos); + tmp = g_string_new_len(text, pos); /* color */ g_string_append(tmp, color); /* middle of the line, stripped */ - middle = strip_codes(text+pos); - pos = tmp->len; - g_string_append(tmp, middle); - g_string_truncate(tmp, pos+hilight_len); + middle = strip_codes(text + pos); + g_string_append_len(tmp, middle, hilight_len); g_free(middle); /* end of the line */ pos = strip_real_length(text, hilight_end, &color_pos, &color_len); if (color_pos > 0) - g_string_append_len(tmp, text+color_pos, color_len); + g_string_append_len(tmp, text + color_pos, color_len); else { /* no colors in line, change back to default */ g_string_append_c(tmp, 4); g_string_append_c(tmp, FORMAT_STYLE_DEFAULTS); } - g_string_append(tmp, text+pos); + g_string_append(tmp, text + pos); newstr = tmp->str; g_string_free(tmp, FALSE); From d6b0dd2b3224dfebb72e1aef7ff55c6d93f963a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 18 Oct 2016 22:12:27 +0200 Subject: [PATCH 0013/1198] Kill legacy proxy support. --- configure.ac | 27 --------------------------- docs/help/in/connect.in | 1 - docs/help/in/server.in | 3 +-- src/core/chat-commands.c | 10 +++------- src/core/server-connect-rec.h | 5 ----- src/core/server-setup-rec.h | 1 - src/core/servers-reconnect.c | 6 ------ src/core/servers-setup.c | 22 ---------------------- src/core/servers.c | 11 ++--------- src/fe-common/core/fe-server.c | 6 ++---- src/fe-common/irc/fe-irc-server.c | 2 -- src/irc/core/irc-servers.c | 19 ------------------- src/perl/irc/Irc.xs | 1 - 13 files changed, 8 insertions(+), 106 deletions(-) diff --git a/configure.ac b/configure.ac index bf87f5aa..54c38ca2 100644 --- a/configure.ac +++ b/configure.ac @@ -25,15 +25,6 @@ AC_CHECK_HEADERS(sys/socket.h sys/time.h sys/utsname.h regex.h) AC_SYS_LARGEFILE -AC_ARG_WITH(socks, -[ --with-socks Build with socks support], - if test x$withval = xno; then - want_socks=no - else - want_socks=yes - fi, - want_socks=no) - AC_ARG_WITH(textui, [ --without-textui Build without text frontend], if test x$withval = xno; then @@ -202,24 +193,6 @@ else AC_ERROR([Couldn't find integer type for off_t]) fi -dnl ** -dnl ** check for socks -dnl ** - -if test "x$want_socks" = "xyes"; then - AC_CHECK_LIB(socks, connect, [ - AC_DEFINE(HAVE_SOCKS,, Build with socks support) - LIBS="$LIBS -lsocks" - AC_CHECK_HEADER(socks.h, [ - AC_DEFINE(HAVE_SOCKS_H) - CFLAGS="$CFLAGS -DSOCKS" - AC_MSG_RESULT(["socks5 library found, building with it"]) - ], [ - AC_MSG_RESULT(["socks4 library found, building with it"]) - CFLAGS="$CFLAGS -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dgetpeername=Rgetpeername -Dbind=Rbind -Daccept=Raccept -Dlisten=Rlisten -Dselect=Rselect" - ]) - ]) -fi dnl ** dnl ** OpenSSL checks diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index e861ad74..7b04a26c 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -17,7 +17,6 @@ -tls_ciphers: TLS cipher suite preference lists. -tls_pinned_cert: Pinned x509 certificate fingerprint. -tls_pinned_pubkey: Pinned public key fingerprint. - -noproxy: Ignores the global proxy configuration. -network: The network this connection belongs to. -host: The hostname you would like to connect from. -rawlog: Immediately open rawlog after connecting. diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 60870111..396bb988 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -36,7 +36,6 @@ -cmdmax: Specifies the maximum number of commands to perform before starting the internal flood protection. -port: Specifies the port to connect to the server. - -noproxy: Ignores the global proxy configuration. -rawlog: Immediately open rawlog after connecting. -noautosendcmd: Doesn't execute autosendcmd. @@ -64,7 +63,7 @@ /SERVER CONNECT chat.freenode.net /SERVER CONNECT +chat.freenode.net /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -port 6667 -4 -network Freenode -noproxy orwell.freenode.net + /SERVER ADD -! -auto -host staff.irssi.org -port 6667 -4 -network Freenode orwell.freenode.net /SERVER MODIFY -network Freenode -noauto orwell.freenode.net /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index c737b810..4b0b7b2a 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -131,10 +131,6 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) conn->no_autosendcmd = TRUE; - if (g_hash_table_lookup(optlist, "noproxy") != NULL) - g_free_and_null(conn->proxy); - - *rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog")); host = g_hash_table_lookup(optlist, "host"); @@ -153,7 +149,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] [-ssl_ciphers ] [-!] [-noautosendcmd] - [-noproxy] [-network ] [-host ] + [-network ] [-host ] [-rawlog ]
| [ [ []]] */ /* NOTE: -network replaces the old -ircnet flag. */ @@ -260,7 +256,7 @@ static void sig_default_command_server(const char *data, SERVER_REC *server, [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] [-ssl_ciphers ] [-!] [-noautosendcmd] - [-noproxy] [-network ] [-host ] + [-network ] [-host ] [-rawlog ] [+]
| [ [ []]] */ /* NOTE: -network replaces the old -ircnet flag. */ @@ -498,7 +494,7 @@ void chat_commands_init(void) signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server); signal_add("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); - command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); + command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host -rawlog noautosendcmd"); command_set_options("msg", "channel nick"); } diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h index fa348769..914087f1 100644 --- a/src/core/server-connect-rec.h +++ b/src/core/server-connect-rec.h @@ -5,11 +5,6 @@ int chat_type; /* chat_protocol_lookup(xx) */ int refcount; -/* if we're connecting via proxy, or just NULLs */ -char *proxy; -int proxy_port; -char *proxy_string, *proxy_string_after, *proxy_password; - unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */ char *tag; /* try to keep this tag when connected to server */ char *address; diff --git a/src/core/server-setup-rec.h b/src/core/server-setup-rec.h index e6b0431c..dc3d7906 100644 --- a/src/core/server-setup-rec.h +++ b/src/core/server-setup-rec.h @@ -26,7 +26,6 @@ IPADDR *own_ip4, *own_ip6; /* resolved own_address if not NULL */ time_t last_connect; /* to avoid reconnecting too fast.. */ unsigned int autoconnect:1; -unsigned int no_proxy:1; unsigned int last_failed:1; /* if last connection attempt failed */ unsigned int banned:1; /* if we're banned from this server */ unsigned int dns_error:1; /* DNS said the host doesn't exist */ diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 1727704c..63d82adc 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -157,12 +157,6 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) server_connect_ref(dest); dest->type = module_get_uniq_id("SERVER CONNECT", 0); dest->reconnection = src->reconnection; - dest->proxy = g_strdup(src->proxy); - dest->proxy_port = src->proxy_port; - dest->proxy_string = g_strdup(src->proxy_string); - dest->proxy_string_after = g_strdup(src->proxy_string_after); - dest->proxy_password = g_strdup(src->proxy_password); - dest->tag = g_strdup(src->tag); if (connect_info) { diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 9492c58c..2f4ea059 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -129,15 +129,6 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn, conn->username = g_strdup(settings_get_str("user_name")); conn->realname = g_strdup(settings_get_str("real_name")); - /* proxy settings */ - if (settings_get_bool("use_proxy")) { - conn->proxy = g_strdup(settings_get_str("proxy_address")); - conn->proxy_port = settings_get_int("proxy_port"); - conn->proxy_string = g_strdup(settings_get_str("proxy_string")); - conn->proxy_string_after = g_strdup(settings_get_str("proxy_string_after")); - conn->proxy_password = g_strdup(settings_get_str("proxy_password")); - } - /* source IP */ if (source_host_ip4 != NULL) { conn->own_ip4 = g_new(IPADDR, 1); @@ -159,9 +150,6 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn, sserver->last_connect = time(NULL); - if (sserver->no_proxy) - g_free_and_null(conn->proxy); - if (sserver->family != 0 && conn->family == 0) conn->family = sserver->family; if (sserver->port > 0 && conn->port <= 0) @@ -456,7 +444,6 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); - rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE); rec->own_host = g_strdup(config_node_get_str(node, "own_host", NULL)); signal_emit("server setup read", 2, rec, node); @@ -525,8 +512,6 @@ static void server_setup_save(SERVER_SETUP_REC *rec) if (rec->autoconnect) iconfig_node_set_bool(node, "autoconnect", TRUE); - if (rec->no_proxy) - iconfig_node_set_bool(node, "no_proxy", TRUE); signal_emit("server setup saved", 2, rec, node); } @@ -640,13 +625,6 @@ void servers_setup_init(void) settings_add_str("server", "user_name", NULL); settings_add_str("server", "real_name", NULL); - settings_add_bool("proxy", "use_proxy", FALSE); - settings_add_str("proxy", "proxy_address", ""); - settings_add_int("proxy", "proxy_port", 6667); - settings_add_str("proxy", "proxy_string", "CONNECT %s %d"); - settings_add_str("proxy", "proxy_string_after", ""); - settings_add_str("proxy", "proxy_password", ""); - setupservers = NULL; source_host_ip4 = source_host_ip6 = NULL; old_source_host = NULL; diff --git a/src/core/servers.c b/src/core/servers.c index b9faab81..23ec4f94 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -217,8 +217,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, if (ip != NULL) { own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4; - port = server->connrec->proxy != NULL ? - server->connrec->proxy_port : server->connrec->port; + port = server->connrec->port; handle = server->connrec->use_tls ? net_connect_ip_ssl(ip, port, own_ip, server) : net_connect_ip(ip, port, own_ip); } else { @@ -414,8 +413,7 @@ int server_start_connect(SERVER_REC *server) server->connect_pipe[0] = g_io_channel_new(fd[0]); server->connect_pipe[1] = g_io_channel_new(fd[1]); - connect_address = server->connrec->proxy != NULL ? - server->connrec->proxy : server->connrec->address; + connect_address = server->connrec->address; server->connect_pid = net_gethostbyname_nonblock(connect_address, server->connect_pipe[1], @@ -610,11 +608,6 @@ void server_connect_unref(SERVER_CONNECT_REC *conn) if (conn->connect_handle != NULL) net_disconnect(conn->connect_handle); - g_free_not_null(conn->proxy); - g_free_not_null(conn->proxy_string); - g_free_not_null(conn->proxy_string_after); - g_free_not_null(conn->proxy_password); - g_free_not_null(conn->tag); g_free_not_null(conn->address); g_free_not_null(conn->chatnet); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index f4c1d3ee..37a176ac 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -217,8 +217,6 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; - if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE; - if (g_hash_table_lookup(optlist, "noproxy")) rec->no_proxy = TRUE; if (*password != '\0' && g_strcmp0(password, "-") != 0) rec->password = g_strdup(password); value = g_hash_table_lookup(optlist, "host"); @@ -434,8 +432,8 @@ void fe_server_init(void) command_bind_first("server", NULL, (SIGNAL_FUNC) server_command); command_bind_first("disconnect", NULL, (SIGNAL_FUNC) server_command); - command_set_options("server add", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); - command_set_options("server modify", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); + command_set_options("server add", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto -host -port noautosendcmd"); + command_set_options("server modify", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto -host -port noautosendcmd"); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting); diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index c4435d8f..017934d9 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -106,8 +106,6 @@ static void cmd_server_list(const char *data) g_string_append(str, "(pass), "); if (rec->autoconnect) g_string_append(str, "autoconnect, "); - if (rec->no_proxy) - g_string_append(str, "noproxy, "); if (rec->use_tls) { g_string_append(str, "tls, "); if (rec->tls_cert) { diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 3117e345..8d148b1f 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -219,19 +219,6 @@ static void server_init(IRC_SERVER_REC *server) conn = server->connrec; - if (conn->proxy != NULL && conn->proxy_password != NULL && - *conn->proxy_password != '\0') { - cmd = g_strdup_printf("PASS %s", conn->proxy_password); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } - - if (conn->proxy != NULL && conn->proxy_string != NULL) { - cmd = g_strdup_printf(conn->proxy_string, conn->address, conn->port); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } - if (conn->sasl_mechanism != SASL_MECHANISM_NONE) cap_toggle(server, "sasl", TRUE); @@ -271,12 +258,6 @@ static void server_init(IRC_SERVER_REC *server) g_free(cmd); g_free(username); - if (conn->proxy != NULL && conn->proxy_string_after != NULL) { - cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } - server->isupport = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 8b3b0c45..1b954ec9 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -165,7 +165,6 @@ static void perl_client_fill_hash(HV *hv, CLIENT_REC *client) { (void) hv_store(hv, "nick", 4, new_pv(client->nick), 0); (void) hv_store(hv, "addr", 4, new_pv(client->addr), 0); - (void) hv_store(hv, "proxy_address", 13, new_pv(client->proxy_address), 0); (void) hv_store(hv, "server", 6, iobject_bless(client->server), 0); (void) hv_store(hv, "pass_sent", 9, newSViv(client->pass_sent), 0); (void) hv_store(hv, "user_sent", 9, newSViv(client->user_sent), 0); From dbc7896cadb02f5e2fc85caa07ac673f10acc996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 18 Oct 2016 22:22:22 +0200 Subject: [PATCH 0014/1198] Add /PROXY command for configuring proxy servers. --- src/common.h | 2 + src/core/Makefile.am | 5 + src/core/core.c | 6 ++ src/core/proxy-protocols.c | 134 ++++++++++++++++++++++++ src/core/proxy-protocols.h | 45 +++++++++ src/core/proxy-rec.h | 7 ++ src/core/proxy.c | 151 ++++++++++++++++++++++++++++ src/core/proxy.h | 52 ++++++++++ src/fe-common/core/Makefile.am | 1 + src/fe-common/core/fe-common-core.c | 5 + src/fe-common/core/fe-proxy.c | 124 +++++++++++++++++++++++ src/fe-common/core/module-formats.c | 10 ++ src/fe-common/core/module-formats.h | 11 +- 13 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 src/core/proxy-protocols.c create mode 100644 src/core/proxy-protocols.h create mode 100644 src/core/proxy-rec.h create mode 100644 src/core/proxy.c create mode 100644 src/core/proxy.h create mode 100644 src/fe-common/core/fe-proxy.c diff --git a/src/common.h b/src/common.h index 0a7b72f0..aa7e97e9 100644 --- a/src/common.h +++ b/src/common.h @@ -103,6 +103,8 @@ typedef struct _RAWLOG_REC RAWLOG_REC; typedef struct _CHAT_PROTOCOL_REC CHAT_PROTOCOL_REC; typedef struct _CHATNET_REC CHATNET_REC; +typedef struct _PROXY_REC PROXY_REC; +typedef struct _PROXY_PROTOCOL_REC PROXY_PROTOCOL_REC; typedef struct _SERVER_REC SERVER_REC; typedef struct _WI_ITEM_REC WI_ITEM_REC; typedef struct _CHANNEL_REC CHANNEL_REC; diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 10bd035a..5376334e 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -34,6 +34,8 @@ libcore_a_SOURCES = \ nicklist.c \ nickmatch-cache.c \ pidwait.c \ + proxy.c \ + proxy-protocols.c \ queries.c \ rawlog.c \ recode.c \ @@ -53,6 +55,7 @@ structure_headers = \ channel-rec.h \ channel-setup-rec.h \ chatnet-rec.h \ + proxy-rec.h \ query-rec.h \ server-rec.h \ server-setup-rec.h \ @@ -86,6 +89,8 @@ pkginc_core_HEADERS = \ nicklist.h \ nickmatch-cache.h \ pidwait.h \ + proxy.h \ + proxy-protocols.h \ queries.h \ rawlog.h \ recode.h \ diff --git a/src/core/core.c b/src/core/core.c index bf7cdd6b..d5bbe91e 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -33,6 +33,8 @@ #include "chat-protocols.h" #include "servers.h" #include "chatnets.h" +#include "proxy.h" +#include "proxy-protocols.h" #include "commands.h" #include "expandos.h" #include "write-buffer.h" @@ -239,6 +241,8 @@ void core_init(void) chat_protocols_init(); chatnets_init(); expandos_init(); + proxy_init(); + proxy_protocols_init(); ignore_init(); servers_init(); write_buffer_init(); @@ -290,6 +294,8 @@ void core_deinit(void) ignore_deinit(); expandos_deinit(); chatnets_deinit(); + proxy_deinit(); + proxy_protocols_deinit(); chat_protocols_deinit(); session_deinit(); diff --git a/src/core/proxy-protocols.c b/src/core/proxy-protocols.c new file mode 100644 index 00000000..d5259133 --- /dev/null +++ b/src/core/proxy-protocols.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * 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 "module.h" +#include "proxy-protocols.h" +#include "signals.h" + +GSList *proxy_protocols; + +static void proxy_protocol_destroy(PROXY_PROTOCOL_REC *rec) +{ + g_return_if_fail(rec != NULL); + + proxy_protocols = g_slist_remove(proxy_protocols, rec); + + signal_emit("proxy protocol destroyed", 1, rec); + + g_free(rec->name); + g_free(rec); +} + +/* Register new Proxy Protocol. */ +PROXY_PROTOCOL_REC *proxy_protocol_register(PROXY_PROTOCOL_REC *rec) +{ + PROXY_PROTOCOL_REC *newrec; + int created; + + g_return_val_if_fail(rec != NULL, NULL); + + newrec = proxy_protocol_find(rec->name); + created = newrec == NULL; + + if (created) { + newrec = g_new0(PROXY_PROTOCOL_REC, 1); + proxy_protocols = g_slist_append(proxy_protocols, newrec); + } else { + g_free(newrec->name); + } + + memcpy(newrec, rec, sizeof(PROXY_PROTOCOL_REC)); + + newrec->id = module_get_uniq_id_str("PROXY PROTOCOL", rec->name); + newrec->name = g_strdup(rec->name); + + if (created) + signal_emit("proxy protocol created", 1, newrec); + else + signal_emit("proxy protocol updated", 1, newrec); + + return newrec; +} + +/* Unregister Proxy Protocol. */ +void proxy_protocol_unregister(const char *name) +{ + PROXY_PROTOCOL_REC *rec; + + g_return_if_fail(name != NULL); + + rec = proxy_protocol_find(name); + + if (rec != NULL) + proxy_protocol_destroy(rec); +} + +/* Lookup Proxy Protocols. */ +int proxy_protocol_lookup(const char *name) +{ + PROXY_PROTOCOL_REC *rec; + + g_return_val_if_fail(name != NULL, -1); + + rec = proxy_protocol_find(name); + + return rec == NULL ? -1 : rec->id; +} + +PROXY_PROTOCOL_REC *proxy_protocol_find(const char *name) +{ + GSList *tmp; + + g_return_val_if_fail(name != NULL, NULL); + + for (tmp = proxy_protocols; tmp != NULL; tmp = tmp->next) { + PROXY_PROTOCOL_REC *rec = tmp->data; + + if (g_ascii_strcasecmp(rec->name, name) == 0) + return rec; + } + + return NULL; +} + +PROXY_PROTOCOL_REC *proxy_protocol_find_id(int id) +{ + GSList *tmp; + + g_return_val_if_fail(id > 0, NULL); + + for (tmp = proxy_protocols; tmp != NULL; tmp = tmp->next) { + PROXY_PROTOCOL_REC *rec = tmp->data; + + if (rec->id == id) + return rec; + } + + return NULL; +} + +void proxy_protocols_init(void) +{ + proxy_protocols = NULL; +} + +void proxy_protocols_deinit(void) +{ + while (proxy_protocols != NULL) + proxy_protocol_destroy(proxy_protocols->data); +} diff --git a/src/core/proxy-protocols.h b/src/core/proxy-protocols.h new file mode 100644 index 00000000..22e9793a --- /dev/null +++ b/src/core/proxy-protocols.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * 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 + */ + +#ifndef __PROXY_PROTOCOLS_H +#define __PROXY_PROTOCOLS_H + +#include "modules.h" + +struct _PROXY_PROTOCOL_REC { + int id; + char *name; +}; + +extern GSList *proxy_protocols; + +/* Register new Proxy Protocol. */ +PROXY_PROTOCOL_REC *proxy_protocol_register(PROXY_PROTOCOL_REC *rec); + +/* Unregister Proxy Protocol. */ +void proxy_protocol_unregister(const char *name); + +/* Lookup Proxy Protocols. */ +int proxy_protocol_lookup(const char *name); +PROXY_PROTOCOL_REC *proxy_protocol_find(const char *name); +PROXY_PROTOCOL_REC *proxy_protocol_find_id(int id); + +void proxy_protocols_init(void); +void proxy_protocols_deinit(void); + +#endif diff --git a/src/core/proxy-rec.h b/src/core/proxy-rec.h new file mode 100644 index 00000000..986de8ff --- /dev/null +++ b/src/core/proxy-rec.h @@ -0,0 +1,7 @@ +int type; /* module_get_uniq_id("PROXY", 0); */ +int proxy_type; /* proxy_protocol_lookup(); */ + +char *name; + +char *address; +int port; diff --git a/src/core/proxy.c b/src/core/proxy.c new file mode 100644 index 00000000..18f51d66 --- /dev/null +++ b/src/core/proxy.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * 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 "module.h" +#include "signals.h" +#include "lib-config/iconfig.h" +#include "settings.h" + +#include "proxy.h" + +GSList *proxies; + +static void proxy_config_save(PROXY_REC *proxy) +{ + CONFIG_NODE *node; + + node = iconfig_node_traverse("proxies", TRUE); + node = iconfig_node_section(node, proxy->name, NODE_TYPE_BLOCK); + iconfig_node_clear(node); + + iconfig_node_set_str(node, "address", proxy->address); + iconfig_node_set_int(node, "port", proxy->port); + + signal_emit("proxy saved", 2, proxy, node); +} + +static void proxy_config_remove(PROXY_REC *proxy) +{ + CONFIG_NODE *node; + + node = iconfig_node_traverse("proxies", FALSE); + + if (node != NULL) + iconfig_node_set_str(node, proxy->name, NULL); +} + +static void read_proxy(CONFIG_NODE *node) +{ + PROXY_REC *rec; + + if (node == NULL || node->key == NULL) + return; + + rec = g_new(PROXY_REC, 1); + rec->name = g_strdup(node->key); + rec->address = g_strdup(config_node_get_str(node, "address", NULL)); + rec->port = config_node_get_int(node, "port", 0); + + proxies = g_slist_append(proxies, rec); + signal_emit("proxy read", 2, rec, node); +} + +static void read_proxies(void) +{ + CONFIG_NODE *node; + GSList *tmp; + + while (proxies != NULL) + proxy_destroy(proxies->data); + + node = iconfig_node_traverse("proxies", FALSE); + + if (node != NULL) { + for (tmp = config_node_first(node->value); tmp != NULL; tmp = config_node_next(tmp)) + read_proxy(tmp->data); + } +} + +void proxy_create(PROXY_REC *proxy) +{ + g_return_if_fail(proxy != NULL); + + proxy->type = module_get_uniq_id("PROXY", 0); + + if (g_slist_find(proxies, proxy) == NULL) + proxies = g_slist_append(proxies, proxy); + + proxy_config_save(proxy); + signal_emit("proxy created", 1, proxy); +} + +void proxy_remove(PROXY_REC *proxy) +{ + g_return_if_fail(proxy != NULL); + + signal_emit("proxy removed", 1, proxy); + + proxy_config_remove(proxy); + proxy_destroy(proxy); +} + +void proxy_destroy(PROXY_REC *proxy) +{ + g_return_if_fail(IS_PROXY(proxy)); + + proxies = g_slist_remove(proxies, proxy); + signal_emit("proxy destroyed", 1, proxy); + + g_free(proxy->name); + g_free(proxy->address); + g_free(proxy); +} + +PROXY_REC *proxy_find(const char *name) +{ + GSList *tmp; + + g_return_val_if_fail(name != NULL, NULL); + + for (tmp = proxies; tmp != NULL; tmp = tmp->next) { + PROXY_REC *rec = tmp->data; + + if (g_ascii_strcasecmp(rec->name, name) == 0) + return rec; + } + + return NULL; +} + +void proxy_init(void) +{ + proxies = NULL; + + settings_add_str("proxy", "default_proxy", NULL); + + signal_add("setup reread", (SIGNAL_FUNC)read_proxies); + signal_add("irssi init read settings", (SIGNAL_FUNC)read_proxies); +} + +void proxy_deinit(void) +{ + module_uniq_destroy("PROXY"); + + signal_remove("setup reread", (SIGNAL_FUNC)read_proxies); + signal_remove("irssi init read settings", (SIGNAL_FUNC)read_proxies); +} diff --git a/src/core/proxy.h b/src/core/proxy.h new file mode 100644 index 00000000..46732806 --- /dev/null +++ b/src/core/proxy.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * 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 + */ + +#ifndef __PROXY_H +#define __PROXY_H + +#include "modules.h" + +#define PROXY(proxy) \ + MODULE_CHECK_CAST(proxy, PROXY_REC, type, "PROXY") + +#define IS_PROXY(proxy) \ + (PROXY(proxy) ? TRUE : FALSE) + +struct _PROXY_REC { +#include "proxy-rec.h" +}; + +extern GSList *proxies; + +/* Add a proxy to the proxy list. */ +void proxy_create(PROXY_REC *proxy); + +/* Remove a proxy from the proxy list. */ +void proxy_remove(PROXY_REC *proxy); + +/* Destroy the proxy structure without removing it from configs. */ +void proxy_destroy(PROXY_REC *proxy); + +/* Find a proxy by name. */ +PROXY_REC *proxy_find(const char *name); + +void proxy_init(void); +void proxy_deinit(void); + +#endif + diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 6efff411..08d6edc7 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -22,6 +22,7 @@ libfe_common_core_a_SOURCES = \ fe-messages.c \ fe-modules.c \ fe-queries.c \ + fe-proxy.c \ fe-server.c \ fe-settings.c \ fe-tls.c \ diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 512fc84c..937f4199 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -82,6 +82,9 @@ void fe_messages_deinit(void); void fe_modules_init(void); void fe_modules_deinit(void); +void fe_proxy_init(void); +void fe_proxy_deinit(void); + void fe_server_init(void); void fe_server_deinit(void); @@ -176,6 +179,7 @@ void fe_common_core_init(void) fe_ignore_init(); fe_log_init(); fe_modules_init(); + fe_proxy_init(); fe_server_init(); fe_settings_init(); fe_tls_init(); @@ -218,6 +222,7 @@ void fe_common_core_deinit(void) fe_ignore_deinit(); fe_log_deinit(); fe_modules_deinit(); + fe_proxy_deinit(); fe_server_deinit(); fe_settings_deinit(); fe_tls_deinit(); diff --git a/src/fe-common/core/fe-proxy.c b/src/fe-common/core/fe-proxy.c new file mode 100644 index 00000000..2ded96bf --- /dev/null +++ b/src/fe-common/core/fe-proxy.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * 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 "module.h" +#include "signals.h" +#include "commands.h" +#include "network.h" +#include "levels.h" +#include "settings.h" +#include "proxy.h" + +#include "module-formats.h" +#include "printtext.h" + +/* SYNTAX: PROXY ADD
*/ +static void cmd_proxy_add(const char *data) +{ + char *name, *type, *address, *port; + GHashTable *optlist; + PROXY_REC *rec; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS, + "proxy add", &optlist, &name, &type, &address, &port)) + return; + + if (*name == '\0' || *type == '\0' || *address == '\0' || *port == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + rec = proxy_find(name); + + if (rec == NULL) { + rec = g_new0(PROXY_REC, 1); + rec->name = g_strdup(name); + } else { + g_free_and_null(rec->address); + } + + rec->address = g_strdup(address); + rec->port = atoi(port); + + proxy_create(rec); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_PROXY_ADDED, name); + + cmd_params_free(free_arg); +} + +/* SYNTAX: PROXY REMOVE */ +static void cmd_proxy_remove(const char *data) +{ + PROXY_REC *rec; + + if (*data == '\0') + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + rec = proxy_find(data); + + if (rec == NULL) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_PROXY_NOT_FOUND, data); + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_PROXY_REMOVED, data); + proxy_remove(rec); + } +} + +/* SYNTAX: PROXY LIST */ +static void cmd_proxy_list(void) +{ + GString *str; + GSList *tmp; + + str = g_string_new(NULL); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_PROXY_HEADER); + + for (tmp = proxies; tmp != NULL; tmp = tmp->next) { + PROXY_REC *rec = tmp->data; + + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_PROXY_LINE, rec->name, rec->address, rec->port, str->str); + } + + g_string_free(str, TRUE); + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_PROXY_FOOTER); +} + +static void cmd_proxy(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + if (*data == '\0') + cmd_proxy_list(); + else + command_runsub("proxy", data, server, item); +} + +void fe_proxy_init(void) +{ + command_bind("proxy", NULL, (SIGNAL_FUNC)cmd_proxy); + command_bind("proxy list", NULL, (SIGNAL_FUNC)cmd_proxy_list); + command_bind("proxy add", NULL, (SIGNAL_FUNC)cmd_proxy_add); + command_bind("proxy remove", NULL, (SIGNAL_FUNC)cmd_proxy_remove); + + command_set_options("proxy add", ""); +} + +void fe_proxy_deinit(void) +{ + command_unbind("proxy", (SIGNAL_FUNC)cmd_proxy); + command_unbind("proxy list", (SIGNAL_FUNC)cmd_proxy_list); + command_unbind("proxy add", (SIGNAL_FUNC)cmd_proxy_add); + command_unbind("proxy remove", (SIGNAL_FUNC)cmd_proxy_remove); +} diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index da9705be..4678e407 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -304,5 +304,15 @@ FORMAT_REC fecommon_core_formats[] = { { "tls_cert_fingerprint", "Certificate Fingerprint: {hilight $0} ({hilight $1})", 2, { 0, 0 } }, { "tls_protocol_version", "Protocol: {hilight $0} ({hilight $1} bit, {hilight $2})", 3, { 0, 1, 0 } }, + /* ---- */ + { NULL, "Proxy", 0 }, + + { "proxy_added", "Proxy $0 added", 1, { 0 } }, + { "proxy_not_found", "Proxy $0 not found", 1, { 0 } }, + { "proxy_removed", "Proxy $0 removed", 1, { 0 } }, + { "proxy_header", "%#Proxy Server Port Settings", 0 }, + { "proxy_line", "%#%|$[!10]0 $[20]1 $[5]2 $3", 4, { 0, 0, 1, 0 } }, + { "proxy_footer", "", 0 }, + { NULL, NULL, 0 } }; diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index a9ed28c5..bec948e9 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -266,7 +266,16 @@ enum { TXT_TLS_CERT_ISSUER, TXT_TLS_PUBKEY_FINGERPRINT, TXT_TLS_CERT_FINGERPRINT, - TXT_TLS_PROTOCOL_VERSION + TXT_TLS_PROTOCOL_VERSION, + + TXT_FILL_16, + + TXT_PROXY_ADDED, + TXT_PROXY_NOT_FOUND, + TXT_PROXY_REMOVED, + TXT_PROXY_HEADER, + TXT_PROXY_LINE, + TXT_PROXY_FOOTER }; extern FORMAT_REC fecommon_core_formats[]; From 3a96dfac0383a17c8da667fb4b2fbf2f0148ac90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 18 Oct 2016 22:33:26 +0200 Subject: [PATCH 0015/1198] Add support for -proxy to /SERVER and /CONNECT. --- src/core/chat-commands.c | 6 +++++- src/core/server-connect-rec.h | 2 ++ src/core/server-setup-rec.h | 2 ++ src/core/servers-reconnect.c | 2 ++ src/core/servers-setup.c | 7 ++++++- src/core/session.c | 2 ++ src/fe-common/core/fe-server.c | 8 ++++++-- src/fe-common/irc/fe-irc-server.c | 4 +++- 8 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 4b0b7b2a..385459ab 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -124,6 +124,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, conn->tls_verify = TRUE; if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) conn->use_tls = TRUE; + if ((tmp = g_hash_table_lookup(optlist, "proxy")) != NULL) + conn->proxy = g_strdup(tmp); if (g_hash_table_lookup(optlist, "!") != NULL) conn->no_autojoin_channels = TRUE; @@ -148,6 +150,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, /* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] [-ssl_ciphers ] + [-proxy ] [-!] [-noautosendcmd] [-network ] [-host ] [-rawlog ] @@ -255,6 +258,7 @@ static void sig_default_command_server(const char *data, SERVER_REC *server, /* SYNTAX: SERVER [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] [-ssl_ciphers ] + [-proxy ] [-!] [-noautosendcmd] [-network ] [-host ] [-rawlog ] @@ -494,7 +498,7 @@ void chat_commands_init(void) signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server); signal_add("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); - command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host -rawlog noautosendcmd"); + command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host +proxy -rawlog noautosendcmd"); command_set_options("msg", "channel nick"); } diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h index 914087f1..f69f6a53 100644 --- a/src/core/server-connect-rec.h +++ b/src/core/server-connect-rec.h @@ -27,6 +27,8 @@ char *tls_ciphers; char *tls_pinned_cert; char *tls_pinned_pubkey; +char *proxy; + GIOChannel *connect_handle; /* connect using this handle */ /* when reconnecting, the old server status */ diff --git a/src/core/server-setup-rec.h b/src/core/server-setup-rec.h index dc3d7906..360c9759 100644 --- a/src/core/server-setup-rec.h +++ b/src/core/server-setup-rec.h @@ -20,6 +20,8 @@ char *tls_ciphers; char *tls_pinned_cert; char *tls_pinned_pubkey; +char *proxy; + char *own_host; /* address to use when connecting this server */ IPADDR *own_ip4, *own_ip6; /* resolved own_address if not NULL */ diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 63d82adc..0cbffa45 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -196,6 +196,8 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) dest->tls_pinned_cert = g_strdup(src->tls_pinned_cert); dest->tls_pinned_pubkey = g_strdup(src->tls_pinned_pubkey); + dest->proxy = g_strdup(src->proxy); + return dest; } diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 2f4ea059..4b636953 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -26,6 +26,7 @@ #include "chat-protocols.h" #include "chatnets.h" +#include "proxy.h" #include "servers.h" #include "servers-setup.h" @@ -173,6 +174,8 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn, conn->tls_pinned_cert = g_strdup(sserver->tls_pinned_cert); if (conn->tls_pinned_pubkey == NULL && sserver->tls_pinned_pubkey != NULL && sserver->tls_pinned_pubkey[0] != '\0') conn->tls_pinned_pubkey = g_strdup(sserver->tls_pinned_pubkey); + if (conn->proxy == NULL && sserver->proxy != NULL && sserver->proxy[0] != '\0') + conn->proxy = g_strdup(sserver->proxy); server_setup_fill_reconn(conn, sserver); @@ -445,6 +448,7 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); rec->own_host = g_strdup(config_node_get_str(node, "own_host", NULL)); + rec->proxy = g_strdup(config_node_get_str(node, "proxy", NULL)); signal_emit("server setup read", 2, rec, node); @@ -503,7 +507,7 @@ static void server_setup_save(SERVER_SETUP_REC *rec) iconfig_node_set_str(node, "tls_ciphers", rec->tls_ciphers); iconfig_node_set_str(node, "tls_pinned_cert", rec->tls_pinned_cert); iconfig_node_set_str(node, "tls_pinned_pubkey", rec->tls_pinned_pubkey); - + iconfig_node_set_str(node, "proxy", rec->proxy); iconfig_node_set_str(node, "own_host", rec->own_host); iconfig_node_set_str(node, "family", @@ -553,6 +557,7 @@ static void server_setup_destroy(SERVER_SETUP_REC *rec) g_free_not_null(rec->tls_ciphers); g_free_not_null(rec->tls_pinned_cert); g_free_not_null(rec->tls_pinned_pubkey); + g_free_not_null(rec->proxy); g_free(rec->address); g_free(rec); } diff --git a/src/core/session.c b/src/core/session.c index 34190c52..d7314a04 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -168,6 +168,8 @@ static void session_save_server(SERVER_REC *server, CONFIG_REC *config, config_node_set_str(config, node, "tls_pinned_cert", server->connrec->tls_pinned_cert); config_node_set_str(config, node, "tls_pinned_pubkey", server->connrec->tls_pinned_pubkey); + config_node_set_str(config, node, "proxy", server->connrec->proxy); + handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle)); config_node_set_int(config, node, "handle", handle); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 37a176ac..d935b529 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -215,6 +215,10 @@ static void cmd_server_add_modify(const char *data, gboolean add) if ((rec->tls_cert != NULL && rec->tls_cert[0] != '\0') || rec->tls_verify == TRUE) rec->use_tls = TRUE; + value = g_hash_table_lookup(optlist, "proxy"); + if (value != NULL && *value != '\0') + rec->proxy = g_strdup(value); + if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; @@ -432,8 +436,8 @@ void fe_server_init(void) command_bind_first("server", NULL, (SIGNAL_FUNC) server_command); command_bind_first("disconnect", NULL, (SIGNAL_FUNC) server_command); - command_set_options("server add", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto -host -port noautosendcmd"); - command_set_options("server modify", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto -host -port noautosendcmd"); + command_set_options("server add", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +proxy auto noauto -host -port noautosendcmd"); + command_set_options("server modify", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +proxy auto noauto -host -port noautosendcmd"); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting); diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index 017934d9..748aae38 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -54,6 +54,7 @@ const char *get_visible_target(IRC_SERVER_REC *server, const char *target) /* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] [-ssl_ciphers ] + [-proxy ] [-auto | -noauto] [-network ] [-host ] [-cmdspeed ] [-cmdmax ] [-port ]
[ []] */ @@ -127,7 +128,6 @@ static void cmd_server_list(const char *data) g_string_append_printf(str, "tls_pinned_cert: %s, ", rec->tls_pinned_cert); if (rec->tls_pinned_pubkey) g_string_append_printf(str, "tls_pinned_pubkey: %s, ", rec->tls_pinned_pubkey); - } if (rec->max_cmds_at_once > 0) g_string_append_printf(str, "cmdmax: %d, ", rec->max_cmds_at_once); @@ -137,6 +137,8 @@ static void cmd_server_list(const char *data) g_string_append_printf(str, "querychans: %d, ", rec->max_query_chans); if (rec->own_host != NULL) g_string_append_printf(str, "host: %s, ", rec->own_host); + if (rec->proxy) + g_string_append_printf(str, "proxy: %s, ", rec->proxy); if (str->len > 1) g_string_truncate(str, str->len-2); printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_LINE, From 77aab7905791823f6ce2c19b4aaacd4231324841 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Dec 2016 21:16:37 +0100 Subject: [PATCH 0016/1198] avoid server_disconnect Closes #4 --- src/irc/core/irc-nicklist.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index b22f3269..1cb1f3e9 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -314,7 +314,11 @@ static void event_whois_ircop(SERVER_REC *server, const char *data) static void event_nick_invalid(IRC_SERVER_REC *server, const char *data) { if (!server->connected) - server_disconnect((SERVER_REC *) server); + /* we used to call server_disconnect but that crashes + irssi because of undefined memory access. instead, + indicate that the connection should be dropped and + let the irc method to the clean-up. */ + server->connection_lost = server->no_reconnect = TRUE; } static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) From 508d2e0860992d6906b5a7b73017edbaa8c94d98 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Dec 2016 16:06:13 +0100 Subject: [PATCH 0017/1198] bail out if nick is NULL in irc_query_find Closes #1 --- src/irc/core/irc-queries.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/irc/core/irc-queries.c b/src/irc/core/irc-queries.c index 12861744..77a5289d 100644 --- a/src/irc/core/irc-queries.c +++ b/src/irc/core/irc-queries.c @@ -45,6 +45,8 @@ QUERY_REC *irc_query_find(IRC_SERVER_REC *server, const char *nick) { GSList *tmp; + g_return_val_if_fail(nick != NULL, NULL); + for (tmp = server->queries; tmp != NULL; tmp = tmp->next) { QUERY_REC *rec = tmp->data; From 8007e9e61d67044a6b29a266300a936e4c86fdd9 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 19 Dec 2016 09:31:38 -0500 Subject: [PATCH 0018/1198] Fix oob read on invalid utf8 in term_addstr --- src/fe-text/term-terminfo.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index b2478c62..3098a4e4 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -539,9 +539,16 @@ int term_addstr(TERM_WINDOW *window, const char *str) 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); + tmp = g_utf8_get_char_validated(ptr, -1); + /* On utf8 error, treat as single byte and try to + continue interpretting rest of string as utf8 */ + if (tmp == (gunichar)-1 || tmp == (gunichar)-2) { + len++; + ptr++; + } else { + len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1; + ptr = g_utf8_next_char(ptr); + } } } else len = raw_len; From 2f59fe206233c0f45256e9e541c121f4d63385dd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Dec 2016 22:03:46 +0100 Subject: [PATCH 0019/1198] add some sequence helper functions --- src/fe-common/core/fe-windows.c | 85 +++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 25 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index ff45f141..d02048be 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -42,6 +42,16 @@ static int daytag; static int daycheck; /* 0 = don't check, 1 = time is 00:00, check, 2 = time is 00:00, already checked */ +static GSequenceIter *windows_seq_begin(void) +{ + return g_sequence_get_begin_iter(windows_seq); +} + +static GSequenceIter *windows_seq_end(void) +{ + return g_sequence_get_end_iter(windows_seq); +} + static int window_get_new_refnum(void) { WINDOW_REC *win; @@ -49,8 +59,8 @@ static int window_get_new_refnum(void) int refnum; refnum = 1; - for (iter = g_sequence_get_begin_iter(windows_seq), - end = g_sequence_get_end_iter(windows_seq); + for (iter = windows_seq_begin(), + end = windows_seq_end(); iter != end; @@ -67,6 +77,11 @@ static int window_get_new_refnum(void) return refnum; } +static GSequenceIter *windows_seq_insert(WINDOW_REC *rec) +{ + return g_sequence_insert_sorted(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); +} + WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) { WINDOW_REC *rec; @@ -76,7 +91,7 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) rec->level = settings_get_level("window_default_level"); windows = g_slist_prepend(windows, rec); - g_sequence_insert_sorted(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); + windows_seq_insert(rec); signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic)); if (item != NULL) window_item_add(rec, item, automatic); @@ -107,6 +122,16 @@ static int window_refnum_lookup(WINDOW_REC *window, void *refnum_p) return window->refnum == refnum ? 0 : window->refnum < refnum ? -1 : 1; } +static GSequenceIter *windows_seq_refnum_lookup(int refnum) +{ + return g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); +} + +static void windows_seq_changed(GSequenceIter *iter) +{ + g_sequence_sort_changed(iter, (GCompareDataFunc)window_refnum_cmp, NULL); +} + /* removed_refnum was removed from the windows list, pack the windows so there won't be any holes. If there is any holes after removed_refnum, leave the windows behind it alone. */ @@ -117,9 +142,9 @@ static void windows_pack(int removed_refnum) GSequenceIter *iter, *end; refnum = removed_refnum+1; - end = g_sequence_get_end_iter(windows_seq); - iter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); - if (iter == NULL) iter = end; + end = windows_seq_end(); + iter = windows_seq_refnum_lookup(refnum); + if (iter == NULL) return; for (; iter != end; refnum++, iter = g_sequence_iter_next(iter)) { window = g_sequence_get(iter); @@ -128,10 +153,15 @@ static void windows_pack(int removed_refnum) break; window_set_refnum0(window, refnum-1); - g_sequence_sort_changed(iter, (GCompareDataFunc)window_refnum_cmp, NULL); + windows_seq_changed(iter); } } +static GSequenceIter *windows_seq_window_lookup(WINDOW_REC *rec) +{ + return g_sequence_lookup(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); +} + void window_destroy(WINDOW_REC *window) { GSequenceIter *iter; @@ -140,7 +170,7 @@ void window_destroy(WINDOW_REC *window) if (window->destroying) return; window->destroying = TRUE; windows = g_slist_remove(windows, window); - iter = g_sequence_lookup(windows_seq, window, (GCompareDataFunc)window_refnum_cmp, NULL); + iter = windows_seq_window_lookup(window); if (iter != NULL) g_sequence_remove(iter); if (active_win == window) { @@ -223,18 +253,18 @@ void window_change_server(WINDOW_REC *window, void *server) void window_set_refnum(WINDOW_REC *window, int refnum) { - GSequenceIter *oiter, *witer; + GSequenceIter *other_iter, *window_iter; int old_refnum; g_return_if_fail(window != NULL); g_return_if_fail(refnum >= 1); if (window->refnum == refnum) return; - oiter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); - witer = g_sequence_lookup(windows_seq, GINT_TO_POINTER(window->refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + other_iter = windows_seq_refnum_lookup(refnum); + window_iter = windows_seq_refnum_lookup(window->refnum); - if (oiter != NULL) { - WINDOW_REC *rec = g_sequence_get(oiter); + if (other_iter != NULL) { + WINDOW_REC *rec = g_sequence_get(other_iter); rec->refnum = window->refnum; signal_emit("window refnum changed", 2, rec, GINT_TO_POINTER(refnum)); @@ -244,10 +274,10 @@ void window_set_refnum(WINDOW_REC *window, int refnum) window->refnum = refnum; signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum)); - if (witer != NULL && oiter != NULL) { - g_sequence_swap(oiter, witer); + if (window_iter != NULL && other_iter != NULL) { + g_sequence_swap(other_iter, window_iter); } else { - g_sequence_sort_changed(witer, (GCompareDataFunc)window_refnum_cmp, NULL); + windows_seq_changed(window_iter); } } @@ -388,7 +418,7 @@ WINDOW_REC *window_find_refnum(int refnum) { GSequenceIter *iter; - iter = g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); + iter = windows_seq_refnum_lookup(refnum); if (iter != NULL) { WINDOW_REC *rec = g_sequence_get(iter); @@ -438,12 +468,17 @@ WINDOW_REC *window_find_item(SERVER_REC *server, const char *name) return window_item_window(item); } +static GSequenceIter *windows_seq_refnum_search_right(int refnum) +{ + return g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); +} + int window_refnum_prev(int refnum, int wrap) { GSequenceIter *iter, *end; - iter = g_sequence_search(windows_seq, GINT_TO_POINTER(refnum-1), (GCompareDataFunc)window_refnum_lookup, NULL); - end = g_sequence_get_end_iter(windows_seq); + iter = windows_seq_refnum_search_right(refnum-1); + end = windows_seq_end(); if (iter != NULL) { WINDOW_REC *rec; @@ -478,8 +513,8 @@ int window_refnum_next(int refnum, int wrap) { GSequenceIter *iter, *end; - iter = g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); - end = g_sequence_get_end_iter(windows_seq); + iter = windows_seq_refnum_search_right(refnum); + end = windows_seq_end(); if (iter != NULL && iter != end) { WINDOW_REC *rec = g_sequence_get(iter); @@ -498,7 +533,7 @@ int window_refnum_next(int refnum, int wrap) if (wrap) { WINDOW_REC *rec; - iter = g_sequence_get_begin_iter(windows_seq); + iter = windows_seq_begin(); if (iter != end) { rec = g_sequence_get(iter); @@ -514,7 +549,7 @@ int windows_refnum_last(void) GSequenceIter *end, *iter; WINDOW_REC *rec; - end = g_sequence_get_end_iter(windows_seq); + end = windows_seq_end(); iter = g_sequence_iter_prev(end); if (iter != end) { rec = g_sequence_get(iter); @@ -536,8 +571,8 @@ GSList *windows_get_sorted(void) GSList *sorted; sorted = NULL; - for (iter = g_sequence_get_end_iter(windows_seq), - begin = g_sequence_get_begin_iter(windows_seq); + for (iter = windows_seq_end(), + begin = windows_seq_begin(); iter != begin; From 7dc2f832c19d8b5c682f5c9abd106ab6be53bf62 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Dec 2016 16:41:57 +0100 Subject: [PATCH 0020/1198] fix %[ --- src/fe-common/core/formats.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index a58d839a..9ce9bce5 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -68,7 +68,7 @@ static void format_expand_code(const char **format, GString *out, int *flags) if (flags == NULL) { /* flags are being ignored - skip the code */ - while (**format != ']') + while (**format != ']' && **format != '\0') (*format)++; return; } @@ -246,6 +246,10 @@ int format_expand_styles(GString *out, const char **format, int *flags) case '[': /* code */ format_expand_code(format, out, flags); + if ((*format)[0] == '\0') + /* oops, reached end prematurely */ + (*format)--; + break; case 'x': case 'X': From 9004265e5417c509e55c5141d5880ebd1e1c3281 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Dec 2016 21:01:16 +0100 Subject: [PATCH 0021/1198] clean up window_refnum_{prev,next} --- src/fe-common/core/fe-windows.c | 46 ++++++++++----------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index d02048be..97034192 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -473,35 +473,29 @@ static GSequenceIter *windows_seq_refnum_search_right(int refnum) return g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); } +static GSequenceIter *windows_seq_refnum_search_left(int refnum) +{ + GSequenceIter *iter = windows_seq_refnum_search_right(refnum-1); + return iter == windows_seq_begin() ? NULL : g_sequence_iter_prev(iter); +} + int window_refnum_prev(int refnum, int wrap) { + WINDOW_REC *rec; GSequenceIter *iter, *end; - iter = windows_seq_refnum_search_right(refnum-1); + iter = windows_seq_refnum_search_left(refnum); end = windows_seq_end(); if (iter != NULL) { - WINDOW_REC *rec; - if (iter != end) { - rec = g_sequence_get(iter); - - if (rec->refnum < refnum) - return rec->refnum; - } - - iter = g_sequence_iter_prev(iter); rec = g_sequence_get(iter); - - if (rec->refnum < refnum) - return rec->refnum; + return rec->refnum; } if (wrap) { - WINDOW_REC *rec; iter = g_sequence_iter_prev(end); if (iter != end) { rec = g_sequence_get(iter); - return rec->refnum; } } @@ -511,32 +505,21 @@ int window_refnum_prev(int refnum, int wrap) int window_refnum_next(int refnum, int wrap) { + WINDOW_REC *rec; GSequenceIter *iter, *end; iter = windows_seq_refnum_search_right(refnum); end = windows_seq_end(); - if (iter != NULL && iter != end) { - WINDOW_REC *rec = g_sequence_get(iter); - - if (rec->refnum > refnum) - return rec->refnum; - - iter = g_sequence_iter_next(iter); - if (iter != end) { - rec = g_sequence_get(iter); - - if (rec->refnum > refnum) - return rec->refnum; - } + if (iter != end) { + rec = g_sequence_get(iter); + return rec->refnum; } if (wrap) { - WINDOW_REC *rec; iter = windows_seq_begin(); if (iter != end) { rec = g_sequence_get(iter); - return rec->refnum; } } @@ -546,14 +529,13 @@ int window_refnum_next(int refnum, int wrap) int windows_refnum_last(void) { - GSequenceIter *end, *iter; WINDOW_REC *rec; + GSequenceIter *end, *iter; end = windows_seq_end(); iter = g_sequence_iter_prev(end); if (iter != end) { rec = g_sequence_get(iter); - return rec->refnum; } From 03f5dc63fee7c60bb5d5c29698c975073e365b88 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Dec 2016 21:33:51 +0100 Subject: [PATCH 0022/1198] nits --- src/fe-common/core/fe-windows.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 97034192..bd289d2f 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -59,19 +59,17 @@ static int window_get_new_refnum(void) int refnum; refnum = 1; - for (iter = windows_seq_begin(), - end = windows_seq_end(); - - iter != end; - - refnum++, - iter = g_sequence_iter_next(iter)) { + iter = windows_seq_begin(); + end = windows_seq_end(); + while (iter != end) { win = g_sequence_get(iter); - if (refnum != win->refnum) { + if (refnum != win->refnum) return refnum; - } + + refnum++; + iter = g_sequence_iter_next(iter); } return refnum; @@ -141,7 +139,7 @@ static void windows_pack(int removed_refnum) int refnum; GSequenceIter *iter, *end; - refnum = removed_refnum+1; + refnum = removed_refnum + 1; end = windows_seq_end(); iter = windows_seq_refnum_lookup(refnum); if (iter == NULL) return; @@ -152,7 +150,7 @@ static void windows_pack(int removed_refnum) if (window == NULL || window->sticky_refnum || window->refnum != refnum) break; - window_set_refnum0(window, refnum-1); + window_set_refnum0(window, refnum - 1); windows_seq_changed(iter); } } @@ -468,14 +466,19 @@ WINDOW_REC *window_find_item(SERVER_REC *server, const char *name) return window_item_window(item); } +/* search to the numerically right iterator of refnum */ static GSequenceIter *windows_seq_refnum_search_right(int refnum) { return g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); } +/* we want to find the numerically left iterator of refnum, so we + search the right of the previous refnum. but we need to figure out + the case where the iterator is already at the beginning, i.e + iter->refnum >= refnum */ static GSequenceIter *windows_seq_refnum_search_left(int refnum) { - GSequenceIter *iter = windows_seq_refnum_search_right(refnum-1); + GSequenceIter *iter = windows_seq_refnum_search_right(refnum - 1); return iter == windows_seq_begin() ? NULL : g_sequence_iter_prev(iter); } From 9a018a782c40ed9da88ae88a7f1c01265f3342de Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Dec 2016 21:36:56 +0100 Subject: [PATCH 0023/1198] sort windows_seq helpers to top --- src/fe-common/core/fe-windows.c | 84 ++++++++++++++++----------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index bd289d2f..248cd621 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -42,6 +42,12 @@ static int daytag; static int daycheck; /* 0 = don't check, 1 = time is 00:00, check, 2 = time is 00:00, already checked */ +static int window_refnum_lookup(WINDOW_REC *window, void *refnum_p) +{ + int refnum = GPOINTER_TO_INT(refnum_p); + return window->refnum == refnum ? 0 : window->refnum < refnum ? -1 : 1; +} + static GSequenceIter *windows_seq_begin(void) { return g_sequence_get_begin_iter(windows_seq); @@ -52,6 +58,42 @@ static GSequenceIter *windows_seq_end(void) return g_sequence_get_end_iter(windows_seq); } +static GSequenceIter *windows_seq_insert(WINDOW_REC *rec) +{ + return g_sequence_insert_sorted(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); +} + +static GSequenceIter *windows_seq_refnum_lookup(int refnum) +{ + return g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); +} + +static void windows_seq_changed(GSequenceIter *iter) +{ + g_sequence_sort_changed(iter, (GCompareDataFunc)window_refnum_cmp, NULL); +} + +static GSequenceIter *windows_seq_window_lookup(WINDOW_REC *rec) +{ + return g_sequence_lookup(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); +} + +/* search to the numerically right iterator of refnum */ +static GSequenceIter *windows_seq_refnum_search_right(int refnum) +{ + return g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); +} + +/* we want to find the numerically left iterator of refnum, so we + search the right of the previous refnum. but we need to figure out + the case where the iterator is already at the beginning, i.e + iter->refnum >= refnum */ +static GSequenceIter *windows_seq_refnum_search_left(int refnum) +{ + GSequenceIter *iter = windows_seq_refnum_search_right(refnum - 1); + return iter == windows_seq_begin() ? NULL : g_sequence_iter_prev(iter); +} + static int window_get_new_refnum(void) { WINDOW_REC *win; @@ -75,11 +117,6 @@ static int window_get_new_refnum(void) return refnum; } -static GSequenceIter *windows_seq_insert(WINDOW_REC *rec) -{ - return g_sequence_insert_sorted(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); -} - WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic) { WINDOW_REC *rec; @@ -114,22 +151,6 @@ static void window_set_refnum0(WINDOW_REC *window, int refnum) signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum)); } -static int window_refnum_lookup(WINDOW_REC *window, void *refnum_p) -{ - int refnum = GPOINTER_TO_INT(refnum_p); - return window->refnum == refnum ? 0 : window->refnum < refnum ? -1 : 1; -} - -static GSequenceIter *windows_seq_refnum_lookup(int refnum) -{ - return g_sequence_lookup(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); -} - -static void windows_seq_changed(GSequenceIter *iter) -{ - g_sequence_sort_changed(iter, (GCompareDataFunc)window_refnum_cmp, NULL); -} - /* removed_refnum was removed from the windows list, pack the windows so there won't be any holes. If there is any holes after removed_refnum, leave the windows behind it alone. */ @@ -155,11 +176,6 @@ static void windows_pack(int removed_refnum) } } -static GSequenceIter *windows_seq_window_lookup(WINDOW_REC *rec) -{ - return g_sequence_lookup(windows_seq, rec, (GCompareDataFunc)window_refnum_cmp, NULL); -} - void window_destroy(WINDOW_REC *window) { GSequenceIter *iter; @@ -466,22 +482,6 @@ WINDOW_REC *window_find_item(SERVER_REC *server, const char *name) return window_item_window(item); } -/* search to the numerically right iterator of refnum */ -static GSequenceIter *windows_seq_refnum_search_right(int refnum) -{ - return g_sequence_search(windows_seq, GINT_TO_POINTER(refnum), (GCompareDataFunc)window_refnum_lookup, NULL); -} - -/* we want to find the numerically left iterator of refnum, so we - search the right of the previous refnum. but we need to figure out - the case where the iterator is already at the beginning, i.e - iter->refnum >= refnum */ -static GSequenceIter *windows_seq_refnum_search_left(int refnum) -{ - GSequenceIter *iter = windows_seq_refnum_search_right(refnum - 1); - return iter == windows_seq_begin() ? NULL : g_sequence_iter_prev(iter); -} - int window_refnum_prev(int refnum, int wrap) { WINDOW_REC *rec; From 9151f87145e6c9ea40192e0e7c8266eacaaa335f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Dec 2016 21:40:18 +0100 Subject: [PATCH 0024/1198] remove some for loops --- src/fe-common/core/fe-windows.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 248cd621..0afa2914 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -165,7 +165,7 @@ static void windows_pack(int removed_refnum) iter = windows_seq_refnum_lookup(refnum); if (iter == NULL) return; - for (; iter != end; refnum++, iter = g_sequence_iter_next(iter)) { + while (iter != end) { window = g_sequence_get(iter); if (window == NULL || window->sticky_refnum || window->refnum != refnum) @@ -173,6 +173,9 @@ static void windows_pack(int removed_refnum) window_set_refnum0(window, refnum - 1); windows_seq_changed(iter); + + refnum++; + iter = g_sequence_iter_next(iter); } } @@ -556,12 +559,10 @@ GSList *windows_get_sorted(void) GSList *sorted; sorted = NULL; - for (iter = windows_seq_end(), - begin = windows_seq_begin(); + iter = windows_seq_end(); + begin = windows_seq_begin(); - iter != begin; - - ) { + while (iter != begin) { iter = g_sequence_iter_prev(iter); WINDOW_REC *rec = g_sequence_get(iter); From 0a46a1664ab2d5c914ab378d56e0d22825f06522 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 22 Dec 2016 15:38:43 +0100 Subject: [PATCH 0025/1198] Add myself to the core team members --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index eea359cc..c1280552 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,6 +13,7 @@ Irssi staff (current maintainers) : Jase Thew (bazerka) dequis (dx) Ailin Nemui (Nei) + Giuseppe (TheLemonMan, lemonboy) Former developers: @@ -26,7 +27,6 @@ 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: From 7e22d051ae699467575d1feeec6d8e2e2f16721f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 23 Dec 2016 17:59:55 +0100 Subject: [PATCH 0026/1198] Make sure SASL was actually requested before failing. --- src/fe-common/irc/fe-sasl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index 6cba1887..fc8105fc 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -1,7 +1,7 @@ /* fe-sasl.c : irssi - Copyright (C) 2015 The Lemon Man + Copyright (C) 2015-2017 The Lemon Man 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 @@ -22,6 +22,8 @@ #include "module-formats.h" #include "signals.h" #include "levels.h" +#include "misc.h" +#include "sasl.h" #include "irc-servers.h" #include "settings.h" @@ -43,6 +45,7 @@ static void sig_cap_end(IRC_SERVER_REC *server) /* The negotiation has now been terminated, if we didn't manage to * authenticate successfully with the server just disconnect. */ if (!server->sasl_success && + server->connrec->sasl_mechanism != SASL_MECHANISM_NONE && settings_get_bool("sasl_disconnect_on_failure")) { /* We can't use server_disconnect() here because we'd end up * freeing the 'server' object and be guilty of a slew of UaF. */ From 8e5db471e4d8b052f072ce8a351222c6edb42d19 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 14 Jan 2016 14:10:00 +0100 Subject: [PATCH 0027/1198] Use GLib's regexp interface (backed by PCRE) --- src/core/ignore.c | 35 +++++++++++------------------ src/core/ignore.h | 8 +------ src/core/misc.c | 4 ---- src/fe-common/core/fe-ignore.c | 2 -- src/fe-common/core/hilight-text.c | 37 +++++++++++++------------------ src/fe-common/core/hilight-text.h | 8 +------ src/fe-text/textbuffer.c | 35 ++++++++++------------------- 7 files changed, 42 insertions(+), 87 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 2047dc9d..2b8299bd 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -67,12 +67,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) return FALSE; if (rec->regexp) { -#ifdef HAVE_REGEX_H return rec->regexp_compiled && - regexec(&rec->preg, text, 0, NULL, 0) == 0; -#else - return FALSE; -#endif + g_regex_match(rec->preg, text, 0, NULL); } return rec->fullword ? @@ -326,26 +322,23 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { -#ifdef HAVE_REGEX_H - char *errbuf; - int errcode, errbuf_len; + if (rec->regexp_compiled) { + g_regex_unref(rec->preg); + rec->regexp_compiled = FALSE; + } - if (rec->regexp_compiled) regfree(&rec->preg); - rec->regexp_compiled = FALSE; if (rec->regexp && rec->pattern != NULL) { - errcode = regcomp(&rec->preg, rec->pattern, - REG_EXTENDED|REG_ICASE|REG_NOSUB); - if (errcode != 0) { - errbuf_len = regerror(errcode, &rec->preg, 0, 0); - errbuf = g_malloc(errbuf_len); - regerror(errcode, &rec->preg, errbuf, errbuf_len); - g_warning("Failed to compile regexp '%s': %s", rec->pattern, errbuf); - g_free(errbuf); + GError *re_error; + + rec->preg = g_regex_new(rec->pattern, G_REGEX_CASELESS, 0, &re_error); + + if (rec->preg == NULL) { + g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); + g_error_free(re_error); } else { rec->regexp_compiled = TRUE; } } -#endif } void ignore_add_rec(IGNORE_REC *rec) @@ -365,9 +358,7 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->regexp_compiled) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index f889740f..6c9797f5 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,10 +1,6 @@ #ifndef __IGNORE_H #define __IGNORE_H -#ifdef HAVE_REGEX_H -# include -#endif - typedef struct _IGNORE_REC IGNORE_REC; struct _IGNORE_REC { @@ -20,10 +16,8 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ -#ifdef HAVE_REGEX_H unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + GRegex *preg; }; extern GSList *ignores; diff --git a/src/core/misc.c b/src/core/misc.c index 0bb1f7e6..c59eb126 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -22,10 +22,6 @@ #include "misc.h" #include "commands.h" -#ifdef HAVE_REGEX_H -# include -#endif - typedef struct { int condition; GInputFunction function; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 52b11e6b..addfa0b8 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,10 +58,8 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); -#ifdef HAVE_REGEX_H else if (!rec->regexp_compiled) g_string_append(options, "[INVALID!] "); -#endif } if (rec->fullword) g_string_append(options, "-full "); if (rec->replies) g_string_append(options, "-replies "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 4691a708..83b6f67e 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,9 +101,7 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->regexp_compiled) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -120,14 +118,15 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); - if (!rec->regexp) + if (rec->regexp_compiled) { + g_regex_unref(rec->preg); rec->regexp_compiled = FALSE; - else - rec->regexp_compiled = regcomp(&rec->preg, rec->text, - rec->case_sensitive ? REG_EXTENDED : (REG_EXTENDED|REG_ICASE)) == 0; -#endif + } + + rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); + + if (rec->preg != NULL) + rec->regexp_compiled = TRUE; } void hilight_create(HILIGHT_REC *rec) @@ -200,19 +199,15 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, char *match; if (rec->regexp) { -#ifdef HAVE_REGEX_H - regmatch_t rmatch[1]; + GMatchInfo *match; - if (rec->regexp_compiled && - regexec(&rec->preg, text, 1, rmatch, 0) == 0) { - if (rmatch[0].rm_so > 0 && - match_beg != NULL && match_end != NULL) { - *match_beg = rmatch[0].rm_so; - *match_end = rmatch[0].rm_eo; + if (rec->regexp_compiled) { + g_regex_match (rec->preg, text, 0, &match); + + if (g_match_info_matches(match)) { + return g_match_info_fetch_pos(match, 0, match_beg, match_end); } - return TRUE; } -#endif } else { if (rec->case_sensitive) { match = rec->fullword ? @@ -509,10 +504,8 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); -#ifdef HAVE_REGEX_H if (!rec->regexp_compiled) g_string_append(options, "[INVALID!] "); -#endif } if (rec->priority != 0) diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index ae05e1ca..a74c38b0 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,10 +1,6 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H -#ifdef HAVE_REGEX_H -# include -#endif - #include "formats.h" struct _HILIGHT_REC { @@ -24,10 +20,8 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ -#ifdef HAVE_REGEX_H unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + GRegex *preg; char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 24ee62bc..979b2a46 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -27,10 +27,6 @@ #include "textbuffer.h" -#ifdef HAVE_REGEX_H -# include -#endif - #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) TEXT_BUFFER_REC *textbuffer_create(void) @@ -537,9 +533,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int before, int after, int regexp, int fullword, int case_sensitive) { -#ifdef HAVE_REGEX_H - regex_t preg; -#endif + GRegex *preg; LINE_REC *line, *pre_line; GList *matches; GString *str; @@ -550,14 +544,10 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(text != NULL, NULL); if (regexp) { -#ifdef HAVE_REGEX_H - int flags = REG_EXTENDED | REG_NOSUB | - (case_sensitive ? 0 : REG_ICASE); - if (regcomp(&preg, text, flags) != 0) + preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); + + if (preg == NULL) return NULL; -#else - return NULL; -#endif } matches = NULL; match_after = 0; @@ -577,12 +567,11 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (*text != '\0') { textbuffer_line2text(line, FALSE, str); - if (line_matched) - line_matched = -#ifdef HAVE_REGEX_H - regexp ? regexec(&preg, str->str, 0, NULL, 0) == 0 : -#endif - match_func(str->str, text) != NULL; + if (line_matched) { + line_matched = regexp ? + g_regex_match(preg, str->str, 0, NULL) : + match_func(str->str, text) != NULL; + } } if (line_matched) { @@ -610,9 +599,9 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, matches = g_list_append(matches, NULL); } } -#ifdef HAVE_REGEX_H - if (regexp) regfree(&preg); -#endif + + if (regexp) + g_regex_unref(preg); g_string_free(str, TRUE); return matches; } From b5a727c87cf7db944ade9c6714385f1e8598d37e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 29 Jan 2016 16:08:40 +0100 Subject: [PATCH 0028/1198] Remove unused references to regex.h Also remove the prototype for regex_match since it has been removed. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bf87f5aa..7eb1bfe1 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ AC_PATH_PROG(perlpath, perl) AC_CHECK_HEADERS(unistd.h dirent.h sys/ioctl.h sys/resource.h) # check posix headers.. -AC_CHECK_HEADERS(sys/socket.h sys/time.h sys/utsname.h regex.h) +AC_CHECK_HEADERS(sys/socket.h sys/time.h sys/utsname.h) AC_SYS_LARGEFILE From 3fcd3cd2b9fae07a0b7cd3e5ba91049f19cc6501 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 29 Jan 2016 16:22:14 +0100 Subject: [PATCH 0029/1198] Remove the regexp_compiled field. It was made redundant by the introduction of the pointer to the GRegex structure. Silence the compiler warning in textbuffer.c about preg being initialized by setting it to NULL. --- src/core/ignore.c | 14 ++++---------- src/core/ignore.h | 1 - src/fe-common/core/fe-ignore.c | 2 +- src/fe-common/core/hilight-text.c | 13 ++++--------- src/fe-common/core/hilight-text.h | 1 - src/fe-text/textbuffer.c | 2 ++ 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 2b8299bd..30cb7cb8 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -66,10 +66,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) if (text == NULL) return FALSE; - if (rec->regexp) { - return rec->regexp_compiled && - g_regex_match(rec->preg, text, 0, NULL); - } + if (rec->regexp) + return rec->preg && g_regex_match(rec->preg, text, 0, NULL); return rec->fullword ? stristr_full(text, rec->pattern) != NULL : @@ -322,10 +320,8 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { - if (rec->regexp_compiled) { + if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->regexp_compiled = FALSE; - } if (rec->regexp && rec->pattern != NULL) { GError *re_error; @@ -335,8 +331,6 @@ static void ignore_init_rec(IGNORE_REC *rec) if (rec->preg == NULL) { g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); g_error_free(re_error); - } else { - rec->regexp_compiled = TRUE; } } } @@ -358,7 +352,7 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); - if (rec->regexp_compiled) g_regex_unref(rec->preg); + if (rec->preg != NULL) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index 6c9797f5..f37f8b28 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -16,7 +16,6 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ GRegex *preg; }; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index addfa0b8..03fd4dd2 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,7 +58,7 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); - else if (!rec->regexp_compiled) + else if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); } if (rec->fullword) g_string_append(options, "-full "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 83b6f67e..e3dcc2d9 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,7 +101,7 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); - if (rec->regexp_compiled) g_regex_unref(rec->preg); + if (rec->preg != NULL) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -118,15 +118,10 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { - if (rec->regexp_compiled) { + if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->regexp_compiled = FALSE; - } rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); - - if (rec->preg != NULL) - rec->regexp_compiled = TRUE; } void hilight_create(HILIGHT_REC *rec) @@ -201,7 +196,7 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, if (rec->regexp) { GMatchInfo *match; - if (rec->regexp_compiled) { + if (rec->preg != NULL) { g_regex_match (rec->preg, text, 0, &match); if (g_match_info_matches(match)) { @@ -504,7 +499,7 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); - if (!rec->regexp_compiled) + if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); } diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index a74c38b0..93c573c2 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -20,7 +20,6 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ GRegex *preg; char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 979b2a46..7d0806d1 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -543,6 +543,8 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); + preg = NULL; + if (regexp) { preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); From 5eaead761f1812fb9d4058b2bc38468521794693 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 19 Jun 2016 21:08:25 +0200 Subject: [PATCH 0030/1198] Rebase against master. --- src/core/ignore.c | 6 ++++-- src/fe-text/textbuffer.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 30cb7cb8..c91f6e4a 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -66,8 +66,10 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) if (text == NULL) return FALSE; - if (rec->regexp) - return rec->preg && g_regex_match(rec->preg, text, 0, NULL); + if (rec->regexp) { + return rec->preg != NULL && + g_regex_match(rec->preg, text, 0, NULL); + } return rec->fullword ? stristr_full(text, rec->pattern) != NULL : diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 7d0806d1..f35848a2 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -570,7 +570,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, textbuffer_line2text(line, FALSE, str); if (line_matched) { - line_matched = regexp ? + line_matched = regexp ? g_regex_match(preg, str->str, 0, NULL) : match_func(str->str, text) != NULL; } From 5dcf291f2144564363f734dba15760d3a82b61c2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 23 Jun 2016 13:25:23 +0200 Subject: [PATCH 0031/1198] Use the RAW flag when building the regexps. Also, plugged a memory leak when retrieving the match position. --- src/core/ignore.c | 2 +- src/fe-common/core/hilight-text.c | 23 +++++++++++++---------- src/fe-text/textbuffer.c | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index c91f6e4a..cfcbd792 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -328,7 +328,7 @@ static void ignore_init_rec(IGNORE_REC *rec) if (rec->regexp && rec->pattern != NULL) { GError *re_error; - rec->preg = g_regex_new(rec->pattern, G_REGEX_CASELESS, 0, &re_error); + rec->preg = g_regex_new(rec->pattern, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, &re_error); if (rec->preg == NULL) { g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index e3dcc2d9..7a7f473c 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -121,7 +121,7 @@ static void hilight_init_rec(HILIGHT_REC *rec) if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); + rec->preg = g_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, NULL); } void hilight_create(HILIGHT_REC *rec) @@ -188,22 +188,25 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels) return NULL; } -static int hilight_match_text(HILIGHT_REC *rec, const char *text, +static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, int *match_beg, int *match_end) { - char *match; + gboolean ret = FALSE; if (rec->regexp) { - GMatchInfo *match; - if (rec->preg != NULL) { + GMatchInfo *match; + g_regex_match (rec->preg, text, 0, &match); - if (g_match_info_matches(match)) { - return g_match_info_fetch_pos(match, 0, match_beg, match_end); - } + if (g_match_info_matches(match)) + ret = g_match_info_fetch_pos(match, 0, match_beg, match_end); + + g_match_info_free(match); } } else { + char *match; + if (rec->case_sensitive) { match = rec->fullword ? strstr_full(text, rec->text) : @@ -218,11 +221,11 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, *match_beg = (int) (match-text); *match_end = *match_beg + strlen(rec->text); } - return TRUE; + ret = TRUE; } } - return FALSE; + return ret; } #define hilight_match_level(rec, level) \ diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index f35848a2..979a6104 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -546,7 +546,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, preg = NULL; if (regexp) { - preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); + preg = g_regex_new(text, G_REGEX_RAW | (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); if (preg == NULL) return NULL; @@ -602,7 +602,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } } - if (regexp) + if (preg != NULL) g_regex_unref(preg); g_string_free(str, TRUE); return matches; From f5cbbebc2ee858e8792ab40eea6abc9fd7865a28 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 3 Jan 2017 12:04:56 +0100 Subject: [PATCH 0032/1198] switch for gregex and regex.h --- configure.ac | 16 ++++++++++++++++ src/core/ignore.c | 31 ++++++++++++++++++++++++++++++ src/core/ignore.h | 9 +++++++++ src/core/misc.c | 4 ++++ src/fe-common/core/fe-ignore.c | 5 +++++ src/fe-common/core/hilight-text.c | 32 +++++++++++++++++++++++++++++++ src/fe-common/core/hilight-text.h | 9 +++++++++ src/fe-text/textbuffer.c | 29 ++++++++++++++++++++++++++-- 8 files changed, 133 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7eb1bfe1..8d588408 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,15 @@ AC_ARG_ENABLE(true-color, fi, want_truecolor=no) +AC_ARG_ENABLE(gregex, +[ --disable-gregex Build without GRegex (fall back to regex.h)], + if test x$enableval = xno ; then + want_gregex=no + else + want_gregex=yes + fi, + want_gregex=yes) + dnl ** dnl ** just some generic stuff... dnl ** @@ -534,6 +543,12 @@ else want_truecolor=no fi +if test "x$want_gregex" = "xyes"; then + AC_DEFINE([USE_GREGEX], [], [use GRegex for regular expressions]) +else + want_gregex=no +fi + AH_TEMPLATE(HAVE_GMODULE) AH_TEMPLATE(HAVE_SOCKS_H, [misc..]) AH_TEMPLATE(HAVE_STATIC_PERL) @@ -648,6 +663,7 @@ echo echo "Building with 64bit DCC support .. : $offt_64bit" echo "Building with true color support.. : $want_truecolor" +echo "Building with GRegex ............. : $want_gregex" echo echo "If there are any problems, read the INSTALL file." diff --git a/src/core/ignore.c b/src/core/ignore.c index cfcbd792..bf8db04f 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -67,8 +67,13 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) return FALSE; if (rec->regexp) { +#ifdef USE_GREGEX return rec->preg != NULL && g_regex_match(rec->preg, text, 0, NULL); +#else + return rec->regexp_compiled && + regexec(&rec->preg, text, 0, NULL, 0) == 0; +#endif } return rec->fullword ? @@ -322,6 +327,7 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); @@ -335,6 +341,27 @@ static void ignore_init_rec(IGNORE_REC *rec) g_error_free(re_error); } } +#else + char *errbuf; + int errcode, errbuf_len; + + if (rec->regexp_compiled) regfree(&rec->preg); + rec->regexp_compiled = FALSE; + + if (rec->regexp && rec->pattern != NULL) { + errcode = regcomp(&rec->preg, rec->pattern, + REG_EXTENDED|REG_ICASE|REG_NOSUB); + if (errcode != 0) { + errbuf_len = regerror(errcode, &rec->preg, 0, 0); + errbuf = g_malloc(errbuf_len); + regerror(errcode, &rec->preg, errbuf, errbuf_len); + g_warning("Failed to compile regexp '%s': %s", rec->pattern, errbuf); + g_free(errbuf); + } else { + rec->regexp_compiled = TRUE; + } + } +#endif } void ignore_add_rec(IGNORE_REC *rec) @@ -354,7 +381,11 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); +#else + if (rec->regexp_compiled) regfree(&rec->preg); +#endif if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index f37f8b28..80ae1d12 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,6 +1,10 @@ #ifndef __IGNORE_H #define __IGNORE_H +#ifndef USE_GREGEX +# include +#endif + typedef struct _IGNORE_REC IGNORE_REC; struct _IGNORE_REC { @@ -16,7 +20,12 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ +#ifdef USE_GREGEX GRegex *preg; +#else + unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ + regex_t preg; +#endif }; extern GSList *ignores; diff --git a/src/core/misc.c b/src/core/misc.c index c59eb126..1cfa15b6 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -22,6 +22,10 @@ #include "misc.h" #include "commands.h" +#ifndef USE_GREGEX +# include +#endif + typedef struct { int condition; GInputFunction function; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 03fd4dd2..800e881d 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,8 +58,13 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); +#ifdef USE_GREGEX else if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); +#else + else if (!rec->regexp_compiled) + g_string_append(options, "[INVALID!] "); +#endif } if (rec->fullword) g_string_append(options, "-full "); if (rec->replies) g_string_append(options, "-replies "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 7a7f473c..037cde5c 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,7 +101,11 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); +#else + if (rec->regexp_compiled) regfree(&rec->preg); +#endif if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -118,10 +122,19 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); rec->preg = g_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, NULL); +#else + if (rec->regexp_compiled) regfree(&rec->preg); + if (!rec->regexp) + rec->regexp_compiled = FALSE; + else + rec->regexp_compiled = regcomp(&rec->preg, rec->text, + rec->case_sensitive ? REG_EXTENDED : (REG_EXTENDED|REG_ICASE)) == 0; +#endif } void hilight_create(HILIGHT_REC *rec) @@ -194,6 +207,7 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, gboolean ret = FALSE; if (rec->regexp) { +#ifdef USE_GREGEX if (rec->preg != NULL) { GMatchInfo *match; @@ -204,6 +218,19 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, g_match_info_free(match); } +#else + regmatch_t rmatch[1]; + + if (rec->regexp_compiled && + regexec(&rec->preg, text, 1, rmatch, 0) == 0) { + if (rmatch[0].rm_so > 0 && + match_beg != NULL && match_end != NULL) { + *match_beg = rmatch[0].rm_so; + *match_end = rmatch[0].rm_eo; + } + ret = TRUE; + } +#endif } else { char *match; @@ -502,8 +529,13 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); +#ifdef USE_GREGEX if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); +#else + if (!rec->regexp_compiled) + g_string_append(options, "[INVALID!] "); +#endif } if (rec->priority != 0) diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 93c573c2..76beec1f 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,6 +1,10 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H +#ifndef USE_GREGEX +# include +#endif + #include "formats.h" struct _HILIGHT_REC { @@ -20,7 +24,12 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ +#ifdef USE_GREGEX GRegex *preg; +#else + unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ + regex_t preg; +#endif char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 979a6104..ae4636a5 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -27,6 +27,10 @@ #include "textbuffer.h" +#ifndef USE_GREGEX +# include +#endif + #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) TEXT_BUFFER_REC *textbuffer_create(void) @@ -533,7 +537,11 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int before, int after, int regexp, int fullword, int case_sensitive) { +#ifdef USE_GREGEX GRegex *preg; +#else + regex_t preg; +#endif LINE_REC *line, *pre_line; GList *matches; GString *str; @@ -543,6 +551,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); +#ifdef USE_GREGEX preg = NULL; if (regexp) { @@ -551,6 +560,14 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (preg == NULL) return NULL; } +#else + if (regexp) { + int flags = REG_EXTENDED | REG_NOSUB | + (case_sensitive ? 0 : REG_ICASE); + if (regcomp(&preg, text, flags) != 0) + return NULL; + } +#endif matches = NULL; match_after = 0; str = g_string_new(NULL); @@ -571,8 +588,12 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (line_matched) { line_matched = regexp ? - g_regex_match(preg, str->str, 0, NULL) : - match_func(str->str, text) != NULL; +#ifdef USE_GREGEX + g_regex_match(preg, str->str, 0, NULL) +#else + regexec(&preg, str->str, 0, NULL, 0) == 0 +#endif + : match_func(str->str, text) != NULL; } } @@ -602,8 +623,12 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } } +#ifdef USE_GREGEX if (preg != NULL) g_regex_unref(preg); +#else + if (regexp) regfree(&preg); +#endif g_string_free(str, TRUE); return matches; } From 1f72b8e66a06b484dde20b6031c766a2129e0bd2 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 3 Jan 2017 12:29:52 +0100 Subject: [PATCH 0033/1198] up abi version --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 0a7b72f0..43596580 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 6 +#define IRSSI_ABI_VERSION 7 #define DEFAULT_SERVER_ADD_PORT 6667 From 6c6c42e3d1b49d90aacc0b67f8540471cae02a1d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 3 Jan 2017 13:44:58 +0100 Subject: [PATCH 0034/1198] Merge branch 'security' into 'master' See merge request !7 --- src/fe-common/core/formats.c | 10 +++++++++- src/fe-text/term-terminfo.c | 13 ++++++++++--- src/irc/core/irc-nicklist.c | 6 +++++- src/irc/core/irc-queries.c | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index d9a51201..738239a6 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -68,7 +68,7 @@ static void format_expand_code(const char **format, GString *out, int *flags) if (flags == NULL) { /* flags are being ignored - skip the code */ - while (**format != ']') + while (**format != ']' && **format != '\0') (*format)++; return; } @@ -246,6 +246,10 @@ int format_expand_styles(GString *out, const char **format, int *flags) case '[': /* code */ format_expand_code(format, out, flags); + if ((*format)[0] == '\0') + /* oops, reached end prematurely */ + (*format)--; + break; case 'x': case 'X': @@ -972,6 +976,7 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, str++; for (num2 = 0; i_isdigit(*str); str++) num2 = num2*10 + (*str-'0'); + if (*str == '\0') return start; switch (num2) { case 2: @@ -989,6 +994,8 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, for (; i_isdigit(*str); str++) num2 = (num2&~0xff) | (((num2&0xff) * 10 + (*str-'0'))&0xff); + + if (*str == '\0') return start; } if (i == -1) break; @@ -1017,6 +1024,7 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, str++; for (num2 = 0; i_isdigit(*str); str++) num2 = num2*10 + (*str-'0'); + if (*str == '\0') return start; if (num == 38) { flags &= ~GUI_PRINT_FLAG_COLOR_24_FG; diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 27be904e..8fac76b3 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -539,9 +539,16 @@ int term_addstr(TERM_WINDOW *window, const char *str) 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); + tmp = g_utf8_get_char_validated(ptr, -1); + /* On utf8 error, treat as single byte and try to + continue interpretting rest of string as utf8 */ + if (tmp == (gunichar)-1 || tmp == (gunichar)-2) { + len++; + ptr++; + } else { + len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1; + ptr = g_utf8_next_char(ptr); + } } } else len = raw_len; diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index bcb9d1f6..f049fe79 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -314,7 +314,11 @@ static void event_whois_ircop(SERVER_REC *server, const char *data) static void event_nick_invalid(IRC_SERVER_REC *server, const char *data) { if (!server->connected) - server_disconnect((SERVER_REC *) server); + /* we used to call server_disconnect but that crashes + irssi because of undefined memory access. instead, + indicate that the connection should be dropped and + let the irc method to the clean-up. */ + server->connection_lost = server->no_reconnect = TRUE; } static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) diff --git a/src/irc/core/irc-queries.c b/src/irc/core/irc-queries.c index 12861744..77a5289d 100644 --- a/src/irc/core/irc-queries.c +++ b/src/irc/core/irc-queries.c @@ -45,6 +45,8 @@ QUERY_REC *irc_query_find(IRC_SERVER_REC *server, const char *nick) { GSList *tmp; + g_return_val_if_fail(nick != NULL, NULL); + for (tmp = server->queries; tmp != NULL; tmp = tmp->next) { QUERY_REC *rec = tmp->data; From 7cac354161a8914712264408347a9a2882aab22f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 3 Jan 2017 14:24:55 +0100 Subject: [PATCH 0035/1198] tag as 0.8.21 --- NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 265827b3..34bb76a3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +v0.8.21 2017-01-03 The Irssi team + - Correct a NULL pointer dereference in the nickcmp function found by + Joseph Bisch (GL#1) + - Correct an out of bounds read in certain incomplete control codes + found by Joseph Bisch (GL#2) + - Correct an out of bounds read in certain incomplete character + sequences found by Hanno Böck and independently by J. Bisch (GL#3) + - Correct an error when receiving invalid nick message (GL#4, #466) + v0.8.20 2016-09-16 The Irssi team - Correct the name of an emitted sasl signal (#484) - Correct the prototype for the 'message private' signal (#515) diff --git a/configure.ac b/configure.ac index 458c8aa9..59f5ce57 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 0.8.20) +AC_INIT(irssi, 0.8.21) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 33107be74888ea08411904193f2832fcc7747692 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 3 Jan 2017 17:04:24 +0100 Subject: [PATCH 0036/1198] fix GRegex GError problem --- src/core/ignore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index bf8db04f..d4a92e3c 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -332,7 +332,7 @@ static void ignore_init_rec(IGNORE_REC *rec) g_regex_unref(rec->preg); if (rec->regexp && rec->pattern != NULL) { - GError *re_error; + GError *re_error = NULL; rec->preg = g_regex_new(rec->pattern, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, &re_error); From ea7826b0ec097b9fdc29336ff7fe7074052773f5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 3 Jan 2017 16:41:41 +0100 Subject: [PATCH 0037/1198] tag as 1.0.0 --- NEWS | 76 +++++++++++++++++++++++++++++++++++++--------------- configure.ac | 2 +- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index b55b1b4d..81c6004c 100644 --- a/NEWS +++ b/NEWS @@ -1,22 +1,29 @@ -v0.8.22-head 2017-xx-xx The Irssi team - * Removed --disable-ipv6 +v1.0.0 2017-01-03 The Irssi team + * Removed --disable-ipv6 (#408). * /connect Network now aborts with an error if no servers have been - added to that network. + added to that network (#443). * /dcc commands now use quotes around spaces consistently. - + irssiproxy can now forward all tags through a single port. - + irssiproxy can also listen on unix sockets. - + send channel -botcmds immediately when no mask is specified (#175). + * bell_beeps was removed (#524, #565). + * Switch to GRegex instead of regex.h (#412). + + irssiproxy can now forward all tags through a single + port. By Lukas Mai (mauke, #425). + + irssiproxy can also listen on unix sockets. By Lukas Mai (#427). + + send channel -botcmds immediately when no mask is specified (#175, #399). + the kill buffer now remembers consecutive kills. New bindings were added: yank_next_cutbuffer and append_next_kill + By Todd A. Pratt (#353, #414, #455) + connections will avoid looking up IPv6 addresses if the machine does not have an IPv6 address assigned (exact behaviour is implementation - defined). + defined, #410). + Fix potential crash if scripts insert undef values into the completion - list. - + Paste warning is now also shown on pasting overlong lines. + list (#413). + + Paste warning is now also shown on pasting overlong + lines. By Manish Goregaokar (#426). + autolog_ignore_targets and activity_hide_targets learn a new syntax tag/* and * to ignore whole networks or everything. - + /hilight got a -matchcase flag to hilight case sensitively (#421). + By Jari Matilainen (vague666, #437) + + /hilight got a -matchcase flag to hilight case + sensitively. By Thibault B (isundil, #421, #476). + Always build irssi with TLS support. + Rename SSL to TLS in the code and add -tls_* versions of the -ssl_* options to /CONNECT and /SERVER, but make sure the -ssl_* options continue @@ -54,10 +61,36 @@ v0.8.22-head 2017-xx-xx The Irssi team does not rely on the libval library. It is causing a lot of troubles for our downstream maintainers. + + /names and $[...] now uses utf8 string operations. By Xavier + G. (#40, #411, #471, #480). + + New setting completion_nicks_match_case (#488). + + /channel /server /network now support modify subcommand. By + Jari Matilainen (#338, #498). + + Irssi::signal_remove now works with coderefs. By Tom Feist (shabble, #512). + + /script reset got an -autorun switch (#540, #538). + + cap_toggle can now be called from Perl, and fields + cap_active and cap_supported can be inspected (#542). + + Make it possible to disable empty line completion. By Lauri + Tirkkonen (lotheac, #574). + + New option sasl_disconnect_on_failure to disconnect when + SASL log-in failed (#514). - IP addresses are no longer stored when resolve_reverse_lookup is used. - - /names and $[...] now uses utf8 string operations (#40, #411). - - Removed broken support for curses. + - Removed broken support for curses (#521). + - Removed broken dummy mode (#526). + - Fix terminal state after suspend (#450, #452). + - Improve Perl library path detection (#479, #132). + - Reconnect now works on unix connections (#493). + - Fix completion warnings (#125, #496, FS#124). + - Fix a crash in the --more-- item (#501). + - Fix a display issue in /unignore (#517, bdo#577202). + - Fix a crash in some netsplits (#529, #500). + - Fix crashes with some invalid config (#550, #551, #563, #564, #587, #581, #570). + - Add support for SASL Fragmentation. By Kenny Root (kruton, #506). + - Improve netsplit dumping (#420, #465). + - Improve responsibility under DCC I/O strain (#578, #159). + - Fix query nick change on open (#580, #586). + - Correct a few help texts. v0.8.21 2017-01-03 The Irssi team - Correct a NULL pointer dereference in the nickcmp function found by @@ -72,11 +105,11 @@ v0.8.20 2016-09-16 The Irssi team - Correct the name of an emitted sasl signal (#484) - Correct the prototype for the 'message private' signal (#515) - Corrections in away and hilight help text (#477, #518) - - /squery and /servlist commands have been restored. + - /squery and /servlist commands have been restored (#461). - Where Irssi would previously only report "System error" on connect, - it will now try harder to retrieve the system error message. + it will now try harder to retrieve the system error message (#467). - Fixed issue with +channels not working properly (#533) - - Fixed crash in optchan when item has no server (#485) + - Fixed crash in optchan when item has no server (#485, bdo#826525) - Fixed random remote crash in the nicklist handling (#529) - Fixed remote crash due to incorrect bounds checking on formats, reported by Gabriel Campana and Adrien Guinet from @@ -84,16 +117,17 @@ v0.8.20 2016-09-16 The Irssi team v0.8.19 2016-03-23 The Irssi team - Fixed regression when joining and parting channels on IRCnet (#435) - - Fixed SASL EXTERNAL (#432) + - Fixed SASL EXTERNAL. By Mantas Mikulėnas (grawity, #432) - Fixed regression when not using SASL (#438) - - Fixed incorrect SSL disconnects when using SSL from modules/scripts - (#439) + - Fixed incorrect SSL disconnects when using SSL from modules/scripts. + By Will Storey (horgh, #439) - Fixed regression where proxy_string could not be configured or - certain file transfers could not be accepted (#445) - - Fixed storing layout of !channels (#183) - - Fixed restoration of bracketed paste mode on quit (#449) + certain file transfers could not be accepted (#445, #446) + - Fixed storing layout of !channels (#183, #405) + - Fixed restoration of bracketed paste mode on quit (#449, #457) - Make the usage of meta-O for cursor keys configurable with /set term_appkey_mode off + (#430, #459) v0.8.18 2016-02-13 The Irssi team * Modules will now require to define a diff --git a/configure.ac b/configure.ac index c0f8e842..4aa1f3cc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 0.8.22-head) +AC_INIT(irssi, 1.0.0) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From cbb931ed1da91b2cee36f89673edd6a526d56e9a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 3 Jan 2017 17:21:47 +0100 Subject: [PATCH 0038/1198] continue head --- NEWS | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 81c6004c..267eaa2a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +v1.1-head 2017-xx-xx The Irssi team + v1.0.0 2017-01-03 The Irssi team * Removed --disable-ipv6 (#408). * /connect Network now aborts with an error if no servers have been diff --git a/configure.ac b/configure.ac index 4aa1f3cc..15ae74b1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.0.0) +AC_INIT(irssi, 1.1-head) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From c9c45e4f89bc42fec00b71c50844a946bfcc6e0c Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Fri, 6 Jan 2017 12:24:36 +0100 Subject: [PATCH 0039/1198] make irssi --with-perl build with separate object directory irssi 1.0.0 will not build if Perl is enabled and a separate object code directory is used. The problem was a relative path to an internal Perl dependency in four Makefile.PL.in files. --- src/perl/common/Makefile.PL.in | 2 +- src/perl/irc/Makefile.PL.in | 2 +- src/perl/textui/Makefile.PL.in | 2 +- src/perl/ui/Makefile.PL.in | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/perl/common/Makefile.PL.in b/src/perl/common/Makefile.PL.in index 84a80403..70b1d258 100644 --- a/src/perl/common/Makefile.PL.in +++ b/src/perl/common/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi', 'LIBS' => '', diff --git a/src/perl/irc/Makefile.PL.in b/src/perl/irc/Makefile.PL.in index 0fbc5241..582160a0 100644 --- a/src/perl/irc/Makefile.PL.in +++ b/src/perl/irc/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::Irc', 'LIBS' => '', diff --git a/src/perl/textui/Makefile.PL.in b/src/perl/textui/Makefile.PL.in index 3541f75c..ffdda21a 100644 --- a/src/perl/textui/Makefile.PL.in +++ b/src/perl/textui/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::TextUI', 'LIBS' => '', diff --git a/src/perl/ui/Makefile.PL.in b/src/perl/ui/Makefile.PL.in index ed87d528..ceed51c3 100644 --- a/src/perl/ui/Makefile.PL.in +++ b/src/perl/ui/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::UI', 'LIBS' => '', From 752f484c6ce4c2aa7284b617a59a8906b269281c Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 6 Jan 2017 11:47:24 -0300 Subject: [PATCH 0040/1198] Add OPENSSL_NO_EC for solaris 11.3, see issue #598 Original patch by 'Slarky' According to that ticket, the next major version of solaris won't need this. Consider reverting this when solaris 11.3 stops being relevant. --- src/core/network-openssl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 7a1d6e34..1eb85341 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -646,7 +646,11 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) #ifdef SSL_get_server_tmp_key // Show ephemeral key information. EVP_PKEY *ephemeral_key = NULL; + + // OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 +#ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; +#endif char *ephemeral_key_algorithm = NULL; char *cname = NULL; int nid; @@ -658,6 +662,7 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; +#ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(ephemeral_key); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); @@ -670,6 +675,7 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) g_free_and_null(ephemeral_key_algorithm); break; +#endif default: tls_rec_set_ephemeral_key_algorithm(tls, "Unknown"); From ef9da295cdd8af0036396e7fc772fcee8a1c7c51 Mon Sep 17 00:00:00 2001 From: Lasse Toimela Date: Fri, 6 Jan 2017 17:47:08 +0200 Subject: [PATCH 0041/1198] Fix syntax on /help SERVER example --- docs/help/in/server.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 60870111..44de0efc 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -64,7 +64,7 @@ /SERVER CONNECT chat.freenode.net /SERVER CONNECT +chat.freenode.net /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -port 6667 -4 -network Freenode -noproxy orwell.freenode.net + /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 /SERVER MODIFY -network Freenode -noauto orwell.freenode.net /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE From 1831a8e1a710decbbcae524c60cdf6216f19a121 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 6 Jan 2017 12:48:27 -0300 Subject: [PATCH 0042/1198] Don't reset wait_cmd during connection registration (fixes early ISON) --- src/irc/core/irc-servers.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 3117e345..7cbd05a0 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -527,6 +527,12 @@ void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len) return; } + /* Don't reset wait_cmd during connection registration + * (while sending CAP / SASL related commands) */ + if (!server->connected) { + return; + } + g_get_current_time(&server->last_cmd); /* A bit kludgy way to do the flood protection. In ircnet, there From 69e112fbd1b44a6f9f3380167c12bbe0f76693a1 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 6 Jan 2017 11:20:49 -0300 Subject: [PATCH 0043/1198] NEWS: Avoid explicitly mentioning freenode in the pinning examples They have proper certs, so using them as an example is wrong. Particularly worse since they started using letsencrypt recently so every server has a different cert and pubkey. We'll figure out how to link this from the release notes later. --- NEWS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 81c6004c..9604277a 100644 --- a/NEWS +++ b/NEWS @@ -39,16 +39,16 @@ v1.0.0 2017-01-03 The Irssi team values like this: Start by downloading the certificate from a given IRC server: - $ openssl s_client -connect chat.freenode.net:6697 < /dev/null 2>/dev/null | \ - openssl x509 > freenode.cert + $ openssl s_client -connect irc.example.net:6697 < /dev/null 2>/dev/null | \ + openssl x509 > example.cert Find the value for -tls_pinned_cert: - $ openssl x509 -in freenode.cert -fingerprint -sha256 -noout + $ openssl x509 -in example.cert -fingerprint -sha256 -noout Find the value for -tls_pinned_pubkey: - $ openssl x509 -in freenode.cert -pubkey -noout | \ + $ openssl x509 -in example.cert -pubkey -noout | \ openssl pkey -pubin -outform der | \ openssl dgst -sha256 -c | \ tr a-z A-Z From 5917bc6f75dd87806807d3d526826b64e8271a5b Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Fri, 6 Jan 2017 21:58:00 -0800 Subject: [PATCH 0044/1198] Follow g_strsplit with call to g_strfreev --- src/irc/core/modes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index 207461cc..cc3d0faf 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -743,6 +743,7 @@ static char *get_nicks(IRC_SERVER_REC *server, WI_ITEM_REC *item, g_hash_table_lookup(optlist, "yes") == NULL) { /* too many matches */ g_string_free(str, TRUE); + g_strfreev(matches); cmd_params_free(free_arg); signal_emit("error command", 1, @@ -756,7 +757,7 @@ static char *get_nicks(IRC_SERVER_REC *server, WI_ITEM_REC *item, if (str->len > 0) g_string_truncate(str, str->len-1); ret = str->str; g_string_free(str, FALSE); - + g_strfreev(matches); cmd_params_free(free_arg); *ret_channel = channel; From cf4690725667211bc8a8998e362c6bda24dd7528 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Sat, 7 Jan 2017 20:01:07 -0500 Subject: [PATCH 0045/1198] Add frontend for fuzzing Use the following configure command: $ ./configure --with-fuzzer --with-fuzzer-lib=/path/to/libFuzzer.a \ CC=clang CXX=clang++ Places an irssi-fuzz in src/fe-fuzz/ after build. Also can specify SANFLAGS to override the chosen sanitizer flags (defaults to "-g -fsanitize=address -fsanitize-coverage=trace-pc-guard"). --- .gitignore | 4 + configure.ac | 40 ++++++++++ src/Makefile.am | 6 +- src/fe-fuzz/Makefile.am | 25 ++++++ src/fe-fuzz/irssi.c | 58 ++++++++++++++ src/fe-fuzz/module-formats.c | 82 ++++++++++++++++++++ src/fe-fuzz/module-formats.h | 58 ++++++++++++++ src/fe-fuzz/tokens.txt | 143 +++++++++++++++++++++++++++++++++++ 8 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 src/fe-fuzz/Makefile.am create mode 100644 src/fe-fuzz/irssi.c create mode 100644 src/fe-fuzz/module-formats.c create mode 100644 src/fe-fuzz/module-formats.h create mode 100644 src/fe-fuzz/tokens.txt diff --git a/.gitignore b/.gitignore index 945b6cf6..9af0c4b1 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ docs/help/[a-z]* docs/help/in/Makefile.am src/fe-text/irssi +src/fe-fuzz/irssi-fuzz src/fe-common/irc/irc-modules.c src/irc/irc.c @@ -46,6 +47,9 @@ src/perl/ui/*.c src/perl/*/MYMETA.* src/perl/*/Makefile.old +src/fe-fuzz/crash-* +src/fe-fuzz/oom-* + *.a *.bs *.la diff --git a/configure.ac b/configure.ac index 15ae74b1..03c7ddf5 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,19 @@ AC_ARG_WITH(bot, fi, want_irssibot=no) +AC_ARG_WITH(fuzzer, +[ --with-fuzzer Build irssi-fuzzer], + if test x$withval = xno; then + want_irssifuzzer=no + else + want_irssifuzzer=yes + fi, + want_irssifuzzer=no) + +AC_ARG_WITH(fuzzer-lib, +[ --with-fuzzer-lib Specify path to fuzzer library], + fuzzerlibpath="$withval") + AC_ARG_WITH(proxy, [ --with-proxy Build irssi-proxy], if test x$withval = xno; then @@ -297,6 +310,30 @@ if test "x$want_textui" != "xno"; then fi +dnl ** +dnl ** irssifuzzer checks +dnl ** + +if test "$want_irssifuzzer" != "no"; then + dnl * we need to build with -fsanitize-coverage=trace-pc-guard + dnl * otherwise fuzzer won't be very successful at finding bugs :) + if test -z "$SANFLAGS"; then + SANFLAGS="-g -fsanitize=address -fsanitize-coverage=trace-pc-guard" + fi + CFLAGS="$CFLAGS $SANFLAGS" + CXXFLAGS="$CXXFLAGS $SANFLAGS" + + AC_MSG_CHECKING(for fuzzer library) + + if test -z "$fuzzerlibpath"; then + AC_MSG_RESULT([not found, building without fuzzer front end]) + want_irssifuzzer=no + else + FUZZER_LIBS="$fuzzerlibpath" + AC_SUBST(FUZZER_LIBS) + fi +fi + dnl ** dnl ** perl checks dnl ** @@ -456,6 +493,7 @@ fi dnl ** check what we want to build AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes") AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes") +AM_CONDITIONAL(BUILD_IRSSIFUZZER, test "$want_irssifuzzer" = "yes") AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes") AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no") @@ -572,6 +610,7 @@ src/fe-common/core/Makefile src/fe-common/irc/Makefile src/fe-common/irc/dcc/Makefile src/fe-common/irc/notifylist/Makefile +src/fe-fuzz/Makefile src/fe-none/Makefile src/fe-text/Makefile src/lib-config/Makefile @@ -611,6 +650,7 @@ echo echo "Building text frontend ........... : $want_textui" echo "Building irssi bot ............... : $want_irssibot" +echo "Building irssi fuzzer ............ : $want_irssifuzzer" echo "Building irssi proxy ............. : $want_irssiproxy" if test "x$have_gmodule" = "xyes"; then echo "Building with module support ..... : yes" diff --git a/src/Makefile.am b/src/Makefile.am index 76a4af4f..a7fb2ee2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,10 @@ if BUILD_IRSSIBOT BOTUI=fe-none endif +if BUILD_IRSSIFUZZER +FUZZERUI=fe-fuzz +endif + if HAVE_PERL PERLDIR=perl endif @@ -14,4 +18,4 @@ pkginc_srcdir=$(pkgincludedir)/src pkginc_src_HEADERS = \ common.h -SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(TEXTUI) $(BOTUI) +SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(TEXTUI) $(BOTUI) $(FUZZERUI) diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am new file mode 100644 index 00000000..2ecf4a85 --- /dev/null +++ b/src/fe-fuzz/Makefile.am @@ -0,0 +1,25 @@ +bin_PROGRAMS = irssi-fuzz + +# Force link with clang++ for libfuzzer support +CCLD=clang++ $(CXXFLAGS) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core/ \ + -I$(top_srcdir)/src/irc/core/ \ + -I$(top_srcdir)/src/fe-common/core/ \ + $(GLIB_CFLAGS) + +irssi_fuzz_DEPENDENCIES = @COMMON_LIBS@ + +irssi_fuzz_LDADD = \ + @COMMON_LIBS@ \ + @PROG_LIBS@ \ + $(FUZZER_LIBS) + +irssi_fuzz_SOURCES = \ + irssi.c \ + module-formats.c + +noinst_HEADERS = \ + module-formats.h diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c new file mode 100644 index 00000000..3b2c617a --- /dev/null +++ b/src/fe-fuzz/irssi.c @@ -0,0 +1,58 @@ +/* + irssi.c : irssi + + Copyright (C) 2017 Joseph Bisch + + 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 "module.h" +#include "modules-load.h" +#include "levels.h" +#include "module-formats.h" +#include "themes.h" +#include "core.h" +#include "fe-common-core.h" +#include "args.h" +#include "printtext.h" + +#include +#include +#include +#include +#include + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + core_register_options(); + fe_common_core_register_options(); + /* no args */ + args_execute(0, NULL); + core_preinit((*argv)[0]); + core_init(); + fe_common_core_init(); + theme_register(gui_text_formats); + module_register("core", "fe-fuzz"); + printtext_string(NULL, NULL, MSGLEVEL_CLIENTCRAP, "init"); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + char *copy = (char *)malloc(sizeof(char)*(size+1)); + memcpy(copy, data, size); + copy[size] = '\0'; + printtext_string(NULL, NULL, MSGLEVEL_CLIENTCRAP, copy); + free(copy); + return 0; +} diff --git a/src/fe-fuzz/module-formats.c b/src/fe-fuzz/module-formats.c new file mode 100644 index 00000000..899827c2 --- /dev/null +++ b/src/fe-fuzz/module-formats.c @@ -0,0 +1,82 @@ +/* + module-formats.c : irssi + + Copyright (C) 2000 Timo Sirainen + + 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 "module.h" +#include "formats.h" + +FORMAT_REC gui_text_formats[] = +{ + { MODULE_NAME, "Text user interface", 0 }, + + /* ---- */ + { NULL, "Lastlog", 0 }, + + { "lastlog_too_long", "/LASTLOG would print $0 lines. If you really want to print all these lines use -force option.", 1, { 1 } }, + { "lastlog_count", "{hilight Lastlog}: $0 lines", 1, { 1 } }, + { "lastlog_start", "{hilight Lastlog}:", 0 }, + { "lastlog_end", "{hilight End of Lastlog}", 0 }, + { "lastlog_separator", "--", 0 }, + { "lastlog_date", "%%F ", 0 }, + + /* ---- */ + { NULL, "Windows", 0 }, + + { "refnum_not_found", "Window number $0 not found", 1, { 0 } }, + { "window_too_small", "Not enough room to resize this window", 0 }, + { "cant_hide_last", "You can't hide the last window", 0 }, + { "cant_hide_sticky_windows", "You can't hide sticky windows (use /WINDOW STICK OFF)", 0 }, + { "cant_show_sticky_windows", "You can't show sticky windows (use /WINDOW STICK OFF)", 0 }, + { "window_not_sticky", "Window is not sticky", 0 }, + { "window_set_sticky", "Window set sticky", 0 }, + { "window_unset_sticky", "Window is not sticky anymore", 0 }, + { "window_info_sticky", "%#Sticky : $0", 1, { 0 } }, + { "window_info_scroll", "%#Scroll : $0", 1, { 0 } }, + { "window_scroll", "Window scroll mode is now $0", 1, { 0 } }, + { "window_scroll_unknown", "Unknown scroll mode $0, must be ON, OFF or DEFAULT", 1, { 0 } }, + + /* ---- */ + { NULL, "Statusbars", 0 }, + + { "statusbar_list_header", "%#Name Type Placement Position Visible", 0 }, + { "statusbar_list_footer", "", 0 }, + { "statusbar_list", "%#$[30]0 $[6]1 $[9]2 $[8]3 $4", 5, { 0, 0, 0, 1, 0 } }, + { "statusbar_info_name", "%#Statusbar: {hilight $0}", 1, { 0 } }, + { "statusbar_info_type", "%#Type : $0", 1, { 0 } }, + { "statusbar_info_placement", "%#Placement: $0", 1, { 0 } }, + { "statusbar_info_position", "%#Position : $0", 1, { 1 } }, + { "statusbar_info_visible", "%#Visible : $0", 1, { 0 } }, + { "statusbar_info_item_header", "%#Items : Name Priority Alignment", 0 }, + { "statusbar_info_item_footer", "", 0 }, + { "statusbar_info_item_name", "%# : $[35]0 $[9]1 $2", 3, { 0, 1, 0 } }, + { "statusbar_not_found", "Statusbar doesn't exist: $0", 1, { 0 } }, + { "statusbar_item_not_found", "Statusbar item doesn't exist: $0", 1, { 0 } }, + { "statusbar_unknown_command", "Unknown statusbar command: $0", 1, { 0 } }, + { "statusbar_unknown_type", "Statusbar type must be 'window' or 'root'", 1, { 0 } }, + { "statusbar_unknown_placement", "Statusbar placement must be 'top' or 'bottom'", 1, { 0 } }, + { "statusbar_unknown_visibility", "Statusbar visibility must be 'always', 'active' or 'inactive'", 1, { 0 } }, + + /* ---- */ + { NULL, "Pasting", 0 }, + + { "paste_warning", "Pasting $0 lines to $1. Press Ctrl-K if you wish to do this or Ctrl-C to cancel.", 2, { 1, 0 } }, + { "paste_prompt", "Hit Ctrl-K to paste, Ctrl-C to abort?", 0 }, + + { NULL, NULL, 0 } +}; diff --git a/src/fe-fuzz/module-formats.h b/src/fe-fuzz/module-formats.h new file mode 100644 index 00000000..3fa8c511 --- /dev/null +++ b/src/fe-fuzz/module-formats.h @@ -0,0 +1,58 @@ +#include "formats.h" + +enum { + TXT_MODULE_NAME, + + TXT_FILL_1, + + TXT_LASTLOG_TOO_LONG, + TXT_LASTLOG_COUNT, + TXT_LASTLOG_START, + TXT_LASTLOG_END, + TXT_LASTLOG_SEPARATOR, + TXT_LASTLOG_DATE, + + TXT_FILL_2, + + TXT_REFNUM_NOT_FOUND, + TXT_WINDOW_TOO_SMALL, + TXT_CANT_HIDE_LAST, + TXT_CANT_HIDE_STICKY_WINDOWS, + TXT_CANT_SHOW_STICKY_WINDOWS, + TXT_WINDOW_NOT_STICKY, + TXT_WINDOW_SET_STICKY, + TXT_WINDOW_UNSET_STICKY, + TXT_WINDOW_INFO_STICKY, + TXT_WINDOW_INFO_SCROLL, + TXT_WINDOW_SCROLL, + TXT_WINDOW_SCROLL_UNKNOWN, + + TXT_FILL_3, + + TXT_STATUSBAR_LIST_HEADER, + TXT_STATUSBAR_LIST_FOOTER, + TXT_STATUSBAR_LIST, + TXT_STATUSBAR_INFO_NAME, + TXT_STATUSBAR_INFO_TYPE, + TXT_STATUSBAR_INFO_PLACEMENT, + TXT_STATUSBAR_INFO_POSITION, + TXT_STATUSBAR_INFO_VISIBLE, + TXT_STATUSBAR_INFO_ITEM_HEADER, + TXT_STATUSBAR_INFO_ITEM_FOOTER, + TXT_STATUSBAR_INFO_ITEM_NAME, + TXT_STATUSBAR_NOT_FOUND, + TXT_STATUSBAR_ITEM_NOT_FOUND, + TXT_STATUSBAR_UNKNOWN_COMMAND, + TXT_STATUSBAR_UNKNOWN_TYPE, + TXT_STATUSBAR_UNKNOWN_PLACEMENT, + TXT_STATUSBAR_UNKNOWN_VISIBILITY, + + TXT_FILL_4, + + TXT_PASTE_WARNING, + TXT_PASTE_PROMPT, + + TXT_COUNT +}; + +extern FORMAT_REC gui_text_formats[TXT_COUNT+1]; diff --git a/src/fe-fuzz/tokens.txt b/src/fe-fuzz/tokens.txt new file mode 100644 index 00000000..e337b6e9 --- /dev/null +++ b/src/fe-fuzz/tokens.txt @@ -0,0 +1,143 @@ +"@%+" +"*@*!*" +"001" +"002" +"003" +"004" +"005" +"221" +"254" +"271" +"272" +"281" +"301" +"302" +"303" +"305" +"306" +"311" +"312" +"313" +"314" +"315" +"317" +"318" +"319" +"324" +"326" +"327" +"328" +"329" +"330" +"332" +"333" +"338" +"341" +"344" +"345" +"346" +"347" +"348" +"349" +"352" +"353" +"364" +"365" +"366" +"367" +"368" +"369" +"372" +"375" +"376" +"377" +"378" +"379" +"381" +"386" +"387" +"388" +"389" +"396" +"401" +"403" +"404" +"405" +"407" +"408" +"410" +"421" +"422" +"433" +"436" +"437" +"438" +"439" +"442" +"465" +"470" +"471" +"472" +"473" +"474" +"475" +"476" +"477" +"478" +"479" +"482" +"486" +"489" +"494" +"506" +"707" +"716" +"717" +"728" +"729" +"902" +"903" +"904" +"905" +"906" +"907" +":a" +"+a" +"ACK" +"authenticate" +"away" +"-b" +"+b" +"cap" +"#chan" +"connected" +"empty" +"error" +"invite" +"join" +"kick" +"kill" +"LS" +"mode" +"multi-prefix" +"NAK" +"network" +"nick" +"nicklen" +"notice" +"-o" +"+o" +"part" +"ping" +"pong" +"prefix" +"privmsg" +"quit" +"sasl" +"topic" +"wallops" +"watch" +":\x01" +":\x01ACTION" +":\x01PING" +":\x01VERSION" From 17fc77565e3278ffc19c5294be57c2467f43974b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 9 Jan 2017 13:19:37 +0100 Subject: [PATCH 0046/1198] fix regression in completion fixes #609 --- src/fe-common/core/completion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 76dfbb79..914ba80b 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -191,7 +191,7 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i g_strdup_printf("%s%c%s", /* do not accidentally duplicate the word separator */ line == wordstart - 1 ? "" : linestart, - wordstart[-1], word); + old_wordstart[-1], word); g_free(old); g_free(word); From abdae2d5fcc83ef73c7233da4a169ef3305c9743 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 9 Jan 2017 08:19:01 -0500 Subject: [PATCH 0047/1198] Don't duplicate module-formats.* in fe-fuzz --- src/fe-fuzz/Makefile.am | 4 +- src/fe-fuzz/irssi.c | 2 +- src/fe-fuzz/module-formats.c | 82 ------------------------------------ src/fe-fuzz/module-formats.h | 58 ------------------------- 4 files changed, 3 insertions(+), 143 deletions(-) delete mode 100644 src/fe-fuzz/module-formats.c delete mode 100644 src/fe-fuzz/module-formats.h diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index 2ecf4a85..3a547c66 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -19,7 +19,7 @@ irssi_fuzz_LDADD = \ irssi_fuzz_SOURCES = \ irssi.c \ - module-formats.c + $(top_srcdir)/src/fe-text/module-formats.c noinst_HEADERS = \ - module-formats.h + $(top_srcdir)/src/fe-text/module-formats.h diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c index 3b2c617a..12c61147 100644 --- a/src/fe-fuzz/irssi.c +++ b/src/fe-fuzz/irssi.c @@ -21,7 +21,7 @@ #include "module.h" #include "modules-load.h" #include "levels.h" -#include "module-formats.h" +#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text #include "themes.h" #include "core.h" #include "fe-common-core.h" diff --git a/src/fe-fuzz/module-formats.c b/src/fe-fuzz/module-formats.c deleted file mode 100644 index 899827c2..00000000 --- a/src/fe-fuzz/module-formats.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - module-formats.c : irssi - - Copyright (C) 2000 Timo Sirainen - - 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 "module.h" -#include "formats.h" - -FORMAT_REC gui_text_formats[] = -{ - { MODULE_NAME, "Text user interface", 0 }, - - /* ---- */ - { NULL, "Lastlog", 0 }, - - { "lastlog_too_long", "/LASTLOG would print $0 lines. If you really want to print all these lines use -force option.", 1, { 1 } }, - { "lastlog_count", "{hilight Lastlog}: $0 lines", 1, { 1 } }, - { "lastlog_start", "{hilight Lastlog}:", 0 }, - { "lastlog_end", "{hilight End of Lastlog}", 0 }, - { "lastlog_separator", "--", 0 }, - { "lastlog_date", "%%F ", 0 }, - - /* ---- */ - { NULL, "Windows", 0 }, - - { "refnum_not_found", "Window number $0 not found", 1, { 0 } }, - { "window_too_small", "Not enough room to resize this window", 0 }, - { "cant_hide_last", "You can't hide the last window", 0 }, - { "cant_hide_sticky_windows", "You can't hide sticky windows (use /WINDOW STICK OFF)", 0 }, - { "cant_show_sticky_windows", "You can't show sticky windows (use /WINDOW STICK OFF)", 0 }, - { "window_not_sticky", "Window is not sticky", 0 }, - { "window_set_sticky", "Window set sticky", 0 }, - { "window_unset_sticky", "Window is not sticky anymore", 0 }, - { "window_info_sticky", "%#Sticky : $0", 1, { 0 } }, - { "window_info_scroll", "%#Scroll : $0", 1, { 0 } }, - { "window_scroll", "Window scroll mode is now $0", 1, { 0 } }, - { "window_scroll_unknown", "Unknown scroll mode $0, must be ON, OFF or DEFAULT", 1, { 0 } }, - - /* ---- */ - { NULL, "Statusbars", 0 }, - - { "statusbar_list_header", "%#Name Type Placement Position Visible", 0 }, - { "statusbar_list_footer", "", 0 }, - { "statusbar_list", "%#$[30]0 $[6]1 $[9]2 $[8]3 $4", 5, { 0, 0, 0, 1, 0 } }, - { "statusbar_info_name", "%#Statusbar: {hilight $0}", 1, { 0 } }, - { "statusbar_info_type", "%#Type : $0", 1, { 0 } }, - { "statusbar_info_placement", "%#Placement: $0", 1, { 0 } }, - { "statusbar_info_position", "%#Position : $0", 1, { 1 } }, - { "statusbar_info_visible", "%#Visible : $0", 1, { 0 } }, - { "statusbar_info_item_header", "%#Items : Name Priority Alignment", 0 }, - { "statusbar_info_item_footer", "", 0 }, - { "statusbar_info_item_name", "%# : $[35]0 $[9]1 $2", 3, { 0, 1, 0 } }, - { "statusbar_not_found", "Statusbar doesn't exist: $0", 1, { 0 } }, - { "statusbar_item_not_found", "Statusbar item doesn't exist: $0", 1, { 0 } }, - { "statusbar_unknown_command", "Unknown statusbar command: $0", 1, { 0 } }, - { "statusbar_unknown_type", "Statusbar type must be 'window' or 'root'", 1, { 0 } }, - { "statusbar_unknown_placement", "Statusbar placement must be 'top' or 'bottom'", 1, { 0 } }, - { "statusbar_unknown_visibility", "Statusbar visibility must be 'always', 'active' or 'inactive'", 1, { 0 } }, - - /* ---- */ - { NULL, "Pasting", 0 }, - - { "paste_warning", "Pasting $0 lines to $1. Press Ctrl-K if you wish to do this or Ctrl-C to cancel.", 2, { 1, 0 } }, - { "paste_prompt", "Hit Ctrl-K to paste, Ctrl-C to abort?", 0 }, - - { NULL, NULL, 0 } -}; diff --git a/src/fe-fuzz/module-formats.h b/src/fe-fuzz/module-formats.h deleted file mode 100644 index 3fa8c511..00000000 --- a/src/fe-fuzz/module-formats.h +++ /dev/null @@ -1,58 +0,0 @@ -#include "formats.h" - -enum { - TXT_MODULE_NAME, - - TXT_FILL_1, - - TXT_LASTLOG_TOO_LONG, - TXT_LASTLOG_COUNT, - TXT_LASTLOG_START, - TXT_LASTLOG_END, - TXT_LASTLOG_SEPARATOR, - TXT_LASTLOG_DATE, - - TXT_FILL_2, - - TXT_REFNUM_NOT_FOUND, - TXT_WINDOW_TOO_SMALL, - TXT_CANT_HIDE_LAST, - TXT_CANT_HIDE_STICKY_WINDOWS, - TXT_CANT_SHOW_STICKY_WINDOWS, - TXT_WINDOW_NOT_STICKY, - TXT_WINDOW_SET_STICKY, - TXT_WINDOW_UNSET_STICKY, - TXT_WINDOW_INFO_STICKY, - TXT_WINDOW_INFO_SCROLL, - TXT_WINDOW_SCROLL, - TXT_WINDOW_SCROLL_UNKNOWN, - - TXT_FILL_3, - - TXT_STATUSBAR_LIST_HEADER, - TXT_STATUSBAR_LIST_FOOTER, - TXT_STATUSBAR_LIST, - TXT_STATUSBAR_INFO_NAME, - TXT_STATUSBAR_INFO_TYPE, - TXT_STATUSBAR_INFO_PLACEMENT, - TXT_STATUSBAR_INFO_POSITION, - TXT_STATUSBAR_INFO_VISIBLE, - TXT_STATUSBAR_INFO_ITEM_HEADER, - TXT_STATUSBAR_INFO_ITEM_FOOTER, - TXT_STATUSBAR_INFO_ITEM_NAME, - TXT_STATUSBAR_NOT_FOUND, - TXT_STATUSBAR_ITEM_NOT_FOUND, - TXT_STATUSBAR_UNKNOWN_COMMAND, - TXT_STATUSBAR_UNKNOWN_TYPE, - TXT_STATUSBAR_UNKNOWN_PLACEMENT, - TXT_STATUSBAR_UNKNOWN_VISIBILITY, - - TXT_FILL_4, - - TXT_PASTE_WARNING, - TXT_PASTE_PROMPT, - - TXT_COUNT -}; - -extern FORMAT_REC gui_text_formats[TXT_COUNT+1]; From b15c27cc63fa967f3e8fe98fdc6d093dd8692c93 Mon Sep 17 00:00:00 2001 From: dx Date: Tue, 10 Jan 2017 03:09:36 -0300 Subject: [PATCH 0048/1198] Revert "Don't reset wait_cmd during connection registration (fixes early ISON)" --- src/irc/core/irc-servers.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 7cbd05a0..3117e345 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -527,12 +527,6 @@ void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len) return; } - /* Don't reset wait_cmd during connection registration - * (while sending CAP / SASL related commands) */ - if (!server->connected) { - return; - } - g_get_current_time(&server->last_cmd); /* A bit kludgy way to do the flood protection. In ircnet, there From fe1ea4b80a3467c23b1ec2d30bdfe4cfaf9b94d6 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 12 Jan 2017 18:11:09 -0500 Subject: [PATCH 0049/1198] Fix fe-fuzz nits --- configure.ac | 1 - src/fe-fuzz/irssi.c | 1 - 2 files changed, 2 deletions(-) diff --git a/configure.ac b/configure.ac index 03c7ddf5..8d1ba706 100644 --- a/configure.ac +++ b/configure.ac @@ -650,7 +650,6 @@ echo echo "Building text frontend ........... : $want_textui" echo "Building irssi bot ............... : $want_irssibot" -echo "Building irssi fuzzer ............ : $want_irssifuzzer" echo "Building irssi proxy ............. : $want_irssiproxy" if test "x$have_gmodule" = "xyes"; then echo "Building with module support ..... : yes" diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c index 12c61147..77892aaf 100644 --- a/src/fe-fuzz/irssi.c +++ b/src/fe-fuzz/irssi.c @@ -28,7 +28,6 @@ #include "args.h" #include "printtext.h" -#include #include #include #include From 677fb1f55ca52d0e43c93f7d8361d333ff5bffd6 Mon Sep 17 00:00:00 2001 From: Hanno Date: Sun, 15 Jan 2017 22:20:23 +0100 Subject: [PATCH 0050/1198] perl_parse needs NULL terminated parameter list. --- src/perl/perl-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 2c61df70..e4bde559 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -41,7 +41,7 @@ GSList *perl_scripts; PerlInterpreter *my_perl; static int print_script_errors; -static char *perl_args[] = {"", "-e", "0"}; +static char *perl_args[] = {"", "-e", "0", NULL}; #define IS_PERL_SCRIPT(file) \ (strlen(file) > 3 && g_strcmp0(file+strlen(file)-3, ".pl") == 0) @@ -123,7 +123,7 @@ void perl_scripts_init(void) my_perl = perl_alloc(); perl_construct(my_perl); - perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args), perl_args, NULL); + perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args)-1, perl_args, NULL); #if PERL_STATIC_LIBS == 1 perl_eval_pv("Irssi::Core::->boot_Irssi_Core(0.9);", TRUE); #endif From c8dafe2a76f199f35e24440ca85796454717965e Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 16 Jan 2017 12:56:33 -0500 Subject: [PATCH 0051/1198] Add SUPPRESS_PRINTF_FALLBACK There are some cases (such as fuzzing with fe-fuzz) where suppressing printf output may be desirable. --- src/fe-common/core/printtext.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index ba6f3242..01ef2dcd 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -446,7 +446,9 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text) if (dest->window == NULL) { str = strip_codes(text); +#ifndef SUPPRESS_PRINTF_FALLBACK printf("NO WINDOWS: %s\n", str); +#endif g_free(str); return; } From 6221ce520644efe4095bfecbc29f11c9c6962e0f Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 16 Jan 2017 13:04:54 -0500 Subject: [PATCH 0052/1198] Fix glib-2.0.m4 so that $PKG_CONFIG doesn't break configure script If $PKG_CONFIG contains a space, then the test may not work, so surround with quotation mark characters. (for example, PKG_CONFIG="pkg-config --static" breaks configure before this commit). --- m4/glib-2.0.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/glib-2.0.m4 b/m4/glib-2.0.m4 index 2c8760b7..5b7c84c0 100644 --- a/m4/glib-2.0.m4 +++ b/m4/glib-2.0.m4 @@ -43,7 +43,7 @@ AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run min_glib_version=ifelse([$1], ,2.0.0,$1) AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) - if test x$PKG_CONFIG != xno ; then + if test "x$PKG_CONFIG" != xno ; then ## don't try to run the test against uninstalled libtool libs if $PKG_CONFIG --uninstalled $pkg_config_args; then echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" From bc1ff509d2a9dc5592e7c2cb996d0c32cde026ff Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 19 Jan 2017 21:09:56 +0100 Subject: [PATCH 0053/1198] sync mail.pl --- scripts/mail.pl | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/scripts/mail.pl b/scripts/mail.pl index 190c33af..ded02120 100644 --- a/scripts/mail.pl +++ b/scripts/mail.pl @@ -30,6 +30,7 @@ $VERSION = "2.92"; # Check /mailbox help for help. use Irssi::TextUI; +use Irssi; my $maildirmode = 0; # maildir=1, file(spools)=0 my $old_is_not_new = 0; @@ -37,7 +38,7 @@ my $extprog; my ($last_refresh_time, $refresh_tag); # for mbox caching -my $last_size, $last_mtime, $last_mailcount, $last_mode; +my ($last_size, $last_mtime, $last_mailcount, $last_mode); # list of mailboxes my %mailboxes = (); @@ -101,8 +102,9 @@ sub mbox_count { my $old_is_not_new=Irssi::settings_get_bool('mail_oldnotnew'); if ($extprog ne "") { - $total = `$extprog`; - chomp $unread; + my $total = `$extprog`; + chomp $total; + ($read, $unread) = split ' ', $total, 2; } else { if (!$maildirmode) { if (-f $mailfile) { @@ -115,8 +117,7 @@ sub mbox_count { $last_size = $size; $last_mtime = $mtime; - my $f = gensym; - return 0 if (!open($f, "<", $mailfile)); + return 0 if (!open(my $f, "<", $mailfile)); # count new mails only my $internal_removed = 0; @@ -205,7 +206,7 @@ sub mail { my $total = 0; # check all mailboxes for new email - foreach $name (keys(%mailboxes)) { + foreach my $name (keys(%mailboxes)) { my $box = $mailboxes{$name}; # replace "~/" at the beginning by the user's home dir $box =~ s/^~\//$ENV{'HOME'}\//; @@ -233,7 +234,7 @@ sub mail { # Show this only if there are any new, unread messages. if (Irssi::settings_get_bool('mail_show_message') && $unread > $new_mails_in_box{$name}) { - $new_mails = $unread - $new_mails_in_box{$name}; + my $new_mails = $unread - $new_mails_in_box{$name}; if ($nummailboxes == 1) { Irssi::print("You have $new_mails new message" . ($new_mails != 1 ? "s." : "."), MSGLEVEL_CRAP); } else { @@ -263,11 +264,9 @@ sub add_mailboxes { my $boxstring = $_[0]; my @boxes = split(/,/, $boxstring); - foreach $dbox(@boxes) { - my $name = $dbox; - $name = substr($dbox, 0, index($dbox, '=')); - my $box = $dbox; - $box = substr($dbox, index($dbox, '=') + 1, length($dbox)); + foreach my $dbox(@boxes) { + my $name = substr($dbox, 0, index($dbox, '=')); + my $box = substr($dbox, index($dbox, '=') + 1, length($dbox)); addmailbox($name, $box); } } @@ -306,7 +305,7 @@ sub delmailbox { sub update_settings_string { my $setting; - foreach $name (keys(%mailboxes)) { + foreach my $name (keys(%mailboxes)) { $setting .= $name . "=" . $mailboxes{$name} . ","; } @@ -345,7 +344,7 @@ sub cmd_showmailboxes { return; } Irssi::print("Mailboxes:", MSGLEVEL_CRAP); - foreach $box (keys(%mailboxes)) { + foreach my $box (keys(%mailboxes)) { Irssi::print("$box: " . $mailboxes{$box}, MSGLEVEL_CRAP); } } From 876c1dd93e06b9e627918f142f547e3deea682be Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 20 Jan 2017 10:32:23 +0100 Subject: [PATCH 0054/1198] implement break_wide for more pleasant east asian mixed display --- src/fe-text/gui-windows.c | 10 +++++++--- src/fe-text/textbuffer-view.c | 12 +++++++++++- src/fe-text/textbuffer-view.h | 3 +++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 4213149d..c63c495c 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -49,6 +49,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, settings_get_int("indent"), !settings_get_bool("indent_always"), get_default_indent_func()); + textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); if (parent->active == window) textbuffer_view_set_window(gui->view, parent->screen_win); return gui; @@ -201,12 +202,14 @@ void gui_windows_reset_settings(void) for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; - GUI_WINDOW_REC *gui = WINDOW_GUI(rec); + GUI_WINDOW_REC *gui = WINDOW_GUI(rec); - textbuffer_view_set_default_indent(gui->view, + textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); + + textbuffer_view_set_default_indent(gui->view, settings_get_int("indent"), !settings_get_bool("indent_always"), - get_default_indent_func()); + get_default_indent_func()); textbuffer_view_set_scroll(gui->view, gui->use_scroll ? gui->scroll : @@ -281,6 +284,7 @@ void gui_windows_init(void) settings_add_bool("lookandfeel", "autostick_split_windows", TRUE); settings_add_int("lookandfeel", "indent", 10); settings_add_bool("lookandfeel", "indent_always", FALSE); + settings_add_bool("lookandfeel", "break_wide", FALSE); settings_add_bool("lookandfeel", "scroll", TRUE); window_create_override = -1; diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index e2e3707b..486b7234 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -307,7 +307,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) continue; } - if (!view->utf8 && char_width > 1) { + if (view->break_wide && char_width > 1) { last_space = xpos; last_space_ptr = next_ptr; last_color = color; last_fg24 = fg24; last_bg24 = bg24; @@ -665,6 +665,16 @@ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view, view->default_indent_func = indent_func; } +/* Enable breaking of wide chars */ +void textbuffer_view_set_break_wide(TEXT_BUFFER_VIEW_REC *view, + gboolean break_wide) +{ + if (view->break_wide != break_wide) { + view->break_wide = break_wide; + view_reset_cache(view); + } +} + static void view_unregister_indent_func(TEXT_BUFFER_VIEW_REC *view, INDENT_FUNC indent_func) { diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index 21a9bde6..5e7a9d0a 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -59,6 +59,7 @@ struct _TEXT_BUFFER_VIEW_REC { unsigned int longword_noindent:1; unsigned int scroll:1; /* scroll down automatically when at bottom */ unsigned int utf8:1; /* use UTF8 in this view */ + unsigned int break_wide:1; /* Break wide chars in this view */ TEXT_BUFFER_CACHE_REC *cache; int ypos; /* cursor position - visible area is 0..height-1 */ @@ -97,6 +98,8 @@ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view, int longword_noindent, INDENT_FUNC indent_func); void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func); +void textbuffer_view_set_break_wide(TEXT_BUFFER_VIEW_REC *view, + gboolean break_wide); void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll); void textbuffer_view_set_utf8(TEXT_BUFFER_VIEW_REC *view, int utf8); From 697dd19d887c58930c76de68268d58f2251904d6 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 22 Jan 2017 21:49:37 +0100 Subject: [PATCH 0055/1198] Check whether the client certificate is expired. Right now we only warn the user, the connection keeps going. Fixes #211 --- src/core/network-openssl.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 1eb85341..001e2d9d 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -420,16 +420,38 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ if (mycert && *mycert) { char *scert = NULL, *spkey = NULL; + FILE *fp; scert = convert_home(mycert); if (mypkey && *mypkey) spkey = convert_home(mypkey); - ERR_clear_error(); - if (! SSL_CTX_use_certificate_file(ctx, scert, SSL_FILETYPE_PEM)) - g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); - else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM)) - g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error())); - else if (! SSL_CTX_check_private_key(ctx)) - g_warning("Private key does not match the certificate"); + + if ((fp = fopen(scert, "r"))) { + X509 *cert; + /* Let's parse the certificate by hand instead of using + * SSL_CTX_use_certificate_file so that we can validate + * some parts of it. */ + cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass); + if (cert != NULL) { + /* Only the expiration date is checked right now */ + if (X509_cmp_current_time(X509_get_notAfter(cert)) <= 0 || + X509_cmp_current_time(X509_get_notBefore(cert)) >= 0) + g_warning("The client certificate is expired"); + + ERR_clear_error(); + if (! SSL_CTX_use_certificate(ctx, cert)) + g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); + else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM)) + g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error())); + else if (! SSL_CTX_check_private_key(ctx)) + g_warning("Private key does not match the certificate"); + + X509_free(cert); + } else + g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error())); + + fclose(fp); + } else + g_warning("Could not find client certificate '%s'", scert); g_free(scert); g_free(spkey); } From 19c51789967a2f63da033e60f6ef08848b9cd144 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 24 Jan 2017 22:19:50 +0100 Subject: [PATCH 0056/1198] Prevent a memory leak during the processing of the SASL response. We also get rid of an allocation in the process of doing so. --- src/irc/core/sasl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 1021bea4..635b7dfb 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -174,10 +174,16 @@ static gboolean sasl_reassemble_incoming(IRC_SERVER_REC *server, const char *fra *decoded = g_string_new_len("", 0); } else { gsize dec_len; - gchar *tmp; + gint state = 0; + guint save = 0; - tmp = (gchar *) g_base64_decode(enc_req->str, &dec_len); - *decoded = g_string_new_len(tmp, dec_len); + /* Since we're not going to use the enc_req GString anymore we + * can perform the decoding in place. */ + dec_len = g_base64_decode_step(enc_req->str, enc_req->len, + (guchar *)enc_req->str, + &state, &save); + /* A copy of the data is made when the GString is created. */ + *decoded = g_string_new_len(enc_req->str, dec_len); } g_string_free(enc_req, TRUE); From 73e8a065bd24092a03c0938eb6c93fec3ee0f4d9 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 23 Jan 2017 16:53:30 +0100 Subject: [PATCH 0057/1198] Support OpenSSL 1.1.0. - X509_get_notBefore becomes X509_get0_notBefore - X509_get_notAfter becomes X509_get0_notAfter - ASN1_STRING_data becomes ASN1_STRING_get0_data (and drops the const) - The whole library is now initialized by OPENSSL_init_ssl Closes #597 --- src/core/network-openssl.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 1eb85341..f193a61e 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -32,6 +32,17 @@ #include #include +/* OpenSSL 1.1.0 introduced some backward-incompatible changes to the api */ +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +/* 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 +#undef X509_get_notAfter +#define X509_get_notBefore(x) X509_get0_notBefore(x) +#define X509_get_notAfter(x) X509_get0_notAfter(x) +#define ASN1_STRING_data(x) ASN1_STRING_get0_data(x) +#endif + /* ssl i/o channel object */ typedef struct { @@ -352,13 +363,19 @@ static GIOFuncs irssi_ssl_channel_funcs = { static gboolean irssi_ssl_init(void) { +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) + if (!OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL)) { + g_error("Could not initialize OpenSSL"); + return FALSE; + } +#else SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); +#endif ssl_inited = TRUE; return TRUE; - } static int get_pem_password_callback(char *buffer, int max_length, int rwflag, void *pass) From 7c49ed2d17d2325d7bceef632ac38b66a44e8b63 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Jan 2017 12:44:02 +0100 Subject: [PATCH 0058/1198] Merge pull request #602 from McDutchie/master make irssi --with-perl build with separate object directory --- src/perl/common/Makefile.PL.in | 2 +- src/perl/irc/Makefile.PL.in | 2 +- src/perl/textui/Makefile.PL.in | 2 +- src/perl/ui/Makefile.PL.in | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/perl/common/Makefile.PL.in b/src/perl/common/Makefile.PL.in index 84a80403..70b1d258 100644 --- a/src/perl/common/Makefile.PL.in +++ b/src/perl/common/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi', 'LIBS' => '', diff --git a/src/perl/irc/Makefile.PL.in b/src/perl/irc/Makefile.PL.in index 0fbc5241..582160a0 100644 --- a/src/perl/irc/Makefile.PL.in +++ b/src/perl/irc/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::Irc', 'LIBS' => '', diff --git a/src/perl/textui/Makefile.PL.in b/src/perl/textui/Makefile.PL.in index 3541f75c..ffdda21a 100644 --- a/src/perl/textui/Makefile.PL.in +++ b/src/perl/textui/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::TextUI', 'LIBS' => '', diff --git a/src/perl/ui/Makefile.PL.in b/src/perl/ui/Makefile.PL.in index ed87d528..ceed51c3 100644 --- a/src/perl/ui/Makefile.PL.in +++ b/src/perl/ui/Makefile.PL.in @@ -1,4 +1,4 @@ -use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "../Makefile_silent.pm"; +use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';require "@top_srcdir@/src/perl/Makefile_silent.pm"; WriteMakefile('NAME' => 'Irssi::UI', 'LIBS' => '', From 8dbf186ad6e808c269fa10c22444c89df63f2d7d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Jan 2017 16:37:09 +0100 Subject: [PATCH 0059/1198] Merge pull request #604 from dequis/solaris Add OPENSSL_NO_EC for solaris 11.3, see issue #598 --- src/core/network-openssl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 7a1d6e34..1eb85341 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -646,7 +646,11 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) #ifdef SSL_get_server_tmp_key // Show ephemeral key information. EVP_PKEY *ephemeral_key = NULL; + + // OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 +#ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; +#endif char *ephemeral_key_algorithm = NULL; char *cname = NULL; int nid; @@ -658,6 +662,7 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; +#ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(ephemeral_key); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); @@ -670,6 +675,7 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) g_free_and_null(ephemeral_key_algorithm); break; +#endif default: tls_rec_set_ephemeral_key_algorithm(tls, "Unknown"); From 3a3b34fc633fe8e045bf4b696c41857c9f8c5ba5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Jan 2017 17:00:09 +0100 Subject: [PATCH 0060/1198] Merge pull request #606 from or4n/master Fix syntax on /help SERVER example --- docs/help/in/server.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 60870111..44de0efc 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -64,7 +64,7 @@ /SERVER CONNECT chat.freenode.net /SERVER CONNECT +chat.freenode.net /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -port 6667 -4 -network Freenode -noproxy orwell.freenode.net + /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 /SERVER MODIFY -network Freenode -noauto orwell.freenode.net /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE From 929c9477477a4ccf03626388499192d8003b96d5 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 8 Jan 2017 21:55:39 +0100 Subject: [PATCH 0061/1198] Merge pull request #608 from tijko/master Follow g_strsplit with call to g_strfreev --- src/irc/core/modes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index 207461cc..cc3d0faf 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -743,6 +743,7 @@ static char *get_nicks(IRC_SERVER_REC *server, WI_ITEM_REC *item, g_hash_table_lookup(optlist, "yes") == NULL) { /* too many matches */ g_string_free(str, TRUE); + g_strfreev(matches); cmd_params_free(free_arg); signal_emit("error command", 1, @@ -756,7 +757,7 @@ static char *get_nicks(IRC_SERVER_REC *server, WI_ITEM_REC *item, if (str->len > 0) g_string_truncate(str, str->len-1); ret = str->str; g_string_free(str, FALSE); - + g_strfreev(matches); cmd_params_free(free_arg); *ret_channel = channel; From d63c93ae1dbb1254a92e8e4fafc39fe8d69d00ae Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 13 Jan 2017 22:36:44 +0100 Subject: [PATCH 0062/1198] Merge pull request #613 from ailin-nemui/fix_completion fix regression in completion --- src/fe-common/core/completion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 76dfbb79..914ba80b 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -191,7 +191,7 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i g_strdup_printf("%s%c%s", /* do not accidentally duplicate the word separator */ line == wordstart - 1 ? "" : linestart, - wordstart[-1], word); + old_wordstart[-1], word); g_free(old); g_free(word); From 1f42d2aa950e4d70bf4c4aebae3a7040bd710cf3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 15 Jan 2017 22:33:42 +0100 Subject: [PATCH 0063/1198] Merge pull request #619 from hannob/master perl_parse needs NULL terminated parameter list. --- src/perl/perl-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 2c61df70..e4bde559 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -41,7 +41,7 @@ GSList *perl_scripts; PerlInterpreter *my_perl; static int print_script_errors; -static char *perl_args[] = {"", "-e", "0"}; +static char *perl_args[] = {"", "-e", "0", NULL}; #define IS_PERL_SCRIPT(file) \ (strlen(file) > 3 && g_strcmp0(file+strlen(file)-3, ".pl") == 0) @@ -123,7 +123,7 @@ void perl_scripts_init(void) my_perl = perl_alloc(); perl_construct(my_perl); - perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args), perl_args, NULL); + perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args)-1, perl_args, NULL); #if PERL_STATIC_LIBS == 1 perl_eval_pv("Irssi::Core::->boot_Irssi_Core(0.9);", TRUE); #endif From ca5e9bd623862bd9a640bf8799aafa53502b79f6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 21 Jan 2017 03:52:31 +0100 Subject: [PATCH 0064/1198] Merge pull request #624 from ailin-nemui/mail_pl sync mail.pl --- scripts/mail.pl | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/scripts/mail.pl b/scripts/mail.pl index 190c33af..ded02120 100644 --- a/scripts/mail.pl +++ b/scripts/mail.pl @@ -30,6 +30,7 @@ $VERSION = "2.92"; # Check /mailbox help for help. use Irssi::TextUI; +use Irssi; my $maildirmode = 0; # maildir=1, file(spools)=0 my $old_is_not_new = 0; @@ -37,7 +38,7 @@ my $extprog; my ($last_refresh_time, $refresh_tag); # for mbox caching -my $last_size, $last_mtime, $last_mailcount, $last_mode; +my ($last_size, $last_mtime, $last_mailcount, $last_mode); # list of mailboxes my %mailboxes = (); @@ -101,8 +102,9 @@ sub mbox_count { my $old_is_not_new=Irssi::settings_get_bool('mail_oldnotnew'); if ($extprog ne "") { - $total = `$extprog`; - chomp $unread; + my $total = `$extprog`; + chomp $total; + ($read, $unread) = split ' ', $total, 2; } else { if (!$maildirmode) { if (-f $mailfile) { @@ -115,8 +117,7 @@ sub mbox_count { $last_size = $size; $last_mtime = $mtime; - my $f = gensym; - return 0 if (!open($f, "<", $mailfile)); + return 0 if (!open(my $f, "<", $mailfile)); # count new mails only my $internal_removed = 0; @@ -205,7 +206,7 @@ sub mail { my $total = 0; # check all mailboxes for new email - foreach $name (keys(%mailboxes)) { + foreach my $name (keys(%mailboxes)) { my $box = $mailboxes{$name}; # replace "~/" at the beginning by the user's home dir $box =~ s/^~\//$ENV{'HOME'}\//; @@ -233,7 +234,7 @@ sub mail { # Show this only if there are any new, unread messages. if (Irssi::settings_get_bool('mail_show_message') && $unread > $new_mails_in_box{$name}) { - $new_mails = $unread - $new_mails_in_box{$name}; + my $new_mails = $unread - $new_mails_in_box{$name}; if ($nummailboxes == 1) { Irssi::print("You have $new_mails new message" . ($new_mails != 1 ? "s." : "."), MSGLEVEL_CRAP); } else { @@ -263,11 +264,9 @@ sub add_mailboxes { my $boxstring = $_[0]; my @boxes = split(/,/, $boxstring); - foreach $dbox(@boxes) { - my $name = $dbox; - $name = substr($dbox, 0, index($dbox, '=')); - my $box = $dbox; - $box = substr($dbox, index($dbox, '=') + 1, length($dbox)); + foreach my $dbox(@boxes) { + my $name = substr($dbox, 0, index($dbox, '=')); + my $box = substr($dbox, index($dbox, '=') + 1, length($dbox)); addmailbox($name, $box); } } @@ -306,7 +305,7 @@ sub delmailbox { sub update_settings_string { my $setting; - foreach $name (keys(%mailboxes)) { + foreach my $name (keys(%mailboxes)) { $setting .= $name . "=" . $mailboxes{$name} . ","; } @@ -345,7 +344,7 @@ sub cmd_showmailboxes { return; } Irssi::print("Mailboxes:", MSGLEVEL_CRAP); - foreach $box (keys(%mailboxes)) { + foreach my $box (keys(%mailboxes)) { Irssi::print("$box: " . $mailboxes{$box}, MSGLEVEL_CRAP); } } From 97b182089eec8cc158313c424b453dcaa39e05af Mon Sep 17 00:00:00 2001 From: Nei Date: Fri, 3 Feb 2017 11:49:16 +0000 Subject: [PATCH 0065/1198] Merge branch 'dub-the-wub' into 'master' Prevent a memory leak during the processing of the SASL response. See merge request !8 --- src/irc/core/sasl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 1021bea4..635b7dfb 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -174,10 +174,16 @@ static gboolean sasl_reassemble_incoming(IRC_SERVER_REC *server, const char *fra *decoded = g_string_new_len("", 0); } else { gsize dec_len; - gchar *tmp; + gint state = 0; + guint save = 0; - tmp = (gchar *) g_base64_decode(enc_req->str, &dec_len); - *decoded = g_string_new_len(tmp, dec_len); + /* Since we're not going to use the enc_req GString anymore we + * can perform the decoding in place. */ + dec_len = g_base64_decode_step(enc_req->str, enc_req->len, + (guchar *)enc_req->str, + &state, &save); + /* A copy of the data is made when the GString is created. */ + *decoded = g_string_new_len(enc_req->str, dec_len); } g_string_free(enc_req, TRUE); From 8ec923082737276bce122e082998928ac038bf7f Mon Sep 17 00:00:00 2001 From: Paolo Date: Sun, 5 Feb 2017 01:03:02 +0100 Subject: [PATCH 0066/1198] Make themes' docs more consistent. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mentioning "sb-item" was misleading in that there is no such template, nor any occurrence of that exact string anywhere else in the source. In going from `sb-item` to `"sb"` I am following the pattern established in a couple of comments above: "msgownnick" specifies the styling … "ownmsgnick" specifies … --- colorless.theme | 4 ++-- default.theme | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/colorless.theme b/colorless.theme index 668866f5..1b26f628 100644 --- a/colorless.theme +++ b/colorless.theme @@ -261,8 +261,8 @@ abstracts = { # background for topicbar (same default) #sb_topic_bg = "%8"; - # text at the beginning of statusbars. sb-item already puts - # space there,so we don't use anything by default. + # text at the beginning of statusbars. "sb" already puts a space there, + # so we don't use anything by default. sbstart = ""; # text at the end of statusbars. Use space so that it's never # used for anything. diff --git a/default.theme b/default.theme index 6b6aeab8..956d7c4f 100644 --- a/default.theme +++ b/default.theme @@ -261,8 +261,8 @@ abstracts = { # background for topicbar (same default) #sb_topic_bg = "%4"; - # text at the beginning of statusbars. sb-item already puts - # space there,so we don't use anything by default. + # text at the beginning of statusbars. "sb" already puts a space there, + # so we don't use anything by default. sbstart = ""; # text at the end of statusbars. Use space so that it's never # used for anything. From 99e3d8a30bdf68775825eb79e5c29f3af12cd255 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 3 Feb 2017 20:46:20 +0100 Subject: [PATCH 0067/1198] tag as 1.0.1 --- NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 9604277a..f2af5810 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +v1.0.1 2017-02-03 The Irssi team + - Fix Perl compilation in object dir. By Martijn Dekker (#602, #623). + - Disable EC cryptography on Solaris to fix build (#604, #598). + - Fix incorrect HELP SERVER example (#606, #519). + - Correct memory leak in /OP and /VOICE. By Tim Konick (#608). + - Fix regression that broke second level completion (#613, #609). + - Correct missing NULL termination in perl_parse. By Hanno Böck (#619). + - Sync broken mail.pl script (#624, #607). + v1.0.0 2017-01-03 The Irssi team * Removed --disable-ipv6 (#408). * /connect Network now aborts with an error if no servers have been diff --git a/configure.ac b/configure.ac index 4aa1f3cc..4a96920c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.0.0) +AC_INIT(irssi, 1.0.1) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 28df637055bc6f20f26ec40158f428ed4dac3c3d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 16 Jan 2017 20:04:11 +0100 Subject: [PATCH 0068/1198] provide net_start_ssl api fixes #615 --- src/common.h | 2 +- src/core/network-openssl.c | 16 ++++++++++++++++ src/core/network.h | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 43596580..646b7e1a 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 7 +#define IRSSI_ABI_VERSION 8 #define DEFAULT_SERVER_ADD_PORT 6667 diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 1eb85341..aab9176d 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -20,6 +20,7 @@ #include "module.h" #include "network.h" +#include "net-sendbuffer.h" #include "misc.h" #include "servers.h" #include "signals.h" @@ -701,6 +702,21 @@ GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC * return ssl_handle; } +GIOChannel *net_start_ssl(SERVER_REC *server) +{ + GIOChannel *handle, *ssl_handle; + + g_return_val_if_fail(server != NULL, NULL); + + handle = net_sendbuffer_handle(server->handle); + if (handle == NULL) + return NULL; + + ssl_handle = irssi_ssl_get_iochannel(handle, server->connrec->port, server); + return ssl_handle; +} + + int irssi_ssl_handshake(GIOChannel *handle) { GIOSSLChannel *chan = (GIOSSLChannel *)handle; diff --git a/src/core/network.h b/src/core/network.h index 03f3b813..8757f78c 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -40,6 +40,9 @@ int net_ip_compare(IPADDR *ip1, IPADDR *ip2); GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) G_GNUC_DEPRECATED; /* Connect to socket with ip address and SSL*/ GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server); +/* Start TLS */ +GIOChannel *net_start_ssl(SERVER_REC *server); + int irssi_ssl_handshake(GIOChannel *handle); /* Connect to socket with ip address */ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); From 15736ba5ab63d62bfbf8c7907835e5530ba58311 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 11 Feb 2017 00:07:03 -0300 Subject: [PATCH 0069/1198] notify-ison: Don't send ison before the connection is done --- src/irc/notifylist/notify-ison.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index f9ca7b37..8a8865cc 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -80,6 +80,10 @@ static void ison_send(IRC_SERVER_REC *server, GString *cmd) { MODULE_SERVER_REC *mserver; + if (!server->connected) { + return; + } + mserver = MODULE_DATA(server); mserver->ison_count++; From 98ead50b4eea7cda4b357f1c4b19a741205c6fa4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 14 Feb 2017 13:38:59 +0100 Subject: [PATCH 0070/1198] Prevent some potential null-pointer deferences. Spotted by our friend scan-build. --- src/fe-common/core/fe-channels.c | 2 +- src/fe-common/irc/fe-netsplit.c | 2 ++ src/fe-text/mainwindows-layout.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-channels.c b/src/fe-common/core/fe-channels.c index 00aac885..8e434ab5 100644 --- a/src/fe-common/core/fe-channels.c +++ b/src/fe-common/core/fe-channels.c @@ -453,7 +453,7 @@ static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist) } } - if (str->len > strlen(prefix_format)) { + if (prefix_format != NULL && str->len > strlen(prefix_format)) { printtext(channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP, "%s", str->str); } diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 17fb1994..4c69dd10 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -148,6 +148,8 @@ static void print_server_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec, con char *sourceserver; GSList *tmp; + g_return_if_fail(rec->servers != NULL); + destservers = g_string_new(NULL); for (tmp = rec->servers; tmp != NULL; tmp = tmp->next) { NETSPLIT_SERVER_REC *rec = tmp->data; diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index 020969e6..fae02539 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -121,6 +121,8 @@ static void sig_layout_restore(void) if (node == NULL) return; sorted_config = get_sorted_windows_config(node); + if (sorted_config == NULL) return; + windows_count = g_slist_length(sorted_config); /* calculate the saved terminal height */ From c067f8e99b9332ca485bf1e1809b745878c80f4a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 14 Feb 2017 22:04:35 +0100 Subject: [PATCH 0071/1198] Do not alias /server to /server connect Closes #559. --- docs/help/in/server.in | 2 -- src/core/chat-commands.c | 19 ++++++------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 44de0efc..2e757260 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -59,8 +59,6 @@ %9Examples:%9 /SERVER - /SERVER chat.freenode.net - /SERVER +chat.freenode.net /SERVER CONNECT chat.freenode.net /SERVER CONNECT +chat.freenode.net /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index c737b810..69c2fc91 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -250,19 +250,14 @@ static void cmd_server(const char *data, SERVER_REC *server, WI_ITEM_REC *item) command_runsub("server", data, server, item); } -static void sig_default_command_server(const char *data, SERVER_REC *server, - WI_ITEM_REC *item) -{ - signal_emit("command server connect", 3, data, server, item); -} - -/* SYNTAX: SERVER [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] - [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] - [-ssl_ciphers ] - [-!] [-noautosendcmd] +/* SYNTAX: SERVER CONNECT [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] + [-ssl_pass ] [-ssl_verify] [-ssl_cafile ] + [-ssl_capath ] + [-ssl_ciphers ] + [-!] [-noautosendcmd] [-noproxy] [-network ] [-host ] [-rawlog ] - [+]
| [ [ []]] */ + [+]
| [ [ []]] */ /* NOTE: -network replaces the old -ircnet flag. */ static void cmd_server_connect(const char *data, SERVER_REC *server) { @@ -495,7 +490,6 @@ void chat_commands_init(void) command_bind("foreach channel", NULL, (SIGNAL_FUNC) cmd_foreach_channel); command_bind("foreach query", NULL, (SIGNAL_FUNC) cmd_foreach_query); - signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server); signal_add("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); @@ -515,6 +509,5 @@ void chat_commands_deinit(void) command_unbind("foreach channel", (SIGNAL_FUNC) cmd_foreach_channel); command_unbind("foreach query", (SIGNAL_FUNC) cmd_foreach_query); - signal_remove("default command server", (SIGNAL_FUNC) sig_default_command_server); signal_remove("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); } From 9cae98e6421cb454ecc9b3b48d06cce5a042bb6a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 10 Feb 2017 13:59:50 +0100 Subject: [PATCH 0072/1198] Execute what's left in the input queue when the timeout expires. Similar to how vim behaves. --- src/fe-common/core/keyboard.c | 46 ++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index fed7f9cb..6f7907eb 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -35,6 +35,7 @@ GSList *keyinfos; static GHashTable *keys, *default_keys; +static int key_timeout; /* A cache of some sort for key presses that generate a single char only. If the key isn't used, used_keys[key] is zero. */ @@ -48,7 +49,8 @@ static int key_config_frozen; struct _KEYBOARD_REC { char *key_state; /* the ongoing key combo */ - void *gui_data; /* GUI specific data sent in "key pressed" signal */ + guint timer_tag; /* used to check when a pending combo has expired */ + void *gui_data; /* GUI specific data sent in "key pressed" signal */ }; /* Creates a new "keyboard" - this is used only for keeping track of @@ -60,6 +62,7 @@ KEYBOARD_REC *keyboard_create(void *data) rec = g_new0(KEYBOARD_REC, 1); rec->gui_data = data; + rec->timer_tag = 0; signal_emit("keyboard created", 1, rec); return rec; @@ -68,6 +71,11 @@ KEYBOARD_REC *keyboard_create(void *data) /* Destroys a keyboard */ void keyboard_destroy(KEYBOARD_REC *keyboard) { + if (keyboard->timer_tag > 0) { + g_source_remove(keyboard->timer_tag); + keyboard->timer_tag = 0; + } + signal_emit("keyboard destroyed", 1, keyboard); g_free_not_null(keyboard->key_state); @@ -592,6 +600,25 @@ static int key_states_search(const unsigned char *combo, return 0; } +static gboolean key_timeout_expired(KEYBOARD_REC *keyboard) +{ + KEY_REC *rec; + + keyboard->timer_tag = 0; + + /* So, the timeout has expired with the input queue full, let's see if + * what we've got is bound to some action. */ + rec = g_tree_lookup(key_states, keyboard->key_state); + /* Drain the queue anyway. */ + g_free_and_null(keyboard->key_state); + + if (rec != NULL) { + (void)key_emit_signal(keyboard, rec); + } + + return FALSE; +} + int key_pressed(KEYBOARD_REC *keyboard, const char *key) { KEY_REC *rec; @@ -601,6 +628,11 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key) g_return_val_if_fail(keyboard != NULL, FALSE); g_return_val_if_fail(key != NULL && *key != '\0', FALSE); + if (keyboard->timer_tag > 0) { + g_source_remove(keyboard->timer_tag); + keyboard->timer_tag = 0; + } + if (keyboard->key_state == NULL && key[1] == '\0' && !used_keys[(int) (unsigned char) key[0]]) { /* fast check - key not used */ @@ -625,6 +657,13 @@ int key_pressed(KEYBOARD_REC *keyboard, const char *key) if (g_tree_lookup(key_states, combo) != rec) { /* key combo continues.. */ keyboard->key_state = combo; + /* respect the timeout if specified by the user */ + if (key_timeout > 0) { + keyboard->timer_tag = + g_timeout_add(key_timeout, + (GSourceFunc) key_timeout_expired, + keyboard); + } return 0; } @@ -870,6 +909,9 @@ static void read_keyboard_config(void) key_config_read(tmp->data); key_configure_thaw(); + + /* any positive value other than 0 enables the timeout (in ms). */ + key_timeout = settings_get_int("key_timeout"); } void keyboard_init(void) @@ -883,6 +925,8 @@ void keyboard_init(void) key_config_frozen = 0; memset(used_keys, 0, sizeof(used_keys)); + settings_add_int("misc", "key_timeout", 0); + key_bind("command", "Run any command", NULL, NULL, (SIGNAL_FUNC) sig_command); key_bind("key", "Specify name for key binding", NULL, NULL, (SIGNAL_FUNC) sig_key); key_bind("multi", "Run multiple commands", NULL, NULL, (SIGNAL_FUNC) sig_multi); From db85ab7c90f23e00cd444728f6a5b3d1f63254df Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 21 Feb 2017 15:17:37 +0100 Subject: [PATCH 0073/1198] Quote the filename when dcc requests are auto accepted. PR #453 forces the user to quote the filenames given to /DCC commands when they contain spaces but the autoget functionality didn't get updated so the filename was always passed without quotes. Closes #656. --- src/irc/dcc/dcc-autoget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c index de23a5d1..995b3e04 100644 --- a/src/irc/dcc/dcc-autoget.c +++ b/src/irc/dcc/dcc-autoget.c @@ -70,7 +70,7 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) file = dcc_get_download_path(dcc->arg); str = g_strdup_printf(settings_get_bool("dcc_autoresume") && stat(file, &statbuf) == 0 ? - "RESUME %s %s" : "GET %s %s", + "RESUME %s \"%s\"" : "GET %s \"%s\"", dcc->nick, dcc->arg); signal_emit("command dcc", 2, str, dcc->server); g_free(file); From 027acffb4208d7e6ba8e229cbf6c3dae6f5dabaf Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 21 Feb 2017 15:54:31 +0100 Subject: [PATCH 0074/1198] Handle file names with quotes. Let's repurpose escape_string and make it more flexible by letting us choose the characters to escape. --- src/core/misc.c | 20 +++++++++++--------- src/core/misc.h | 4 ++-- src/fe-common/core/chat-completion.c | 2 +- src/irc/dcc/dcc-autoget.c | 8 ++++++-- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 1cfa15b6..03fcce59 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -724,18 +724,20 @@ int expand_escape(const char **data) } } -/* Escape all '"', "'" and '\' chars with '\' */ -char *escape_string(const char *str) +/* Escape all the characters in `what' with a backslash */ +char *escape_string(const char *str, const char *what) { - char *ret, *p; + const char *p; + char *ret; - p = ret = g_malloc(strlen(str)*2+1); - while (*str != '\0') { - if (*str == '"' || *str == '\'' || *str == '\\') - *p++ = '\\'; - *p++ = *str++; + ret = g_malloc(strlen(str) * 2 + 1); + for (p = str; *p != '\0'; p++, ret++) { + if (strchr(what, *p) != NULL) { + *ret++ = '\\'; + } + *ret = *p; } - *p = '\0'; + *ret = '\0'; return ret; } diff --git a/src/core/misc.h b/src/core/misc.h index 00637da0..9e620169 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -88,8 +88,8 @@ char *stristr_full(const char *data, const char *key); char *ascii_strup(char *str); char *ascii_strdown(char *str); -/* Escape all '"', "'" and '\' chars with '\' */ -char *escape_string(const char *str); +/* Escape all the characters in `what' with a backslash */ +char *escape_string(const char *str, const char *what); /* convert all low-ascii (<32) to ^ combinations */ char *show_lowascii(const char *str); diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 1f00feaf..4fe9509a 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1113,7 +1113,7 @@ static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item) /* the nick is quoted in case it contains '-' character. also spaces should work too now :) The nick is also escaped in case it contains '\' characters */ - target = escape_string(window_item_get_target(item)); + target = escape_string(window_item_get_target(item), "\"'\\"); str = g_strdup_printf(IS_CHANNEL(item) ? "-channel \"%s\" %s" : IS_QUERY(item) ? "-nick \"%s\" %s" : "%s %s", target, line); diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c index 995b3e04..21417211 100644 --- a/src/irc/dcc/dcc-autoget.c +++ b/src/irc/dcc/dcc-autoget.c @@ -23,6 +23,7 @@ #include "masks.h" #include "settings.h" #include "servers.h" +#include "misc.h" #include "dcc-get.h" @@ -30,7 +31,7 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) { struct stat statbuf; const char *masks; - char *str, *file; + char *str, *file, *esc_arg; int max_size; if (!IS_DCC_GET(dcc)) return; @@ -68,11 +69,14 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) /* ok. but do we want/need to resume? */ file = dcc_get_download_path(dcc->arg); + /* we have to escape the quotes as the whole file name gets quoted */ + esc_arg = escape_string(dcc->arg, "\""); str = g_strdup_printf(settings_get_bool("dcc_autoresume") && stat(file, &statbuf) == 0 ? "RESUME %s \"%s\"" : "GET %s \"%s\"", - dcc->nick, dcc->arg); + dcc->nick, esc_arg); signal_emit("command dcc", 2, str, dcc->server); + g_free(esc_arg); g_free(file); g_free(str); } From 9aaa6449a0a554c83d40b56ce0a87bd0cba8bdbf Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 27 Feb 2017 13:43:58 +0100 Subject: [PATCH 0075/1198] make foreach send commands --- src/core/chat-commands.c | 43 ++++++++++++++++++++++------ src/fe-common/core/window-commands.c | 18 ++++++++---- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 69c2fc91..e86fdf9d 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -438,41 +438,66 @@ static void cmd_foreach(const char *data, SERVER_REC *server, /* SYNTAX: FOREACH SERVER */ static void cmd_foreach_server(const char *data, SERVER_REC *server) { - GSList *list; + GSList *list; + const char *cmdchars; + char *str; + + cmdchars = settings_get_str("cmdchars"); + str = strchr(cmdchars, *data) != NULL ? g_strdup(data) : + g_strdup_printf("%c%s", *cmdchars, data); list = g_slist_copy(servers); while (list != NULL) { - signal_emit("send command", 3, data, list->data, NULL); - list = g_slist_remove(list, list->data); + signal_emit("send command", 3, str, list->data, NULL); + list = g_slist_remove(list, list->data); } + + g_free(str); } /* SYNTAX: FOREACH CHANNEL */ static void cmd_foreach_channel(const char *data) { - GSList *list; + GSList *list; + const char *cmdchars; + char *str; + + cmdchars = settings_get_str("cmdchars"); + str = strchr(cmdchars, *data) != NULL ? g_strdup(data) : + g_strdup_printf("%c%s", *cmdchars, data); list = g_slist_copy(channels); while (list != NULL) { CHANNEL_REC *rec = list->data; - signal_emit("send command", 3, data, rec->server, rec); - list = g_slist_remove(list, list->data); + signal_emit("send command", 3, str, rec->server, rec); + list = g_slist_remove(list, list->data); } + + g_free(str); } /* SYNTAX: FOREACH QUERY */ static void cmd_foreach_query(const char *data) { - GSList *list; + GSList *list; + const char *cmdchars; + char *str; + + cmdchars = settings_get_str("cmdchars"); + str = strchr(cmdchars, *data) != NULL ? g_strdup(data) : + g_strdup_printf("%c%s", *cmdchars, data); + list = g_slist_copy(queries); while (list != NULL) { QUERY_REC *rec = list->data; - signal_emit("send command", 3, data, rec->server, rec); - list = g_slist_remove(list, list->data); + signal_emit("send command", 3, str, rec->server, rec); + list = g_slist_remove(list, list->data); } + + g_free(str); } void chat_commands_init(void) diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index 9e4aab3a..57c81ac2 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -839,23 +839,31 @@ static void cmd_layout(const char *data, SERVER_REC *server, WI_ITEM_REC *item) /* SYNTAX: FOREACH WINDOW */ static void cmd_foreach_window(const char *data) { - WINDOW_REC *old; - GSList *list; + WINDOW_REC *old; + GSList *list; + const char *cmdchars; + char *str; - old = active_win; + cmdchars = settings_get_str("cmdchars"); + str = strchr(cmdchars, *data) != NULL ? g_strdup(data) : + g_strdup_printf("%c%s", *cmdchars, data); + + old = active_win; list = g_slist_copy(windows); while (list != NULL) { WINDOW_REC *rec = list->data; active_win = rec; - signal_emit("send command", 3, data, rec->active_server, + signal_emit("send command", 3, str, rec->active_server, rec->active); - list = g_slist_remove(list, list->data); + list = g_slist_remove(list, list->data); } if (g_slist_find(windows, old) != NULL) active_win = old; + + g_free(str); } void window_commands_init(void) From 7c09b72848f99886964266ff531b41c69fe138f5 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 27 Feb 2017 23:42:57 -0300 Subject: [PATCH 0076/1198] fe-netjoin: remove irc servers on "server disconnected" signal --- src/fe-common/irc/fe-netjoin.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index 4eb388c0..8272093f 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -470,6 +470,20 @@ static void read_settings(void) } } +static void sig_server_disconnected(IRC_SERVER_REC *server) +{ + NETJOIN_SERVER_REC *netjoin_server; + + g_return_if_fail(server != NULL); + + if (!IS_IRC_SERVER(server)) + return; + + if ((netjoin_server = netjoin_find_server(server))) { + netjoin_server_remove(netjoin_server); + } +} + void fe_netjoin_init(void) { settings_add_bool("misc", "hide_netsplit_quits", TRUE); @@ -480,6 +494,7 @@ void fe_netjoin_init(void) read_settings(); signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); } void fe_netjoin_deinit(void) @@ -492,6 +507,7 @@ void fe_netjoin_deinit(void) } signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("message quit", (SIGNAL_FUNC) msg_quit); signal_remove("message join", (SIGNAL_FUNC) msg_join); From 5c4e6304ce12a3c94cc58eec01d4ef45db4dabc3 Mon Sep 17 00:00:00 2001 From: Stephen Oberholtzer Date: Tue, 28 Feb 2017 23:48:56 -0500 Subject: [PATCH 0077/1198] Don't emit the script destroyed signal before script is actually destroyed The script unloading code originally worked like this: 1. Destroy package 2. Emit 'script destroyed' signal 3. Unhook script's signal handlers If a script added a 'script destroyed' signal handler, unloading that script would cause the 'script destroyed' signal to be sent to the (already destroyed) package. This would cause a script error, which would trigger a script unload, which would start the whole process over again, until we run out of heap or stack space and segfault. This commit simply reorders the operations so that the 'script destroyed' signal is sent *after* the script is fully destroyed. --- src/perl/perl-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index e4bde559..39389157 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -67,11 +67,11 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script) { perl_scripts = g_slist_remove(perl_scripts, script); - signal_emit("script destroyed", 1, script); - perl_signal_remove_script(script); perl_source_remove_script(script); + signal_emit("script destroyed", 1, script); + g_free(script->name); g_free(script->package); g_free_not_null(script->path); From dc99f8d7a5f90eebd4c52cef8d186bf20e2a9912 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 15 Feb 2017 14:19:36 +0100 Subject: [PATCH 0078/1198] Properly check the command arguments in tail place. A command requiring an argument and given in tail position would not raise an error but silently set the value to the empty string ''. --- src/core/commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/commands.c b/src/core/commands.c index 607baf77..8e21a88a 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -567,13 +567,14 @@ static int get_cmd_options(char **data, int ignore_unknown, option = NULL; pos = -1; for (;;) { - if (**data == '-') { + if (**data == '\0' || **data == '-') { if (option != NULL && *optlist[pos] == '+') { /* required argument missing! */ *data = optlist[pos] + 1; return CMDERR_OPTION_ARG_MISSING; } - + } + if (**data == '-') { (*data)++; if (**data == '-' && (*data)[1] == ' ') { /* -- option means end of options even From 62fd3ac1804d5d45bc2302ceac9ee9c7ef372e1a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 6 Mar 2017 11:27:55 +0100 Subject: [PATCH 0079/1198] Revert "Quote the filename when dcc requests are auto accepted." --- src/core/misc.c | 20 +++++++++----------- src/core/misc.h | 4 ++-- src/fe-common/core/chat-completion.c | 2 +- src/irc/dcc/dcc-autoget.c | 10 +++------- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 03fcce59..1cfa15b6 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -724,20 +724,18 @@ int expand_escape(const char **data) } } -/* Escape all the characters in `what' with a backslash */ -char *escape_string(const char *str, const char *what) +/* Escape all '"', "'" and '\' chars with '\' */ +char *escape_string(const char *str) { - const char *p; - char *ret; + char *ret, *p; - ret = g_malloc(strlen(str) * 2 + 1); - for (p = str; *p != '\0'; p++, ret++) { - if (strchr(what, *p) != NULL) { - *ret++ = '\\'; - } - *ret = *p; + p = ret = g_malloc(strlen(str)*2+1); + while (*str != '\0') { + if (*str == '"' || *str == '\'' || *str == '\\') + *p++ = '\\'; + *p++ = *str++; } - *ret = '\0'; + *p = '\0'; return ret; } diff --git a/src/core/misc.h b/src/core/misc.h index 9e620169..00637da0 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -88,8 +88,8 @@ char *stristr_full(const char *data, const char *key); char *ascii_strup(char *str); char *ascii_strdown(char *str); -/* Escape all the characters in `what' with a backslash */ -char *escape_string(const char *str, const char *what); +/* Escape all '"', "'" and '\' chars with '\' */ +char *escape_string(const char *str); /* convert all low-ascii (<32) to ^ combinations */ char *show_lowascii(const char *str); diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 4fe9509a..1f00feaf 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1113,7 +1113,7 @@ static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item) /* the nick is quoted in case it contains '-' character. also spaces should work too now :) The nick is also escaped in case it contains '\' characters */ - target = escape_string(window_item_get_target(item), "\"'\\"); + target = escape_string(window_item_get_target(item)); str = g_strdup_printf(IS_CHANNEL(item) ? "-channel \"%s\" %s" : IS_QUERY(item) ? "-nick \"%s\" %s" : "%s %s", target, line); diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c index 21417211..de23a5d1 100644 --- a/src/irc/dcc/dcc-autoget.c +++ b/src/irc/dcc/dcc-autoget.c @@ -23,7 +23,6 @@ #include "masks.h" #include "settings.h" #include "servers.h" -#include "misc.h" #include "dcc-get.h" @@ -31,7 +30,7 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) { struct stat statbuf; const char *masks; - char *str, *file, *esc_arg; + char *str, *file; int max_size; if (!IS_DCC_GET(dcc)) return; @@ -69,14 +68,11 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) /* ok. but do we want/need to resume? */ file = dcc_get_download_path(dcc->arg); - /* we have to escape the quotes as the whole file name gets quoted */ - esc_arg = escape_string(dcc->arg, "\""); str = g_strdup_printf(settings_get_bool("dcc_autoresume") && stat(file, &statbuf) == 0 ? - "RESUME %s \"%s\"" : "GET %s \"%s\"", - dcc->nick, esc_arg); + "RESUME %s %s" : "GET %s %s", + dcc->nick, dcc->arg); signal_emit("command dcc", 2, str, dcc->server); - g_free(esc_arg); g_free(file); g_free(str); } From 7bd1b80687cc97010094de0d398b429480e0a608 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 7 Mar 2017 23:23:54 +0100 Subject: [PATCH 0080/1198] fix dcc get fixes #656 --- src/irc/dcc/dcc-autoget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c index de23a5d1..dd12f438 100644 --- a/src/irc/dcc/dcc-autoget.c +++ b/src/irc/dcc/dcc-autoget.c @@ -23,6 +23,7 @@ #include "masks.h" #include "settings.h" #include "servers.h" +#include "misc.h" #include "dcc-get.h" @@ -30,7 +31,7 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) { struct stat statbuf; const char *masks; - char *str, *file; + char *str, *file, *esc_arg; int max_size; if (!IS_DCC_GET(dcc)) return; @@ -68,11 +69,13 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) /* ok. but do we want/need to resume? */ file = dcc_get_download_path(dcc->arg); + esc_arg = escape_string(dcc->arg); str = g_strdup_printf(settings_get_bool("dcc_autoresume") && stat(file, &statbuf) == 0 ? - "RESUME %s %s" : "GET %s %s", - dcc->nick, dcc->arg); + "RESUME %s \"%s\"" : "GET %s \"%s\"", + dcc->nick, esc_arg); signal_emit("command dcc", 2, str, dcc->server); + g_free(esc_arg); g_free(file); g_free(str); } From 93c158d8156293bd95e4bf5bdb75cf8d44bc4eab Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 8 Mar 2017 18:57:53 -0300 Subject: [PATCH 0081/1198] expand_escape: expand double backslash as a backslash --- src/core/misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/misc.c b/src/core/misc.c index 1cfa15b6..d8437430 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -690,6 +690,8 @@ int expand_escape(const char **data) return '\n'; case 'e': return 27; /* ESC */ + case '\\': + return '\\'; case 'x': /* hex digit */ From 24e62b0525ac852517230fa39330042325f105a5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 4 Mar 2017 21:36:00 +0000 Subject: [PATCH 0082/1198] Merge pull request #652 from LemonBoy/trailing-arg Properly check the command arguments in tail place. commit 5a92a3926fab4def4bcb7d14642b93184eeb4f71 Merge: 647ef193a896cc8a97d9bc664a6337b8b779f3c4 e4601b4b43af6177375c90a423546d892fbf6bfd Rebased: e4601b4b43af6177375c90a423546d892fbf6bfd dc99f8d7a5f90eebd4c52cef8d186bf20e2a9912 From 22bc7fcc3906ff3dd6e3837e049d37dc352edf94 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 5 Feb 2017 21:33:19 +0100 Subject: [PATCH 0083/1198] amend forgotten fix (cherry picked from commit 0ada284a257cfb08da984a78dab24c3ddaf09ec7) --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 2553d0da..7cd788ac 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ v1.0.1 2017-02-03 The Irssi team - Fix regression that broke second level completion (#613, #609). - Correct missing NULL termination in perl_parse. By Hanno Böck (#619). - Sync broken mail.pl script (#624, #607). + - Prevent a memory leak during the processing of the SASL + response (GL!8, GL#5) v1.0.0 2017-01-03 The Irssi team * Removed --disable-ipv6 (#408). From 3930f91edcf4b1e96c9d857233d58f7cb45c8a86 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 10 Mar 2017 17:41:04 +0100 Subject: [PATCH 0084/1198] tag as 1.0.2 (cherry picked from commit 2a53853f369b47e42e32e183c8109e3d63808899) --- NEWS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/NEWS b/NEWS index 7cd788ac..af330804 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,15 @@ v1.1-head 2017-xx-xx The Irssi team +v1.0.2 2017-03-10 The Irssi team + - Prevent some null-pointer crashes (GL!9). + - Fix compilation with OpenSSL 1.1.0 (#628, #597). + - Correct dereferencing of already freed server objects during + output of netjoins. Found by APic (GL!10, GL#7). + - Fix in command arg parser to detect missing arguments in tail place + (#652, #651). + - Fix regression that broke incoming DCC file transfers (#667, #656). + - Fix issue with escaping \ in evaluated strings (#669, #520). + v1.0.1 2017-02-03 The Irssi team - Fix Perl compilation in object dir. By Martijn Dekker (#602, #623). - Disable EC cryptography on Solaris to fix build (#604, #598). From 966efced3c178031f5f75a1009acc0ec8f897b4a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 14 Mar 2017 09:54:28 +0100 Subject: [PATCH 0085/1198] up abi ver --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 646b7e1a..b6f9153e 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 8 +#define IRSSI_ABI_VERSION 9 #define DEFAULT_SERVER_ADD_PORT 6667 From a720c3b5efdcd9b580110441bb22be91a4a16732 Mon Sep 17 00:00:00 2001 From: Rodrigo Rebello Date: Mon, 20 Mar 2017 13:17:42 -0300 Subject: [PATCH 0086/1198] Get back to using pkg-config to check for OpenSSL Commit 6300dfec7 removed the option to disable SSL support from the configure script since it became a requirement, but it also removed the use of pkg-config for finding the OpenSSL library and its dependencies. This had the unfortunate consequence of breaking the correct detection of library flags in many static linking scenarios. In some cases, for example, OpenSSL might have been built with zlib, which requires `-lz` to be passed to the linker when doing a static link of the irssi executable. Thus, pkg-config becomes an invaluable tool in such situations, since no guessing work is needed as the OpenSSL .pc file provides all the necessary flags. So, this commit re-inserts the PKG_CHECK_MODULES macro in the configure script when looking for OpenSSL. The test using AC_CHECK_LIB remains, but only as a last resort in case the one using pkg-config fails. Also, because the macro AM_PATH_GLIB_2_0 contains an unconditional call to PKG_PROG_PKG_CONFIG, the OpenSSL checks are moved so that they come after the Glib ones in order to avoid doubly checking for the pkg-config binary (PKG_CHECK_MODULES skips that check if it has been performed before, but PKG_PROG_PKG_CONFIG does not). --- configure.ac | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 8d1ba706..dd5064c9 100644 --- a/configure.ac +++ b/configure.ac @@ -243,11 +243,6 @@ if test "x$want_socks" = "xyes"; then ]) fi -dnl ** -dnl ** OpenSSL checks -dnl ** -AC_CHECK_LIB([ssl], [SSL_library_init]) - dnl ** dnl ** fe-text checks dnl ** @@ -289,7 +284,21 @@ if test -z "$GLIB_LIBS"; then AC_ERROR([GLIB is required to build irssi.]) fi -LIBS="$LIBS $GLIB_LIBS -lssl -lcrypto" +LIBS="$LIBS $GLIB_LIBS" + +dnl ** +dnl ** OpenSSL checks +dnl ** +PKG_CHECK_MODULES([OPENSSL], [openssl], [ + CFLAGS="$CFLAGS $OPENSSL_CFLAGS" + LIBS="$LIBS $OPENSSL_LIBS" +], [ + AC_CHECK_LIB([ssl], [SSL_library_init], [ + LIBS="$LIBS -lssl -lcrypto" + ], [ + AC_MSG_ERROR([The OpenSSL library was not found]) + ]) +]) dnl ** dnl ** curses checks From 449b8a4589f1fcadae44387999260ed5f8c6c2bf Mon Sep 17 00:00:00 2001 From: Rodrigo Rebello Date: Mon, 20 Mar 2017 15:47:24 -0300 Subject: [PATCH 0087/1198] Remove outdated information from INSTALL Disabling SSL support is no longer an option. --- INSTALL | 4 ---- 1 file changed, 4 deletions(-) diff --git a/INSTALL b/INSTALL index 629a75c6..d2a0acc2 100644 --- a/INSTALL +++ b/INSTALL @@ -30,10 +30,6 @@ configure options Build the irssi proxy (see startup-HOWTO). - --disable-ssl - - Disable SSL support. - --with-perl=[yes|no|module] Enable Perl support From 70f9db3cbdc0a3c6b622e64edbd504592f921892 Mon Sep 17 00:00:00 2001 From: Stephen Oberholtzer Date: Tue, 21 Mar 2017 09:08:42 -0400 Subject: [PATCH 0088/1198] Fix delay at startup when running against glib 2.49.3+ In glib v2.49.3, an optimization was made to eliminate certain unnecessary wakeups. (The specific change was made in e4ee3079c5afc3c1c3d2415f20c3e8605728f074). Before this change, the first call to g_main_iteration would always complete immediately. In Irssi, this effectively reversed the order of the main loop, causing the reload_config check and the dirty_check to run *before* the first blocking call to g_main_iteration. With the new logic, the first g_main_iteration call now blocks, preventing the screen from being refreshed until the user starts typing or a timer goes off. (It also delays processing of SIGHUP, but I expect that is not a common situation.) This commit reorders the main loop to wait at the end of the loop, rather than the beginning, addressing the problem. (This closes Debian bug #856201.) --- src/fe-text/irssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index ad79e0c4..e9e9b8b2 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -317,10 +317,6 @@ int main(int argc, char **argv) /* Does the same as g_main_run(main_loop), except we can call our dirty-checker after each iteration */ while (!quitting) { - term_refresh_freeze(); - g_main_iteration(TRUE); - term_refresh_thaw(); - if (reload_config) { /* SIGHUP received, do /RELOAD */ reload_config = FALSE; @@ -328,6 +324,10 @@ int main(int argc, char **argv) } dirty_check(); + + term_refresh_freeze(); + g_main_iteration(TRUE); + term_refresh_thaw(); } g_main_destroy(main_loop); From 2b9be6e2ed446293008d0e850fd726aad30fbcd2 Mon Sep 17 00:00:00 2001 From: Stephen Oberholtzer Date: Tue, 21 Mar 2017 10:27:39 -0400 Subject: [PATCH 0089/1198] Intentation/whitespace fixes Change several instances of space-indentation to tabs, matching the surrounding code. --- src/fe-text/irssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index e9e9b8b2..b5df47c9 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -318,21 +318,21 @@ int main(int argc, char **argv) can call our dirty-checker after each iteration */ while (!quitting) { if (reload_config) { - /* SIGHUP received, do /RELOAD */ + /* SIGHUP received, do /RELOAD */ reload_config = FALSE; - signal_emit("command reload", 1, ""); + signal_emit("command reload", 1, ""); } dirty_check(); term_refresh_freeze(); g_main_iteration(TRUE); - term_refresh_thaw(); + term_refresh_thaw(); } g_main_destroy(main_loop); textui_deinit(); - session_upgrade(); /* if we /UPGRADEd, start the new process */ + session_upgrade(); /* if we /UPGRADEd, start the new process */ return 0; } From a4cc4e0ad7278835d976aa5e75ca2b42443f5bb1 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Fri, 31 Mar 2017 15:37:48 -0400 Subject: [PATCH 0090/1198] Fix off by one error with char_expandos --- src/core/expandos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/expandos.c b/src/core/expandos.c index 67aea837..2e4265d5 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -51,7 +51,7 @@ const char *current_expando = NULL; static int timer_tag; -static EXPANDO_REC *char_expandos[255]; +static EXPANDO_REC *char_expandos[256]; static GHashTable *expandos; static char *last_sent_msg, *last_sent_msg_body; static char *last_privmsg_from, *last_public_from; From 41776d71f76924664bce1562ebe37743ba0cc9b7 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Wed, 5 Apr 2017 11:00:25 -0400 Subject: [PATCH 0091/1198] Fix strange history behavior when history is empty If text is being entered and then the user presses the up arrow followed by the down arrow, the expected behavior is to return to the text being entered. Prior to this commit that was not the case. Fixes #462 --- src/fe-common/core/command-history.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 1060744e..405700e5 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -116,6 +116,8 @@ const char *command_history_prev(WINDOW_REC *window, const char *text) history->pos = history->pos->prev; if (history->pos == NULL) history->over_counter++; + } else if (history->lines == 0) { + history->over_counter++; } else { history->pos = g_list_last(history->list); } From 7c86575b02d4f80539bcd2da3bef8195b963fa92 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 6 Apr 2017 20:27:39 -0400 Subject: [PATCH 0092/1198] Don't allow command history to wrap around This changes the behavior of the command history to avoid wrapping back to the bottom once the top of the history is reached. --- src/fe-common/core/command-history.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 405700e5..f957d385 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -113,11 +113,9 @@ const char *command_history_prev(WINDOW_REC *window, const char *text) pos = history->pos; if (pos != NULL) { - history->pos = history->pos->prev; - if (history->pos == NULL) - history->over_counter++; - } else if (history->lines == 0) { - history->over_counter++; + /* don't go past the first entry (no wrap around) */ + if (history->pos->prev != NULL) + history->pos = history->pos->prev; } else { history->pos = g_list_last(history->list); } @@ -128,7 +126,7 @@ const char *command_history_prev(WINDOW_REC *window, const char *text) command_history_add(history, text); } - return history->pos == NULL ? "" : history->pos->data; + return history->pos == NULL ? text : history->pos->data; } const char *command_history_next(WINDOW_REC *window, const char *text) @@ -141,10 +139,6 @@ const char *command_history_next(WINDOW_REC *window, const char *text) if (pos != NULL) history->pos = history->pos->next; - else if (history->over_counter > 0) { - history->over_counter--; - history->pos = history->list; - } if (*text != '\0' && (pos == NULL || g_strcmp0(pos->data, text) != 0)) { From 405136440cbfd18a39e2d5aa01c812a1247c369d Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Fri, 7 Apr 2017 08:20:28 -0400 Subject: [PATCH 0093/1198] Remove over_counter We are no longer using over_counter for any functional purpose, so remove it. --- src/fe-common/core/command-history.c | 1 - src/fe-common/core/command-history.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index f957d385..55474b1b 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -150,7 +150,6 @@ const char *command_history_next(WINDOW_REC *window, const char *text) void command_history_clear_pos_func(HISTORY_REC *history, gpointer user_data) { - history->over_counter = 0; history->pos = NULL; } diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index a572216b..45126092 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -7,7 +7,7 @@ typedef struct { char *name; GList *list, *pos; - int lines, over_counter; + int lines; int refcount; } HISTORY_REC; From 3297fafcd9be1fc3f48557a12023a1ef20884985 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Fri, 7 Apr 2017 12:54:18 -0400 Subject: [PATCH 0094/1198] Add syntax info for completion Allows syntax info to be picked up and displayed by help command. Fixes #687 --- src/fe-common/core/completion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 914ba80b..a97adc21 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -784,6 +784,7 @@ static void sig_complete_command(GList **list, WINDOW_REC *window, if (*list != NULL) signal_stop(); } +/* SYNTAX: COMPLETION [-auto] [-delete] */ static void cmd_completion(const char *data) { GHashTable *optlist; From c8a19e112499c0ca1d2b07a98d68415ca1509614 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 May 2017 12:27:23 +0200 Subject: [PATCH 0095/1198] detect Netbsd terminfo fixes #694 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dd5064c9..3855ba4c 100644 --- a/configure.ac +++ b/configure.ac @@ -308,7 +308,7 @@ if test "x$want_textui" != "xno"; then TEXTUI_NO_LIBS="$LIBS" LIBS= - AC_SEARCH_LIBS([setupterm], [tinfo ncursesw ncurses], [want_textui=yes], [ + AC_SEARCH_LIBS([setupterm], [tinfo ncursesw ncurses terminfo], [want_textui=yes], [ AC_ERROR(Terminfo not found - install libncurses-dev or ncurses-devel package) want_textui="no, Terminfo not found" ]) From 0c760b0c1bd86134fd5f55205b2ea45ba8e2f4af Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 8 May 2017 13:45:13 -0400 Subject: [PATCH 0096/1198] Add fuzz.diff for fuzzing with afl Authored by dx. --- fuzz-support/fuzz.diff | 269 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 fuzz-support/fuzz.diff diff --git a/fuzz-support/fuzz.diff b/fuzz-support/fuzz.diff new file mode 100644 index 00000000..a3683493 --- /dev/null +++ b/fuzz-support/fuzz.diff @@ -0,0 +1,269 @@ +diff --git a/src/core/network.c b/src/core/network.c +index 3e1b7c7..1e5324a 100644 +--- a/src/core/network.c ++++ b/src/core/network.c +@@ -199,6 +199,10 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) + /* Connect to named UNIX socket */ + GIOChannel *net_connect_unix(const char *path) + { ++ if (strcmp(path, "/dev/stdin") == 0) { ++ return g_io_channel_new(0); ++ } ++ + struct sockaddr_un sa; + int handle, ret; + +@@ -336,6 +340,8 @@ int net_receive(GIOChannel *handle, char *buf, int len) + /* Transmit data, return number of bytes sent, -1 = error */ + int net_transmit(GIOChannel *handle, const char *data, int len) + { ++ return write(1, data, len); ++ + gsize ret; + GIOStatus status; + GError *err = NULL; +@@ -495,6 +501,7 @@ int net_host2ip(const char *host, IPADDR *ip) + /* Get socket error */ + int net_geterror(GIOChannel *handle) + { ++ return 0; + int data; + socklen_t len = sizeof(data); + +diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c +index 58c9dd0..0c6ec1b 100644 +--- a/src/core/servers-reconnect.c ++++ b/src/core/servers-reconnect.c +@@ -484,7 +484,8 @@ void servers_reconnect_init(void) + reconnects = NULL; + last_reconnect_tag = 0; + +- reconnect_timeout_tag = g_timeout_add(1000, (GSourceFunc) server_reconnect_timeout, NULL); ++ (void) server_reconnect_timeout; ++ + read_settings(); + + signal_add("server connect failed", (SIGNAL_FUNC) sig_reconnect); +diff --git a/src/core/settings.c b/src/core/settings.c +index e65ceb2..f9dc678 100644 +--- a/src/core/settings.c ++++ b/src/core/settings.c +@@ -704,7 +704,10 @@ int irssi_config_is_changed(const char *fname) + + static CONFIG_REC *parse_configfile(const char *fname) + { +- CONFIG_REC *config; ++ CONFIG_REC *config = config_open(NULL, -1); ++ config_parse_data(config, default_config, "internal"); ++ return config; ++ + struct stat statbuf; + const char *path; + char *str; +@@ -871,8 +874,6 @@ void settings_init(void) + init_configfile(); + + settings_add_bool("misc", "settings_autosave", TRUE); +- timeout_tag = g_timeout_add(SETTINGS_AUTOSAVE_TIMEOUT, +- (GSourceFunc) sig_autosave, NULL); + signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); + signal_add("gui exit", (SIGNAL_FUNC) sig_autosave); + } +diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c +index 1b2ab1e..4344cd9 100644 +--- a/src/fe-common/core/fe-common-core.c ++++ b/src/fe-common/core/fe-common-core.c +@@ -320,6 +320,8 @@ static void autoconnect_servers(void) + GSList *tmp, *chatnets; + char *str; + ++ return; ++ + if (autocon_server != NULL) { + /* connect to specified server */ + if (autocon_password == NULL) +@@ -390,6 +392,7 @@ static void sig_setup_changed(void) + + static void autorun_startup(void) + { ++ return; + char *path; + GIOChannel *handle; + GString *buf; +diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c +index 2b1459b..2e518a1 100644 +--- a/src/fe-common/core/themes.c ++++ b/src/fe-common/core/themes.c +@@ -790,9 +790,8 @@ static void theme_read_module(THEME_REC *theme, const char *module) + { + CONFIG_REC *config; + +- config = config_open(theme->path, -1); +- if (config != NULL) +- config_parse(config); ++ config = config_open(NULL, -1); ++ config_parse_data(config, default_theme, "internal"); + + theme_init_module(theme, module, config); + +@@ -987,7 +986,7 @@ static int theme_read(THEME_REC *theme, const char *path) + THEME_READ_REC rec; + char *str; + +- config = config_open(path, -1) ; ++ config = config_open(NULL, -1) ; + if (config == NULL) { + /* didn't exist or no access? */ + str = g_strdup_printf("Error reading theme file %s: %s", +@@ -997,7 +996,7 @@ static int theme_read(THEME_REC *theme, const char *path) + return FALSE; + } + +- if (path == NULL) ++ if (1) + config_parse_data(config, default_theme, "internal"); + else + config_parse(config); +@@ -1200,6 +1199,7 @@ static void module_save(const char *module, MODULE_THEME_REC *rec, + + static void theme_save(THEME_REC *theme, int save_all) + { ++ return; + CONFIG_REC *config; + THEME_SAVE_REC data; + char *path; +diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c +index 7c71edd..6bf2177 100644 +--- a/src/fe-text/gui-readline.c ++++ b/src/fe-text/gui-readline.c +@@ -1126,7 +1126,6 @@ void gui_readline_init(void) + paste_timeout_id = -1; + paste_bracketed_mode = FALSE; + g_get_current_time(&last_keypress); +- input_listen_init(STDIN_FILENO); + + settings_add_bool("lookandfeel", "term_appkey_mode", TRUE); + settings_add_str("history", "scroll_page_count", "/2"); +diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c +index ad79e0c..84d0c5c 100644 +--- a/src/fe-text/irssi.c ++++ b/src/fe-text/irssi.c +@@ -314,20 +314,16 @@ int main(int argc, char **argv) + textui_finish_init(); + main_loop = g_main_new(TRUE); + ++#ifdef __AFL_HAVE_MANUAL_CONTROL ++ __AFL_INIT(); ++#endif ++ ++ signal_emit("command connect", 1, "/dev/stdin 6667"); ++ + /* Does the same as g_main_run(main_loop), except we + can call our dirty-checker after each iteration */ + while (!quitting) { +- term_refresh_freeze(); + g_main_iteration(TRUE); +- term_refresh_thaw(); +- +- if (reload_config) { +- /* SIGHUP received, do /RELOAD */ +- reload_config = FALSE; +- signal_emit("command reload", 1, ""); +- } +- +- dirty_check(); + } + + g_main_destroy(main_loop); +diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c +index b2478c6..cebe260 100644 +--- a/src/fe-text/term-terminfo.c ++++ b/src/fe-text/term-terminfo.c +@@ -29,6 +29,10 @@ + #include + #include + ++#undef putc ++#define putc(x, y) (void) (x) ++#define fputc(x, y) (void) (x), 0 ++ + /* returns number of characters in the beginning of the buffer being a + a single character, or -1 if more input is needed. The character will be + saved in result */ +@@ -113,7 +117,8 @@ int term_init(void) + vcmove = FALSE; cforcemove = TRUE; + curs_visible = TRUE; + +- current_term = terminfo_core_init(stdin, stdout); ++ FILE *devnull = fopen("/dev/null", "r+"); ++ current_term = terminfo_core_init(devnull, devnull); + if (current_term == NULL) + return FALSE; + +@@ -670,6 +675,7 @@ void term_set_input_type(int type) + + void term_gets(GArray *buffer, int *line_count) + { ++ return; + int ret, i, char_len; + + /* fread() doesn't work */ +diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c +index 9c9179a..6349935 100644 +--- a/src/fe-text/terminfo-core.c ++++ b/src/fe-text/terminfo-core.c +@@ -6,6 +6,10 @@ + # define _POSIX_VDISABLE 0 + #endif + ++#undef putc ++#define putc(x, y) (void) (x) ++#define fputc(x, y) (void) (x), 0 ++ + #define tput(s) tputs(s, 0, term_putchar) + inline static int term_putchar(int c) + { +diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c +index 4dce3fc..25fbb34 100644 +--- a/src/irc/core/irc.c ++++ b/src/irc/core/irc.c +@@ -383,12 +383,13 @@ static void irc_parse_incoming(SERVER_REC *server) + signal_emit_id(signal_server_incoming, 2, server, str); + + if (server->connection_lost) +- server_disconnect(server); ++ exit(0); + + count++; + } + if (ret == -1) { + /* connection lost */ ++ exit(0); + server->connection_lost = TRUE; + server_disconnect(server); + } +diff --git a/src/lib-config/write.c b/src/lib-config/write.c +index 37e51f0..ee82726 100644 +--- a/src/lib-config/write.c ++++ b/src/lib-config/write.c +@@ -299,6 +299,8 @@ static int config_write_block(CONFIG_REC *rec, CONFIG_NODE *node, int list, int + + int config_write(CONFIG_REC *rec, const char *fname, int create_mode) + { ++ return 0; ++ + int ret; + int fd; + +diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c +index 2c61df7..485fe25 100644 +--- a/src/perl/perl-core.c ++++ b/src/perl/perl-core.c +@@ -395,6 +395,7 @@ int perl_get_api_version(void) + + void perl_scripts_autorun(void) + { ++ return; + DIR *dirp; + struct dirent *dp; + struct stat statbuf; From dbde9f0fe3c9fcd7eb8e56e9b1beffb71b0607e1 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 11 May 2017 10:57:24 +0200 Subject: [PATCH 0097/1198] Added support for -notls and -notls_verify --- src/fe-common/core/fe-server.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index f4c1d3ee..207dae7d 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -156,6 +156,10 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) rec->use_tls = TRUE; + else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) { + rec->use_tls = FALSE; + rec->tls_verify = FALSE; + } value = g_hash_table_lookup(optlist, "tls_cert"); if (value == NULL) @@ -177,6 +181,8 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (g_hash_table_lookup(optlist, "tls_verify") || g_hash_table_lookup(optlist, "ssl_verify")) rec->tls_verify = TRUE; + else if (g_hash_table_lookup(optlist, "notls_verify") || g_hash_table_lookup(optlist, "nossl_verify")) + rec->tls_verify = FALSE; value = g_hash_table_lookup(optlist, "tls_cafile"); if (value == NULL) @@ -434,8 +440,8 @@ void fe_server_init(void) command_bind_first("server", NULL, (SIGNAL_FUNC) server_command); command_bind_first("disconnect", NULL, (SIGNAL_FUNC) server_command); - command_set_options("server add", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); - command_set_options("server modify", "4 6 !! ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); + command_set_options("server add", "4 6 !! ssl nossl +ssl_cert +ssl_pkey +ssl_pass ssl_verify nossl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls notls +tls_cert +tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); + command_set_options("server modify", "4 6 !! ssl nossl +ssl_cert +ssl_pkey +ssl_pass ssl_verify nossl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls notls +tls_cert +tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting); From f060292a9cd0835dd9cc8c24a4ede67909a2b68b Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 11 May 2017 11:17:14 +0200 Subject: [PATCH 0098/1198] Added braces --- src/fe-common/core/fe-server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 207dae7d..c9488e25 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -154,8 +154,9 @@ static void cmd_server_add_modify(const char *data, gboolean add) else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; - if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) + if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) { rec->use_tls = TRUE; + } else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) { rec->use_tls = FALSE; rec->tls_verify = FALSE; From 25f9c71f690f9fd846a39e646fbd11f715ffbfa5 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 11 May 2017 14:02:23 +0200 Subject: [PATCH 0099/1198] Allow -port or irc.host.tld in /server add and /server modify --- src/fe-common/core/fe-server.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index f4c1d3ee..89d6f739 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -117,7 +117,11 @@ static void cmd_server_add_modify(const char *data, gboolean add) return; if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - port = *portstr == '\0' ? DEFAULT_SERVER_ADD_PORT : atoi(portstr); + + value = g_hash_table_lookup(optlist, "port"); + port = *portstr == '\0' ? + (value != NULL && *value != '\0' ? atoi(value) : DEFAULT_SERVER_ADD_PORT) + : atoi(portstr); chatnet = g_hash_table_lookup(optlist, "network"); @@ -137,11 +141,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) return; } rec->address = g_strdup(addr); - rec->port = port; } else { - value = g_hash_table_lookup(optlist, "port"); - if (value != NULL && *value != '\0') rec->port = atoi(value); - if (*password != '\0') g_free_and_null(rec->password); if (g_hash_table_lookup(optlist, "host")) { g_free_and_null(rec->own_host); @@ -149,6 +149,8 @@ static void cmd_server_add_modify(const char *data, gboolean add) } } + rec->port = port; + if (g_hash_table_lookup(optlist, "6")) rec->family = AF_INET6; else if (g_hash_table_lookup(optlist, "4")) From 783458e9ba068117089d23730add317069cf6447 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 11 May 2017 14:08:45 +0200 Subject: [PATCH 0100/1198] Added code comments --- src/fe-common/core/fe-server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index c9488e25..03feba32 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -159,6 +159,8 @@ static void cmd_server_add_modify(const char *data, gboolean add) } else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) { rec->use_tls = FALSE; + /* if rec has tls_verify = TRUE then use_tls will be set to true on lines 224-225 + so explicitly set tls_verify to FALSE when -notls is used */ rec->tls_verify = FALSE; } From 787e192567626dab7788e54363dbccda52d5322c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 12 May 2017 13:36:48 +0200 Subject: [PATCH 0101/1198] improve nicklist performance --- src/core/nicklist.c | 53 ++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/core/nicklist.c b/src/core/nicklist.c index 770b0afc..50199f63 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -166,41 +166,50 @@ void nicklist_rename_unique(SERVER_REC *server, nicklist_get_same_unique(server, old_nick_id)); } +#define NICKLIST_GETNICKS_LOOP_INIT(hashtable) \ + do { \ + GHashTableIter _iter; \ + g_hash_table_iter_init(&_iter, (hashtable)); \ + while (g_hash_table_iter_next(&_iter, NULL, (void*)&nick)) { \ + while (nick != NULL) { +#define NICKLIST_GETNICKS_LOOP_END \ + nick = nick->next; \ + } \ + } \ + } while (0) + static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel, const char *mask) { - GSList *nicks, *tmp; NICK_REC *nick; - nicks = nicklist_getnicks(channel); - nick = NULL; - for (tmp = nicks; tmp != NULL; tmp = tmp->next) { - nick = tmp->data; + NICKLIST_GETNICKS_LOOP_INIT(channel->nicks); - if (mask_match_address(channel->server, mask, - nick->nick, nick->host)) - break; - } - g_slist_free(nicks); - return tmp == NULL ? NULL : nick; + if (mask_match_address(channel->server, mask, + nick->nick, nick->host)) + return nick; + + NICKLIST_GETNICKS_LOOP_END; + return NULL; } GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask) { - GSList *nicks, *tmp, *next; + GSList *nicks; + NICK_REC *nick; g_return_val_if_fail(IS_CHANNEL(channel), NULL); g_return_val_if_fail(mask != NULL, NULL); - nicks = nicklist_getnicks(channel); - for (tmp = nicks; tmp != NULL; tmp = next) { - NICK_REC *nick = tmp->data; + nicks = NULL; - next = tmp->next; - if (!mask_match_address(channel->server, mask, - nick->nick, nick->host)) - nicks = g_slist_remove(nicks, tmp->data); - } + NICKLIST_GETNICKS_LOOP_INIT(channel->nicks); + + if (mask_match_address(channel->server, mask, + nick->nick, nick->host)) + nicks = g_slist_prepend(nicks, nick); + + NICKLIST_GETNICKS_LOOP_END; return nicks; } @@ -264,8 +273,8 @@ NICK_REC *nicklist_find_mask(CHANNEL_REC *channel, const char *mask) static void get_nicks_hash(gpointer key, NICK_REC *rec, GSList **list) { while (rec != NULL) { - *list = g_slist_append(*list, rec); - rec = rec->next; + *list = g_slist_prepend(*list, rec); + rec = rec->next; } } From 371eb7f5052b9cce7efcbcc4086cd6f6716e21fd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 12 May 2017 16:27:33 +0200 Subject: [PATCH 0102/1198] expand macro --- src/core/nicklist.c | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/core/nicklist.c b/src/core/nicklist.c index 50199f63..54dfb5fb 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -166,30 +166,21 @@ void nicklist_rename_unique(SERVER_REC *server, nicklist_get_same_unique(server, old_nick_id)); } -#define NICKLIST_GETNICKS_LOOP_INIT(hashtable) \ - do { \ - GHashTableIter _iter; \ - g_hash_table_iter_init(&_iter, (hashtable)); \ - while (g_hash_table_iter_next(&_iter, NULL, (void*)&nick)) { \ - while (nick != NULL) { -#define NICKLIST_GETNICKS_LOOP_END \ - nick = nick->next; \ - } \ - } \ - } while (0) - static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel, const char *mask) { NICK_REC *nick; + GHashTableIter iter; - NICKLIST_GETNICKS_LOOP_INIT(channel->nicks); + g_hash_table_iter_init(&iter, channel->nicks); + while (g_hash_table_iter_next(&iter, NULL, (void*)&nick)) { + for (; nick != NULL; nick = nick->next) { + if (mask_match_address(channel->server, mask, + nick->nick, nick->host)) + return nick; + } + } - if (mask_match_address(channel->server, mask, - nick->nick, nick->host)) - return nick; - - NICKLIST_GETNICKS_LOOP_END; return NULL; } @@ -197,19 +188,21 @@ GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask) { GSList *nicks; NICK_REC *nick; + GHashTableIter iter; g_return_val_if_fail(IS_CHANNEL(channel), NULL); g_return_val_if_fail(mask != NULL, NULL); nicks = NULL; - NICKLIST_GETNICKS_LOOP_INIT(channel->nicks); - - if (mask_match_address(channel->server, mask, - nick->nick, nick->host)) - nicks = g_slist_prepend(nicks, nick); - - NICKLIST_GETNICKS_LOOP_END; + g_hash_table_iter_init(&iter, channel->nicks); + while (g_hash_table_iter_next(&iter, NULL, (void*)&nick)) { + for (; nick != NULL; nick = nick->next) { + if (mask_match_address(channel->server, mask, + nick->nick, nick->host)) + nicks = g_slist_prepend(nicks, nick); + } + } return nicks; } From 4a6fbdbe7891859ffd7b51a87147ecb6158df141 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Sun, 14 May 2017 03:01:01 +0200 Subject: [PATCH 0103/1198] Spaces to tabs --- src/fe-common/core/fe-server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 89d6f739..73c77e77 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -118,9 +118,9 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - value = g_hash_table_lookup(optlist, "port"); - port = *portstr == '\0' ? - (value != NULL && *value != '\0' ? atoi(value) : DEFAULT_SERVER_ADD_PORT) + value = g_hash_table_lookup(optlist, "port"); + port = *portstr == '\0' ? + (value != NULL && *value != '\0' ? atoi(value) : DEFAULT_SERVER_ADD_PORT) : atoi(portstr); chatnet = g_hash_table_lookup(optlist, "network"); From 81cf8d8813c4226e0d9db5f776e0f6a6904813e0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 14 May 2017 09:43:38 +0200 Subject: [PATCH 0104/1198] Update fe-server.c --- src/fe-common/core/fe-server.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 03feba32..e8e9f33f 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -159,8 +159,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) } else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) { rec->use_tls = FALSE; - /* if rec has tls_verify = TRUE then use_tls will be set to true on lines 224-225 - so explicitly set tls_verify to FALSE when -notls is used */ + /* tls_verify implies use_tls, disable it explicitly */ rec->tls_verify = FALSE; } From 0c26aeb9fc716416aa7dde2356cc59643f7cc793 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Mon, 15 May 2017 23:07:01 +0200 Subject: [PATCH 0105/1198] Make sure port is only set on /server modify if specified --- src/fe-common/core/fe-server.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 73c77e77..46d25ae9 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -120,7 +120,8 @@ static void cmd_server_add_modify(const char *data, gboolean add) value = g_hash_table_lookup(optlist, "port"); port = *portstr == '\0' ? - (value != NULL && *value != '\0' ? atoi(value) : DEFAULT_SERVER_ADD_PORT) + (value != NULL && *value != '\0' ? + atoi(value) : DEFAULT_SERVER_ADD_PORT) : atoi(portstr); chatnet = g_hash_table_lookup(optlist, "network"); @@ -141,7 +142,11 @@ static void cmd_server_add_modify(const char *data, gboolean add) return; } rec->address = g_strdup(addr); + rec->port = port; } else { + if (*portstr != '\0' || g_hash_table_lookup(optlist, "port")) + rec->port = port; + if (*password != '\0') g_free_and_null(rec->password); if (g_hash_table_lookup(optlist, "host")) { g_free_and_null(rec->own_host); @@ -149,8 +154,6 @@ static void cmd_server_add_modify(const char *data, gboolean add) } } - rec->port = port; - if (g_hash_table_lookup(optlist, "6")) rec->family = AF_INET6; else if (g_hash_table_lookup(optlist, "4")) From 5045f4766a72f18a3d682d1c9eeeffb40ab32569 Mon Sep 17 00:00:00 2001 From: mh Date: Wed, 17 May 2017 12:17:27 +0200 Subject: [PATCH 0106/1198] dcc.in: fixed typo 'resolved' -> 'resolves' n/t --- docs/help/in/dcc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/dcc.in b/docs/help/in/dcc.in index 18a77ee9..2e58c9b1 100644 --- a/docs/help/in/dcc.in +++ b/docs/help/in/dcc.in @@ -27,7 +27,7 @@ and file transfers. If you are behind NAT, or if the firewall is too restrictive, you might - want to try if using the passive parameter resolved your connection + want to try if using the passive parameter resolves your connection problem. You can send files which contain special character or spaces by enclosing From 632b0ce5e68ce32ade90382cb64fbb8d1e75090d Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 17 May 2017 06:18:49 -0300 Subject: [PATCH 0107/1198] Add parse_uint function to improve integer overflow handling Originally found by oss-fuzz (issue 525) in get_ansi_color using ubsan. After a lot of analysis I'm 99% sure this isn't security relevant so it's fine to handle this publicly. The fix is mainly adding a function that does it right and use it everywhere. This is harder than it seems because the strtol() family of functions doesn't have the friendliest of interfaces. Aside from get_ansi_color(), there were other pieces of code that used the same (out*10+(*in-'0')) pattern, like the parse_size() and parse_time_interval() functions, which are mostly used for settings. Those are interesting cases, since they multiply the parsed number (resulting in more overflows) and they write to a signed integer parameter (which can accidentally make the uints negative without UB) Thanks to Pascal Cuoq for enlightening me about the undefined behavior of parse_size (and, in particular, the implementation-defined behavior of one of the WIP versions of this commit, where something like signed integer overflow happened, but it was legal). Also for writing tis-interpreter, which is better than ubsan to verify these things. --- src/core/misc.c | 119 ++++++++++++++++++++++++++++++----- src/core/misc.h | 1 + src/core/special-vars.c | 9 ++- src/fe-common/core/formats.c | 28 ++++++--- 4 files changed, 130 insertions(+), 27 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index d8437430..0f038cbb 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -750,10 +750,42 @@ int nearest_power(int num) return n; } -int parse_time_interval(const char *time, int *msecs) +/* Parses unsigned integers from strings with decent error checking. + * Returns true on success, false otherwise (overflow, no valid number, etc) + * There's a 31 bit limit so the output can be assigned to signed positive ints */ +int parse_uint(const char *nptr, char **endptr, int base, guint *number) +{ + char *endptr_; + gulong parsed; + + /* strtoul accepts whitespace and plus/minus signs, for some reason */ + if (!i_isdigit(*nptr)) { + return FALSE; + } + + errno = 0; + parsed = strtoul(nptr, &endptr_, base); + + if (errno || endptr_ == nptr || parsed >= (1U << 31)) { + return FALSE; + } + + if (endptr) { + *endptr = endptr_; + } + + if (number) { + *number = (guint) parsed; + } + + return TRUE; +} + +static int parse_time_interval_uint(const char *time, guint *msecs) { const char *desc; - int number, sign, len, ret, digits; + guint number; + int sign, len, ret, digits; *msecs = 0; @@ -769,8 +801,11 @@ int parse_time_interval(const char *time, int *msecs) } for (;;) { if (i_isdigit(*time)) { - number = number*10 + (*time - '0'); - time++; + char *endptr; + if (!parse_uint(time, &endptr, 10, &number)) { + return FALSE; + } + time = endptr; digits = TRUE; continue; } @@ -835,10 +870,11 @@ int parse_time_interval(const char *time, int *msecs) return ret; } -int parse_size(const char *size, int *bytes) +static int parse_size_uint(const char *size, guint *bytes) { const char *desc; - int number, len; + guint number, multiplier, limit; + int len; *bytes = 0; @@ -846,8 +882,11 @@ int parse_size(const char *size, int *bytes) number = 0; while (*size != '\0') { if (i_isdigit(*size)) { - number = number*10 + (*size - '0'); - size++; + char *endptr; + if (!parse_uint(size, &endptr, 10, &number)) { + return FALSE; + } + size = endptr; continue; } @@ -869,14 +908,31 @@ int parse_size(const char *size, int *bytes) return FALSE; } - if (g_ascii_strncasecmp(desc, "gbytes", len) == 0) - *bytes += number * 1024*1024*1024; - if (g_ascii_strncasecmp(desc, "mbytes", len) == 0) - *bytes += number * 1024*1024; - if (g_ascii_strncasecmp(desc, "kbytes", len) == 0) - *bytes += number * 1024; - if (g_ascii_strncasecmp(desc, "bytes", len) == 0) - *bytes += number; + multiplier = 0; + limit = 0; + + if (g_ascii_strncasecmp(desc, "gbytes", len) == 0) { + multiplier = 1U << 30; + limit = 2U << 0; + } + if (g_ascii_strncasecmp(desc, "mbytes", len) == 0) { + multiplier = 1U << 20; + limit = 2U << 10; + } + if (g_ascii_strncasecmp(desc, "kbytes", len) == 0) { + multiplier = 1U << 10; + limit = 2U << 20; + } + if (g_ascii_strncasecmp(desc, "bytes", len) == 0) { + multiplier = 1; + limit = 2U << 30; + } + + if (limit && number > limit) { + return FALSE; + } + + *bytes += number * multiplier; /* skip punctuation */ while (*size != '\0' && i_ispunct(*size)) @@ -886,6 +942,37 @@ int parse_size(const char *size, int *bytes) return TRUE; } +int parse_size(const char *size, int *bytes) +{ + guint bytes_; + int ret; + + ret = parse_size_uint(size, &bytes_); + + if (bytes_ > (1U << 31)) { + return FALSE; + } + + *bytes = bytes_; + return ret; +} + +int parse_time_interval(const char *time, int *msecs) +{ + guint msecs_; + int ret; + + ret = parse_time_interval_uint(time, &msecs_); + + if (msecs_ > (1U << 31)) { + return FALSE; + } + + *msecs = msecs_; + return ret; +} + + char *ascii_strup(char *str) { char *s; diff --git a/src/core/misc.h b/src/core/misc.h index 00637da0..375744db 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -71,6 +71,7 @@ int expand_escape(const char **data); int nearest_power(int num); /* Returns TRUE / FALSE */ +int parse_uint(const char *nptr, char **endptr, int base, guint *number); int parse_time_interval(const char *time, int *msecs); int parse_size(const char *size, int *bytes); diff --git a/src/core/special-vars.c b/src/core/special-vars.c index 6ca080fc..aaf8da8f 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -275,6 +275,8 @@ static char *get_special_value(char **cmd, SERVER_REC *server, void *item, static int get_alignment_args(char **data, int *align, int *flags, char *pad) { char *str; + char *endptr; + guint align_; *align = 0; *flags = ALIGN_CUT|ALIGN_PAD; @@ -295,10 +297,11 @@ static int get_alignment_args(char **data, int *align, int *flags, char *pad) return FALSE; /* expecting number */ /* get the alignment size */ - while (i_isdigit(*str)) { - *align = (*align) * 10 + (*str-'0'); - str++; + if (!parse_uint(str, &endptr, 10, &align_)) { + return FALSE; } + str = endptr; + *align = align_; /* get the pad character */ while (*str != '\0' && *str != ']') { diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 17c13a97..005e6fb7 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -33,6 +33,7 @@ #include "themes.h" #include "recode.h" #include "utf8.h" +#include "misc.h" static const char *format_backs = "04261537"; static const char *format_fores = "kbgcrmyw"; @@ -870,8 +871,9 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, { static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; const char *start; - int fg, bg, flags, num, i; - unsigned int num2; + char *endptr; + int fg, bg, flags, i; + guint num, num2; if (*str != '[') return str; @@ -886,8 +888,10 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, if (*str == '\0') return start; if (i_isdigit(*str)) { - num = num*10 + (*str-'0'); - continue; + if (!parse_uint(str, &endptr, 10, &num)) { + return start; + } + str = endptr; } if (*str != ';' && *str != 'm') @@ -958,8 +962,12 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, /* ANSI indexed color or RGB color */ if (*str != ';') break; str++; - for (num2 = 0; i_isdigit(*str); str++) - num2 = num2*10 + (*str-'0'); + + if (!parse_uint(str, &endptr, 10, &num2)) { + return start; + } + str = endptr; + if (*str == '\0') return start; switch (num2) { @@ -1006,8 +1014,12 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, /* indexed */ if (*str != ';') break; str++; - for (num2 = 0; i_isdigit(*str); str++) - num2 = num2*10 + (*str-'0'); + + if (!parse_uint(str, &endptr, 10, &num2)) { + return start; + } + str = endptr; + if (*str == '\0') return start; if (num == 38) { From d61c54c32b6383186a8f32d852594cc4e10240d9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 27 May 2017 00:12:54 +0200 Subject: [PATCH 0108/1198] do not reset true colour bit on colour reset fixes #710 --- src/fe-text/textbuffer-view.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 58bd36fb..cb066f5e 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -114,7 +114,6 @@ static void update_cmd_color(unsigned char cmd, int *color) if (cmd & LINE_COLOR_BG) { /* set background color */ *color &= FGATTR; - *color &= ~ATTR_FGCOLOR24; if ((cmd & LINE_COLOR_DEFAULT) == 0) *color |= (cmd & 0x0f) << BG_SHIFT; else { @@ -123,7 +122,6 @@ static void update_cmd_color(unsigned char cmd, int *color) } else { /* set foreground color */ *color &= BGATTR; - *color &= ~ATTR_BGCOLOR24; if ((cmd & LINE_COLOR_DEFAULT) == 0) *color |= cmd & 0x0f; else { From 601be187746234c36c407a17ca54b17c82264e1b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 29 May 2017 11:07:06 +0200 Subject: [PATCH 0109/1198] Update list.in Add a more detailed paragraph about service bots Fixes #699 I would like to add another paragraph about how freenode is broken and spits at you the whole list instead of empty list if you attempt to use network side filtering...... --- docs/help/in/list.in | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/help/in/list.in b/docs/help/in/list.in index b796eed0..6dda79e6 100644 --- a/docs/help/in/list.in +++ b/docs/help/in/list.in @@ -24,11 +24,15 @@ %9Remarks:%9 - Not all networks support server-side filtering and may provide a network + Not all networks support server-side filtering. Some provide a network service or service bot instead; on IRCnet, you may use the List service: - /SQUERY List HELP - /MSG ALIS HELP + /SQUERY Alis HELP + + Other networks with service bots (like ChanServ) may also provide a list + service bot (confirm with /WHOIS ALIS): + + /MSG Alis HELP %9See also:%9 STATS, SQUERY, WHOIS From 30a92754bb650c3dedd507d41110443142899a65 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 29 May 2017 14:43:24 -0400 Subject: [PATCH 0110/1198] Fix oob read of one byte in get_file_params_count{,_resume} We can use continue to handle cases such as: "abc" --- src/irc/dcc/dcc-get.c | 2 ++ src/irc/dcc/dcc-resume.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 73c1b864..eff516db 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -382,6 +382,8 @@ int get_file_params_count(char **params, int paramcount) if (*params[0] == '"') { /* quoted file name? */ for (pos = 0; pos < paramcount-3; pos++) { + if (strlen(params[pos]) == 0) + continue; if (params[pos][strlen(params[pos])-1] == '"' && get_params_match(params, pos+1)) return pos+1; diff --git a/src/irc/dcc/dcc-resume.c b/src/irc/dcc/dcc-resume.c index 36f84ddf..ce0ac925 100644 --- a/src/irc/dcc/dcc-resume.c +++ b/src/irc/dcc/dcc-resume.c @@ -62,6 +62,8 @@ int get_file_params_count_resume(char **params, int paramcount) if (*params[0] == '"') { /* quoted file name? */ for (pos = 0; pos < paramcount-2; pos++) { + if (strlen(params[pos]) == 0) + continue; if (params[pos][strlen(params[pos])-1] == '"' && get_params_match_resume(params, pos+1)) return pos+1; From 528f51bfbe5c65c5b24546faa244009dd5b3c586 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Wed, 17 May 2017 10:08:51 -0400 Subject: [PATCH 0111/1198] Fix dcc_request where addr is NULL --- src/irc/dcc/dcc-get.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 73c1b864..98294099 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -428,6 +428,10 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data, int p_id = -1; int passive = FALSE; + if (addr == NULL) { + addr = ""; + } + /* SEND
[...] */ /* SEND
0 (DCC SEND passive protocol) */ params = g_strsplit(data, " ", -1); From 1ce9e07be0ad33fbdac9413e9045c45e66afff37 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 1 Jun 2017 23:59:19 -0400 Subject: [PATCH 0112/1198] Use CXX for fe-fuzz linking --- src/fe-fuzz/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index 3a547c66..c11b3dbb 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = irssi-fuzz -# Force link with clang++ for libfuzzer support -CCLD=clang++ $(CXXFLAGS) +# Force link with CXX for libfuzzer support +CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ -I$(top_srcdir)/src \ From 79bbca4644cad7f2dee89c7ac6b8f9acc2c8b427 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 16 Feb 2017 22:48:13 +0100 Subject: [PATCH 0113/1198] Refactor regex and implement UTF8 mode for GRegex - with non-unicode byte to Private Use Area A mapping - move all ifdefs to iregex.h file only --- configure.ac | 1 + src/core/Makefile.am | 8 ++ src/core/ignore.c | 40 ++------- src/core/ignore.h | 11 +-- src/core/iregex-gregex.c | 137 ++++++++++++++++++++++++++++++ src/core/iregex-regexh.c | 101 ++++++++++++++++++++++ src/core/iregex.h | 52 ++++++++++++ src/core/misc.c | 4 - src/fe-common/core/fe-ignore.c | 5 -- src/fe-common/core/hilight-text.c | 51 +++-------- src/fe-common/core/hilight-text.h | 12 +-- src/fe-text/textbuffer.c | 37 ++------ 12 files changed, 327 insertions(+), 132 deletions(-) create mode 100644 src/core/iregex-gregex.c create mode 100644 src/core/iregex-regexh.c create mode 100644 src/core/iregex.h diff --git a/configure.ac b/configure.ac index 3855ba4c..459d3a2d 100644 --- a/configure.ac +++ b/configure.ac @@ -505,6 +505,7 @@ AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes") AM_CONDITIONAL(BUILD_IRSSIFUZZER, test "$want_irssifuzzer" = "yes") AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes") AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no") +AM_CONDITIONAL(USE_GREGEX, test "x$want_gregex" = "xyes") # move LIBS to PROG_LIBS so they're not tried to be used when linking eg. perl libraries PROG_LIBS=$LIBS diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 10bd035a..91daba3f 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -7,6 +7,12 @@ AM_CPPFLAGS = \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DMODULEDIR=\""$(libdir)/irssi/modules"\" +if USE_GREGEX +regex_impl=iregex-gregex.c +else +regex_impl=iregex-regexh.c +endif + libcore_a_SOURCES = \ args.c \ channels.c \ @@ -45,6 +51,7 @@ libcore_a_SOURCES = \ signals.c \ special-vars.c \ utf8.c \ + $(regex_impl) \ wcwidth.c \ tls.c \ write-buffer.c @@ -97,6 +104,7 @@ pkginc_core_HEADERS = \ signals.h \ special-vars.h \ utf8.h \ + iregex.h \ window-item-def.h \ tls.h \ write-buffer.h \ diff --git a/src/core/ignore.c b/src/core/ignore.c index d4a92e3c..63a507f5 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -24,6 +24,7 @@ #include "levels.h" #include "lib-config/iconfig.h" #include "settings.h" +#include "iregex.h" #include "masks.h" #include "servers.h" @@ -67,13 +68,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) return FALSE; if (rec->regexp) { -#ifdef USE_GREGEX return rec->preg != NULL && - g_regex_match(rec->preg, text, 0, NULL); -#else - return rec->regexp_compiled && - regexec(&rec->preg, text, 0, NULL, 0) == 0; -#endif + i_regex_match(rec->preg, text, 0, NULL, NULL); } return rec->fullword ? @@ -327,41 +323,19 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { -#ifdef USE_GREGEX if (rec->preg != NULL) - g_regex_unref(rec->preg); + i_regex_unref(rec->preg); if (rec->regexp && rec->pattern != NULL) { GError *re_error = NULL; - rec->preg = g_regex_new(rec->pattern, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, &re_error); + rec->preg = i_regex_new(rec->pattern, G_REGEX_OPTIMIZE | G_REGEX_CASELESS, 0, &re_error); if (rec->preg == NULL) { g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); g_error_free(re_error); } } -#else - char *errbuf; - int errcode, errbuf_len; - - if (rec->regexp_compiled) regfree(&rec->preg); - rec->regexp_compiled = FALSE; - - if (rec->regexp && rec->pattern != NULL) { - errcode = regcomp(&rec->preg, rec->pattern, - REG_EXTENDED|REG_ICASE|REG_NOSUB); - if (errcode != 0) { - errbuf_len = regerror(errcode, &rec->preg, 0, 0); - errbuf = g_malloc(errbuf_len); - regerror(errcode, &rec->preg, errbuf, errbuf_len); - g_warning("Failed to compile regexp '%s': %s", rec->pattern, errbuf); - g_free(errbuf); - } else { - rec->regexp_compiled = TRUE; - } - } -#endif } void ignore_add_rec(IGNORE_REC *rec) @@ -381,11 +355,7 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); -#ifdef USE_GREGEX - if (rec->preg != NULL) g_regex_unref(rec->preg); -#else - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->preg != NULL) i_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index 80ae1d12..e18be3c4 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,9 +1,7 @@ #ifndef __IGNORE_H #define __IGNORE_H -#ifndef USE_GREGEX -# include -#endif +#include "iregex.h" typedef struct _IGNORE_REC IGNORE_REC; @@ -20,12 +18,7 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ -#ifdef USE_GREGEX - GRegex *preg; -#else - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + Regex *preg; }; extern GSList *ignores; diff --git a/src/core/iregex-gregex.c b/src/core/iregex-gregex.c new file mode 100644 index 00000000..0de11e64 --- /dev/null +++ b/src/core/iregex-gregex.c @@ -0,0 +1,137 @@ +#include + +#include "iregex.h" + +const gchar * +make_valid_utf8(const gchar *text, gboolean *free_ret) +{ + GString *str; + const gchar *ptr; + if (g_utf8_validate(text, -1, NULL)) { + if (free_ret) + *free_ret = FALSE; + return text; + } + + str = g_string_sized_new(strlen(text) + 12); + + ptr = text; + while (*ptr) { + gunichar c = g_utf8_get_char_validated(ptr, -1); + /* the unicode is invalid */ + if (c == (gunichar)-1 || c == (gunichar)-2) { + /* encode the byte into PUA-A */ + g_string_append_unichar(str, (gunichar) (0xfff00 | (*ptr & 0xff))); + ptr++; + } else { + g_string_append_unichar(str, c); + ptr = g_utf8_next_char(ptr); + } + } + + if (free_ret) + *free_ret = TRUE; + return g_string_free(str, FALSE); +} + +Regex * +i_regex_new (const gchar *pattern, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options, + GError **error) +{ + const gchar *valid_pattern; + gboolean free_valid_pattern; + Regex *ret = NULL; + + valid_pattern = make_valid_utf8(pattern, &free_valid_pattern); + ret = g_regex_new(valid_pattern, compile_options, match_options, error); + + if (free_valid_pattern) + g_free_not_null((gchar *)valid_pattern); + + return ret; +} + +void +i_regex_unref (Regex *regex) +{ + g_regex_unref(regex); +} + +/* if new_string is present, the caller must free new_string. + otherwise, g_match_info_get_string must not be used. */ +gboolean +i_regex_match (const Regex *regex, + const gchar *string, + GRegexMatchFlags match_options, + MatchInfo **match_info, + const gchar **new_string) +{ + gboolean ret; + gboolean free_valid_string; + const gchar *valid_string = make_valid_utf8(string, &free_valid_string); + + ret = g_regex_match(regex, valid_string, match_options, match_info); + if (free_valid_string) { + if (new_string) + *new_string = valid_string; + else + g_free_not_null((gchar *)valid_string); + } + return ret; +} + +gsize +strlen_pua_oddly(const char *str) +{ + const gchar *ptr; + gsize ret = 0; + ptr = str; + + while (*ptr) { + const gchar *old; + gunichar c = g_utf8_get_char(ptr); + old = ptr; + ptr = g_utf8_next_char(ptr); + + /* it is our PUA encoded byte */ + if ((c & 0xfff00) == 0xfff00) + ret++; + else + ret += ptr - old; + } + + return ret; +} + +gboolean +i_match_info_fetch_pos (const MatchInfo *match_info, + gint match_num, + gint *start_pos, + gint *end_pos, + const gchar *new_string) +{ + gint tmp_start, tmp_end, new_start_pos; + gboolean ret; + + if (!new_string || (!start_pos && !end_pos)) + return g_match_info_fetch_pos(match_info, match_num, start_pos, end_pos); + + ret = g_match_info_fetch_pos(match_info, match_num, &tmp_start, &tmp_end); + if (start_pos || end_pos) { + gchar *to_start = g_strndup(new_string, tmp_start); + new_start_pos = strlen_pua_oddly(to_start); + g_free_not_null(to_start); + + if (start_pos) + *start_pos = new_start_pos; + + if (end_pos) { + gchar *to_end = g_strndup(new_string + tmp_start, tmp_end - tmp_start); + *end_pos = new_start_pos + strlen_pua_oddly(to_end); + g_free_not_null(to_end); + } + } + return ret; +} diff --git a/src/core/iregex-regexh.c b/src/core/iregex-regexh.c new file mode 100644 index 00000000..aabe44f6 --- /dev/null +++ b/src/core/iregex-regexh.c @@ -0,0 +1,101 @@ +#include "iregex.h" + +Regex * +i_regex_new (const gchar *pattern, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options, + GError **error) +{ + Regex *regex; + char *errbuf; + int cflags; + int errcode, errbuf_len; + + regex = g_new0(Regex, 1); + cflags = REG_EXTENDED; + if (compile_options & G_REGEX_CASELESS) + cflags |= REG_ICASE; + if (compile_options & G_REGEX_MULTILINE) + cflags |= REG_NEWLINE; + if (match_options & G_REGEX_MATCH_NOTBOL) + cflags |= REG_NOTBOL; + if (match_options & G_REGEX_MATCH_NOTEOL) + cflags |= REG_NOTEOL; + + errcode = regcomp(regex, pattern, cflags); + if (errcode != 0) { + errbuf_len = regerror(errcode, regex, 0, 0); + errbuf = g_malloc(errbuf_len); + regerror(errcode, regex, errbuf, errbuf_len); + g_set_error(error, G_REGEX_ERROR, errcode, "%s", errbuf); + g_free(errbuf); + g_free(regex); + return NULL; + } else { + return regex; + } +} + +void +i_regex_unref (Regex *regex) +{ + regfree(regex); + g_free(regex); +} + +gboolean +i_regex_match (const Regex *regex, + const gchar *string, + GRegexMatchFlags match_options, + MatchInfo **match_info, + const gchar **new_string) +{ + int groups; + int eflags; + + g_return_val_if_fail(regex != NULL, FALSE); + + if (match_info != NULL) { + groups = 1 + regex->re_nsub; + *match_info = g_new0(MatchInfo, groups); + } else { + groups = 0; + } + + eflags = 0; + if (match_options & G_REGEX_MATCH_NOTBOL) + eflags |= REG_NOTBOL; + if (match_options & G_REGEX_MATCH_NOTEOL) + eflags |= REG_NOTEOL; + + return regexec(regex, string, groups, groups ? *match_info : NULL, eflags) == 0; +} + +gboolean +i_match_info_fetch_pos (const MatchInfo *match_info, + gint match_num, + gint *start_pos, + gint *end_pos, + const gchar *new_string) +{ + if (start_pos != NULL) + *start_pos = match_info[match_num].rm_so; + if (end_pos != NULL) + *end_pos = match_info[match_num].rm_eo; + + return TRUE; +} + +gboolean +i_match_info_matches (const MatchInfo *match_info) +{ + g_return_val_if_fail(match_info != NULL, FALSE); + + return match_info[0].rm_so != -1; +} + +void +i_match_info_free (MatchInfo *match_info) +{ + g_free(match_info); +} diff --git a/src/core/iregex.h b/src/core/iregex.h new file mode 100644 index 00000000..adeea987 --- /dev/null +++ b/src/core/iregex.h @@ -0,0 +1,52 @@ +#ifndef __REGEX_H +#define __REGEX_H + +#include "common.h" + +#ifdef USE_GREGEX + +#include +typedef GRegex Regex; +typedef GMatchInfo MatchInfo; + +#define i_match_info_matches g_match_info_matches +#define i_match_info_free g_match_info_free + +#else + +#include +typedef regex_t Regex; +typedef regmatch_t MatchInfo; + +gboolean +i_match_info_matches (const MatchInfo *match_info); + +void +i_match_info_free (MatchInfo *match_info); + +#endif + +Regex * +i_regex_new (const gchar *pattern, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options, + GError **error); + +void +i_regex_unref (Regex *regex); + +gboolean +i_regex_match (const Regex *regex, + const gchar *string, + GRegexMatchFlags match_options, + MatchInfo **match_info, + const gchar **new_string); + +gboolean +i_match_info_fetch_pos (const MatchInfo *match_info, + gint match_num, + gint *start_pos, + gint *end_pos, + const gchar *new_string); + +#endif diff --git a/src/core/misc.c b/src/core/misc.c index 0f038cbb..4b1e72f6 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -22,10 +22,6 @@ #include "misc.h" #include "commands.h" -#ifndef USE_GREGEX -# include -#endif - typedef struct { int condition; GInputFunction function; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 800e881d..03fd4dd2 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,13 +58,8 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); -#ifdef USE_GREGEX else if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); -#else - else if (!rec->regexp_compiled) - g_string_append(options, "[INVALID!] "); -#endif } if (rec->fullword) g_string_append(options, "-full "); if (rec->replies) g_string_append(options, "-replies "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index dd38be87..6a2c97dc 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -26,6 +26,7 @@ #include "misc.h" #include "lib-config/iconfig.h" #include "settings.h" +#include "iregex.h" #include "servers.h" #include "channels.h" @@ -101,11 +102,7 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); -#ifdef USE_GREGEX - if (rec->preg != NULL) g_regex_unref(rec->preg); -#else - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->preg != NULL) i_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -122,19 +119,10 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { -#ifdef USE_GREGEX if (rec->preg != NULL) - g_regex_unref(rec->preg); + i_regex_unref(rec->preg); - rec->preg = g_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, NULL); -#else - if (rec->regexp_compiled) regfree(&rec->preg); - if (!rec->regexp) - rec->regexp_compiled = FALSE; - else - rec->regexp_compiled = regcomp(&rec->preg, rec->text, - rec->case_sensitive ? REG_EXTENDED : (REG_EXTENDED|REG_ICASE)) == 0; -#endif + rec->preg = i_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_CASELESS, 0, NULL); } void hilight_create(HILIGHT_REC *rec) @@ -207,30 +195,18 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, gboolean ret = FALSE; if (rec->regexp) { -#ifdef USE_GREGEX if (rec->preg != NULL) { - GMatchInfo *match; + MatchInfo *match; + const char *new_text = NULL; - g_regex_match (rec->preg, text, 0, &match); + i_regex_match(rec->preg, text, 0, &match, &new_text); - if (g_match_info_matches(match)) - ret = g_match_info_fetch_pos(match, 0, match_beg, match_end); + if (i_match_info_matches(match)) + ret = i_match_info_fetch_pos(match, 0, match_beg, match_end, new_text); - g_match_info_free(match); + i_match_info_free(match); + g_free_not_null((char *)new_text); } -#else - regmatch_t rmatch[1]; - - if (rec->regexp_compiled && - regexec(&rec->preg, text, 1, rmatch, 0) == 0) { - if (rmatch[0].rm_so > 0 && - match_beg != NULL && match_end != NULL) { - *match_beg = rmatch[0].rm_so; - *match_end = rmatch[0].rm_eo; - } - ret = TRUE; - } -#endif } else { char *match; @@ -524,13 +500,8 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); -#ifdef USE_GREGEX if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); -#else - if (!rec->regexp_compiled) - g_string_append(options, "[INVALID!] "); -#endif } if (rec->priority != 0) diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 76beec1f..1d942f29 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,10 +1,7 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H -#ifndef USE_GREGEX -# include -#endif - +#include "iregex.h" #include "formats.h" struct _HILIGHT_REC { @@ -24,12 +21,7 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ -#ifdef USE_GREGEX - GRegex *preg; -#else - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + Regex *preg; char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 3668f4c7..eb841096 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -24,13 +24,10 @@ #include "misc.h" #include "formats.h" #include "utf8.h" +#include "iregex.h" #include "textbuffer.h" -#ifndef USE_GREGEX -# include -#endif - #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) TEXT_BUFFER_REC *textbuffer_create(void) @@ -545,11 +542,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int before, int after, int regexp, int fullword, int case_sensitive) { -#ifdef USE_GREGEX - GRegex *preg; -#else - regex_t preg; -#endif + Regex *preg; LINE_REC *line, *pre_line; GList *matches; GString *str; @@ -559,23 +552,14 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); -#ifdef USE_GREGEX preg = NULL; if (regexp) { - preg = g_regex_new(text, G_REGEX_RAW | (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); + preg = i_regex_new(text, case_sensitive ? 0 : G_REGEX_CASELESS, 0, NULL); if (preg == NULL) return NULL; } -#else - if (regexp) { - int flags = REG_EXTENDED | REG_NOSUB | - (case_sensitive ? 0 : REG_ICASE); - if (regcomp(&preg, text, flags) != 0) - return NULL; - } -#endif matches = NULL; match_after = 0; str = g_string_new(NULL); @@ -592,17 +576,16 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, (line->info.level & nolevel) == 0; if (*text != '\0') { + const char *tmp = NULL; textbuffer_line2text(line, FALSE, str); if (line_matched) { line_matched = regexp ? -#ifdef USE_GREGEX - g_regex_match(preg, str->str, 0, NULL) -#else - regexec(&preg, str->str, 0, NULL, 0) == 0 -#endif + i_regex_match(preg, str->str, 0, NULL, &tmp) : match_func(str->str, text) != NULL; } + if (tmp && tmp != str->str) + g_free_not_null((char *)tmp); } if (line_matched) { @@ -631,12 +614,8 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } } -#ifdef USE_GREGEX if (preg != NULL) - g_regex_unref(preg); -#else - if (regexp) regfree(&preg); -#endif + i_regex_unref(preg); g_string_free(str, TRUE); return matches; } From e84adeca15084a82c04ff6c3b5c7b8941c297322 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Sun, 4 Jun 2017 17:41:38 +0200 Subject: [PATCH 0114/1198] change ternary operator to if/else statements, add default ssl port support --- src/common.h | 1 + src/fe-common/core/fe-server.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/common.h b/src/common.h index b6f9153e..ddbb1deb 100644 --- a/src/common.h +++ b/src/common.h @@ -9,6 +9,7 @@ #define IRSSI_ABI_VERSION 9 #define DEFAULT_SERVER_ADD_PORT 6667 +#define DEFAULT_SERVER_ADD_TLS_PORT 6697 #ifdef HAVE_CONFIG_H #include "irssi-config.h" diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 46d25ae9..6e373139 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -119,10 +119,15 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); value = g_hash_table_lookup(optlist, "port"); - port = *portstr == '\0' ? - (value != NULL && *value != '\0' ? - atoi(value) : DEFAULT_SERVER_ADD_PORT) - : atoi(portstr); + + if (*portstr != '\0') + port = atoi(portstr); + else if (value != NULL && *value != '\0') + port = atoi(value); + else if (g_hash_table_lookup(optlist, "tls")) + port = DEFAULT_SERVER_ADD_TLS_PORT; + else + port = DEFAULT_SERVER_ADD_PORT; chatnet = g_hash_table_lookup(optlist, "network"); From 78a390f4796a97a3624feee2728018484c8485f8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 4 Jun 2017 19:03:40 +0200 Subject: [PATCH 0115/1198] abi up --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index b6f9153e..b4fc6d28 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 9 +#define IRSSI_ABI_VERSION 10 #define DEFAULT_SERVER_ADD_PORT 6667 From f28c64a3dc1e66f9d1e49650d5b2ab15795b9e53 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Sun, 4 Jun 2017 19:47:30 +0200 Subject: [PATCH 0116/1198] Make backward compatible with ssl flags --- src/fe-common/core/fe-server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 6e373139..75f857c2 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -124,7 +124,8 @@ static void cmd_server_add_modify(const char *data, gboolean add) port = atoi(portstr); else if (value != NULL && *value != '\0') port = atoi(value); - else if (g_hash_table_lookup(optlist, "tls")) + else if (g_hash_table_lookup(optlist, "tls") || + g_hash_table_lookup(optlist, "ssl")) port = DEFAULT_SERVER_ADD_TLS_PORT; else port = DEFAULT_SERVER_ADD_PORT; From 00354c365187cecb9bc3ce3c3b3482e32d04729a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 5 Jun 2017 10:10:38 +0200 Subject: [PATCH 0117/1198] Update iregex-gregex.c make helper functions static --- src/core/iregex-gregex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/iregex-gregex.c b/src/core/iregex-gregex.c index 0de11e64..1a77d5b3 100644 --- a/src/core/iregex-gregex.c +++ b/src/core/iregex-gregex.c @@ -2,7 +2,7 @@ #include "iregex.h" -const gchar * +static const gchar * make_valid_utf8(const gchar *text, gboolean *free_ret) { GString *str; @@ -82,7 +82,7 @@ i_regex_match (const Regex *regex, return ret; } -gsize +static gsize strlen_pua_oddly(const char *str) { const gchar *ptr; From 48899a123d68051fbc73acb8ad151e89fdcb6b31 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 5 Jun 2017 10:23:16 +0200 Subject: [PATCH 0118/1198] Update iregex-gregex.c add 2 comments about new_string --- src/core/iregex-gregex.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/iregex-gregex.c b/src/core/iregex-gregex.c index 1a77d5b3..4a1623b9 100644 --- a/src/core/iregex-gregex.c +++ b/src/core/iregex-gregex.c @@ -60,7 +60,9 @@ i_regex_unref (Regex *regex) } /* if new_string is present, the caller must free new_string. - otherwise, g_match_info_get_string must not be used. */ + otherwise, g_match_info_get_string must not be used. + if string is not vali utf8, new_string will be assigned + a similar, but valid utf8, string */ gboolean i_regex_match (const Regex *regex, const gchar *string, @@ -105,6 +107,9 @@ strlen_pua_oddly(const char *str) return ret; } +/* new_string should be passed in here from the i_regex_match call. + The start_pos and end_pos will then be calculated as if they were on + the original string */ gboolean i_match_info_fetch_pos (const MatchInfo *match_info, gint match_num, From 4edfccfce794d4c10b2a92c02fe982bb089c6629 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 5 Jun 2017 11:41:50 +0200 Subject: [PATCH 0119/1198] get rid of new_text --- src/core/ignore.c | 2 +- src/core/iregex-gregex.c | 55 ++++++++++++++++++++++--------- src/core/iregex-regexh.c | 6 ++-- src/core/iregex.h | 15 +++------ src/fe-common/core/hilight-text.c | 7 ++-- src/fe-text/textbuffer.c | 5 +-- 6 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 63a507f5..cec91e6b 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -69,7 +69,7 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) if (rec->regexp) { return rec->preg != NULL && - i_regex_match(rec->preg, text, 0, NULL, NULL); + i_regex_match(rec->preg, text, 0, NULL); } return rec->fullword ? diff --git a/src/core/iregex-gregex.c b/src/core/iregex-gregex.c index 4a1623b9..36b4faa4 100644 --- a/src/core/iregex-gregex.c +++ b/src/core/iregex-gregex.c @@ -2,6 +2,11 @@ #include "iregex.h" +struct _MatchInfo { + const char *valid_string; + GMatchInfo *g_match_info; +}; + static const gchar * make_valid_utf8(const gchar *text, gboolean *free_ret) { @@ -59,28 +64,29 @@ i_regex_unref (Regex *regex) g_regex_unref(regex); } -/* if new_string is present, the caller must free new_string. - otherwise, g_match_info_get_string must not be used. - if string is not vali utf8, new_string will be assigned - a similar, but valid utf8, string */ gboolean i_regex_match (const Regex *regex, const gchar *string, GRegexMatchFlags match_options, - MatchInfo **match_info, - const gchar **new_string) + MatchInfo **match_info) { gboolean ret; gboolean free_valid_string; const gchar *valid_string = make_valid_utf8(string, &free_valid_string); - ret = g_regex_match(regex, valid_string, match_options, match_info); + if (match_info != NULL) + *match_info = g_new0(MatchInfo, 1); + + ret = g_regex_match(regex, valid_string, match_options, + match_info != NULL ? &(*match_info)->g_match_info : NULL); + if (free_valid_string) { - if (new_string) - *new_string = valid_string; + if (match_info != NULL) + (*match_info)->valid_string = valid_string; else g_free_not_null((gchar *)valid_string); } + return ret; } @@ -114,18 +120,20 @@ gboolean i_match_info_fetch_pos (const MatchInfo *match_info, gint match_num, gint *start_pos, - gint *end_pos, - const gchar *new_string) + gint *end_pos) { gint tmp_start, tmp_end, new_start_pos; gboolean ret; - if (!new_string || (!start_pos && !end_pos)) - return g_match_info_fetch_pos(match_info, match_num, start_pos, end_pos); + if (!match_info->valid_string || (!start_pos && !end_pos)) + return g_match_info_fetch_pos(match_info->g_match_info, + match_num, start_pos, end_pos); - ret = g_match_info_fetch_pos(match_info, match_num, &tmp_start, &tmp_end); + ret = g_match_info_fetch_pos(match_info->g_match_info, + match_num, &tmp_start, &tmp_end); if (start_pos || end_pos) { - gchar *to_start = g_strndup(new_string, tmp_start); + const gchar *str = match_info->valid_string; + gchar *to_start = g_strndup(str, tmp_start); new_start_pos = strlen_pua_oddly(to_start); g_free_not_null(to_start); @@ -133,10 +141,25 @@ i_match_info_fetch_pos (const MatchInfo *match_info, *start_pos = new_start_pos; if (end_pos) { - gchar *to_end = g_strndup(new_string + tmp_start, tmp_end - tmp_start); + gchar *to_end = g_strndup(str + tmp_start, tmp_end - tmp_start); *end_pos = new_start_pos + strlen_pua_oddly(to_end); g_free_not_null(to_end); } } return ret; } + +gboolean +i_match_info_matches (const MatchInfo *match_info) +{ + g_return_val_if_fail(match_info != NULL, FALSE); + + return g_match_info_matches(match_info->g_match_info); +} + +void +i_match_info_free (MatchInfo *match_info) +{ + g_match_info_free(match_info->g_match_info); + g_free(match_info); +} diff --git a/src/core/iregex-regexh.c b/src/core/iregex-regexh.c index aabe44f6..897eb7e2 100644 --- a/src/core/iregex-regexh.c +++ b/src/core/iregex-regexh.c @@ -47,8 +47,7 @@ gboolean i_regex_match (const Regex *regex, const gchar *string, GRegexMatchFlags match_options, - MatchInfo **match_info, - const gchar **new_string) + MatchInfo **match_info) { int groups; int eflags; @@ -75,8 +74,7 @@ gboolean i_match_info_fetch_pos (const MatchInfo *match_info, gint match_num, gint *start_pos, - gint *end_pos, - const gchar *new_string) + gint *end_pos) { if (start_pos != NULL) *start_pos = match_info[match_num].rm_so; diff --git a/src/core/iregex.h b/src/core/iregex.h index adeea987..e67378d7 100644 --- a/src/core/iregex.h +++ b/src/core/iregex.h @@ -7,10 +7,7 @@ #include typedef GRegex Regex; -typedef GMatchInfo MatchInfo; - -#define i_match_info_matches g_match_info_matches -#define i_match_info_free g_match_info_free +typedef struct _MatchInfo MatchInfo; #else @@ -18,14 +15,14 @@ typedef GMatchInfo MatchInfo; typedef regex_t Regex; typedef regmatch_t MatchInfo; +#endif + gboolean i_match_info_matches (const MatchInfo *match_info); void i_match_info_free (MatchInfo *match_info); -#endif - Regex * i_regex_new (const gchar *pattern, GRegexCompileFlags compile_options, @@ -39,14 +36,12 @@ gboolean i_regex_match (const Regex *regex, const gchar *string, GRegexMatchFlags match_options, - MatchInfo **match_info, - const gchar **new_string); + MatchInfo **match_info); gboolean i_match_info_fetch_pos (const MatchInfo *match_info, gint match_num, gint *start_pos, - gint *end_pos, - const gchar *new_string); + gint *end_pos); #endif diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 6a2c97dc..62e6f0de 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -197,15 +197,12 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, if (rec->regexp) { if (rec->preg != NULL) { MatchInfo *match; - const char *new_text = NULL; - - i_regex_match(rec->preg, text, 0, &match, &new_text); + i_regex_match(rec->preg, text, 0, &match); if (i_match_info_matches(match)) - ret = i_match_info_fetch_pos(match, 0, match_beg, match_end, new_text); + ret = i_match_info_fetch_pos(match, 0, match_beg, match_end); i_match_info_free(match); - g_free_not_null((char *)new_text); } } else { char *match; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index eb841096..9e791f4c 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -576,16 +576,13 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, (line->info.level & nolevel) == 0; if (*text != '\0') { - const char *tmp = NULL; textbuffer_line2text(line, FALSE, str); if (line_matched) { line_matched = regexp ? - i_regex_match(preg, str->str, 0, NULL, &tmp) + i_regex_match(preg, str->str, 0, NULL) : match_func(str->str, text) != NULL; } - if (tmp && tmp != str->str) - g_free_not_null((char *)tmp); } if (line_matched) { From 52bb06ccd9f9bd639a454045eba1235e4133b034 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 5 Jun 2017 15:58:43 -0300 Subject: [PATCH 0120/1198] fe-dcc-(get|send): Fix some -Wpointer-compare with newer gcc The warning itself: >warning: comparison between pointer and zero character constant [-Wpointer-compare] Harmless stuff as far as I can tell. The fix adds a null check that probably isn't needed. The old code that compared against '\0' worked a lot like a null check so it makes sense to keep that, while also adding the intended check for empty string. This was visible with "/dcc close send a" showing an empty filename. The equivalent for get didn't show the filename in the format string. --- src/fe-common/irc/dcc/fe-dcc-get.c | 2 +- src/fe-common/irc/dcc/fe-dcc-send.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-common/irc/dcc/fe-dcc-get.c b/src/fe-common/irc/dcc/fe-dcc-get.c index 675cab65..99b6b963 100644 --- a/src/fe-common/irc/dcc/fe-dcc-get.c +++ b/src/fe-common/irc/dcc/fe-dcc-get.c @@ -108,7 +108,7 @@ static void dcc_error_close_not_found(const char *type, const char *nick, g_return_if_fail(fname != NULL); if (g_ascii_strcasecmp(type, "GET") != 0) return; - if (fname == '\0') fname = "(ANY)"; + if (fname == NULL || *fname == '\0') fname = "(ANY)"; printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_GET_NOT_FOUND, nick, fname); } diff --git a/src/fe-common/irc/dcc/fe-dcc-send.c b/src/fe-common/irc/dcc/fe-dcc-send.c index 1fc43abd..7920bedc 100644 --- a/src/fe-common/irc/dcc/fe-dcc-send.c +++ b/src/fe-common/irc/dcc/fe-dcc-send.c @@ -108,7 +108,7 @@ static void dcc_error_close_not_found(const char *type, const char *nick, g_return_if_fail(fname != NULL); if (g_ascii_strcasecmp(type, "SEND") != 0) return; - if (fname == '\0') fname = "(ANY)"; + if (fname == NULL || *fname == '\0') fname = "(ANY)"; printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_SEND_NOT_FOUND, nick, fname); } From 0e44ea891645044f47bf3754e141045ee3b24324 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 5 Jun 2017 16:05:00 -0300 Subject: [PATCH 0121/1198] Performance improvements for /lastlog with big result sets This applies to "/lastlog" with no filters (or with filters that don't filter a lot) and with large amounts of text in the scrollback. Test case: /exec seq 1 500000 /lastlog -file log.txt Thanks to morning for reporting this. --- src/fe-text/textbuffer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 3668f4c7..fdb95451 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -616,21 +616,23 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } for (; pre_line != line; pre_line = pre_line->next) - matches = g_list_append(matches, pre_line); + matches = g_list_prepend(matches, pre_line); match_after = after; } if (line_matched || match_after > 0) { /* matched */ - matches = g_list_append(matches, line); + matches = g_list_prepend(matches, line); if ((!line_matched && --match_after == 0) || (line_matched && match_after == 0 && before > 0)) - matches = g_list_append(matches, NULL); + matches = g_list_prepend(matches, NULL); } } + matches = g_list_reverse(matches); + #ifdef USE_GREGEX if (preg != NULL) g_regex_unref(preg); From e498265328bd619b231ea4c985734ea43bf89696 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 5 Jun 2017 18:04:20 -0300 Subject: [PATCH 0122/1198] Performance improvements for /lastlog -before This avoids the use of g_list_find() to find if a match was already added to the list of results, by checking the last two added matches instead. Checking just the last match isn't enough because a NULL match is added as a separator (shown as -- in the UI) --- src/fe-text/textbuffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index fdb95451..1f587f97 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -610,7 +610,8 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, pre_line = line; for (i = 0; i < before; i++) { if (pre_line->prev == NULL || - g_list_find(matches, pre_line->prev) != NULL) + g_list_nth_data(matches, 0) == pre_line->prev || + g_list_nth_data(matches, 1) == pre_line->prev) break; pre_line = pre_line->prev; } From fc67fd5111ac84cd101d961fc9a5b0bc1b25613b Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 6 Jun 2017 21:06:35 +0200 Subject: [PATCH 0123/1198] Merge tag '1.0.3' --- NEWS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/NEWS b/NEWS index af330804..b0a895ad 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,23 @@ v1.1-head 2017-xx-xx The Irssi team +v1.0.3 2017-06-06 The Irssi team + - Fix out of bounds read when scanning expandos (GL!11). + - Fix invalid memory access with quoted filenames in DCC + (GL#8, GL!12). + - Fix null-pointer dereference on DCC without address (GL#9, GL!13). + - Improve integer overflow handling. Originally reported by + oss-fuzz#525 (#706). + - Improve nicklist performance from O(N^2) to O(N) (#705). + - Fix initial screen redraw delay. By Stephen Oberholtzer + (#680, bdo#856201). + - Fix incorrect reset of true colours when resetting background. (#711). + - Fix missing -notls option in /SERVER. By Jari Matilainen (#117, #702). + - Fix minor history glitch on overcounter (#462, #685). + - Improved OpenSSL detection at compile time. By Rodrigo Rebello (#677). + - Improved NetBSD Terminfo detection. By Maya Rashish (#694, #698). + - Add missing syntax info for COMPLETION (#687, #688). + - Minor typo correction in help. By Michael Hansen (#707). + v1.0.2 2017-03-10 The Irssi team - Prevent some null-pointer crashes (GL!9). - Fix compilation with OpenSSL 1.1.0 (#628, #597). From 4b1c60b2ecb030550716647bffb0f9dd7e97c31a Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 17 Jun 2017 13:47:13 -0300 Subject: [PATCH 0124/1198] term-terminfo: Avoid switching out of alt screen on unexpected exits Perl sucks and kills the whole process when there's a version mismatch in Perl_xs_handshake(). Our atexit handler catches the exit and deinitializes the terminal, removing the error. This commit uses the 'quitting' global variable which is set when irssi is voluntarily quitting, and avoids sending TI_rmcup, which restores the original screen and makes the error invisible. --- src/fe-text/term-terminfo.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 3098a4e4..bca37efc 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -102,6 +102,17 @@ static GSourceFuncs sigcont_funcs = { .dispatch = sigcont_dispatch }; +static void term_atexit(void) +{ + if (!quitting && current_term && current_term->TI_rmcup) { + /* Unexpected exit, avoid switching out of alternate screen + to keep any on-screen errors (like noperl_die()'s) */ + current_term->TI_rmcup = NULL; + } + + term_deinit(); +} + int term_init(void) { struct sigaction act; @@ -140,7 +151,7 @@ int term_init(void) term_set_input_type(TERM_TYPE_8BIT); term_common_init(); - atexit(term_deinit); + atexit(term_atexit); return TRUE; } From 7354a74c654f1717d08a37c2b118141655974bc0 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 17 Jun 2017 14:30:37 -0300 Subject: [PATCH 0125/1198] parse_time_interval: Allow negative time in settings This splits sign parsing out of parse_time_interval_uint() so that the negative sign is applied outside of the unsigned context where the number parsing is done, and after all the checks that it's lower than (1 << 31) This fixes issues with settings like `server_reconnect_time`, `server_connect_timeout` and `lag_max_before_disconnect`, which accepted -1 as a valid value. --- src/core/misc.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 0f038cbb..ce49925b 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -781,24 +781,35 @@ int parse_uint(const char *nptr, char **endptr, int base, guint *number) return TRUE; } +static int parse_number_sign(const char *input, char **endptr, int *sign) +{ + int sign_ = 1; + + while (i_isspace(*input)) + input++; + + if (*input == '-') { + sign_ = -sign_; + input++; + } + + *sign = sign_; + *endptr = (char *) input; + return TRUE; +} + static int parse_time_interval_uint(const char *time, guint *msecs) { const char *desc; guint number; - int sign, len, ret, digits; + int len, ret, digits; *msecs = 0; /* max. return value is around 24 days */ - number = 0; sign = 1; ret = TRUE; digits = FALSE; + number = 0; ret = TRUE; digits = FALSE; while (i_isspace(*time)) time++; - if (*time == '-') { - sign = -sign; - time++; - while (i_isspace(*time)) - time++; - } for (;;) { if (i_isdigit(*time)) { char *endptr; @@ -828,7 +839,6 @@ static int parse_time_interval_uint(const char *time, guint *msecs) if (*time != '\0') return FALSE; *msecs += number * 1000; /* assume seconds */ - *msecs *= sign; return TRUE; } @@ -866,7 +876,6 @@ static int parse_time_interval_uint(const char *time, guint *msecs) digits = FALSE; } - *msecs *= sign; return ret; } @@ -960,15 +969,18 @@ int parse_size(const char *size, int *bytes) int parse_time_interval(const char *time, int *msecs) { guint msecs_; - int ret; + char *number; + int ret, sign; - ret = parse_time_interval_uint(time, &msecs_); + parse_number_sign(time, &number, &sign); + + ret = parse_time_interval_uint(number, &msecs_); if (msecs_ > (1U << 31)) { return FALSE; } - *msecs = msecs_; + *msecs = msecs_ * sign; return ret; } From 02a5d1a00b4f484b4b2422785944e022810bbbb0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Jun 2017 14:09:02 +0200 Subject: [PATCH 0126/1198] fix weird n-fold unescaping --- src/fe-common/core/chat-completion.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 1f00feaf..1c9db28e 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1011,13 +1011,17 @@ static void sig_complete_target(GList **list, WINDOW_REC *window, } } +static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item); + /* expand \n, \t and \\ */ static char *expand_escapes(const char *line, SERVER_REC *server, WI_ITEM_REC *item) { char *ptr, *ret; - int chr; + const char *prev; + int chr; + prev = line; ret = ptr = g_malloc(strlen(line)+1); for (; *line != '\0'; line++) { if (*line != '\\') { @@ -1036,9 +1040,11 @@ static char *expand_escapes(const char *line, SERVER_REC *server, /* newline .. we need to send another "send text" event to handle it (or actually the text before the newline..) */ - if (ret != ptr) { - *ptr = '\0'; - signal_emit("send text", 3, ret, server, item); + if (prev != line) { + const char *prev_line = g_strndup(prev, (line - prev) - 1); + event_text(prev_line, server, item); + g_free((char *)prev_line); + prev = line + 1; ptr = ret; } } else if (chr != -1) { From 12d671a05645d67e811264d5be06d9758458452f Mon Sep 17 00:00:00 2001 From: Oscar Linderholm Date: Wed, 21 Jun 2017 10:40:01 +0200 Subject: [PATCH 0127/1198] Escape nicks during nick completion when expand_escapes is enabled Fixes #693 --- src/fe-common/core/completion.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index a97adc21..78b1b24b 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -137,8 +137,9 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i int old_startpos, old_wordlen; GString *result; - char *word, *wordstart, *linestart, *ret; - int continue_complete, want_space; + const char *cmdchars; + char *word, *wordstart, *linestart, *ret, *data; + int continue_complete, want_space, expand_escapes; g_return_val_if_fail(line != NULL, NULL); g_return_val_if_fail(pos != NULL, NULL); @@ -241,14 +242,24 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i if (complist == NULL) return NULL; + /* get the cmd char */ + cmdchars = settings_get_str("cmdchars"); + + /* get the expand_escapes setting */ + expand_escapes = settings_get_bool("expand_escapes"); + + /* escape if the word doesn't begin with '/' and expand_escapes are turned on */ + data = strchr(cmdchars, *line) == NULL && expand_escapes ? + escape_string(complist->data) : g_strdup(complist->data); + /* word completed */ - *pos = startpos+strlen(complist->data); + *pos = startpos + strlen(data); /* replace the word in line - we need to return a full new line */ result = g_string_new(line); g_string_erase(result, startpos, wordlen); - g_string_insert(result, startpos, complist->data); + g_string_insert(result, startpos, data); if (want_space) { if (!isseparator(result->str[*pos])) @@ -256,13 +267,17 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i (*pos)++; } - wordlen = strlen(complist->data); + wordlen = strlen(data); last_line_pos = *pos; g_free_not_null(last_line); last_line = g_strdup(result->str); ret = result->str; g_string_free(result, FALSE); + + /* free the data */ + g_free(data); + return ret; } From bbf8b860747c13a478657b9070c191735d35e00a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 22 Jun 2017 09:33:33 +0200 Subject: [PATCH 0128/1198] remove const --- src/fe-common/core/chat-completion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 1c9db28e..97cd0565 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1041,9 +1041,9 @@ static char *expand_escapes(const char *line, SERVER_REC *server, event to handle it (or actually the text before the newline..) */ if (prev != line) { - const char *prev_line = g_strndup(prev, (line - prev) - 1); + char *prev_line = g_strndup(prev, (line - prev) - 1); event_text(prev_line, server, item); - g_free((char *)prev_line); + g_free(prev_line); prev = line + 1; ptr = ret; } From b483ec5faa76dc38f2e338f89c54a6e4cd06c764 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 23 Jun 2017 12:03:05 +0200 Subject: [PATCH 0129/1198] test trusty container --- .travis.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 804dc58c..b4b93919 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,15 @@ sudo: false +dist: trusty language: perl perl: - - "5.20-shrplib" - - "5.18-shrplib" + # ~stretch + - "5.24-shrplib" + # ~xenial + # - "5.22-shrplib" + # ~jessie + # - "5.20-shrplib" + # ~trusty + # - "5.18-shrplib" - "system-perl" env: - CC=clang From 29ebac987da1da2c892aed5ed329256b7bc94bca Mon Sep 17 00:00:00 2001 From: Nei Date: Thu, 29 Jun 2017 13:48:44 +0000 Subject: [PATCH 0130/1198] Check return value of localtime Fixes #10 --- src/core/misc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/misc.c b/src/core/misc.c index ce49925b..0b2d8e77 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -560,6 +560,9 @@ char *my_asctime(time_t t) int len; tm = localtime(&t); + if (tm == NULL) + return g_strdup("???"); + str = g_strdup(asctime(tm)); len = strlen(str); From 73b851c39c11d01199e6c040749fb20e468f6c8d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 4 Jul 2017 16:10:55 +0200 Subject: [PATCH 0131/1198] correct GHashTable usage --- src/core/nicklist.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/nicklist.c b/src/core/nicklist.c index 54dfb5fb..0bc88ab8 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -54,23 +54,26 @@ static void nick_hash_add(CHANNEL_REC *channel, NICK_REC *nick) static void nick_hash_remove(CHANNEL_REC *channel, NICK_REC *nick) { - NICK_REC *list; + NICK_REC *list, *newlist; list = g_hash_table_lookup(channel->nicks, nick->nick); if (list == NULL) return; - if (list == nick || list->next == NULL) { - g_hash_table_remove(channel->nicks, nick->nick); - if (list->next != NULL) { - g_hash_table_insert(channel->nicks, nick->next->nick, - nick->next); - } + if (list == nick) { + newlist = nick->next; } else { + newlist = list; while (list->next != nick) list = list->next; list->next = nick->next; } + + g_hash_table_remove(channel->nicks, nick->nick); + if (newlist != NULL) { + g_hash_table_insert(channel->nicks, newlist->nick, + newlist); + } } /* Add new nick to list */ From 5d7e54cd998ab48b1dc5d82aa74896bc9a91b705 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 5 Jul 2017 14:30:11 +0200 Subject: [PATCH 0132/1198] More accurately describe clear --- docs/help/in/clear.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/help/in/clear.in b/docs/help/in/clear.in index d43830dd..affa7677 100644 --- a/docs/help/in/clear.in +++ b/docs/help/in/clear.in @@ -12,8 +12,8 @@ %9Description:%9 - Clears the window of all text; you may use this to clear a windows that - contains sensitive information or has rendered improperly. + Scrolls up the text in the window and fill the window with blank lines; you + may want to use this to make new text start at the top of the window again. %9See also:%9 REDRAW From 8b82d741b79e1cbb68c9e01d85d344fa0dc817ca Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 5 Jul 2017 19:39:17 +0200 Subject: [PATCH 0133/1198] Update clear.in --- docs/help/in/clear.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/help/in/clear.in b/docs/help/in/clear.in index affa7677..3b76a7c9 100644 --- a/docs/help/in/clear.in +++ b/docs/help/in/clear.in @@ -12,8 +12,8 @@ %9Description:%9 - Scrolls up the text in the window and fill the window with blank lines; you + Scrolls up the text in the window and fills the window with blank lines; you may want to use this to make new text start at the top of the window again. -%9See also:%9 REDRAW +%9See also:%9 REDRAW, SCROLLBACK CLEAR From 91ec153c7f89ed96fa592ebae7a931fe50a4bb42 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 5 Jul 2017 21:30:59 +0200 Subject: [PATCH 0134/1198] Merge tag '1.0.4' into integrate/1.0.4 --- NEWS | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/NEWS b/NEWS index b0a895ad..feb52275 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,18 @@ v1.1-head 2017-xx-xx The Irssi team +v1.0.4 2017-07-07 The Irssi team + - Fix null pointer dereference when parsing invalid timestamp (GL#10, + GL!15). Reported by Brian 'geeknik' Carpenter. + - Fix use-after-free condition when removing nicks from the internal + nicklist (GL#11, GL!16). Reported by Brian 'geeknik' Carpenter. + - Fix incorrect string comparison in DCC file names (#714). + - Fix regression in Irssi 1.0.3 where it would claim "Invalid time '-1'" + (#716, #722). + - Fix a bug when using \n to separate lines with expand_escapes (#723). + - Retain screen output on improper exit, to better see any error + messages (#287, #721). + - Minor help update (#729). + v1.0.3 2017-06-06 The Irssi team - Fix out of bounds read when scanning expandos (GL!11). - Fix invalid memory access with quoted filenames in DCC From 2bc10386610eba0fe5741228f143e89e1acd2a7d Mon Sep 17 00:00:00 2001 From: Tristan Date: Fri, 21 Jul 2017 20:40:29 -0400 Subject: [PATCH 0135/1198] Clarified ambiguous autogen.sh error autogen.sh now instructs the user to install elinks or lynx if needed --- autogen.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/autogen.sh b/autogen.sh index 946f1ebb..60eb4fb8 100755 --- a/autogen.sh +++ b/autogen.sh @@ -39,6 +39,7 @@ elif type links >/dev/null 2>&1 ; then links -dump docs/faq.html|perl -pe 's/^ *//; if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = " $_"; };' > docs/faq.txt else echo "**Error**: No lynx or elinks present" + echo "Install lynx or elinks, then run autogen.sh again" exit 1 fi From d971c0292082823182f333a412207a9a8f6ad008 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 17 Jun 2017 17:01:42 +0200 Subject: [PATCH 0136/1198] Allow the user to clear the sasl-related fields There was no easy way for the user to disable the SASL authentication or to clear the username/password once the network was created. Closes #718 --- docs/help/in/network.in | 1 + src/fe-common/irc/fe-ircnet.c | 6 +++--- src/irc/core/irc-servers-setup.c | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/help/in/network.in b/docs/help/in/network.in index ba08ef69..4c2eeed4 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -36,6 +36,7 @@ -sasl_mechanism Specifies the mechanism to use for the SASL authentication. At the moment irssi only supports the 'plain' and the 'external' mechanisms. + Use '' to disable the authentication. -sasl_username Specifies the username to use during the SASL authentication. -sasl_password Specifies the password to use during the SASL authentication. diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index b70a9ea7..24dad63f 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -163,11 +163,11 @@ static void cmd_network_add_modify(const char *data, gboolean add) /* the validity of the parameters is checked in sig_server_setup_fill_chatnet */ value = g_hash_table_lookup(optlist, "sasl_mechanism"); - if (value != NULL && *value != '\0') rec->sasl_mechanism = g_strdup(value); + if (value != NULL) rec->sasl_mechanism = *value != '\0' ? g_strdup(value) : NULL; value = g_hash_table_lookup(optlist, "sasl_username"); - if (value != NULL && *value != '\0') rec->sasl_username = g_strdup(value); + if (value != NULL) rec->sasl_username = *value != '\0' ? g_strdup(value) : NULL; value = g_hash_table_lookup(optlist, "sasl_password"); - if (value != NULL && *value != '\0') rec->sasl_password = g_strdup(value); + if (value != NULL) rec->sasl_password = *value != '\0' ? g_strdup(value) : NULL; ircnet_create(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_ADDED, name); diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index f425b587..6040d3a5 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -89,6 +89,8 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, /* Validate the SASL parameters filled by sig_chatnet_read() or cmd_network_add */ conn->sasl_mechanism = SASL_MECHANISM_NONE; + conn->sasl_username = NULL; + conn->sasl_password = NULL; if (ircnet->sasl_mechanism != NULL) { if (!g_ascii_strcasecmp(ircnet->sasl_mechanism, "plain")) { @@ -102,9 +104,7 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, g_warning("The fields sasl_username and sasl_password are either missing or empty"); } else if (!g_ascii_strcasecmp(ircnet->sasl_mechanism, "external")) { - conn->sasl_mechanism = SASL_MECHANISM_EXTERNAL; - conn->sasl_username = NULL; - conn->sasl_password = NULL; + conn->sasl_mechanism = SASL_MECHANISM_EXTERNAL; } else g_warning("Unsupported SASL mechanism \"%s\" selected", ircnet->sasl_mechanism); From e08e2bd87aceafc2a34d72ca3fd362f2f2ea90eb Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 03:56:02 +0100 Subject: [PATCH 0137/1198] Don't compute log_dir_create_mode in three different places. Signed-off-by: Edward Tomasz Napierala --- src/core/log.c | 5 ++--- src/core/log.h | 2 ++ src/core/rawlog.c | 9 +-------- src/fe-common/core/fe-log.c | 9 --------- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/core/log.c b/src/core/log.c index 6af1effc..cee1dab5 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -33,6 +33,8 @@ #define DEFAULT_LOG_FILE_CREATE_MODE 600 GSList *logs; +int log_file_create_mode; +int log_dir_create_mode; static const char *log_item_types[] = { "target", @@ -42,8 +44,6 @@ static const char *log_item_types[] = { }; static char *log_timestamp; -static int log_file_create_mode; -static int log_dir_create_mode; static int rotate_tag; static int log_item_str2type(const char *type) @@ -562,7 +562,6 @@ static void read_settings(void) log_timestamp = g_strdup(settings_get_str("log_timestamp")); log_file_create_mode = octal2dec(settings_get_int("log_create_mode")); - log_dir_create_mode = log_file_create_mode; if (log_file_create_mode & 0400) log_dir_create_mode |= 0100; if (log_file_create_mode & 0040) log_dir_create_mode |= 0010; diff --git a/src/core/log.h b/src/core/log.h index fae872c7..5a07859b 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -35,6 +35,8 @@ struct _LOG_REC { }; extern GSList *logs; +extern int log_file_create_mode; +extern int log_dir_create_mode; /* Create log record - you still need to call log_update() to actually add it into log list */ diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 5927e730..2192e256 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -20,6 +20,7 @@ #include "module.h" #include "rawlog.h" +#include "log.h" #include "modules.h" #include "signals.h" #include "commands.h" @@ -31,8 +32,6 @@ static int rawlog_lines; static int signal_rawlog; -static int log_file_create_mode; -static int log_dir_create_mode; RAWLOG_REC *rawlog_create(void) { @@ -174,12 +173,6 @@ void rawlog_set_size(int lines) static void read_settings(void) { rawlog_set_size(settings_get_int("rawlog_lines")); - log_file_create_mode = octal2dec(settings_get_int("log_create_mode")); - log_dir_create_mode = log_file_create_mode; - if (log_file_create_mode & 0400) log_dir_create_mode |= 0100; - if (log_file_create_mode & 0040) log_dir_create_mode |= 0010; - if (log_file_create_mode & 0004) log_dir_create_mode |= 0001; - } static void cmd_rawlog(const char *data, SERVER_REC *server, void *item) diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 5bc5c4e1..37b29990 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -49,8 +49,6 @@ static THEME_REC *log_theme; static int skip_next_printtext; static char *log_theme_name; -static int log_dir_create_mode; - static char **autolog_ignore_targets; static char *log_colorizer_strip(const char *str) @@ -676,7 +674,6 @@ static void sig_theme_destroyed(THEME_REC *theme) static void read_settings(void) { int old_autolog = autolog_level; - int log_file_create_mode; g_free_not_null(autolog_path); autolog_path = g_strdup(settings_get_str("autolog_path")); @@ -704,12 +701,6 @@ static void read_settings(void) log_theme = log_theme_name == NULL ? NULL : theme_load(log_theme_name); - log_file_create_mode = octal2dec(settings_get_int("log_create_mode")); - log_dir_create_mode = log_file_create_mode; - if (log_file_create_mode & 0400) log_dir_create_mode |= 0100; - if (log_file_create_mode & 0040) log_dir_create_mode |= 0010; - if (log_file_create_mode & 0004) log_dir_create_mode |= 0001; - if (autolog_ignore_targets != NULL) g_strfreev(autolog_ignore_targets); From 42b5e89f6e9fba17111f67441e25db38a737a3bd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 04:49:14 +0100 Subject: [PATCH 0138/1198] Add missing diagnostics for rawlog open(). Signed-off-by: Edward Tomasz Napierala --- src/core/rawlog.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 2192e256..d929682a 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -128,6 +128,9 @@ void rawlog_open(RAWLOG_REC *rawlog, const char *fname) path = convert_home(fname); rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); + if (rawlog->handle == -1) { + g_warning("rawlog open() failed: %s", strerror(errno)); + } g_free(path); rawlog_dump(rawlog, rawlog->handle); From 08dc6734b90389c357c73544023ec614e43b0860 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 09:25:51 +0100 Subject: [PATCH 0139/1198] When rawlog open fails, there's no point in trying to write. Don't. Signed-off-by: Edward Tomasz Napierala --- src/core/rawlog.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index d929682a..43f140f3 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -128,13 +128,15 @@ void rawlog_open(RAWLOG_REC *rawlog, const char *fname) path = convert_home(fname); rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); - if (rawlog->handle == -1) { - g_warning("rawlog open() failed: %s", strerror(errno)); - } g_free(path); + if (rawlog->handle == -1) { + g_warning("rawlog open() failed: %s", strerror(errno)); + return; + } + rawlog_dump(rawlog, rawlog->handle); - rawlog->logging = rawlog->handle != -1; + rawlog->logging = TRUE; } void rawlog_close(RAWLOG_REC *rawlog) From 2914498b291ea0ca432a320004aa3d2499e50eb5 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 10:42:53 +0100 Subject: [PATCH 0140/1198] Consistency: use FALSE instead of 0. Signed-off-by: Edward Tomasz Napierala --- src/core/rawlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 43f140f3..2ec155fa 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -144,7 +144,7 @@ void rawlog_close(RAWLOG_REC *rawlog) if (rawlog->logging) { write_buffer_flush(); close(rawlog->handle); - rawlog->logging = 0; + rawlog->logging = FALSE; } } From 2907a82b446d9d0a25157aa4ab560b49853f80d2 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 12:32:15 +0100 Subject: [PATCH 0141/1198] Fix vertical alignment in ./configure --help output. Signed-off-by: Edward Tomasz Napierala --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 459d3a2d..c7c8edef 100644 --- a/configure.ac +++ b/configure.ac @@ -158,7 +158,7 @@ AC_ARG_ENABLE(true-color, want_truecolor=no) AC_ARG_ENABLE(gregex, -[ --disable-gregex Build without GRegex (fall back to regex.h)], +[ --disable-gregex Build without GRegex (fall back to regex.h)], if test x$enableval = xno ; then want_gregex=no else From f468008b25c7218a03cc0b327082d4d69d5481ef Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 25 Jul 2017 19:39:15 +0100 Subject: [PATCH 0142/1198] Make autotools detect Capsicum. Signed-off-by: Edward Tomasz Napierala --- configure.ac | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/configure.ac b/configure.ac index c7c8edef..f0c4cc5d 100644 --- a/configure.ac +++ b/configure.ac @@ -166,6 +166,15 @@ AC_ARG_ENABLE(gregex, fi, want_gregex=yes) +AC_ARG_WITH(capsicum, +[ --with-capsicum Build with Capsicum support], + if test x$withval = xno; then + want_capsicum=no + else + want_capsicum=yes + fi, + want_capsicum=yes) + dnl ** dnl ** just some generic stuff... dnl ** @@ -499,6 +508,18 @@ if test "$want_perl" != "no"; then fi fi +dnl ** +dnl ** check for capsicum +dnl ** + +if test "x$want_capsicum" = "xyes"; then + AC_CHECK_LIB(c, cap_enter, [ + AC_DEFINE(HAVE_CAPSICUM,, Build with Capsicum support) + ], [ + want_capsicum="no, cap_enter not found" + ]) +fi + dnl ** check what we want to build AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes") AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes") @@ -713,6 +734,7 @@ echo echo "Building with 64bit DCC support .. : $offt_64bit" echo "Building with true color support.. : $want_truecolor" echo "Building with GRegex ............. : $want_gregex" +echo "Building with Capsicum ........... : $want_capsicum" echo echo "If there are any problems, read the INSTALL file." From 56c94570b420dea28b253af5f2c91184423acee1 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 25 Jul 2017 20:15:14 +0100 Subject: [PATCH 0143/1198] Implement /cap_enter. Signed-off-by: Edward Tomasz Napierala --- configure.ac | 3 ++- src/core/Makefile.am | 5 +++++ src/core/capsicum.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ src/core/capsicum.h | 7 +++++++ src/core/core.c | 3 +++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/core/capsicum.c create mode 100644 src/core/capsicum.h diff --git a/configure.ac b/configure.ac index f0c4cc5d..773f9eea 100644 --- a/configure.ac +++ b/configure.ac @@ -167,7 +167,7 @@ AC_ARG_ENABLE(gregex, want_gregex=yes) AC_ARG_WITH(capsicum, -[ --with-capsicum Build with Capsicum support], +[ --with-capsicum Build with Capsicum support], if test x$withval = xno; then want_capsicum=no else @@ -526,6 +526,7 @@ AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes") AM_CONDITIONAL(BUILD_IRSSIFUZZER, test "$want_irssifuzzer" = "yes") AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes") AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no") +AM_CONDITIONAL(HAVE_CAPSICUM, test "x$want_capsicum" = "xyes") AM_CONDITIONAL(USE_GREGEX, test "x$want_gregex" = "xyes") # move LIBS to PROG_LIBS so they're not tried to be used when linking eg. perl libraries diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 91daba3f..f3bc1674 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -56,6 +56,11 @@ libcore_a_SOURCES = \ tls.c \ write-buffer.c +if HAVE_CAPSICUM +libcore_a_SOURCES += \ + capsicum.c +endif + structure_headers = \ channel-rec.h \ channel-setup-rec.h \ diff --git a/src/core/capsicum.c b/src/core/capsicum.c new file mode 100644 index 00000000..702b895a --- /dev/null +++ b/src/core/capsicum.c @@ -0,0 +1,46 @@ +/* + capsicum.c : Capsicum sandboxing support + + Copyright (C) 2017 Edward Tomasz Napierala + + 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 "module.h" +#include "signals.h" +#include "commands.h" + +#include +#include + +static void cmd_cap_enter(void) +{ + int error; + + error = cap_enter(); + if (error != 0) + g_error("cap_enter(2) failed: %s", strerror(errno)); +} + +void capsicum_init(void) +{ + + command_bind("cap_enter", NULL, (SIGNAL_FUNC) cmd_cap_enter); +} + +void capsicum_deinit(void) +{ + command_unbind("cap_enter", (SIGNAL_FUNC) cmd_cap_enter); +} diff --git a/src/core/capsicum.h b/src/core/capsicum.h new file mode 100644 index 00000000..75c70080 --- /dev/null +++ b/src/core/capsicum.h @@ -0,0 +1,7 @@ +#ifndef __CAPSICUM_H +#define __CAPSICUM_H + +void capsicum_init(void); +void capsicum_deinit(void); + +#endif diff --git a/src/core/core.c b/src/core/core.c index bf7cdd6b..72631f91 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -29,6 +29,7 @@ #include "signals.h" #include "settings.h" #include "session.h" +#include "capsicum.h" #include "chat-protocols.h" #include "servers.h" @@ -235,6 +236,7 @@ void core_init(void) commands_init(); nickmatch_cache_init(); session_init(); + capsicum_init(); chat_protocols_init(); chatnets_init(); @@ -292,6 +294,7 @@ void core_deinit(void) chatnets_deinit(); chat_protocols_deinit(); + capsicum_deinit(); session_deinit(); nickmatch_cache_deinit(); commands_deinit(); From d5d45c29b8e00c304a6b6656983cafee84fe6bc8 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 26 Jul 2017 01:00:25 +0100 Subject: [PATCH 0144/1198] Add capability mode error/success messages. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 24 +++++++++++- src/fe-common/core/Makefile.am | 5 +++ src/fe-common/core/fe-capsicum.c | 60 +++++++++++++++++++++++++++++ src/fe-common/core/fe-capsicum.h | 7 ++++ src/fe-common/core/fe-common-core.c | 3 ++ src/fe-common/core/module-formats.c | 3 ++ src/fe-common/core/module-formats.h | 3 ++ 7 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 src/fe-common/core/fe-capsicum.c create mode 100644 src/fe-common/core/fe-capsicum.h diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 702b895a..eb30fef3 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -30,17 +30,37 @@ static void cmd_cap_enter(void) int error; error = cap_enter(); - if (error != 0) - g_error("cap_enter(2) failed: %s", strerror(errno)); + if (error != 0) { + signal_emit("capability mode failed", 1, strerror(errno)); + } else { + signal_emit("capability mode enabled", 0); + } +} + +static void cmd_cap_getmode(void) +{ + u_int mode; + int error; + + error = cap_getmode(&mode); + if (error != 0) { + signal_emit("capability mode failed", 1, strerror(errno)); + } else if (mode == 0) { + signal_emit("capability mode disabled", 0); + } else { + signal_emit("capability mode enabled", 0); + } } void capsicum_init(void) { command_bind("cap_enter", NULL, (SIGNAL_FUNC) cmd_cap_enter); + command_bind("cap_getmode", NULL, (SIGNAL_FUNC) cmd_cap_getmode); } void capsicum_deinit(void) { command_unbind("cap_enter", (SIGNAL_FUNC) cmd_cap_enter); + command_unbind("cap_getmode", (SIGNAL_FUNC) cmd_cap_getmode); } diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 6efff411..08e41520 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -38,6 +38,11 @@ libfe_common_core_a_SOURCES = \ windows-layout.c \ fe-windows.c +if HAVE_CAPSICUM +libfe_common_core_a_SOURCES += \ + fe-capsicum.c +endif + pkginc_fe_common_coredir=$(pkgincludedir)/src/fe-common/core pkginc_fe_common_core_HEADERS = \ command-history.h \ diff --git a/src/fe-common/core/fe-capsicum.c b/src/fe-common/core/fe-capsicum.c new file mode 100644 index 00000000..5816b223 --- /dev/null +++ b/src/fe-common/core/fe-capsicum.c @@ -0,0 +1,60 @@ +/* + fe-capsicum.c : irssi + + Copyright (C) 2017 Edward Tomasz Napierala + + 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 "module.h" +#include "module-formats.h" +#include "signals.h" +#include "printtext.h" + +#include "levels.h" +#include "servers.h" + +static void capability_mode_enabled(void) +{ + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CAPSICUM_ENABLED); +} + +static void capability_mode_disabled(void) +{ + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CAPSICUM_DISABLED); +} + +static void capability_mode_failed(gchar *msg) +{ + + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_CAPSICUM_FAILED, msg); +} + +void fe_capsicum_init(void) +{ + + signal_add("capability mode enabled", (SIGNAL_FUNC) capability_mode_enabled); + signal_add("capability mode disabled", (SIGNAL_FUNC) capability_mode_disabled); + signal_add("capability mode failed", (SIGNAL_FUNC) capability_mode_failed); +} + +void fe_capsicum_deinit(void) +{ + signal_remove("capability mode enabled", (SIGNAL_FUNC) capability_mode_enabled); + signal_remove("capability mode disabled", (SIGNAL_FUNC) capability_mode_disabled); + signal_remove("capability mode failed", (SIGNAL_FUNC) capability_mode_failed); +} diff --git a/src/fe-common/core/fe-capsicum.h b/src/fe-common/core/fe-capsicum.h new file mode 100644 index 00000000..a7cb743b --- /dev/null +++ b/src/fe-common/core/fe-capsicum.h @@ -0,0 +1,7 @@ +#ifndef __FE_CAPSICUM_H +#define __FE_CAPSICUM_H + +void fe_capsicum_init(void); +void fe_capsicum_deinit(void); + +#endif diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 512fc84c..a0388827 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -32,6 +32,7 @@ #include "special-vars.h" #include "fe-core-commands.h" #include "fe-queries.h" +#include "fe-capsicum.h" #include "hilight-text.h" #include "command-history.h" #include "completion.h" @@ -179,6 +180,7 @@ void fe_common_core_init(void) fe_server_init(); fe_settings_init(); fe_tls_init(); + fe_capsicum_init(); windows_init(); window_activity_init(); window_commands_init(); @@ -221,6 +223,7 @@ void fe_common_core_deinit(void) fe_server_deinit(); fe_settings_deinit(); fe_tls_deinit(); + fe_capsicum_deinit(); windows_deinit(); window_activity_deinit(); window_commands_deinit(); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index da9705be..eb0ddb61 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -290,6 +290,9 @@ FORMAT_REC fecommon_core_formats[] = { { "completion_header", "%#Key Value Auto", 0 }, { "completion_line", "%#$[10]0 $[!40]1 $2", 3, { 0, 0, 0 } }, { "completion_footer", "", 0 }, + { "capsicum_enabled", "Capability mode enabled", 0 }, + { "capsicum_disabled", "Capability mode not enabled", 0 }, + { "capsicum_failed", "Capability mode failed: $0", 1, { 0 } }, /* ---- */ { NULL, "TLS", 0 }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index a9ed28c5..4e2f72d9 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -255,6 +255,9 @@ enum { TXT_COMPLETION_HEADER, TXT_COMPLETION_LINE, TXT_COMPLETION_FOOTER, + TXT_CAPSICUM_ENABLED, + TXT_CAPSICUM_DISABLED, + TXT_CAPSICUM_FAILED, TLS_FILL_15, From 3200c381dbcb02e99c7667bd955c90ee859d15a0 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 26 Jul 2017 02:11:46 +0100 Subject: [PATCH 0145/1198] Rename to "/capability enter" and "/capability status". Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index eb30fef3..69a379e2 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -25,7 +25,12 @@ #include #include -static void cmd_cap_enter(void) +static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) +{ + command_runsub("capsicum", data, server, item); +} + +static void cmd_capsicum_enter(void) { int error; @@ -37,7 +42,7 @@ static void cmd_cap_enter(void) } } -static void cmd_cap_getmode(void) +static void cmd_capsicum_status(void) { u_int mode; int error; @@ -55,12 +60,14 @@ static void cmd_cap_getmode(void) void capsicum_init(void) { - command_bind("cap_enter", NULL, (SIGNAL_FUNC) cmd_cap_enter); - command_bind("cap_getmode", NULL, (SIGNAL_FUNC) cmd_cap_getmode); + command_bind("capsicum", NULL, (SIGNAL_FUNC) cmd_capsicum); + command_bind("capsicum enter", NULL, (SIGNAL_FUNC) cmd_capsicum_enter); + command_bind("capsicum status", NULL, (SIGNAL_FUNC) cmd_capsicum_status); } void capsicum_deinit(void) { - command_unbind("cap_enter", (SIGNAL_FUNC) cmd_cap_enter); - command_unbind("cap_getmode", (SIGNAL_FUNC) cmd_cap_getmode); + command_unbind("capsicum", (SIGNAL_FUNC) cmd_capsicum); + command_unbind("capsicum enter", (SIGNAL_FUNC) cmd_capsicum_enter); + command_unbind("capsicum status", (SIGNAL_FUNC) cmd_capsicum_status); } From cec68557aa436b4f16505d2095af02f83d154eda Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 27 Jul 2017 14:20:47 +0100 Subject: [PATCH 0146/1198] /connect works - although only with IP addresses. --- configure.ac | 7 ++- src/core/capsicum.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ src/core/capsicum.h | 3 ++ src/core/network.c | 33 ++++++++++-- src/core/network.h | 2 + 5 files changed, 165 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 773f9eea..9c026c5d 100644 --- a/configure.ac +++ b/configure.ac @@ -514,7 +514,12 @@ dnl ** if test "x$want_capsicum" = "xyes"; then AC_CHECK_LIB(c, cap_enter, [ - AC_DEFINE(HAVE_CAPSICUM,, Build with Capsicum support) + AC_CHECK_LIB(nv, nvlist_create, [ + AC_DEFINE(HAVE_CAPSICUM,, Build with Capsicum support) + LIBS="$LIBS -lnv" + ], [ + want_capsicum="no, nvlist_create not found" + ]) ], [ want_capsicum="no, cap_enter not found" ]) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 69a379e2..19ca858e 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -19,21 +19,147 @@ */ #include "module.h" +#include "network.h" #include "signals.h" #include "commands.h" +#include #include +#include +#include +#include #include +static int symbiontfds[2]; + +gboolean capsicum_enabled(void) +{ + u_int mode; + int error; + + error = cap_getmode(&mode); + if (error != 0) + return FALSE; + + if (mode == 0) + return FALSE; + + return TRUE; +} + +int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) +{ + nvlist_t *nvl; + int error, saved_errno, sock; + + /* Send request to the symbiont. */ + nvl = nvlist_create(0); + nvlist_add_binary(nvl, "ip", ip, sizeof(*ip)); + nvlist_add_number(nvl, "port", port); + if (my_ip != NULL) { + /* nvlist_add_binary(3) can't handle NULL values. */ + nvlist_add_binary(nvl, "my_ip", my_ip, sizeof(*my_ip)); + } + error = nvlist_send(symbiontfds[1], nvl); + nvlist_destroy(nvl); + if (error != 0) { + g_warning("nvlist_send: %s", strerror(errno)); + return -1; + } + + /* Receive response. */ + nvl = nvlist_recv(symbiontfds[1], 0); + if (nvl == NULL) { + g_warning("nvlist_recv: %s", strerror(errno)); + return -1; + } + if (nvlist_exists_descriptor(nvl, "sock")) { + sock = nvlist_take_descriptor(nvl, "sock"); + } else { + sock = -1; + } + saved_errno = nvlist_get_number(nvl, "errno"); + nvlist_destroy(nvl); + errno = saved_errno; + + return sock; +} + static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) { command_runsub("capsicum", data, server, item); } +static int start_symbiont(void) +{ + pid_t pid; + nvlist_t *nvl; + IPADDR *ip, *my_ip; + int childfd, error, port, saved_errno, sock; + + error = socketpair(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, symbiontfds); + if (error != 0) { + g_warning("socketpair: %s", strerror(errno)); + return 1; + } + + pid = pdfork(&childfd, PD_CLOEXEC); + if (pid < 0) { + g_warning("pdfork: %s", strerror(errno)); + return 1; + } + + if (pid > 0) { + close(symbiontfds[0]); + return 0; + } + + /* We're the child, running outside the Capsicum sandbox. */ + setproctitle("capsicum symbiont"); + close(symbiontfds[1]); + close(0); + close(1); + close(2); + for (;;) { + /* Receive parameters from the main irssi process. */ + nvl = nvlist_recv(symbiontfds[0], 0); + if (nvl == NULL) + exit(1); + ip = nvlist_get_binary(nvl, "ip", NULL); + port = (int)nvlist_get_number(nvl, "port"); + if (nvlist_exists(nvl, "my_ip")) + my_ip = nvlist_get_binary(nvl, "my_ip", NULL); + else + my_ip = NULL; + + /* Connect. */ + sock = net_connect_ip_handle(ip, port, my_ip); + saved_errno = errno; + + /* Send back the socket fd. */ + nvlist_destroy(nvl); + nvl = nvlist_create(0); + + if (sock != -1) + nvlist_move_descriptor(nvl, "sock", sock); + nvlist_add_number(nvl, "errno", saved_errno); + error = nvlist_send(symbiontfds[0], nvl); + if (error != 0) + exit(1); + nvlist_destroy(nvl); + } +} + static void cmd_capsicum_enter(void) { int error; + error = start_symbiont(); + if (error != 0) { + signal_emit("capability mode failed", 1, strerror(errno)); + return; + } + error = cap_enter(); if (error != 0) { signal_emit("capability mode failed", 1, strerror(errno)); diff --git a/src/core/capsicum.h b/src/core/capsicum.h index 75c70080..f8cec28e 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -1,6 +1,9 @@ #ifndef __CAPSICUM_H #define __CAPSICUM_H +gboolean capsicum_enabled(void); +int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); + void capsicum_init(void); void capsicum_deinit(void); diff --git a/src/core/network.c b/src/core/network.c index 3e1b7c70..b182d19f 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -20,6 +20,9 @@ #include "module.h" #include "network.h" +#ifdef HAVE_CAPSICUM +#include "capsicum.h" +#endif #include @@ -144,8 +147,7 @@ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) return net_connect_ip(ip, port, my_ip); } -/* Connect to socket with ip address */ -GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) +int net_connect_ip_handle(IPADDR *ip, int port, IPADDR *my_ip) { union sockaddr_union so; int handle, ret, opt = 1; @@ -161,7 +163,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) handle = socket(ip->family, SOCK_STREAM, 0); if (handle == -1) - return NULL; + return -1; /* set socket options */ fcntl(handle, F_SETFL, O_NONBLOCK); @@ -176,7 +178,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) close(handle); errno = old_errno; - return NULL; + return -1; } } @@ -190,9 +192,30 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) int old_errno = errno; close(handle); errno = old_errno; - return NULL; + return -1; } + return handle; +} + + +/* Connect to socket with ip address */ +GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) +{ + int handle = -1; + +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + handle = capsicum_net_connect_ip(ip, port, my_ip); + else + handle = net_connect_ip_handle(ip, port, my_ip); +#else + handle = net_connect_ip_handle(ip, port, my_ip); +#endif + + if (handle == -1) + return (NULL); + return g_io_channel_new(handle); } diff --git a/src/core/network.h b/src/core/network.h index 8757f78c..5ccacc0d 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -36,6 +36,8 @@ GIOChannel *g_io_channel_new(int handle); /* returns 1 if IPADDRs are the same */ int net_ip_compare(IPADDR *ip1, IPADDR *ip2); +int net_connect_ip_handle(IPADDR *ip, int port, IPADDR *my_ip); + /* Connect to socket */ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) G_GNUC_DEPRECATED; /* Connect to socket with ip address and SSL*/ From 925240155e5c0c20569bcb5fafe4d3047055768a Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 27 Jul 2017 14:56:35 +0100 Subject: [PATCH 0147/1198] Config file support for "capsicum" parameter. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 19ca858e..7674ca4d 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -19,9 +19,10 @@ */ #include "module.h" -#include "network.h" -#include "signals.h" #include "commands.h" +#include "network.h" +#include "settings.h" +#include "signals.h" #include #include @@ -183,8 +184,17 @@ static void cmd_capsicum_status(void) } } +void sig_init_finished(void) +{ + if (settings_get_bool("capsicum")) + cmd_capsicum_enter(); +} + void capsicum_init(void) { + settings_add_bool("misc", "capsicum", FALSE); + + signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); command_bind("capsicum", NULL, (SIGNAL_FUNC) cmd_capsicum); command_bind("capsicum enter", NULL, (SIGNAL_FUNC) cmd_capsicum_enter); @@ -193,6 +203,8 @@ void capsicum_init(void) void capsicum_deinit(void) { + signal_remove("irssi init finished", (SIGNAL_FUNC) sig_init_finished); + command_unbind("capsicum", (SIGNAL_FUNC) cmd_capsicum); command_unbind("capsicum enter", (SIGNAL_FUNC) cmd_capsicum_enter); command_unbind("capsicum status", (SIGNAL_FUNC) cmd_capsicum_status); From f4546be7ecb8a0801fb0d30415586c15d721494a Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 27 Jul 2017 15:35:14 +0100 Subject: [PATCH 0148/1198] Reorder functions. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 7674ca4d..a0375077 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -86,11 +86,6 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) return sock; } -static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) -{ - command_runsub("capsicum", data, server, item); -} - static int start_symbiont(void) { pid_t pid; @@ -151,6 +146,11 @@ static int start_symbiont(void) } } +static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) +{ + command_runsub("capsicum", data, server, item); +} + static void cmd_capsicum_enter(void) { int error; From 509eca76f0755e94b5981f464f9f9a882499180a Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 02:21:40 +0100 Subject: [PATCH 0149/1198] Make DNS work in capability mode. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 173 ++++++++++++++++++++++++++++++++++---------- src/core/capsicum.h | 1 + src/core/network.c | 5 ++ 3 files changed, 142 insertions(+), 37 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index a0375077..99f7ff0f 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -31,6 +31,9 @@ #include #include +#define OPCODE_CONNECT 1 +#define OPCODE_GETHOSTBYNAME 2 + static int symbiontfds[2]; gboolean capsicum_enabled(void) @@ -55,6 +58,7 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) /* Send request to the symbiont. */ nvl = nvlist_create(0); + nvlist_add_number(nvl, "opcode", OPCODE_CONNECT); nvlist_add_binary(nvl, "ip", ip, sizeof(*ip)); nvlist_add_number(nvl, "port", port); if (my_ip != NULL) { @@ -86,12 +90,139 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) return sock; } +int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) +{ + nvlist_t *nvl; + IPADDR *received_ip4, *received_ip6; + int error, ret, saved_errno; + + /* Send request to the symbiont. */ + nvl = nvlist_create(0); + nvlist_add_number(nvl, "opcode", OPCODE_GETHOSTBYNAME); + nvlist_add_string(nvl, "addr", addr); + error = nvlist_send(symbiontfds[1], nvl); + nvlist_destroy(nvl); + if (error != 0) { + g_warning("nvlist_send: %s", strerror(errno)); + return -1; + } + + /* Receive response. */ + nvl = nvlist_recv(symbiontfds[1], 0); + if (nvl == NULL) { + g_warning("nvlist_recv: %s", strerror(errno)); + return -1; + } + + received_ip4 = nvlist_get_binary(nvl, "ip4", NULL); + received_ip6 = nvlist_get_binary(nvl, "ip6", NULL); + memcpy(ip4, received_ip4, sizeof(*ip4)); + memcpy(ip6, received_ip6, sizeof(*ip6)); + + ret = nvlist_get_number(nvl, "ret"); + saved_errno = nvlist_get_number(nvl, "errno"); + nvlist_destroy(nvl); + errno = saved_errno; + + return ret; +} + +nvlist_t *symbiont_connect(const nvlist_t *request) +{ + nvlist_t *response; + IPADDR *ip, *my_ip; + int port, saved_errno, sock; + + ip = nvlist_get_binary(request, "ip", NULL); + port = (int)nvlist_get_number(request, "port"); + if (nvlist_exists(request, "my_ip")) + my_ip = nvlist_get_binary(request, "my_ip", NULL); + else + my_ip = NULL; + + /* Connect. */ + sock = net_connect_ip_handle(ip, port, my_ip); + saved_errno = errno; + + /* Send back the socket fd. */ + response = nvlist_create(0); + + if (sock != -1) + nvlist_move_descriptor(response, "sock", sock); + nvlist_add_number(response, "errno", saved_errno); + + return (response); +} + +nvlist_t *symbiont_gethostbyname(const nvlist_t *request) +{ + nvlist_t *response; + IPADDR ip4, ip6; + const char *addr; + int ret, saved_errno; + + addr = nvlist_get_string(request, "addr"); + + /* Connect. */ + ret = net_gethostbyname(addr, &ip4, &ip6); + saved_errno = errno; + + /* Send back the IPs. */ + response = nvlist_create(0); + + nvlist_add_number(response, "ret", ret); + nvlist_add_number(response, "errno", saved_errno); + nvlist_add_binary(response, "ip4", &ip4, sizeof(ip4)); + nvlist_add_binary(response, "ip6", &ip6, sizeof(ip6)); + + return (response); +} + +/* + * Child process, running outside the Capsicum sandbox. + */ +_Noreturn static void symbiont(void) +{ + nvlist_t *request, *response; + int error, opcode; + + setproctitle("capsicum symbiont"); + close(symbiontfds[1]); + close(0); + close(1); + close(2); + + for (;;) { + /* Receive parameters from the main irssi process. */ + request = nvlist_recv(symbiontfds[0], 0); + if (request == NULL) + exit(1); + + opcode = nvlist_get_number(request, "opcode"); + switch (opcode) { + case OPCODE_CONNECT: + response = symbiont_connect(request); + break; + case OPCODE_GETHOSTBYNAME: + response = symbiont_gethostbyname(request); + break; + default: + exit(1); + } + + /* Send back the response. */ + error = nvlist_send(symbiontfds[0], response); + if (error != 0) + exit(1); + nvlist_destroy(request); + nvlist_destroy(response); + } +} + static int start_symbiont(void) { + int childfd, error; pid_t pid; - nvlist_t *nvl; - IPADDR *ip, *my_ip; - int childfd, error, port, saved_errno, sock; error = socketpair(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, symbiontfds); if (error != 0) { @@ -110,40 +241,8 @@ static int start_symbiont(void) return 0; } - /* We're the child, running outside the Capsicum sandbox. */ - setproctitle("capsicum symbiont"); - close(symbiontfds[1]); - close(0); - close(1); - close(2); - for (;;) { - /* Receive parameters from the main irssi process. */ - nvl = nvlist_recv(symbiontfds[0], 0); - if (nvl == NULL) - exit(1); - ip = nvlist_get_binary(nvl, "ip", NULL); - port = (int)nvlist_get_number(nvl, "port"); - if (nvlist_exists(nvl, "my_ip")) - my_ip = nvlist_get_binary(nvl, "my_ip", NULL); - else - my_ip = NULL; - - /* Connect. */ - sock = net_connect_ip_handle(ip, port, my_ip); - saved_errno = errno; - - /* Send back the socket fd. */ - nvlist_destroy(nvl); - nvl = nvlist_create(0); - - if (sock != -1) - nvlist_move_descriptor(nvl, "sock", sock); - nvlist_add_number(nvl, "errno", saved_errno); - error = nvlist_send(symbiontfds[0], nvl); - if (error != 0) - exit(1); - nvlist_destroy(nvl); - } + symbiont(); + /* NOTREACHED */ } static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) diff --git a/src/core/capsicum.h b/src/core/capsicum.h index f8cec28e..2733c1ea 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -3,6 +3,7 @@ gboolean capsicum_enabled(void); int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); +int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); void capsicum_init(void); void capsicum_deinit(void); diff --git a/src/core/network.c b/src/core/network.c index b182d19f..2954af54 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -406,6 +406,11 @@ int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) struct addrinfo hints, *ai, *ailist; int ret, count_v4, count_v6, use_v4, use_v6; +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + return (capsicum_net_gethostbyname(addr, ip4, ip6)); +#endif + g_return_val_if_fail(addr != NULL, -1); memset(ip4, 0, sizeof(IPADDR)); From 1f57ceec4c4e7c3d42f341921e36fe4aab612e57 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 18:10:45 +0100 Subject: [PATCH 0150/1198] Prevent the user from calling "/capsicum enter" twice. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 99f7ff0f..f44b326d 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -252,8 +252,15 @@ static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) static void cmd_capsicum_enter(void) { + u_int mode; int error; + error = cap_getmode(&mode); + if (error == 0 && mode != 0) { + g_warning("Already in capability mode"); + return; + } + error = start_symbiont(); if (error != 0) { signal_emit("capability mode failed", 1, strerror(errno)); From 939371aa1dfdbf11fe98648e1eafc4c95e80bb9e Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 18:44:18 +0100 Subject: [PATCH 0151/1198] Fix warnings. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 4 ++-- src/core/network.c | 2 +- src/core/network.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index f44b326d..5a59adcd 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -93,7 +93,7 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) { nvlist_t *nvl; - IPADDR *received_ip4, *received_ip6; + const IPADDR *received_ip4, *received_ip6; int error, ret, saved_errno; /* Send request to the symbiont. */ @@ -130,7 +130,7 @@ int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) nvlist_t *symbiont_connect(const nvlist_t *request) { nvlist_t *response; - IPADDR *ip, *my_ip; + const IPADDR *ip, *my_ip; int port, saved_errno, sock; ip = nvlist_get_binary(request, "ip", NULL); diff --git a/src/core/network.c b/src/core/network.c index 2954af54..01e56eb5 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -147,7 +147,7 @@ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) return net_connect_ip(ip, port, my_ip); } -int net_connect_ip_handle(IPADDR *ip, int port, IPADDR *my_ip) +int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip) { union sockaddr_union so; int handle, ret, opt = 1; diff --git a/src/core/network.h b/src/core/network.h index 5ccacc0d..d1582a2e 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -36,7 +36,7 @@ GIOChannel *g_io_channel_new(int handle); /* returns 1 if IPADDRs are the same */ int net_ip_compare(IPADDR *ip1, IPADDR *ip2); -int net_connect_ip_handle(IPADDR *ip, int port, IPADDR *my_ip); +int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); /* Connect to socket */ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) G_GNUC_DEPRECATED; From 241dd66ac11d54b37c671cd56f1320fe5b83803d Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 28 Jul 2017 05:08:34 +0100 Subject: [PATCH 0152/1198] Working /log and /rawlog. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 33 +++++++++++++++++++++++++++++++++ src/core/capsicum.h | 1 + src/core/log.c | 15 ++++++++++++++- src/core/log.h | 2 ++ src/core/network.c | 1 - src/core/rawlog.c | 17 +++++++++++++++-- 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 5a59adcd..6667276c 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -20,6 +20,8 @@ #include "module.h" #include "commands.h" +#include "log.h" +#include "misc.h" #include "network.h" #include "settings.h" #include "signals.h" @@ -34,6 +36,9 @@ #define OPCODE_CONNECT 1 #define OPCODE_GETHOSTBYNAME 2 +static char *irclogs_path; +static size_t irclogs_path_len; +static int irclogs_fd; static int symbiontfds[2]; gboolean capsicum_enabled(void) @@ -127,6 +132,23 @@ int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) return ret; } +int capsicum_open(const char *path, int flags, int mode) +{ + int fd; + + /* +1 is for slash separating irclogs_path and the rest. */ + if (strlen(path) > irclogs_path_len + 1 && strncmp(path, irclogs_path, irclogs_path_len) == 0) { + fd = openat(irclogs_fd, path + irclogs_path_len + 1, flags, mode); + } else { + fd = open(path, flags, mode); + } + + if (fd < 0 && (errno == ENOTCAPABLE || errno == ECAPMODE)) + g_warning("File system access restricted to %s due to capability mode", irclogs_path); + + return (fd); +} + nvlist_t *symbiont_connect(const nvlist_t *request) { nvlist_t *response; @@ -261,6 +283,16 @@ static void cmd_capsicum_enter(void) return; } + irclogs_path = convert_home(settings_get_str("capsicum_irclogs_path")); + g_mkdir_with_parents(irclogs_path, log_dir_create_mode); + irclogs_path_len = strlen(irclogs_path); + irclogs_fd = open(irclogs_path, O_DIRECTORY | O_CLOEXEC); + if (irclogs_fd < 0) { + g_warning("Unable to open %s: %s", irclogs_path, strerror(errno)); + signal_emit("capability mode failed", 1, strerror(errno)); + return; + } + error = start_symbiont(); if (error != 0) { signal_emit("capability mode failed", 1, strerror(errno)); @@ -299,6 +331,7 @@ void sig_init_finished(void) void capsicum_init(void) { settings_add_bool("misc", "capsicum", FALSE); + settings_add_str("misc", "capsicum_irclogs_path", "~/irclogs"); signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); diff --git a/src/core/capsicum.h b/src/core/capsicum.h index 2733c1ea..ca35fd05 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -4,6 +4,7 @@ gboolean capsicum_enabled(void); int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); +int capsicum_open(const char *path, int flags, int mode); void capsicum_init(void); void capsicum_deinit(void); diff --git a/src/core/log.c b/src/core/log.c index cee1dab5..00686bee 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -26,6 +26,9 @@ #include "servers.h" #include "log.h" #include "write-buffer.h" +#ifdef HAVE_CAPSICUM +#include "capsicum.h" +#endif #include "lib-config/iconfig.h" #include "settings.h" @@ -73,6 +76,16 @@ static void log_write_timestamp(int handle, const char *format, if (text != NULL) write_buffer(handle, text, strlen(text)); } +static int log_open_wrapper(const char *path, int flags, int mode) +{ +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + return capsicum_open(path, flags, mode); +#endif + + return open(path, flags, mode); +} + static char *log_filename(LOG_REC *log) { char *str, fname[1024]; @@ -119,7 +132,7 @@ int log_start_logging(LOG_REC *log) } log->handle = log->real_fname == NULL ? -1 : - open(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, + log_open_wrapper(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); if (log->handle == -1) { signal_emit("log create failed", 1, log); diff --git a/src/core/log.h b/src/core/log.h index 5a07859b..52660bb9 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -38,6 +38,8 @@ extern GSList *logs; extern int log_file_create_mode; extern int log_dir_create_mode; +extern int log_dir_create_mode; + /* Create log record - you still need to call log_update() to actually add it into log list */ LOG_REC *log_create_rec(const char *fname, int level); diff --git a/src/core/network.c b/src/core/network.c index 01e56eb5..4494dbc6 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -198,7 +198,6 @@ int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip) return handle; } - /* Connect to socket with ip address */ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) { diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 2ec155fa..5df02981 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -27,12 +27,25 @@ #include "misc.h" #include "write-buffer.h" #include "settings.h" +#ifdef HAVE_CAPSICUM +#include "capsicum.h" +#endif #include "servers.h" static int rawlog_lines; static int signal_rawlog; +static int rawlog_open_wrapper(const char *path, int flags, int mode) +{ +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + return capsicum_open(path, flags, mode); +#endif + + return open(path, flags, mode); +} + RAWLOG_REC *rawlog_create(void) { RAWLOG_REC *rec; @@ -126,7 +139,7 @@ void rawlog_open(RAWLOG_REC *rawlog, const char *fname) return; path = convert_home(fname); - rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT, + rawlog->handle = rawlog_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); g_free(path); @@ -158,7 +171,7 @@ void rawlog_save(RAWLOG_REC *rawlog, const char *fname) g_free(dir); path = convert_home(fname); - f = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); + f = rawlog_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); g_free(path); if (f < 0) { From e777ae986d64863a444132885b160ab2e9c7458e Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 10:32:24 +0100 Subject: [PATCH 0153/1198] Working autolog. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 51 ++++++++++++++++++++++++++++++++++--- src/core/capsicum.h | 1 + src/core/log.c | 7 +++++ src/core/rawlog.c | 9 ++++++- src/fe-common/core/fe-log.c | 10 ++++++++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 6667276c..c554fcf7 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -136,19 +136,62 @@ int capsicum_open(const char *path, int flags, int mode) { int fd; - /* +1 is for slash separating irclogs_path and the rest. */ - if (strlen(path) > irclogs_path_len + 1 && strncmp(path, irclogs_path, irclogs_path_len) == 0) { - fd = openat(irclogs_fd, path + irclogs_path_len + 1, flags, mode); + /* +1 is for the slash separating irclogs_path and the rest. */ + if (strlen(path) > irclogs_path_len + 1 && + strncmp(path, irclogs_path, irclogs_path_len) == 0) { + fd = openat(irclogs_fd, path + irclogs_path_len + 1, + flags, mode); } else { fd = open(path, flags, mode); } if (fd < 0 && (errno == ENOTCAPABLE || errno == ECAPMODE)) - g_warning("File system access restricted to %s due to capability mode", irclogs_path); + g_warning("File system access restricted to %s " + "due to capability mode", irclogs_path); return (fd); } +void capsicum_mkdir_with_parents(const char *path, int mode) +{ + char *component, *copy, *tofree; + int error, fd, newfd; + + /* +1 is for the slash separating irclogs_path and the rest. */ + if (strlen(path) <= irclogs_path_len + 1 || + strncmp(path, irclogs_path, irclogs_path_len) != 0) { + g_warning("Cannot create %s: file system access restricted " + "to %s due to capability mode", path, irclogs_path); + return; + } + + copy = tofree = g_strdup(path + irclogs_path_len + 1); + fd = irclogs_fd; + for (;;) { + component = strsep(©, "/"); + if (component == NULL) + break; + error = mkdirat(fd, component, mode); + if (error != 0 && errno != EEXIST) { + g_warning("cannot create %s: %s", + component, strerror(errno)); + break; + } + newfd = openat(fd, component, O_DIRECTORY); + if (newfd < 0) { + g_warning("cannot open %s: %s", + component, strerror(errno)); + break; + } + if (fd != irclogs_fd) + close(fd); + fd = newfd; + } + g_free(tofree); + if (fd != irclogs_fd) + close(fd); +} + nvlist_t *symbiont_connect(const nvlist_t *request) { nvlist_t *response; diff --git a/src/core/capsicum.h b/src/core/capsicum.h index ca35fd05..1eb56402 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -5,6 +5,7 @@ gboolean capsicum_enabled(void); int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); int capsicum_open(const char *path, int flags, int mode); +void capsicum_mkdir_with_parents(const char *path, int mode); void capsicum_init(void); void capsicum_deinit(void); diff --git a/src/core/log.c b/src/core/log.c index 00686bee..9394263f 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -127,7 +127,14 @@ int log_start_logging(LOG_REC *log) /* path may contain variables (%time, $vars), make sure the directory is created */ dir = g_path_get_dirname(log->real_fname); +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + capsicum_mkdir_with_parents(dir, log_dir_create_mode); + else + g_mkdir_with_parents(dir, log_dir_create_mode); +#else g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); } diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 5df02981..dd86af7c 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -167,7 +167,14 @@ void rawlog_save(RAWLOG_REC *rawlog, const char *fname) int f; dir = g_path_get_dirname(fname); - g_mkdir_with_parents(dir, log_dir_create_mode); +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + capsicum_mkdir_with_parents(dir, log_dir_create_mode); + else + g_mkdir_with_parents(dir, log_dir_create_mode); +#else + g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); path = convert_home(fname); diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 37b29990..deb70991 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -30,6 +30,9 @@ #include "special-vars.h" #include "settings.h" #include "lib-config/iconfig.h" +#ifdef HAVE_CAPSICUM +#include "capsicum.h" +#endif #include "fe-windows.h" #include "window-items.h" @@ -451,7 +454,14 @@ static void autolog_open(SERVER_REC *server, const char *server_tag, log_item_add(log, LOG_ITEM_TARGET, target, server_tag); dir = g_path_get_dirname(log->real_fname); +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + capsicum_mkdir_with_parents(dir, log_dir_create_mode); + else + g_mkdir_with_parents(dir, log_dir_create_mode); +#else g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); log->temp = TRUE; From c00d4753aee732b5a815f12dda3c9fced41ef1f5 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 11:41:56 +0100 Subject: [PATCH 0154/1198] Restrict port range available in capability mode. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index c554fcf7..e87704dd 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -40,6 +40,8 @@ static char *irclogs_path; static size_t irclogs_path_len; static int irclogs_fd; static int symbiontfds[2]; +static int port_min; +static int port_max; gboolean capsicum_enabled(void) { @@ -90,6 +92,13 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) } saved_errno = nvlist_get_number(nvl, "errno"); nvlist_destroy(nvl); + + if (sock == -1 && (port < port_min || port > port_max)) { + g_warning("Access restricted to ports between %d and %d " + "due to capability mode", + port_min, port_max); + } + errno = saved_errno; return sock; @@ -205,9 +214,19 @@ nvlist_t *symbiont_connect(const nvlist_t *request) else my_ip = NULL; - /* Connect. */ - sock = net_connect_ip_handle(ip, port, my_ip); - saved_errno = errno; + /* + * Check if the port is in allowed range. This is to minimize + * the chance of the attacker rooting another system in case of + * compromise. + */ + if (port < port_min || port > port_max) { + sock = -1; + saved_errno = EPERM; + } else { + /* Connect. */ + sock = net_connect_ip_handle(ip, port, my_ip); + saved_errno = errno; + } /* Send back the socket fd. */ response = nvlist_create(0); @@ -326,6 +345,9 @@ static void cmd_capsicum_enter(void) return; } + port_min = settings_get_int("capsicum_port_min"); + port_max = settings_get_int("capsicum_port_max"); + irclogs_path = convert_home(settings_get_str("capsicum_irclogs_path")); g_mkdir_with_parents(irclogs_path, log_dir_create_mode); irclogs_path_len = strlen(irclogs_path); @@ -375,6 +397,8 @@ void capsicum_init(void) { settings_add_bool("misc", "capsicum", FALSE); settings_add_str("misc", "capsicum_irclogs_path", "~/irclogs"); + settings_add_int("misc", "capsicum_port_min", 6667); + settings_add_int("misc", "capsicum_port_max", 6697); signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); From 12e2c46d6a778f131c1ca6a7134af1cd5e722dbe Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 12:28:49 +0100 Subject: [PATCH 0155/1198] Add wrappers to reduce #ifdefs. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 17 +++++++++++++++++ src/core/capsicum.h | 12 +++++++++++- src/core/log.c | 23 ++--------------------- src/core/rawlog.c | 29 ++++++----------------------- src/fe-common/core/fe-log.c | 11 +---------- 5 files changed, 37 insertions(+), 55 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index e87704dd..99a4e795 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -161,6 +161,14 @@ int capsicum_open(const char *path, int flags, int mode) return (fd); } +int capsicum_open_wrapper(const char *path, int flags, int mode) +{ + if (capsicum_enabled()) { + return capsicum_open(path, flags, mode); + } + return open(path, flags, mode); +} + void capsicum_mkdir_with_parents(const char *path, int mode) { char *component, *copy, *tofree; @@ -201,6 +209,15 @@ void capsicum_mkdir_with_parents(const char *path, int mode) close(fd); } +void capsicum_mkdir_with_parents_wrapper(const char *path, int mode) +{ + if (capsicum_enabled()) { + capsicum_mkdir_with_parents(path, mode); + return; + } + g_mkdir_with_parents(path, mode); +} + nvlist_t *symbiont_connect(const nvlist_t *request) { nvlist_t *response; diff --git a/src/core/capsicum.h b/src/core/capsicum.h index 1eb56402..3c1234e1 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -7,7 +7,17 @@ int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); int capsicum_open(const char *path, int flags, int mode); void capsicum_mkdir_with_parents(const char *path, int mode); +#ifdef HAVE_CAPSICUM +int capsicum_open_wrapper(const char *path, int flags, int mode); +void capsicum_mkdir_with_parents_wrapper(const char *path, int mode); +#else +#define capsicum_open_wrapper(P, F, M) \ + open(P, F, M) +#define capsicum_mkdir_with_parents_wrapper(P, M) \ + g_mkdir_with_parents(P, M) +#endif + void capsicum_init(void); void capsicum_deinit(void); -#endif +#endif /* !__CAPSICUM_H */ diff --git a/src/core/log.c b/src/core/log.c index 9394263f..ea2f1a1d 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -26,9 +26,7 @@ #include "servers.h" #include "log.h" #include "write-buffer.h" -#ifdef HAVE_CAPSICUM #include "capsicum.h" -#endif #include "lib-config/iconfig.h" #include "settings.h" @@ -76,16 +74,6 @@ static void log_write_timestamp(int handle, const char *format, if (text != NULL) write_buffer(handle, text, strlen(text)); } -static int log_open_wrapper(const char *path, int flags, int mode) -{ -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - return capsicum_open(path, flags, mode); -#endif - - return open(path, flags, mode); -} - static char *log_filename(LOG_REC *log) { char *str, fname[1024]; @@ -127,19 +115,12 @@ int log_start_logging(LOG_REC *log) /* path may contain variables (%time, $vars), make sure the directory is created */ dir = g_path_get_dirname(log->real_fname); -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - capsicum_mkdir_with_parents(dir, log_dir_create_mode); - else - g_mkdir_with_parents(dir, log_dir_create_mode); -#else - g_mkdir_with_parents(dir, log_dir_create_mode); -#endif + capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); g_free(dir); } log->handle = log->real_fname == NULL ? -1 : - log_open_wrapper(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, + capsicum_open_wrapper(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); if (log->handle == -1) { signal_emit("log create failed", 1, log); diff --git a/src/core/rawlog.c b/src/core/rawlog.c index dd86af7c..8f674e6b 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -27,25 +27,13 @@ #include "misc.h" #include "write-buffer.h" #include "settings.h" -#ifdef HAVE_CAPSICUM #include "capsicum.h" -#endif #include "servers.h" static int rawlog_lines; static int signal_rawlog; -static int rawlog_open_wrapper(const char *path, int flags, int mode) -{ -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - return capsicum_open(path, flags, mode); -#endif - - return open(path, flags, mode); -} - RAWLOG_REC *rawlog_create(void) { RAWLOG_REC *rec; @@ -139,8 +127,9 @@ void rawlog_open(RAWLOG_REC *rawlog, const char *fname) return; path = convert_home(fname); - rawlog->handle = rawlog_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, - log_file_create_mode); + rawlog->handle = capsicum_open_wrapper(path, + O_WRONLY | O_APPEND | O_CREAT, + log_file_create_mode); g_free(path); if (rawlog->handle == -1) { @@ -167,18 +156,12 @@ void rawlog_save(RAWLOG_REC *rawlog, const char *fname) int f; dir = g_path_get_dirname(fname); -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - capsicum_mkdir_with_parents(dir, log_dir_create_mode); - else - g_mkdir_with_parents(dir, log_dir_create_mode); -#else - g_mkdir_with_parents(dir, log_dir_create_mode); -#endif + capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); g_free(dir); path = convert_home(fname); - f = rawlog_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); + f = capsicum_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, + log_file_create_mode); g_free(path); if (f < 0) { diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index deb70991..3d8910c9 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -30,9 +30,7 @@ #include "special-vars.h" #include "settings.h" #include "lib-config/iconfig.h" -#ifdef HAVE_CAPSICUM #include "capsicum.h" -#endif #include "fe-windows.h" #include "window-items.h" @@ -454,14 +452,7 @@ static void autolog_open(SERVER_REC *server, const char *server_tag, log_item_add(log, LOG_ITEM_TARGET, target, server_tag); dir = g_path_get_dirname(log->real_fname); -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - capsicum_mkdir_with_parents(dir, log_dir_create_mode); - else - g_mkdir_with_parents(dir, log_dir_create_mode); -#else - g_mkdir_with_parents(dir, log_dir_create_mode); -#endif + capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); g_free(dir); log->temp = TRUE; From 8c04c2be14fc053bd7b5ff03b8e4ba8cb5023700 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 12:30:27 +0100 Subject: [PATCH 0156/1198] Fix build without Capsicum. Signed-off-by: Edward Tomasz Napierala --- src/core/core.c | 4 ++++ src/fe-common/core/fe-common-core.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/core/core.c b/src/core/core.c index 72631f91..c95879de 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -236,7 +236,9 @@ void core_init(void) commands_init(); nickmatch_cache_init(); session_init(); +#ifdef HAVE_CAPSICUM capsicum_init(); +#endif chat_protocols_init(); chatnets_init(); @@ -294,7 +296,9 @@ void core_deinit(void) chatnets_deinit(); chat_protocols_deinit(); +#ifdef HAVE_CAPSICUM capsicum_deinit(); +#endif session_deinit(); nickmatch_cache_deinit(); commands_deinit(); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index a0388827..67c9e20c 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -180,7 +180,9 @@ void fe_common_core_init(void) fe_server_init(); fe_settings_init(); fe_tls_init(); +#ifdef HAVE_CAPSICUM fe_capsicum_init(); +#endif windows_init(); window_activity_init(); window_commands_init(); @@ -223,7 +225,9 @@ void fe_common_core_deinit(void) fe_server_deinit(); fe_settings_deinit(); fe_tls_deinit(); +#ifdef HAVE_CAPSICUM fe_capsicum_deinit(); +#endif windows_deinit(); window_activity_deinit(); window_commands_deinit(); From 7f2697d30744d1f33cf67430aa48013b8f4ae9cd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 12:38:06 +0100 Subject: [PATCH 0157/1198] Cosmetics. Signed-off-by: Edward Tomasz Napierala --- src/core/log.h | 2 -- src/core/rawlog.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/log.h b/src/core/log.h index 52660bb9..5a07859b 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -38,8 +38,6 @@ extern GSList *logs; extern int log_file_create_mode; extern int log_dir_create_mode; -extern int log_dir_create_mode; - /* Create log record - you still need to call log_update() to actually add it into log list */ LOG_REC *log_create_rec(const char *fname, int level); diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 8f674e6b..a95b9a92 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -156,7 +156,7 @@ void rawlog_save(RAWLOG_REC *rawlog, const char *fname) int f; dir = g_path_get_dirname(fname); - capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); + capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); g_free(dir); path = convert_home(fname); From a29eeaa9f2e85630b08fc46b3a2b8749b9719efd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Jul 2017 20:04:28 +0100 Subject: [PATCH 0158/1198] Fix trailing slash handling for capsicum_irclogs_path. This is mostly an anti-footshooting measure, but still. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 99a4e795..01f5f95c 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -147,6 +147,7 @@ int capsicum_open(const char *path, int flags, int mode) /* +1 is for the slash separating irclogs_path and the rest. */ if (strlen(path) > irclogs_path_len + 1 && + path[irclogs_path_len] == '/' && strncmp(path, irclogs_path, irclogs_path_len) == 0) { fd = openat(irclogs_fd, path + irclogs_path_len + 1, flags, mode); @@ -176,6 +177,7 @@ void capsicum_mkdir_with_parents(const char *path, int mode) /* +1 is for the slash separating irclogs_path and the rest. */ if (strlen(path) <= irclogs_path_len + 1 || + path[irclogs_path_len] != '/' || strncmp(path, irclogs_path, irclogs_path_len) != 0) { g_warning("Cannot create %s: file system access restricted " "to %s due to capability mode", path, irclogs_path); @@ -366,8 +368,15 @@ static void cmd_capsicum_enter(void) port_max = settings_get_int("capsicum_port_max"); irclogs_path = convert_home(settings_get_str("capsicum_irclogs_path")); - g_mkdir_with_parents(irclogs_path, log_dir_create_mode); irclogs_path_len = strlen(irclogs_path); + + /* Strip trailing slashes, if any. */ + while (irclogs_path_len > 0 && irclogs_path[irclogs_path_len - 1] == '/') { + irclogs_path[irclogs_path_len - 1] = '\0'; + irclogs_path_len--; + } + + g_mkdir_with_parents(irclogs_path, log_dir_create_mode); irclogs_fd = open(irclogs_path, O_DIRECTORY | O_CLOEXEC); if (irclogs_fd < 0) { g_warning("Unable to open %s: %s", irclogs_path, strerror(errno)); From 8bb392a3f47d74cccb9e2d7e3633e3e534306968 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 30 Jul 2017 01:27:33 +0100 Subject: [PATCH 0159/1198] Hook up capsicum.h and fe-capsicum.h to autotools. This hopefully fixes Travis build. Signed-off-by: Edward Tomasz Napierala --- src/core/Makefile.am | 1 + src/fe-common/core/Makefile.am | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/Makefile.am b/src/core/Makefile.am index f3bc1674..983f7e32 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -74,6 +74,7 @@ structure_headers = \ pkginc_coredir=$(pkgincludedir)/src/core pkginc_core_HEADERS = \ args.h \ + capsicum.h \ channels.h \ channels-setup.h \ commands.h \ diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 08e41520..29cc941a 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -48,6 +48,7 @@ pkginc_fe_common_core_HEADERS = \ command-history.h \ chat-completion.h \ completion.h \ + fe-capsicum.h \ fe-channels.h \ fe-common-core.h \ fe-core-commands.h \ From 5551b4fe9504f5d5b4e81a680741cab72bec82e9 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 30 Jul 2017 11:47:08 +0100 Subject: [PATCH 0160/1198] Update copyrights. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 4 ++++ src/fe-common/core/fe-capsicum.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 01f5f95c..b5f704f7 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -3,6 +3,10 @@ Copyright (C) 2017 Edward Tomasz Napierala + This software was developed by SRI International and the University of + Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + ("CTSRD"), as part of the DARPA CRASH research programme. + 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 diff --git a/src/fe-common/core/fe-capsicum.c b/src/fe-common/core/fe-capsicum.c index 5816b223..4666eda7 100644 --- a/src/fe-common/core/fe-capsicum.c +++ b/src/fe-common/core/fe-capsicum.c @@ -3,6 +3,10 @@ Copyright (C) 2017 Edward Tomasz Napierala + This software was developed by SRI International and the University of + Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + ("CTSRD"), as part of the DARPA CRASH research programme. + 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 From aeaa420ad330a528391ed149371b55581a808655 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 1 Aug 2017 01:15:25 +0100 Subject: [PATCH 0161/1198] Clean up includes a bit. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 1 + src/fe-common/core/fe-capsicum.c | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index b5f704f7..06cb8d9b 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -23,6 +23,7 @@ */ #include "module.h" +#include "capsicum.h" #include "commands.h" #include "log.h" #include "misc.h" diff --git a/src/fe-common/core/fe-capsicum.c b/src/fe-common/core/fe-capsicum.c index 4666eda7..54a43d27 100644 --- a/src/fe-common/core/fe-capsicum.c +++ b/src/fe-common/core/fe-capsicum.c @@ -23,12 +23,11 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "printtext.h" - +#include "fe-capsicum.h" #include "levels.h" -#include "servers.h" +#include "module-formats.h" +#include "printtext.h" +#include "signals.h" static void capability_mode_enabled(void) { From 96f4fe10c6081cf441122039c39eb6422eef13e8 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 1 Aug 2017 01:47:45 +0100 Subject: [PATCH 0162/1198] Change the way we load default CA certificates so it works with Capsicum. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 8 ++++++++ src/core/network-openssl.c | 23 ++++++++++++++++++++--- src/core/network-openssl.h | 6 ++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/core/network-openssl.h diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 06cb8d9b..79db780a 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -28,6 +28,7 @@ #include "log.h" #include "misc.h" #include "network.h" +#include "network-openssl.h" #include "settings.h" #include "signals.h" @@ -361,6 +362,7 @@ static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) static void cmd_capsicum_enter(void) { u_int mode; + gboolean inited; int error; error = cap_getmode(&mode); @@ -369,6 +371,12 @@ static void cmd_capsicum_enter(void) return; } + inited = irssi_ssl_init(); + if (!inited) { + signal_emit("capability mode failed", 1, strerror(errno)); + return; + } + port_min = settings_get_int("capsicum_port_min"); port_max = settings_get_int("capsicum_port_max"); diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 4de3cb3c..78bdcce4 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -20,6 +20,7 @@ #include "module.h" #include "network.h" +#include "network-openssl.h" #include "net-sendbuffer.h" #include "misc.h" #include "servers.h" @@ -58,6 +59,7 @@ typedef struct } GIOSSLChannel; static int ssl_inited = FALSE; +static X509_STORE *store = NULL; static void irssi_ssl_free(GIOChannel *handle) { @@ -362,8 +364,10 @@ static GIOFuncs irssi_ssl_channel_funcs = { irssi_ssl_get_flags }; -static gboolean irssi_ssl_init(void) +gboolean irssi_ssl_init(void) { + int success; + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) if (!OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL)) { g_error("Could not initialize OpenSSL"); @@ -374,6 +378,20 @@ static gboolean irssi_ssl_init(void) SSL_load_error_strings(); OpenSSL_add_all_algorithms(); #endif + store = X509_STORE_new(); + if (store == NULL) { + g_error("Could not initialize OpenSSL: X509_STORE_new() failed"); + return FALSE; + } + + success = X509_STORE_set_default_paths(store); + if (success == 0) { + g_error("Could not load default certificates"); + X509_STORE_free(store); + store = NULL; + return FALSE; + } + ssl_inited = TRUE; return TRUE; @@ -492,8 +510,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ g_free(scapath); verify = TRUE; } else { - if (!SSL_CTX_set_default_verify_paths(ctx)) - g_warning("Could not load default certificates"); + SSL_CTX_set_cert_store(ctx, store); } if(!(ssl = SSL_new(ctx))) diff --git a/src/core/network-openssl.h b/src/core/network-openssl.h new file mode 100644 index 00000000..4cd6d711 --- /dev/null +++ b/src/core/network-openssl.h @@ -0,0 +1,6 @@ +#ifndef __NETWORK_OPENSSL_H +#define __NETWORK_OPENSSL_H + +gboolean irssi_ssl_init(void); + +#endif /* !__NETWORK_OPENSSL_H */ From 5db6caee0d17eb125d8c7f3090c325ffbee35920 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 1 Aug 2017 01:50:16 +0100 Subject: [PATCH 0163/1198] Attempt to fix build by adding the forgotten header. Signed-off-by: Edward Tomasz Napierala --- src/core/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 983f7e32..f64d9e2e 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -95,6 +95,7 @@ pkginc_core_HEADERS = \ net-nonblock.h \ net-sendbuffer.h \ network.h \ + network-openssl.h \ nick-rec.h \ nicklist.h \ nickmatch-cache.h \ From 788e47032f9f6b7eea188a1a6e7fc1a19531c1b0 Mon Sep 17 00:00:00 2001 From: Paul Townsend Date: Sat, 5 Aug 2017 21:02:35 +0100 Subject: [PATCH 0164/1198] Update /CONNECT and /SERVER syntax tags (-ssl -> -tls). --- src/core/chat-commands.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index e86fdf9d..d5a133f8 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -149,9 +149,9 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, return conn; } -/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] - [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] - [-ssl_ciphers ] +/* SYNTAX: CONNECT [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] [-tls_pass ] + [-tls_verify] [-tls_cafile ] [-tls_capath ] + [-tls_ciphers ] [-tls_pinned_cert ] [-tls_pinned_pubkey ] [-!] [-noautosendcmd] [-noproxy] [-network ] [-host ] [-rawlog ] @@ -250,10 +250,10 @@ static void cmd_server(const char *data, SERVER_REC *server, WI_ITEM_REC *item) command_runsub("server", data, server, item); } -/* SYNTAX: SERVER CONNECT [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] - [-ssl_pass ] [-ssl_verify] [-ssl_cafile ] - [-ssl_capath ] - [-ssl_ciphers ] +/* SYNTAX: SERVER CONNECT [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] + [-tls_pass ] [-tls_verify] [-tls_cafile ] + [-tls_capath ] + [-tls_ciphers ] [-tls_pinned_cert ] [-tls_pinned_pubkey ] [-!] [-noautosendcmd] [-noproxy] [-network ] [-host ] [-rawlog ] From 947682e5dde85aa5e0277c01d7fb4afc1032ea04 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 7 Aug 2017 15:24:07 +0200 Subject: [PATCH 0165/1198] Revert "Merge pull request #452 from LemonBoy/terminfo-cup" Fixes #733. The fix outlined in #452 had adverse effects for the following reason. The code removed the restoration path that would go on the code path from kill SIGTSTP. The problem is this: When Irssi is not running in a controlling parent (like a shell), the TSTP will in fact be ignored. In that case, there is no process sending a CONT either and thus the screen state never gets restored. Luckily, the patch in #457 is sufficient to prevent the problem in #450 (which lead to the development of #452). To that end, we do end up with potentially calling terminfo_cont twice but that is better than not calling it at all. This reverts commit b1ffd5f6472584aa3966746da9728c5afefcc4ce, reversing changes made to 9cb0419435d1ad331c1f55361a003d9682fae9a8. --- src/fe-text/term-terminfo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index bca37efc..6645cfb0 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -629,6 +629,13 @@ void term_stop(void) { terminfo_stop(current_term); kill(getpid(), SIGTSTP); + /* this call needs to stay here in case the TSTP was ignored, + because then we never see a CONT to call the restoration + code. On the other hand we also cannot remove the CONT + handler because then nothing would restore the screen when + Irssi is killed with TSTP/STOP from external. */ + terminfo_cont(current_term); + irssi_redraw(); } static int input_utf8(const unsigned char *buffer, int size, unichar *result) From 0c49a84ffb8d74506a13653183bfa1ef8ffd2554 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 9 Aug 2017 11:06:36 +0100 Subject: [PATCH 0166/1198] Add back some ifdefs. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.h | 10 +--------- src/core/core.c | 2 ++ src/core/log.c | 12 ++++++++++++ src/core/rawlog.c | 16 ++++++++++++++++ src/fe-common/core/fe-common-core.c | 2 ++ src/fe-common/core/fe-log.c | 6 ++++++ 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/core/capsicum.h b/src/core/capsicum.h index 3c1234e1..7d89f2aa 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -5,17 +5,9 @@ gboolean capsicum_enabled(void); int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); int capsicum_open(const char *path, int flags, int mode); -void capsicum_mkdir_with_parents(const char *path, int mode); - -#ifdef HAVE_CAPSICUM int capsicum_open_wrapper(const char *path, int flags, int mode); +void capsicum_mkdir_with_parents(const char *path, int mode); void capsicum_mkdir_with_parents_wrapper(const char *path, int mode); -#else -#define capsicum_open_wrapper(P, F, M) \ - open(P, F, M) -#define capsicum_mkdir_with_parents_wrapper(P, M) \ - g_mkdir_with_parents(P, M) -#endif void capsicum_init(void); void capsicum_deinit(void); diff --git a/src/core/core.c b/src/core/core.c index c95879de..506d6a13 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -29,7 +29,9 @@ #include "signals.h" #include "settings.h" #include "session.h" +#ifdef HAVE_CAPSICUM #include "capsicum.h" +#endif #include "chat-protocols.h" #include "servers.h" diff --git a/src/core/log.c b/src/core/log.c index ea2f1a1d..f7741d3d 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -26,7 +26,9 @@ #include "servers.h" #include "log.h" #include "write-buffer.h" +#ifdef HAVE_CAPSICUM #include "capsicum.h" +#endif #include "lib-config/iconfig.h" #include "settings.h" @@ -115,13 +117,23 @@ int log_start_logging(LOG_REC *log) /* path may contain variables (%time, $vars), make sure the directory is created */ dir = g_path_get_dirname(log->real_fname); +#ifdef HAVE_CAPSICUM capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); +#else + g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); } +#ifdef HAVE_CAPSICUM log->handle = log->real_fname == NULL ? -1 : capsicum_open_wrapper(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); +#else + log->handle = log->real_fname == NULL ? -1 : + open(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, + log_file_create_mode); +#endif if (log->handle == -1) { signal_emit("log create failed", 1, log); log->failed = TRUE; diff --git a/src/core/rawlog.c b/src/core/rawlog.c index a95b9a92..fdd51241 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -27,7 +27,9 @@ #include "misc.h" #include "write-buffer.h" #include "settings.h" +#ifdef HAVE_CAPSICUM #include "capsicum.h" +#endif #include "servers.h" @@ -127,9 +129,15 @@ void rawlog_open(RAWLOG_REC *rawlog, const char *fname) return; path = convert_home(fname); +#ifdef HAVE_CAPSICUM rawlog->handle = capsicum_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); +#else + rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT, + log_file_create_mode); +#endif + g_free(path); if (rawlog->handle == -1) { @@ -156,12 +164,20 @@ void rawlog_save(RAWLOG_REC *rawlog, const char *fname) int f; dir = g_path_get_dirname(fname); +#ifdef HAVE_CAPSICUM capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); +#else + g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); path = convert_home(fname); +#ifdef HAVE_CAPSICUM f = capsicum_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); +#else + f = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); +#endif g_free(path); if (f < 0) { diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 67c9e20c..a3b7364c 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -32,7 +32,9 @@ #include "special-vars.h" #include "fe-core-commands.h" #include "fe-queries.h" +#ifdef HAVE_CAPSICUM #include "fe-capsicum.h" +#endif #include "hilight-text.h" #include "command-history.h" #include "completion.h" diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 3d8910c9..0fed8642 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -30,7 +30,9 @@ #include "special-vars.h" #include "settings.h" #include "lib-config/iconfig.h" +#ifdef HAVE_CAPSICUM #include "capsicum.h" +#endif #include "fe-windows.h" #include "window-items.h" @@ -452,7 +454,11 @@ static void autolog_open(SERVER_REC *server, const char *server_tag, log_item_add(log, LOG_ITEM_TARGET, target, server_tag); dir = g_path_get_dirname(log->real_fname); +#ifdef HAVE_CAPSICUM capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); +#else + g_mkdir_with_parents(dir, log_dir_create_mode); +#endif g_free(dir); log->temp = TRUE; From 4bcbb41113bf23b1d121ad6fbd7b86473f7fa89d Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 9 Aug 2017 14:36:06 +0100 Subject: [PATCH 0167/1198] Fix indentation; no functional changes. (Take two.) Signed-off-by: Edward Tomasz Napierala --- src/fe-common/core/module-formats.h | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index a9ed28c5..f361befb 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -12,21 +12,21 @@ enum { TXT_DAYCHANGE, TXT_TALKING_WITH, TXT_REFNUM_TOO_LOW, - TXT_ERROR_SERVER_STICKY, - TXT_SET_SERVER_STICKY, + TXT_ERROR_SERVER_STICKY, + TXT_SET_SERVER_STICKY, TXT_UNSET_SERVER_STICKY, - TXT_WINDOW_NAME_NOT_UNIQUE, - TXT_WINDOW_LEVEL, - TXT_WINDOW_SET_IMMORTAL, - TXT_WINDOW_UNSET_IMMORTAL, - TXT_WINDOW_IMMORTAL_ERROR, + TXT_WINDOW_NAME_NOT_UNIQUE, + TXT_WINDOW_LEVEL, + TXT_WINDOW_SET_IMMORTAL, + TXT_WINDOW_UNSET_IMMORTAL, + TXT_WINDOW_IMMORTAL_ERROR, TXT_WINDOWLIST_HEADER, TXT_WINDOWLIST_LINE, TXT_WINDOWLIST_FOOTER, TXT_WINDOWS_LAYOUT_SAVED, TXT_WINDOWS_LAYOUT_RESET, - TXT_WINDOW_INFO_HEADER, - TXT_WINDOW_INFO_FOOTER, + TXT_WINDOW_INFO_HEADER, + TXT_WINDOW_INFO_FOOTER, TXT_WINDOW_INFO_REFNUM, TXT_WINDOW_INFO_REFNUM_STICKY, TXT_WINDOW_INFO_NAME, @@ -34,22 +34,22 @@ enum { TXT_WINDOW_INFO_IMMORTAL, TXT_WINDOW_INFO_SIZE, TXT_WINDOW_INFO_LEVEL, - TXT_WINDOW_INFO_SERVER, + TXT_WINDOW_INFO_SERVER, TXT_WINDOW_INFO_SERVER_STICKY, - TXT_WINDOW_INFO_THEME, + TXT_WINDOW_INFO_THEME, TXT_WINDOW_INFO_BOUND_ITEMS_HEADER, TXT_WINDOW_INFO_BOUND_ITEM, TXT_WINDOW_INFO_BOUND_ITEMS_FOOTER, TXT_WINDOW_INFO_ITEMS_HEADER, TXT_WINDOW_INFO_ITEM, - TXT_WINDOW_INFO_ITEMS_FOOTER, + TXT_WINDOW_INFO_ITEMS_FOOTER, TXT_FILL_2, TXT_LOOKING_UP, TXT_CONNECTING, - TXT_RECONNECTING, - TXT_CONNECTION_ESTABLISHED, + TXT_RECONNECTING, + TXT_CONNECTION_ESTABLISHED, TXT_CANT_CONNECT, TXT_CONNECTION_LOST, TXT_LAG_DISCONNECTED, @@ -100,7 +100,7 @@ enum { TXT_CHANSETUP_LINE, TXT_CHANSETUP_FOOTER, - TXT_FILL_4, + TXT_FILL_4, TXT_OWN_MSG, TXT_OWN_MSG_CHANNEL, @@ -162,7 +162,7 @@ enum { TXT_MODULE_HEADER, TXT_MODULE_LINE, - TXT_MODULE_FOOTER, + TXT_MODULE_FOOTER, TXT_MODULE_ALREADY_LOADED, TXT_MODULE_NOT_LOADED, TXT_MODULE_LOAD_ERROR, @@ -183,7 +183,7 @@ enum { TXT_NOT_JOINED, TXT_CHAN_NOT_FOUND, TXT_CHAN_NOT_SYNCED, - TXT_ILLEGAL_PROTO, + TXT_ILLEGAL_PROTO, TXT_NOT_GOOD_IDEA, TXT_INVALID_NUMBER, TXT_INVALID_TIME, @@ -232,8 +232,8 @@ enum { TXT_FILL_14, - TXT_UNKNOWN_CHAT_PROTOCOL, - TXT_UNKNOWN_CHATNET, + TXT_UNKNOWN_CHAT_PROTOCOL, + TXT_UNKNOWN_CHATNET, TXT_NOT_TOGGLE, TXT_PERL_ERROR, TXT_BIND_HEADER, @@ -245,15 +245,15 @@ enum { TXT_CONFIG_RELOADED, TXT_CONFIG_MODIFIED, TXT_GLIB_ERROR, - TXT_OVERWRITE_CONFIG, - TXT_SET_TITLE, - TXT_SET_ITEM, - TXT_SET_UNKNOWN, + TXT_OVERWRITE_CONFIG, + TXT_SET_TITLE, + TXT_SET_ITEM, + TXT_SET_UNKNOWN, TXT_SET_NOT_BOOLEAN, TXT_NO_COMPLETIONS, - TXT_COMPLETION_REMOVED, + TXT_COMPLETION_REMOVED, TXT_COMPLETION_HEADER, - TXT_COMPLETION_LINE, + TXT_COMPLETION_LINE, TXT_COMPLETION_FOOTER, TLS_FILL_15, From edee0ba587069a860eac43f9219f8ecfa49fe1fa Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 10 Aug 2017 14:35:34 +0100 Subject: [PATCH 0168/1198] Don't error out on failure to load default certificate store. This restores the previous behaviour. Signed-off-by: Edward Tomasz Napierala --- src/core/network-openssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 78bdcce4..2054f28a 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -386,10 +386,10 @@ gboolean irssi_ssl_init(void) success = X509_STORE_set_default_paths(store); if (success == 0) { - g_error("Could not load default certificates"); + g_warning("Could not load default certificates"); X509_STORE_free(store); store = NULL; - return FALSE; + /* Don't return an error; the user might have their own cafile/capath. */ } ssl_inited = TRUE; @@ -509,7 +509,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ g_free(scafile); g_free(scapath); verify = TRUE; - } else { + } else if (store != NULL) { SSL_CTX_set_cert_store(ctx, store); } From 245a3fd4c1afb86b38eb17477a42c60c52cef793 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 28 Aug 2017 06:13:28 +0100 Subject: [PATCH 0169/1198] Add docs/capsicum.txt. Signed-off-by: Edward Tomasz Napierala --- docs/Makefile.am | 1 + docs/capsicum.txt | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 docs/capsicum.txt diff --git a/docs/Makefile.am b/docs/Makefile.am index 861a2ca4..32722391 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -2,6 +2,7 @@ man_MANS = \ irssi.1 doc_DATA = \ + capsicum.txt \ design.txt \ formats.txt \ manual.txt \ diff --git a/docs/capsicum.txt b/docs/capsicum.txt new file mode 100644 index 00000000..3093bfe5 --- /dev/null +++ b/docs/capsicum.txt @@ -0,0 +1,30 @@ +Capsicum is a lightweight OS capability and sandbox framework provided +by FreeBSD. When built with Capsicum support - which is the default under +FreeBSD - Irssi can enter a Capsicum capability mode (a sandbox), greatly +limiting possible consequences of a potential security hole in Irssi +or the libraries it depends on. + +To make Irssi enter capability mode on startup, add + +capsicum = "yes"; + +to your ~/.irssi/config and restart the client. Alternatively you can +enter it "by hand", using the "/capsicum enter" command. From the security +point of view it's strongly preferable to use the former method, to avoid +establishing connections without the sandbox protection; the "/capsicum" +command is only intended for experimentation, and in cases where you need +to do something that's not possible in capability mode - run scripts, +for example - before continuing. + +There is no way to leave the capability mode, apart from exiting Irssi. +When running in capability mode, there are certain restrictions - Irssi +won't be able to access any files outside the directory pointed to by +capsicum_irclogs_path (which defaults to ~/irclogs/). If you change +the path when already in capability mode it won't be effective until +you restart Irssi. Capability mode also makes it impossible to use +the "/save" command. + +Currently there is no way to use custom SSL certificates. As a workaround +you can establish connections and enter the capability mode afterwards +using the "/capsicum enter" command. + From 7086eae650a616615bc81e688cdfa44d444463e0 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 29 Aug 2017 21:03:42 +0200 Subject: [PATCH 0170/1198] Complete filenames ending with a slash --- src/fe-common/core/completion.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 78b1b24b..e78fe7d5 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -321,6 +321,10 @@ GList *filename_complete(const char *path, const char *default_path) g_return_val_if_fail(path != NULL, NULL); + if (path[0] == '\0') { + return NULL; + } + list = NULL; /* get directory part of the path - expand ~/ */ @@ -350,7 +354,14 @@ GList *filename_complete(const char *path, const char *default_path) g_free_and_null(dir); } - basename = g_path_get_basename(path); + len = strlen(path); + /* g_path_get_basename() returns the component before the last slash if + * the path ends with a directory separator, that's not what we want */ + if (len > 0 && path[len - 1] == G_DIR_SEPARATOR) { + basename = g_strdup(""); + } else { + basename = g_path_get_basename(path); + } len = strlen(basename); /* add all files in directory to completion list */ From b529e1a9df134bbc5618752abcf19af0110b6868 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 1 Sep 2017 10:39:14 +0100 Subject: [PATCH 0171/1198] Fix /back in Capsicum capability mode. Signed-off-by: Edward Tomasz Napierala --- src/fe-common/core/fe-core-commands.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 97a246ec..fb98cc25 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -28,6 +28,9 @@ #include "settings.h" #include "irssi-version.h" #include "servers.h" +#ifdef HAVE_CAPSICUM +#include "capsicum.h" +#endif #include "fe-windows.h" #include "printtext.h" @@ -120,6 +123,9 @@ static void cmd_cat(const char *data) GIOChannel *handle; GString *buf; gsize tpos; +#ifdef HAVE_CAPSICUM + int fd; +#endif if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr)) return; @@ -128,7 +134,15 @@ static void cmd_cat(const char *data) fpos = atoi(fposstr); cmd_params_free(free_arg); +#ifdef HAVE_CAPSICUM + fd = capsicum_open_wrapper(fname, O_RDONLY, 0); + if (fd > 0) + handle = g_io_channel_unix_new(fd); + else + handle = NULL; +#else handle = g_io_channel_new_file(fname, "r", NULL); +#endif g_free(fname); if (handle == NULL) { From 96d5a4669d696d57a511119963ae5c651346e167 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 11 Sep 2017 16:32:36 +0200 Subject: [PATCH 0172/1198] Increment the X509_STORE refcount during the connection OpenSSL doesn't increment the reference count when the store is assigned to a SSL_CTX. --- src/core/network-openssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 2054f28a..feb2295d 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -510,6 +510,10 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ g_free(scapath); verify = TRUE; } else if (store != NULL) { + /* Make sure to increment the refcount every time the store is + * used, that's essential not to get it free'd by OpenSSL when + * the SSL_CTX is destroyed. */ + X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx, store); } From 36d8b974fc42ed8eb1ff88811e09d0910ae61187 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 11 Sep 2017 17:07:50 +0200 Subject: [PATCH 0173/1198] Restore compatibility with old OpenSSL versions Let's implement X509_STORE_up_ref on our own. --- src/core/network-openssl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index feb2295d..7ec902fb 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -45,6 +45,19 @@ #define ASN1_STRING_data(x) ASN1_STRING_get0_data(x) #endif +/* OpenSSL 1.1.0 also introduced some useful additions to the api */ +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER) +static int X509_STORE_up_ref(X509_STORE *vfy) +{ + int n; + + n = CRYPTO_add(&vfy->references, 1, CRYPTO_LOCK_X509_STORE); + g_assert(n > 1); + + return (n > 1) ? 1 : 0; +} +#endif + /* ssl i/o channel object */ typedef struct { From 624ef4a696fc736779c6b7af94c7e376b7033590 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 Sep 2017 14:19:17 +0100 Subject: [PATCH 0174/1198] Get rid of the zombies in Capsicum capability mode. Signed-off-by: Edward Tomasz Napierala --- src/core/capsicum.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 79db780a..3b0708cb 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -403,6 +403,13 @@ static void cmd_capsicum_enter(void) return; } + /* + * XXX: We should use pdwait(2) to wait for children. Unfortunately + * it's not implemented yet. Thus the workaround, to get rid + * of the zombies at least. + */ + signal(SIGCHLD, SIG_IGN); + error = cap_enter(); if (error != 0) { signal_emit("capability mode failed", 1, strerror(errno)); From 0468c5d912fc8a89bd552611ef6243bd1c889df7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 13 Sep 2017 13:58:00 +0200 Subject: [PATCH 0175/1198] add new function to set the position in bytes fixes #752 --- src/fe-text/gui-entry.c | 20 ++++++++++++++++++++ src/fe-text/gui-entry.h | 1 + src/fe-text/gui-readline.c | 6 ++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index f05decd2..e91fcfb3 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -936,6 +936,26 @@ void gui_entry_set_pos(GUI_ENTRY_REC *entry, int pos) gui_entry_draw(entry); } +void gui_entry_set_text_and_pos_bytes(GUI_ENTRY_REC *entry, const char *str, int pos_bytes) +{ + int pos; + const char *ptr; + + g_return_if_fail(entry != NULL); + + gui_entry_set_text(entry, str); + + if (entry->utf8) { + g_utf8_validate(str, pos_bytes, &ptr); + pos = g_utf8_pointer_to_offset(str, ptr); + } else if (term_type == TERM_TYPE_BIG5) + pos = strlen_big5((const unsigned char *)str) - strlen_big5((const unsigned char *)(str + pos_bytes)); + else + pos = pos_bytes; + + gui_entry_set_pos(entry, pos); +} + void gui_entry_move_pos(GUI_ENTRY_REC *entry, int pos) { g_return_if_fail(entry != NULL); diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 8777f083..000c5f03 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -50,6 +50,7 @@ void gui_entry_set_utf8(GUI_ENTRY_REC *entry, int utf8); void gui_entry_set_text(GUI_ENTRY_REC *entry, const char *str); char *gui_entry_get_text(GUI_ENTRY_REC *entry); char *gui_entry_get_text_and_pos(GUI_ENTRY_REC *entry, int *pos); +void gui_entry_set_text_and_pos_bytes(GUI_ENTRY_REC *entry, const char *str, int pos_bytes); void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str); void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 2c2eac21..3688f15e 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -878,8 +878,7 @@ static void key_completion(int erase, int backward) g_free(text); if (line != NULL) { - gui_entry_set_text(active_entry, line); - gui_entry_set_pos(active_entry, pos); + gui_entry_set_text_and_pos_bytes(active_entry, line, pos); g_free(line); } } @@ -909,8 +908,7 @@ static void key_check_replaces(void) g_free(text); if (line != NULL) { - gui_entry_set_text(active_entry, line); - gui_entry_set_pos(active_entry, pos); + gui_entry_set_text_and_pos_bytes(active_entry, line, pos); g_free(line); } } From 8dfeca57ede1e726de07522a87203ce13676882d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 8 Sep 2017 15:19:40 +0200 Subject: [PATCH 0176/1198] hidden lines --- src/common.h | 2 +- src/core/levels.c | 21 +++++----- src/core/levels.h | 4 +- src/fe-text/gui-windows.c | 4 ++ src/fe-text/mainwindows-layout.c | 10 +++++ src/fe-text/module-formats.c | 1 + src/fe-text/module-formats.h | 1 + src/fe-text/textbuffer-commands.c | 21 ++++++++++ src/fe-text/textbuffer-view.c | 67 ++++++++++++++++++++++++++++--- src/fe-text/textbuffer-view.h | 36 +++++++++++------ src/fe-text/textbuffer.c | 1 + src/fe-text/textbuffer.h | 2 +- 12 files changed, 139 insertions(+), 31 deletions(-) diff --git a/src/common.h b/src/common.h index 100d00cb..159f7124 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 10 +#define IRSSI_ABI_VERSION 11 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/levels.c b/src/core/levels.c index e623c4de..eb7efcf7 100644 --- a/src/core/levels.c +++ b/src/core/levels.c @@ -21,6 +21,7 @@ #include "module.h" #include "levels.h" +/* the order of these levels must match the bits in levels.h */ static const char *levels[] = { "CRAP", "MSGS", @@ -44,9 +45,6 @@ static const char *levels[] = { "CLIENTCRAP", "CLIENTERRORS", "HILIGHTS", - - "NOHILIGHT", - "NO_ACT", NULL }; @@ -63,6 +61,9 @@ int level_get(const char *level) if (g_ascii_strcasecmp(level, "NO_ACT") == 0) return MSGLEVEL_NO_ACT; + if (g_ascii_strcasecmp(level, "HIDDEN") == 0) + return MSGLEVEL_HIDDEN; + len = strlen(level); if (len == 0) return 0; @@ -138,17 +139,13 @@ char *bits2level(int bits) str = g_string_new(NULL); - if (bits & MSGLEVEL_NEVER) { + if (bits & MSGLEVEL_NEVER) g_string_append(str, "NEVER "); - bits &= ~MSGLEVEL_NEVER; - } - if (bits & MSGLEVEL_NO_ACT) { + if (bits & MSGLEVEL_NO_ACT) g_string_append(str, "NO_ACT "); - bits &= ~MSGLEVEL_NO_ACT; - } - if (bits == MSGLEVEL_ALL) { + if ((bits & MSGLEVEL_ALL) == MSGLEVEL_ALL) { g_string_append(str, "ALL "); } else { for (n = 0; levels[n] != NULL; n++) { @@ -156,6 +153,10 @@ char *bits2level(int bits) g_string_append_printf(str, "%s ", levels[n]); } } + + if (bits & MSGLEVEL_HIDDEN) + g_string_append(str, "HIDDEN "); + if (str->len > 0) g_string_truncate(str, str->len-1); diff --git a/src/core/levels.h b/src/core/levels.h index 9f7e588f..b0ebafba 100644 --- a/src/core/levels.h +++ b/src/core/levels.h @@ -36,7 +36,9 @@ enum { MSGLEVEL_NOHILIGHT = 0x1000000, /* Don't highlight this message */ MSGLEVEL_NO_ACT = 0x2000000, /* Don't trigger channel activity */ MSGLEVEL_NEVER = 0x4000000, /* never ignore / never log */ - MSGLEVEL_LASTLOG = 0x8000000 /* never ignore / never log */ + MSGLEVEL_LASTLOG = 0x8000000, /* used for /lastlog */ + + MSGLEVEL_HIDDEN = 0x10000000 /* Hidden from view */ }; int level_get(const char *level); diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index c63c495c..34c55772 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -23,6 +23,7 @@ #include "misc.h" #include "settings.h" #include "special-vars.h" +#include "levels.h" #include "term.h" #include "gui-entry.h" @@ -50,6 +51,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, !settings_get_bool("indent_always"), get_default_indent_func()); textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); + textbuffer_view_set_hidden_level(gui->view, MSGLEVEL_HIDDEN); if (parent->active == window) textbuffer_view_set_window(gui->view, parent->screen_win); return gui; @@ -204,6 +206,8 @@ 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/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index fae02539..acbcb6b9 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -23,6 +23,7 @@ #include "misc.h" #include "lib-config/iconfig.h" #include "settings.h" +#include "levels.h" #include "mainwindows.h" #include "gui-windows.h" @@ -41,6 +42,12 @@ static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) iconfig_node_set_int(node, "parent", active->refnum); } + if (gui->view->hidden_level != MSGLEVEL_HIDDEN) { + char *level = bits2level(gui->view->hidden_level); + iconfig_node_set_str(node, "hidelevel", level); + g_free(level); + } + if (gui->use_scroll) iconfig_node_set_bool(node, "scroll", gui->scroll); } @@ -58,6 +65,9 @@ static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) if (config_node_get_bool(node, "sticky", FALSE)) gui_window_set_sticky(window); + + textbuffer_view_set_hidden_level(gui->view, level2bits(config_node_get_str(node, "hidelevel", "HIDDEN"), NULL)); + if (config_node_get_str(node, "scroll", NULL) != NULL) { gui->use_scroll = TRUE; gui->scroll = config_node_get_bool(node, "scroll", TRUE); diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index 899827c2..0cde9946 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -50,6 +50,7 @@ FORMAT_REC gui_text_formats[] = { "window_info_scroll", "%#Scroll : $0", 1, { 0 } }, { "window_scroll", "Window scroll mode is now $0", 1, { 0 } }, { "window_scroll_unknown", "Unknown scroll mode $0, must be ON, OFF or DEFAULT", 1, { 0 } }, + { "window_hidelevel", "Window hidden level is now $0", 1, { 0 } }, /* ---- */ { NULL, "Statusbars", 0 }, diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h index 3fa8c511..acc2627c 100644 --- a/src/fe-text/module-formats.h +++ b/src/fe-text/module-formats.h @@ -26,6 +26,7 @@ enum { TXT_WINDOW_INFO_SCROLL, TXT_WINDOW_SCROLL, TXT_WINDOW_SCROLL_UNKNOWN, + TXT_WINDOW_HIDELEVEL, TXT_FILL_3, diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c index 648862e7..97d897f3 100644 --- a/src/fe-text/textbuffer-commands.c +++ b/src/fe-text/textbuffer-commands.c @@ -89,6 +89,25 @@ static void cmd_window_scroll(const char *data) gui->scroll : settings_get_bool("scroll")); } +/* SYNTAX: WINDOW HIDELEVEL [] */ +static void cmd_window_hidelevel(const char *data) +{ + GUI_WINDOW_REC *gui; + char *level; + + g_return_if_fail(data != NULL); + + gui = WINDOW_GUI(active_win); + textbuffer_view_set_hidden_level(gui->view, + combine_level(gui->view->hidden_level, data)); + textbuffer_view_redraw(gui->view); + level = gui->view->hidden_level == 0 ? g_strdup("NONE") : + bits2level(gui->view->hidden_level); + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, + TXT_WINDOW_HIDELEVEL, level); + g_free(level); +} + static void cmd_scrollback(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { @@ -358,6 +377,7 @@ void textbuffer_commands_init(void) { command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear); command_bind("window scroll", NULL, (SIGNAL_FUNC) cmd_window_scroll); + command_bind("window hidelevel", NULL, (SIGNAL_FUNC) cmd_window_hidelevel); command_bind("scrollback", NULL, (SIGNAL_FUNC) cmd_scrollback); command_bind("scrollback clear", NULL, (SIGNAL_FUNC) cmd_scrollback_clear); command_bind("scrollback levelclear", NULL, (SIGNAL_FUNC) cmd_scrollback_levelclear); @@ -377,6 +397,7 @@ void textbuffer_commands_deinit(void) { command_unbind("clear", (SIGNAL_FUNC) cmd_clear); command_unbind("window scroll", (SIGNAL_FUNC) cmd_window_scroll); + command_unbind("window hidelevel", (SIGNAL_FUNC) cmd_window_hidelevel); command_unbind("scrollback", (SIGNAL_FUNC) cmd_scrollback); command_unbind("scrollback clear", (SIGNAL_FUNC) cmd_scrollback_clear); command_unbind("scrollback levelclear", (SIGNAL_FUNC) cmd_scrollback_levelclear); diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index cb066f5e..b54f1c8e 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -41,9 +41,15 @@ static GSList *views; #define view_is_bottom(view) \ ((view)->ypos >= -1 && (view)->ypos < (view)->height) -#define view_get_linecount(view, line) \ +#define view_get_linecount_hidden(view, line) \ textbuffer_view_get_line_cache(view, line)->count +#define view_line_is_hidden(view, line) \ + (((line)->info.level & (view)->hidden_level) != 0) + +#define view_get_linecount(view, line) \ + (view_line_is_hidden(view, line) ? 0 : view_get_linecount_hidden(view, line)) + static GSList *textbuffer_get_views(TEXT_BUFFER_REC *buffer) { GSList *tmp, *list; @@ -552,6 +558,9 @@ static void textbuffer_view_init_bottom(TEXT_BUFFER_VIEW_REC *view) total = 0; line = textbuffer_line_last(view->buffer); for (; line != NULL; line = line->prev) { + if (view_line_is_hidden(view, line)) + continue; + linecount = view_get_linecount(view, line); if (line == view->bottom_startline) { /* keep the old one, make sure that subline is ok */ @@ -614,6 +623,8 @@ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer, view->subline = view->bottom_subline; view->bottom = TRUE; + view->hidden_level = 0; + textbuffer_view_init_ypos(view); view->bookmarks = g_hash_table_new((GHashFunc) g_str_hash, @@ -726,8 +737,10 @@ static void view_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, return; while (line != NULL && lines > 0) { - linecount = view_line_draw(view, line, subline, ypos, lines); - ypos += linecount; lines -= linecount; + if (!view_line_is_hidden(view, line)) { + linecount = view_line_draw(view, line, subline, ypos, lines); + ypos += linecount; lines -= linecount; + } subline = 0; line = line->next; @@ -768,7 +781,12 @@ static void view_draw_bottom(TEXT_BUFFER_VIEW_REC *view, int lines) view_draw(view, line, subline, maxline, lines, TRUE); } -/* Returns number of lines actually scrolled */ +/* lines: this pointer is scrolled by scrollcount screen lines + subline: this pointer contains the subline position + scrollcount: the number of lines to scroll down (negative: up) + draw_nonclean: whether to redraw the screen now + + Returns number of lines actually scrolled */ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines, int *subline, int scrollcount, int draw_nonclean) { @@ -1027,7 +1045,7 @@ static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) view->bottom = view_is_bottom(view); } - if (view->window != NULL) { + if (view->window != NULL && !view_line_is_hidden(view, line)) { ypos = view->ypos+1 - view_get_linecount(view, line); if (ypos >= 0) subline = 0; @@ -1042,7 +1060,7 @@ static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) } } - if (view->window != NULL) + if (view->window != NULL && !view_line_is_hidden(view, line)) term_refresh(view->window); } @@ -1122,6 +1140,12 @@ static int view_get_lines_height(TEXT_BUFFER_VIEW_REC *view, return height < view->height ? height : view->height; } +/* line: line to remove + linecount: linecount of that line, to be offset when the line was in/below view + + scroll the window maintaining the startline while removing line + if startline is removed, make the previous line the new startline +*/ static void view_remove_line_update_startline(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int linecount) { @@ -1318,6 +1342,37 @@ LINE_REC *textbuffer_view_get_bookmark(TEXT_BUFFER_VIEW_REC *view, return g_hash_table_lookup(view->bookmarks, name); } +void textbuffer_view_set_hidden_level(TEXT_BUFFER_VIEW_REC *view, int level) +{ + g_return_if_fail(view != NULL); + + if (view->hidden_level != level) { + if (view->empty_linecount > 0 && view->startline != NULL) { + int old_height, new_height; + LINE_REC *hidden_start; + + hidden_start = view->startline; + while (hidden_start->prev != NULL && view_line_is_hidden(view, hidden_start->prev)) { + hidden_start = hidden_start->prev; + } + + old_height = view_get_lines_height(view, hidden_start, view->subline, NULL); + view->hidden_level = level; + new_height = view_get_lines_height(view, hidden_start, view->subline, NULL); + + view->empty_linecount -= new_height - old_height; + + if (view->empty_linecount < 0) + view->empty_linecount = 0; + else if (view->empty_linecount > view->height) + view->empty_linecount = view->height; + } else { + view->hidden_level = level; + } + textbuffer_view_resize(view, view->width, view->height); + } +} + /* Specify window where the changes in view should be drawn, NULL disables it. */ void textbuffer_view_set_window(TEXT_BUFFER_VIEW_REC *view, diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index 5e7a9d0a..a670df2b 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -49,41 +49,51 @@ typedef struct { struct _TEXT_BUFFER_VIEW_REC { TEXT_BUFFER_REC *buffer; - GSList *siblings; /* other views that use the same buffer */ + /* other views that use the same buffer */ + GSList *siblings; TERM_WINDOW *window; int width, height; int default_indent; INDENT_FUNC default_indent_func; - unsigned int longword_noindent:1; - unsigned int scroll:1; /* scroll down automatically when at bottom */ - unsigned int utf8:1; /* use UTF8 in this view */ - unsigned int break_wide:1; /* Break wide chars in this view */ TEXT_BUFFER_CACHE_REC *cache; - int ypos; /* cursor position - visible area is 0..height-1 */ + /* cursor position - visible area is 0..height-1 */ + int ypos; - LINE_REC *startline; /* line at the top of the screen */ - int subline; /* number of "real lines" to skip from `startline' */ + /* line at the top of the screen */ + LINE_REC *startline; + /* number of "real lines" to skip from `startline' */ + int subline; /* marks the bottom of the text buffer */ LINE_REC *bottom_startline; int bottom_subline; + /* Bookmarks to the lines in the buffer - removed automatically + when the line gets removed from buffer */ + GHashTable *bookmarks; + + /* these levels should be hidden */ + int hidden_level; /* how many empty lines are in screen. a screenful when started or used /CLEAR */ int empty_linecount; + + unsigned int longword_noindent:1; + /* scroll down automatically when at bottom */ + unsigned int scroll:1; + /* use UTF8 in this view */ + unsigned int utf8:1; + /* Break wide chars in this view */ + unsigned int break_wide:1; /* window is at the bottom of the text buffer */ unsigned int bottom:1; /* if !bottom - new text has been printed since we were at bottom */ unsigned int more_text:1; /* Window needs a redraw */ unsigned int dirty:1; - - /* Bookmarks to the lines in the buffer - removed automatically - when the line gets removed from buffer */ - GHashTable *bookmarks; }; /* Create new view. */ @@ -143,6 +153,8 @@ void textbuffer_view_set_bookmark_bottom(TEXT_BUFFER_VIEW_REC *view, /* Return the line for bookmark */ LINE_REC *textbuffer_view_get_bookmark(TEXT_BUFFER_VIEW_REC *view, const char *name); +/* Set hidden level for view */ +void textbuffer_view_set_hidden_level(TEXT_BUFFER_VIEW_REC *view, int level); /* Specify window where the changes in view should be drawn, NULL disables it. */ diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index a920fab2..01cdd118 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -230,6 +230,7 @@ LINE_REC *textbuffer_line_last(TEXT_BUFFER_REC *buffer) return buffer->cur_line; } +/* returns TRUE if `search' comes on or after `line' in the buffer */ int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search) { while (line != NULL) { diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 303789a3..2aa22f1a 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -65,10 +65,10 @@ typedef struct { LINE_REC *cur_line; TEXT_CHUNK_REC *cur_text; - unsigned int last_eol:1; int last_fg; int last_bg; int last_flags; + unsigned int last_eol:1; } TEXT_BUFFER_REC; /* Create new buffer */ From 32f33e7bb34598e8603b9f6a931ef063f6bd31f2 Mon Sep 17 00:00:00 2001 From: Robert Bisewski Date: Tue, 3 Oct 2017 22:49:21 -0500 Subject: [PATCH 0177/1198] improving HOWTO document --- docs/startup-HOWTO.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 07a9f47c..fe317ad9 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -635,7 +635,7 @@ separated by : from the actual proxy password.

12. Statusbar

-

/STATUSBAR displays a list of statusbars:

+

/STATUSBAR displays a list of the current statusbars, along with their position and visibility:

 Name                           Type   Placement Position Visible
  window                         window bottom    0        always
@@ -644,9 +644,9 @@ separated by : from the actual proxy password.

topic root top 1 always
-

/STATUSBAR <name> prints the statusbar settings and it’s items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to it’s default settings, or if the statusbar was created by you, it will be removed.

+

/STATUSBAR <name> prints the statusbar settings (type, placement, position, visibility) as well as its items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to its default settings, or if the statusbar was created by you, it will be removed.

-

Type can be window or root, meaning if the statusbar should be created for each split window, or just once. Placement can be top or bottom. Position is a number, the higher the value the lower in screen it is. Visible can be always, active or inactive. Active/inactive is useful only with split windows, one split window is active and the rest are inactive. These settings can be changed with:

+

The statusbar type can be either window or root. If the type is window, then a statusbar will be created for each split window, otherwise it will be created only once. Placement can be top or bottom, which refers to the top or bottom of the screen. Position is a number, the higher the value the lower it will appear in-screen. Visible can be always, active or inactive. Active/inactive is useful only with split windows; one split window is active and the rest are inactive. To adjust these settings, the following commands are available:

 /STATUSBAR <name> TYPE window|root
  /STATUSBAR <name> PLACEMENT top|bottom
@@ -654,10 +654,10 @@ separated by : from the actual proxy password.

/STATUSBAR <name> VISIBLE always|active|inactive
-

When loading a new statusbar scripts, you’ll need to also specify where you want to show it. Statusbar items can be modified with:

+

Statusbar items can also be added or removed via command. Note that when loading new statusbar scripts that add items, you will need to specify where you want to show the item and how it is aligned. This can be accomplished using the below commands:

 /STATUSBAR <name> ADD [-before | -after <item>] [-priority #] [-alignment left|right] <item>
  /STATUSBAR <name> REMOVE <item>
 
-

The item name with statusbar scripts is usually same as the script’s name. Script’s documentation should tell if this isn’t the case. So, to add mail.pl before the window activity item (see the list with /STATUSBAR window), use: /STATUSBAR window ADD -before act mail.

+

For statusbar scripts, the item name is usually equivalent to the script name. The documentation of the script ought to tell you if this is not the case. For example, to add mail.pl before the window activity item, use: /STATUSBAR window ADD -before act mail.

From 1f7de4c3bd8cb03af76c14aff71fc535ce9f23de Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 5 Oct 2017 11:31:33 +0200 Subject: [PATCH 0178/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 100d00cb..159f7124 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 10 +#define IRSSI_ABI_VERSION 11 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From e1e632d31e1d8efc3370db76ddcc4bda200e4d31 Mon Sep 17 00:00:00 2001 From: Robert Bisewski Date: Thu, 5 Oct 2017 22:47:15 -0500 Subject: [PATCH 0179/1198] correcting and expanding content of statusbar help text --- docs/help/in/statusbar.in | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/help/in/statusbar.in b/docs/help/in/statusbar.in index ac475dd5..7fff7fb8 100644 --- a/docs/help/in/statusbar.in +++ b/docs/help/in/statusbar.in @@ -5,22 +5,31 @@ %9Parameters:%9 - ENABLE: Enables the statusbar. - DISABLE: Disabled the statusbar. + ENABLE: Adds a statusbar to the list of statusbars. + DISABLE: Removes a statusbar from the list. RESET: Restores the default statusbar configuration. - TYPE: Identifies the type of statusbar. - PLACEMENT: Identifies the placement of the statusbar. - POSITION: Identifies the position of the statusbar. - VISIBLE: Identifies the visibility of the statusbar. - ADD: Adds a statusbar into the configuration. - REMOVE: Removes a statusbar from the configuration. + TYPE: Refers to the type of statusbar, for each split window + or only for the current root screen. + PLACEMENT: Refers to the placement of the statusbar, either at the + top or the bottom of the screen. + POSITION: Refers to the position of the statusbar. Represented as + an unsigned integer, with 0 implying the first position. + VISIBLE: Refers to the visibility of the statusbar or item. If set + to always it is visible on all screens, otherwise if set + to inactive or active then it is only visible on inactive + or active screens, respectively. + ADD: Adds an item to the specified statusbar. It can be set to + appear before/after another item and left/right aligned + to a specified position on the screen. + REMOVE: Removes an item from the specified statusbar. - The name of the statusbar; if no argument is given, the list of statusbars - will be displayed. + Where name refers to the name of the statusbar; if no argument is + given, the entire list of statusbars will be displayed. %9Description:%9 - Modified the attributes of the statusbar. + Allows adjustment of the attributes and items of a statusbar, as well + as where it is located and whether or not it is currently visible. %9Examples:%9 From 0883ff8d320be47336e05aa38cf11427bd79b3af Mon Sep 17 00:00:00 2001 From: Robert Bisewski Date: Fri, 6 Oct 2017 07:13:30 -0500 Subject: [PATCH 0180/1198] reverting changes to startup HOWTO --- docs/startup-HOWTO.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index fe317ad9..07a9f47c 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -635,7 +635,7 @@ separated by : from the actual proxy password.

12. Statusbar

-

/STATUSBAR displays a list of the current statusbars, along with their position and visibility:

+

/STATUSBAR displays a list of statusbars:

 Name                           Type   Placement Position Visible
  window                         window bottom    0        always
@@ -644,9 +644,9 @@ separated by : from the actual proxy password.

topic root top 1 always
-

/STATUSBAR <name> prints the statusbar settings (type, placement, position, visibility) as well as its items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to its default settings, or if the statusbar was created by you, it will be removed.

+

/STATUSBAR <name> prints the statusbar settings and it’s items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to it’s default settings, or if the statusbar was created by you, it will be removed.

-

The statusbar type can be either window or root. If the type is window, then a statusbar will be created for each split window, otherwise it will be created only once. Placement can be top or bottom, which refers to the top or bottom of the screen. Position is a number, the higher the value the lower it will appear in-screen. Visible can be always, active or inactive. Active/inactive is useful only with split windows; one split window is active and the rest are inactive. To adjust these settings, the following commands are available:

+

Type can be window or root, meaning if the statusbar should be created for each split window, or just once. Placement can be top or bottom. Position is a number, the higher the value the lower in screen it is. Visible can be always, active or inactive. Active/inactive is useful only with split windows, one split window is active and the rest are inactive. These settings can be changed with:

 /STATUSBAR <name> TYPE window|root
  /STATUSBAR <name> PLACEMENT top|bottom
@@ -654,10 +654,10 @@ separated by : from the actual proxy password.

/STATUSBAR <name> VISIBLE always|active|inactive
-

Statusbar items can also be added or removed via command. Note that when loading new statusbar scripts that add items, you will need to specify where you want to show the item and how it is aligned. This can be accomplished using the below commands:

+

When loading a new statusbar scripts, you’ll need to also specify where you want to show it. Statusbar items can be modified with:

 /STATUSBAR <name> ADD [-before | -after <item>] [-priority #] [-alignment left|right] <item>
  /STATUSBAR <name> REMOVE <item>
 
-

For statusbar scripts, the item name is usually equivalent to the script name. The documentation of the script ought to tell you if this is not the case. For example, to add mail.pl before the window activity item, use: /STATUSBAR window ADD -before act mail.

+

The item name with statusbar scripts is usually same as the script’s name. Script’s documentation should tell if this isn’t the case. So, to add mail.pl before the window activity item (see the list with /STATUSBAR window), use: /STATUSBAR window ADD -before act mail.

From 84bfea52af8776e13d754e2ee20387f07556fc90 Mon Sep 17 00:00:00 2001 From: Robert Bisewski Date: Fri, 6 Oct 2017 07:54:54 -0500 Subject: [PATCH 0181/1198] adjusting text content as per the pull-request discussion --- docs/help/in/statusbar.in | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/help/in/statusbar.in b/docs/help/in/statusbar.in index 7fff7fb8..13977891 100644 --- a/docs/help/in/statusbar.in +++ b/docs/help/in/statusbar.in @@ -6,15 +6,17 @@ %9Parameters:%9 ENABLE: Adds a statusbar to the list of statusbars. - DISABLE: Removes a statusbar from the list. + DISABLE: Removes a statusbar from the list. Note that for + built-in statusbars they can be enabled again should the + user wish to add back the default statusbars. RESET: Restores the default statusbar configuration. - TYPE: Refers to the type of statusbar, for each split window - or only for the current root screen. - PLACEMENT: Refers to the placement of the statusbar, either at the - top or the bottom of the screen. - POSITION: Refers to the position of the statusbar. Represented as - an unsigned integer, with 0 implying the first position. - VISIBLE: Refers to the visibility of the statusbar or item. If set + TYPE: Sets the type of statusbar, for each split window or only + for the current root screen. + PLACEMENT: Sets the placement of the statusbar, either at the top or + the bottom of the screen. + POSITION: Sets the position of the statusbar. Represented as a + number, with 0 implying the first position. + VISIBLE: Sets the visibility of the statusbar or item. If set to to always it is visible on all screens, otherwise if set to inactive or active then it is only visible on inactive or active screens, respectively. From 4b42eca7c57fdd3d5ded8d5b1d4c75d01fc28569 Mon Sep 17 00:00:00 2001 From: Robert Bisewski Date: Fri, 6 Oct 2017 07:58:27 -0500 Subject: [PATCH 0182/1198] minor word correction --- docs/help/in/statusbar.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/help/in/statusbar.in b/docs/help/in/statusbar.in index 13977891..7d64b816 100644 --- a/docs/help/in/statusbar.in +++ b/docs/help/in/statusbar.in @@ -17,8 +17,8 @@ POSITION: Sets the position of the statusbar. Represented as a number, with 0 implying the first position. VISIBLE: Sets the visibility of the statusbar or item. If set to - to always it is visible on all screens, otherwise if set - to inactive or active then it is only visible on inactive + always it is visible on all screens, otherwise if set to + inactive or active then it is only visible on inactive or active screens, respectively. ADD: Adds an item to the specified statusbar. It can be set to appear before/after another item and left/right aligned From 1fd285dccfd43b740e88f7f4e168132387d39843 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Oct 2017 14:58:47 +0200 Subject: [PATCH 0183/1198] refactor history to use history_entries list this allows access to the global history even when a using /window history named or /set window_history on, and you want to recall something from one of the other windows' histories. usage (default): ctrl+up/down --- src/fe-common/core/command-history.c | 187 +++++++++++++++++++++------ src/fe-common/core/command-history.h | 16 ++- src/fe-text/gui-readline.c | 28 ++++ src/perl/ui/Window.xs | 5 +- 4 files changed, 196 insertions(+), 40 deletions(-) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 55474b1b..5de76969 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -30,10 +30,93 @@ #include "command-history.h" /* command history */ +static GList *history_entries; static HISTORY_REC *global_history; static int window_history; static GSList *histories; +static HISTORY_ENTRY_REC *history_entry_new(HISTORY_REC *history, const char *text) +{ + HISTORY_ENTRY_REC *entry; + + entry = g_new0(HISTORY_ENTRY_REC, 1); + entry->text = g_strdup(text); + entry->history = history; + entry->time = time(NULL); + + return entry; +} + +static void history_entry_destroy(HISTORY_ENTRY_REC *entry) +{ + g_free((char *)entry->text); + g_free(entry); +} + +GList *command_history_list_last(HISTORY_REC *history) +{ + GList *link; + + link = g_list_last(history_entries); + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->prev; + } + + return link; +} + +GList *command_history_list_first(HISTORY_REC *history) +{ + GList *link; + + link = history_entries; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->next; + } + + return link; +} + +GList *command_history_list_prev(HISTORY_REC *history, GList *pos) +{ + GList *link; + + link = pos != NULL ? pos->prev : NULL; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->prev; + } + + return link; +} + +GList *command_history_list_next(HISTORY_REC *history, GList *pos) +{ + GList *link; + + link = pos != NULL ? pos->next : NULL; + while (link != NULL && history != NULL && ((HISTORY_ENTRY_REC *)link->data)->history != history) { + link = link->next; + } + + return link; +} + +static void command_history_clear_pos_for_unlink_func(HISTORY_REC *history, GList* link) +{ + if (history->pos == link) { + history->pos = command_history_list_next(history, link); + history->redo = 1; + } +} + +static void history_list_delete_link_and_destroy(GList *link) +{ + g_slist_foreach(histories, + (GFunc) command_history_clear_pos_for_unlink_func, link); + history_entry_destroy(link->data); + history_entries = g_list_delete_link(history_entries, link); +} + void command_history_add(HISTORY_REC *history, const char *text) { GList *link; @@ -41,21 +124,19 @@ void command_history_add(HISTORY_REC *history, const char *text) g_return_if_fail(history != NULL); g_return_if_fail(text != NULL); - link = g_list_last(history->list); - if (link != NULL && g_strcmp0(link->data, text) == 0) - return; /* same as previous entry */ + link = command_history_list_last(history); + if (link != NULL && g_strcmp0(((HISTORY_ENTRY_REC *)link->data)->text, text) == 0) + return; /* same as previous entry */ if (settings_get_int("max_command_history") < 1 || history->lines < settings_get_int("max_command_history")) history->lines++; else { - link = history->list; - g_free(link->data); - history->list = g_list_remove_link(history->list, link); - g_list_free_1(link); + link = command_history_list_first(history); + history_list_delete_link_and_destroy(link); } - history->list = g_list_append(history->list, g_strdup(text)); + history_entries = g_list_append(history_entries, history_entry_new(history, text)); } HISTORY_REC *command_history_find(HISTORY_REC *history) @@ -104,7 +185,44 @@ HISTORY_REC *command_history_current(WINDOW_REC *window) return global_history; } +static const char *command_history_prev_int(WINDOW_REC *window, const char *text, gboolean global) +{ + HISTORY_REC *history; + GList *pos; + + history = command_history_current(window); + pos = history->pos; + history->redo = 0; + + if (pos != NULL) { + /* don't go past the first entry (no wrap around) */ + GList *prev = command_history_list_prev(global ? NULL : history, history->pos); + if (prev != NULL) + history->pos = prev; + } else { + history->pos = command_history_list_last(global ? NULL : history); + } + + if (*text != '\0' && + (pos == NULL || g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) != 0)) { + /* save the old entry to history */ + command_history_add(history, text); + } + + return history->pos == NULL ? text : ((HISTORY_ENTRY_REC *)history->pos->data)->text; +} + const char *command_history_prev(WINDOW_REC *window, const char *text) +{ + return command_history_prev_int(window, text, FALSE); +} + +const char *command_global_history_prev(WINDOW_REC *window, const char *text) +{ + return command_history_prev_int(window, text, TRUE); +} + +static const char *command_history_next_int(WINDOW_REC *window, const char *text, gboolean global) { HISTORY_REC *history; GList *pos; @@ -112,40 +230,26 @@ const char *command_history_prev(WINDOW_REC *window, const char *text) history = command_history_current(window); pos = history->pos; - if (pos != NULL) { - /* don't go past the first entry (no wrap around) */ - if (history->pos->prev != NULL) - history->pos = history->pos->prev; - } else { - history->pos = g_list_last(history->list); - } + if (!(history->redo) && pos != NULL) + history->pos = command_history_list_next(global ? NULL : history, history->pos); + history->redo = 0; if (*text != '\0' && - (pos == NULL || g_strcmp0(pos->data, text) != 0)) { + (pos == NULL || g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) != 0)) { /* save the old entry to history */ command_history_add(history, text); } - - return history->pos == NULL ? text : history->pos->data; + return history->pos == NULL ? "" : ((HISTORY_ENTRY_REC *)history->pos->data)->text; } const char *command_history_next(WINDOW_REC *window, const char *text) { - HISTORY_REC *history; - GList *pos; + return command_history_next_int(window, text, FALSE); +} - history = command_history_current(window); - pos = history->pos; - - if (pos != NULL) - history->pos = history->pos->next; - - if (*text != '\0' && - (pos == NULL || g_strcmp0(pos->data, text) != 0)) { - /* save the old entry to history */ - command_history_add(history, text); - } - return history->pos == NULL ? "" : history->pos->data; +const char *command_global_history_next(WINDOW_REC *window, const char *text) +{ + return command_history_next_int(window, text, TRUE); } void command_history_clear_pos_func(HISTORY_REC *history, gpointer user_data) @@ -175,12 +279,17 @@ HISTORY_REC *command_history_create(const char *name) void command_history_clear(HISTORY_REC *history) { + GList *link, *next; + 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; + link = command_history_list_first(history); + while (link != NULL) { + next = command_history_list_next(history, link); + history_list_delete_link_and_destroy(link); + link = next; + } history->lines = 0; } @@ -264,8 +373,8 @@ static char *special_history_func(const char *text, void *item, int *free_ret) ret = NULL; history = command_history_current(window); - for (tmp = history->list; tmp != NULL; tmp = tmp->next) { - const char *line = tmp->data; + for (tmp = command_history_list_first(history); tmp != NULL; tmp = command_history_list_next(history, tmp)) { + const char *line = ((HISTORY_ENTRY_REC *)tmp->data)->text; if (match_wildcards(findtext, line)) { *free_ret = TRUE; @@ -289,6 +398,8 @@ void command_history_init(void) special_history_func_set(special_history_func); + history_entries = NULL; + global_history = command_history_create(NULL); read_settings(); @@ -308,4 +419,6 @@ void command_history_deinit(void) signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_history_destroy(global_history); + + g_list_free_full(history_entries, (GDestroyNotify) history_entry_destroy); } diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 45126092..ddc8f5e6 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -6,12 +6,19 @@ typedef struct { char *name; - GList *list, *pos; + GList *pos; int lines; int refcount; + int redo:1; } HISTORY_REC; +typedef struct { + const char *text; + HISTORY_REC *history; + time_t time; +} HISTORY_ENTRY_REC; + HISTORY_REC *command_history_find(HISTORY_REC *history); HISTORY_REC *command_history_find_name(const char *name); @@ -22,8 +29,15 @@ void command_history_deinit(void); void command_history_add(HISTORY_REC *history, const char *text); +GList *command_history_list_last(HISTORY_REC *history); +GList *command_history_list_first(HISTORY_REC *history); +GList *command_history_list_prev(HISTORY_REC *history, GList *pos); +GList *command_history_list_next(HISTORY_REC *history, GList *pos); + const char *command_history_prev(WINDOW_REC *window, const char *text); const char *command_history_next(WINDOW_REC *window, const char *text); +const char *command_global_history_prev(WINDOW_REC *window, const char *text); +const char *command_global_history_next(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 3688f15e..0528ed94 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -530,6 +530,28 @@ static void key_forward_history(void) g_free(line); } +static void key_backward_global_history(void) +{ + const char *text; + char *line; + + line = gui_entry_get_text(active_entry); + text = command_global_history_prev(active_win, line); + gui_entry_set_text(active_entry, text); + g_free(line); +} + +static void key_forward_global_history(void) +{ + const char *text; + char *line; + + line = gui_entry_get_text(active_entry); + text = command_global_history_next(active_win, line); + gui_entry_set_text(active_entry, text); + g_free(line); +} + static void key_beginning_of_line(void) { gui_entry_set_pos(active_entry, 0); @@ -1176,6 +1198,8 @@ void gui_readline_init(void) key_bind("key", NULL, "meta2-5C", "cright", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "meta2-1;5D", "cleft", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "meta2-1;5C", "cright", (SIGNAL_FUNC) key_combo); + key_bind("key", NULL, "meta2-1;5A", "cup", (SIGNAL_FUNC) key_combo); + key_bind("key", NULL, "meta2-1;5B", "cdown", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "meta2-1;3A", "mup", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "meta2-1;3B", "mdown", (SIGNAL_FUNC) key_combo); @@ -1217,6 +1241,8 @@ void gui_readline_init(void) /* history */ key_bind("backward_history", "Go back one line in the history", "up", NULL, (SIGNAL_FUNC) key_backward_history); key_bind("forward_history", "Go forward one line in the history", "down", NULL, (SIGNAL_FUNC) key_forward_history); + key_bind("backward_global_history", "Go back one line in the global history", "cup", NULL, (SIGNAL_FUNC) key_backward_global_history); + key_bind("forward_global_history", "Go forward one line in the global history", "cdown", NULL, (SIGNAL_FUNC) key_forward_global_history); /* line editing */ key_bind("backspace", "Delete the previous character", "backspace", NULL, (SIGNAL_FUNC) key_backspace); @@ -1310,6 +1336,8 @@ void gui_readline_deinit(void) key_unbind("backward_history", (SIGNAL_FUNC) key_backward_history); key_unbind("forward_history", (SIGNAL_FUNC) key_forward_history); + key_unbind("backward_global_history", (SIGNAL_FUNC) key_backward_global_history); + key_unbind("forward_global_history", (SIGNAL_FUNC) key_forward_global_history); key_unbind("backspace", (SIGNAL_FUNC) key_backspace); key_unbind("delete_character", (SIGNAL_FUNC) key_delete_character); diff --git a/src/perl/ui/Window.xs b/src/perl/ui/Window.xs index 8c994cc2..b8d68ad8 100644 --- a/src/perl/ui/Window.xs +++ b/src/perl/ui/Window.xs @@ -252,8 +252,9 @@ PREINIT: GList *tmp; PPCODE: rec = command_history_current(window); - for (tmp = rec->list; tmp != NULL; tmp = tmp->next) - XPUSHs(sv_2mortal(new_pv(tmp->data))); + for (tmp = command_history_list_first(rec); tmp != NULL; tmp = command_history_list_next(rec, tmp)) + XPUSHs(sv_2mortal(new_pv(((HISTORY_ENTRY_REC *)tmp->data)->text))); + #******************************* MODULE = Irssi::UI::Window PACKAGE = Irssi::Windowitem PREFIX = window_item_ From 16d68a86ca75b73c53aa81fe6d3d36361cb35b99 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Oct 2017 15:02:15 +0200 Subject: [PATCH 0184/1198] add two XSFuncs to manipulate command history entries it is possible to use Irssi::UI::Window::get_history_entries to save the history entries, load_history_entries to load entries into the command history and delete_history_entries to remove history entries (for example to remove history selectively) --- src/fe-common/core/command-history.c | 55 +++++++++++ src/fe-common/core/command-history.h | 2 + src/perl/ui/Window.xs | 139 +++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 5de76969..a6a800d3 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -168,6 +168,61 @@ HISTORY_REC *command_history_find_name(const char *name) return NULL; } +static int history_entry_after_time_sort(const HISTORY_ENTRY_REC *a, const HISTORY_ENTRY_REC *b) +{ + return a->time == b->time ? 1 : a->time - b->time; +} + +void command_history_load_entry(time_t history_time, HISTORY_REC *history, const char *text) +{ + HISTORY_ENTRY_REC *entry; + + g_return_if_fail(history != NULL); + g_return_if_fail(text != NULL); + + entry = g_new0(HISTORY_ENTRY_REC, 1); + entry->text = g_strdup(text); + entry->history = history; + entry->time = history_time; + + history->lines++; + + history_entries = g_list_insert_sorted(history_entries, entry, (GCompareFunc)history_entry_after_time_sort); +} + +static int history_entry_find_func(const HISTORY_ENTRY_REC *data, const HISTORY_ENTRY_REC *user_data) +{ + if ((user_data->time == -1 || (data->time == user_data->time)) && + (user_data->history == NULL || (data->history == user_data->history)) && + g_strcmp0(data->text, user_data->text) == 0) { + return 0; + } else { + return -1; + } +} + +gboolean command_history_delete_entry(time_t history_time, HISTORY_REC *history, const char *text) +{ + GList *link; + HISTORY_ENTRY_REC entry; + + g_return_val_if_fail(history != NULL, FALSE); + g_return_val_if_fail(text != NULL, FALSE); + + entry.text = text; + entry.history = history; + entry.time = history_time; + + link = g_list_find_custom(history_entries, &entry, (GCompareFunc)history_entry_find_func); + if (link != NULL) { + ((HISTORY_ENTRY_REC *)link->data)->history->lines--; + history_list_delete_link_and_destroy(link); + return TRUE; + } else { + return FALSE; + } +} + HISTORY_REC *command_history_current(WINDOW_REC *window) { HISTORY_REC *rec; diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index ddc8f5e6..dc4d46da 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -28,6 +28,8 @@ void command_history_init(void); void command_history_deinit(void); void command_history_add(HISTORY_REC *history, const char *text); +void command_history_load_entry(time_t time, HISTORY_REC *history, const char *text); +gboolean command_history_delete_entry(time_t history_time, HISTORY_REC *history, const char *text); GList *command_history_list_last(HISTORY_REC *history); GList *command_history_list_first(HISTORY_REC *history); diff --git a/src/perl/ui/Window.xs b/src/perl/ui/Window.xs index b8d68ad8..85e284bb 100644 --- a/src/perl/ui/Window.xs +++ b/src/perl/ui/Window.xs @@ -255,6 +255,145 @@ PPCODE: for (tmp = command_history_list_first(rec); tmp != NULL; tmp = command_history_list_next(rec, tmp)) XPUSHs(sv_2mortal(new_pv(((HISTORY_ENTRY_REC *)tmp->data)->text))); +void +window_get_history_entries(window) + Irssi::UI::Window window +PREINIT: + HISTORY_REC *rec; + HISTORY_ENTRY_REC *ent; + WINDOW_REC *win; + GList *tmp; + GSList *stmp; + HV *hv; +PPCODE: + rec = window == NULL ? NULL : command_history_current(window); + for (tmp = command_history_list_first(rec); tmp != NULL; tmp = command_history_list_next(rec, tmp)) { + hv = (HV*)sv_2mortal((SV*)newHV()); + ent = tmp->data; + hv_store(hv, "text", 4, newSVpv(ent->text, 0), 0); + hv_store(hv, "time", 4, newSViv(ent->time), 0); + if (ent->history == command_history_current(NULL)) { + hv_store(hv, "history", 7, newSV(0), 0); + hv_store(hv, "window", 6, newSV(0), 0); + } else { + if (ent->history->name == NULL) { + hv_store(hv, "history", 7, newSV(0), 0); + for (stmp = windows; stmp != NULL; stmp = stmp->next) { + win = stmp->data; + if (win->history == ent->history) { + hv_store(hv, "window", 6, newSViv(win->refnum), 0); + break; + } + } + } else { + hv_store(hv, "history", 7, new_pv(ent->history->name), 0); + hv_store(hv, "window", 6, newSV(0), 0); + } + } + XPUSHs(sv_2mortal(newRV_inc((SV*)hv))); + } + +void +window_load_history_entries(window, ...) + Irssi::UI::Window window +PREINIT: + HV *hv; + SV **sv; + HISTORY_REC *history; + WINDOW_REC *tmp; + const char *text; + long hist_time; + int i; +PPCODE: + for (i = 1; i < items; i++) { + if (!is_hvref(ST(i))) { + croak("Usage: Irssi::UI::Window::load_history_entries(window, hash...)"); + } + hv = hvref(ST(i)); + if (hv != NULL) { + tmp = NULL; + text = NULL; + hist_time = time(NULL); + history = command_history_current(NULL); + + sv = hv_fetch(hv, "text", 4, 0); + if (sv != NULL) text = SvPV_nolen(*sv); + sv = hv_fetch(hv, "time", 4, 0); + if (sv != NULL && SvOK(*sv)) hist_time = SvIV(*sv); + + if (window != NULL) { + history = command_history_current(window); + } else { + sv = hv_fetch(hv, "history", 7, 0); + if (sv != NULL && SvOK(*sv)) { + history = command_history_find_name(SvPV_nolen(*sv)); + } + + sv = hv_fetch(hv, "window", 6, 0); + if (sv != NULL && SvOK(*sv)) { + tmp = window_find_refnum(SvIV(*sv)); + if (tmp != NULL) { + history = tmp->history; + } + } + } + + if (text != NULL && history != NULL) { + command_history_load_entry(hist_time, history, text); + } + } + } + +void +window_delete_history_entries(window, ...) + Irssi::UI::Window window +PREINIT: + HV *hv; + SV **sv; + HISTORY_REC *history; + WINDOW_REC *tmp; + const char *text; + long hist_time; + int i; +PPCODE: + for (i = 1; i < items; i++) { + if (!is_hvref(ST(i))) { + croak("Usage: Irssi::UI::Window::delete_history_entries(window, hash...)"); + } + hv = hvref(ST(i)); + if (hv != NULL) { + tmp = NULL; + text = NULL; + hist_time = -1; + history = command_history_current(NULL); + + sv = hv_fetch(hv, "text", 4, 0); + if (sv != NULL) text = SvPV_nolen(*sv); + sv = hv_fetch(hv, "time", 4, 0); + if (sv != NULL && SvOK(*sv)) hist_time = SvIV(*sv); + + if (window != NULL) { + history = command_history_current(window); + } else { + sv = hv_fetch(hv, "history", 7, 0); + if (sv != NULL && SvOK(*sv)) { + history = command_history_find_name(SvPV_nolen(*sv)); + } + + sv = hv_fetch(hv, "window", 6, 0); + if (sv != NULL && SvOK(*sv)) { + tmp = window_find_refnum(SvIV(*sv)); + if (tmp != NULL) { + history = tmp->history; + } + } + } + + if (text != NULL && history != NULL) { + XPUSHs(boolSV(command_history_delete_entry(hist_time, history, text))); + } + } + } #******************************* MODULE = Irssi::UI::Window PACKAGE = Irssi::Windowitem PREFIX = window_item_ From deac66f33c0fb1d6914d15ce63bde3f030a9c06d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Oct 2017 15:31:52 +0200 Subject: [PATCH 0185/1198] add a key binding to erase history entries it is possible to delete the current history entry using the erase_history_entry key binding --- src/fe-common/core/command-history.c | 17 +++++++++++++++++ src/fe-common/core/command-history.h | 1 + src/fe-text/gui-readline.c | 13 +++++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index a6a800d3..32d7adaa 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -307,6 +307,23 @@ const char *command_global_history_next(WINDOW_REC *window, const char *text) return command_history_next_int(window, text, TRUE); } +const char *command_history_delete_current(WINDOW_REC *window, const char *text) +{ + HISTORY_REC *history; + GList *pos; + + history = command_history_current(window); + pos = history->pos; + + if (pos != NULL && g_strcmp0(((HISTORY_ENTRY_REC *)pos->data)->text, text) == 0) { + ((HISTORY_ENTRY_REC *)pos->data)->history->lines--; + history_list_delete_link_and_destroy(pos); + } + + history->redo = 0; + return history->pos == NULL ? "" : ((HISTORY_ENTRY_REC *)history->pos->data)->text; +} + void command_history_clear_pos_func(HISTORY_REC *history, gpointer user_data) { history->pos = NULL; diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index dc4d46da..ed093415 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -40,6 +40,7 @@ const char *command_history_prev(WINDOW_REC *window, const char *text); const char *command_history_next(WINDOW_REC *window, const char *text); const char *command_global_history_prev(WINDOW_REC *window, const char *text); const char *command_global_history_next(WINDOW_REC *window, const char *text); +const char *command_history_delete_current(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 0528ed94..b3a78396 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -552,6 +552,17 @@ static void key_forward_global_history(void) g_free(line); } +static void key_erase_history_entry(void) +{ + const char *text; + char *line; + + line = gui_entry_get_text(active_entry); + text = command_history_delete_current(active_win, line); + gui_entry_set_text(active_entry, text); + g_free(line); +} + static void key_beginning_of_line(void) { gui_entry_set_pos(active_entry, 0); @@ -1243,6 +1254,7 @@ void gui_readline_init(void) key_bind("forward_history", "Go forward one line in the history", "down", NULL, (SIGNAL_FUNC) key_forward_history); key_bind("backward_global_history", "Go back one line in the global history", "cup", NULL, (SIGNAL_FUNC) key_backward_global_history); key_bind("forward_global_history", "Go forward one line in the global history", "cdown", NULL, (SIGNAL_FUNC) key_forward_global_history); + key_bind("erase_history_entry", "Erase the currently active entry from the history", NULL, NULL, (SIGNAL_FUNC) key_erase_history_entry); /* line editing */ key_bind("backspace", "Delete the previous character", "backspace", NULL, (SIGNAL_FUNC) key_backspace); @@ -1338,6 +1350,7 @@ void gui_readline_deinit(void) key_unbind("forward_history", (SIGNAL_FUNC) key_forward_history); key_unbind("backward_global_history", (SIGNAL_FUNC) key_backward_global_history); key_unbind("forward_global_history", (SIGNAL_FUNC) key_forward_global_history); + key_unbind("erase_history_entry", (SIGNAL_FUNC) key_erase_history_entry); key_unbind("backspace", (SIGNAL_FUNC) key_backspace); key_unbind("delete_character", (SIGNAL_FUNC) key_delete_character); From 5da0b73a12b3b319a2c7d6b18657ec13d52b6476 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Oct 2017 15:31:59 +0200 Subject: [PATCH 0186/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 159f7124..a7eaa7cf 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 11 +#define IRSSI_ABI_VERSION 12 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 40ae8f5fa67cb7ec529f9fea5816fb8804c9bba8 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 7 Oct 2017 03:28:02 +0100 Subject: [PATCH 0187/1198] Limit capsicum rights to stdio. This requires FreeBSD fix (https://reviews.freebsd.org/D12622) to work properly. --- src/core/capsicum.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 3b0708cb..1c5c59da 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #define OPCODE_CONNECT 1 @@ -410,6 +411,13 @@ static void cmd_capsicum_enter(void) */ signal(SIGCHLD, SIG_IGN); + error = caph_limit_stdio(); + if (error != 0) { + g_warning("caph_limit_stdio(3) failed: %s", strerror(errno)); + signal_emit("capability mode failed", 1, strerror(errno)); + return; + } + error = cap_enter(); if (error != 0) { signal_emit("capability mode failed", 1, strerror(errno)); From 00c80cb6fcca40cfc421fe3fc181115ac4907191 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 7 Oct 2017 20:45:13 +0200 Subject: [PATCH 0188/1198] fix out of bounds read in compress_colors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported by Hanno Böck. Fixes GL#12 --- src/fe-common/core/themes.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 2b1459be..cb1cce8f 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -587,7 +587,7 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format) /* a normal character */ g_string_append_c(str, *format); format++; - } else { + } else if (format[1] != '\0') { /* %format */ format++; if (IS_OLD_FORMAT(*format, last_fg, last_bg)) { @@ -614,6 +614,11 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format) last_bg = '\0'; } format++; + } else { + /* % at end of string */ + format++; + g_string_append_c(str, '%'); + g_string_append_c(str, '%'); } } From 49ace3251b79a9e97c6e4d0bc640f9143dc71b90 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 8 Oct 2017 19:47:50 +0200 Subject: [PATCH 0189/1198] fix uaf in chanquery module the chanquery needs to be removed in any case if a channel rec is destroyed, regardless of any state Fixes GL#13 --- src/irc/core/channels-query.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 857ebaf0..d161aec1 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -125,15 +125,15 @@ static void query_remove_all(IRC_CHANNEL_REC *channel) rec->queries[n] = g_slist_remove(rec->queries[n], channel); rec->current_queries = g_slist_remove(rec->current_queries, channel); - query_check(channel->server); + if (!channel->server->disconnected) + query_check(channel->server); } static void sig_channel_destroyed(IRC_CHANNEL_REC *channel) { g_return_if_fail(channel != NULL); - if (IS_IRC_CHANNEL(channel) && !channel->server->disconnected && - !channel->synced) + if (IS_IRC_CHANNEL(channel)) query_remove_all(channel); } From 2edd816e7db13b4ac0b20df9bf7fe55ee7718215 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Sun, 8 Oct 2017 22:02:44 -0400 Subject: [PATCH 0190/1198] Fix segfault in query_remove_all It is possible for rec to be NULL in query_remove_all, resulting in a segfault. So return without doing anything if rec is NULL. --- src/irc/core/channels-query.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index d161aec1..d7dadf04 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -119,6 +119,7 @@ static void query_remove_all(IRC_CHANNEL_REC *channel) int n; rec = channel->server->chanqueries; + if (rec == NULL) return; /* remove channel from query lists */ for (n = 0; n < CHANNEL_QUERIES; n++) From 4ccff71f678f79da71713a29d8528812379bb584 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 9 Oct 2017 12:50:04 -0700 Subject: [PATCH 0191/1198] Set host to an empty string on error While investigating #317, I noticed that it was possible we would access an uninitialized buffer due to failing to check the return value of net_ip2host(). This is done in several places. To make such uses safe, set the host buffer to an empty string on error. It is possible callers could be improved by handling the error in each spot, but this gives us some safety. --- src/core/network.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/network.c b/src/core/network.c index 4494dbc6..8d9c6b06 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -489,7 +489,16 @@ int net_gethostbyaddr(IPADDR *ip, char **name) int net_ip2host(IPADDR *ip, char *host) { - return inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN) ? 0 : -1; + if (inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN)) { + return 0; + } + + // For callers that do not check our return value and pass in an + // uninitialized buffer assuming it will be set, ensure the buffer is a valid + // string. Ideally callers should check what we return and handle + // appropriately, but this at least gives us safety. + host[0] = '\0'; + return -1; } int net_host2ip(const char *host, IPADDR *ip) From cb5f3cba1f2b5dbad67bcc107f3fe4a1875cc52d Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 9 Oct 2017 13:14:34 -0700 Subject: [PATCH 0192/1198] Delete unused function net_ip_compare() --- src/core/network.c | 12 ------------ src/core/network.h | 3 --- 2 files changed, 15 deletions(-) diff --git a/src/core/network.c b/src/core/network.c index 4494dbc6..36e04c7a 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -60,18 +60,6 @@ IPADDR ip4_any = { #endif }; -int net_ip_compare(IPADDR *ip1, IPADDR *ip2) -{ - if (ip1->family != ip2->family) - return 0; - - if (ip1->family == AF_INET6) - return memcmp(&ip1->ip, &ip2->ip, sizeof(ip1->ip)) == 0; - - return memcmp(&ip1->ip, &ip2->ip, 4) == 0; -} - - static void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) { if (ip == NULL) { diff --git a/src/core/network.h b/src/core/network.h index d1582a2e..471ab2d8 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -33,9 +33,6 @@ extern IPADDR ip4_any; GIOChannel *g_io_channel_new(int handle); -/* returns 1 if IPADDRs are the same */ -int net_ip_compare(IPADDR *ip1, IPADDR *ip2); - int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); /* Connect to socket */ From 3b3939b146bb2f80182d572a2afc08ba405037a1 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 9 Oct 2017 13:14:59 -0700 Subject: [PATCH 0193/1198] Delete commented out CYGWIN define --- src/core/network.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/network.c b/src/core/network.c index 36e04c7a..38f4e65a 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -48,9 +48,6 @@ GIOChannel *g_io_channel_new(int handle) return chan; } -/* Cygwin need this, don't know others.. */ -/*#define BLOCKING_SOCKETS 1*/ - IPADDR ip4_any = { AF_INET, #if defined(IN6ADDR_ANY_INIT) From b8b90c76d4ea87d7e50c2a34fbc36ab732e3e89e Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 9 Oct 2017 13:20:44 -0700 Subject: [PATCH 0194/1198] Delete unused function net_connect() --- src/core/network.c | 34 ---------------------------------- src/core/network.h | 2 -- 2 files changed, 36 deletions(-) diff --git a/src/core/network.c b/src/core/network.c index 38f4e65a..52619e4f 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -98,40 +98,6 @@ static int sin_get_port(union sockaddr_union *so) so->sin.sin_port); } -/* Connect to socket */ -GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) -{ - IPADDR ip4, ip6, *ip; - - g_return_val_if_fail(addr != NULL, NULL); - - if (net_gethostbyname(addr, &ip4, &ip6) == -1) - return NULL; - - if (my_ip == NULL) { - /* prefer IPv4 addresses */ - ip = ip4.family != 0 ? &ip4 : &ip6; - } else if (IPADDR_IS_V6(my_ip)) { - /* my_ip is IPv6 address, use it if possible */ - if (ip6.family != 0) - ip = &ip6; - else { - my_ip = NULL; - ip = &ip4; - } - } else { - /* my_ip is IPv4 address, use it if possible */ - if (ip4.family != 0) - ip = &ip4; - else { - my_ip = NULL; - ip = &ip6; - } - } - - return net_connect_ip(ip, port, my_ip); -} - int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip) { union sockaddr_union so; diff --git a/src/core/network.h b/src/core/network.h index 471ab2d8..a02f0db9 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -35,8 +35,6 @@ GIOChannel *g_io_channel_new(int handle); int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); -/* Connect to socket */ -GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) G_GNUC_DEPRECATED; /* Connect to socket with ip address and SSL*/ GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server); /* Start TLS */ From 174adee9dd91c23615f79b979b3b3c5f72ad1240 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Tue, 10 Oct 2017 18:21:05 -0700 Subject: [PATCH 0195/1198] Always initialize the host string This also removes a wordy comment --- src/core/network.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/core/network.c b/src/core/network.c index 8d9c6b06..b38c9102 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -489,16 +489,8 @@ int net_gethostbyaddr(IPADDR *ip, char **name) int net_ip2host(IPADDR *ip, char *host) { - if (inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN)) { - return 0; - } - - // For callers that do not check our return value and pass in an - // uninitialized buffer assuming it will be set, ensure the buffer is a valid - // string. Ideally callers should check what we return and handle - // appropriately, but this at least gives us safety. host[0] = '\0'; - return -1; + return inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN) ? 0 : -1; } int net_host2ip(const char *host, IPADDR *ip) From 17b195021dc35b95b24c1cce6f2e891e0e6b85ec Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 Oct 2017 14:34:38 +0100 Subject: [PATCH 0196/1198] Bump default capsicum_port_max to 9999. This is needed for servers like ssl.efnet.org, which, per default config, listen on 9999. --- src/core/capsicum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 1c5c59da..945d3197 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -452,7 +452,7 @@ void capsicum_init(void) settings_add_bool("misc", "capsicum", FALSE); settings_add_str("misc", "capsicum_irclogs_path", "~/irclogs"); settings_add_int("misc", "capsicum_port_min", 6667); - settings_add_int("misc", "capsicum_port_max", 6697); + settings_add_int("misc", "capsicum_port_max", 9999); signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); From 87955b69cb82314becf1aa9f66c707705f517d0f Mon Sep 17 00:00:00 2001 From: Paul Townsend Date: Wed, 11 Oct 2017 21:33:14 +0100 Subject: [PATCH 0197/1198] Add alternate_nick as a network-specific property. --- docs/help/in/network.in | 1 + src/core/chatnet-rec.h | 1 + src/fe-common/irc/fe-ircnet.c | 11 ++++++++--- src/irc/core/irc-servers-setup.c | 9 ++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/help/in/network.in b/docs/help/in/network.in index 4c2eeed4..fbdaa0b4 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -11,6 +11,7 @@ REMOVE: Removes a network from your configuration. -nick: Specifies the nickname to use. + -alternate_nick Specifies the alternate nickname to use. -user: Specifies the user identity to use. -realname: Specifies the real name to use. -host: Specifies the hostname to use. diff --git a/src/core/chatnet-rec.h b/src/core/chatnet-rec.h index e3ed8aa0..96ef6914 100644 --- a/src/core/chatnet-rec.h +++ b/src/core/chatnet-rec.h @@ -4,6 +4,7 @@ int chat_type; /* chat_protocol_lookup(xx) */ char *name; char *nick; +char *alternate_nick; char *username; char *realname; diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index 24dad63f..8f1d2efd 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -48,6 +48,8 @@ static void cmd_network_list(void) g_string_truncate(str, 0); if (rec->nick != NULL) g_string_append_printf(str, "nick: %s, ", rec->nick); + if (rec->alternate_nick != NULL) + g_string_append_printf(str, "alternate_nick: %s, ", rec->alternate_nick); if (rec->username != NULL) g_string_append_printf(str, "username: %s, ", rec->username); if (rec->realname != NULL) @@ -114,6 +116,7 @@ static void cmd_network_add_modify(const char *data, gboolean add) rec->name = g_strdup(name); } else { if (g_hash_table_lookup(optlist, "nick")) g_free_and_null(rec->nick); + if (g_hash_table_lookup(optlist, "alternate_nick")) g_free_and_null(rec->alternate_nick); if (g_hash_table_lookup(optlist, "user")) g_free_and_null(rec->username); if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname); if (g_hash_table_lookup(optlist, "host")) { @@ -145,6 +148,8 @@ static void cmd_network_add_modify(const char *data, gboolean add) value = g_hash_table_lookup(optlist, "nick"); if (value != NULL && *value != '\0') rec->nick = g_strdup(value); + value = g_hash_table_lookup(optlist, "alternate_nick"); + if (value != NULL && *value != '\0') rec->alternate_nick = g_strdup(value); value = g_hash_table_lookup(optlist, "user"); if (value != NULL && *value != '\0') rec->username = g_strdup(value); value = g_hash_table_lookup(optlist, "realname"); @@ -175,7 +180,7 @@ static void cmd_network_add_modify(const char *data, gboolean add) cmd_params_free(free_arg); } -/* SYNTAX: NETWORK ADD|MODIFY [-nick ] [-user ] [-realname ] +/* SYNTAX: NETWORK ADD|MODIFY [-nick ] [-alternate_nick ] [-user ] [-realname ] [-host ] [-usermode ] [-autosendcmd ] [-querychans ] [-whois ] [-msgs ] [-kicks ] [-modes ] [-cmdspeed ] @@ -228,9 +233,9 @@ void fe_ircnet_init(void) command_bind("network remove", NULL, (SIGNAL_FUNC) cmd_network_remove); command_set_options("network add", "-kicks -msgs -modes -whois -cmdspeed " - "-cmdmax -nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); + "-cmdmax -nick -alternate_nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); command_set_options("network modify", "-kicks -msgs -modes -whois -cmdspeed " - "-cmdmax -nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); + "-cmdmax -nick -alternate_nick -user -realname -host -autosendcmd -querychans -usermode -sasl_mechanism -sasl_username -sasl_password"); } void fe_ircnet_deinit(void) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 6040d3a5..a51ce2e2 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -69,7 +69,14 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, return; g_return_if_fail(IS_IRCNET(ircnet)); - if (ircnet->nick != NULL) g_free_and_null(conn->alternate_nick); + if (ircnet->nick != NULL) { + g_free_and_null(conn->nick); + conn->nick = g_strdup(ircnet->nick); + } + if (ircnet->alternate_nick != NULL) { + g_free_and_null(conn->alternate_nick); + conn->alternate_nick = g_strdup(ircnet->alternate_nick); + } if (ircnet->usermode != NULL) { g_free_and_null(conn->usermode); conn->usermode = g_strdup(ircnet->usermode); From 1e66cbd62e231f8ae47589cf4f1c0c6c62bb7ca8 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 Oct 2017 23:13:06 +0100 Subject: [PATCH 0198/1198] Improve Capsicum stdio limits to fix terminal state on exit. --- src/core/capsicum.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 945d3197..5f2556ab 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -360,6 +360,38 @@ static void cmd_capsicum(const char *data, SERVER_REC *server, void *item) command_runsub("capsicum", data, server, item); } +/* + * The main difference between this and caph_limit_stdio(3) is that this + * one permits TIOCSETAW, which is requred for restoring the terminal state + * on exit. + */ +static int +limit_stdio_fd(int fd) +{ + cap_rights_t rights; + unsigned long cmds[] = { TIOCGETA, TIOCGWINSZ, TIOCSETAW, FIODTYPE }; + + cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT, CAP_FCNTL, + CAP_FSTAT, CAP_IOCTL, CAP_SEEK); + + if (cap_rights_limit(fd, &rights) < 0) { + g_warning("cap_rights_limit(3) failed: %s", strerror(errno)); + return (-1); + } + + if (cap_ioctls_limit(fd, cmds, nitems(cmds)) < 0) { + g_warning("cap_ioctls_limit(3) failed: %s", strerror(errno)); + return (-1); + } + + if (cap_fcntls_limit(fd, CAP_FCNTL_GETFL) < 0) { + g_warning("cap_fcntls_limit(3) failed: %s", strerror(errno)); + return (-1); + } + + return (0); +} + static void cmd_capsicum_enter(void) { u_int mode; @@ -411,9 +443,9 @@ static void cmd_capsicum_enter(void) */ signal(SIGCHLD, SIG_IGN); - error = caph_limit_stdio(); - if (error != 0) { - g_warning("caph_limit_stdio(3) failed: %s", strerror(errno)); + if (limit_stdio_fd(STDIN_FILENO) != 0 || + limit_stdio_fd(STDOUT_FILENO) != 0 || + limit_stdio_fd(STDERR_FILENO) != 0) { signal_emit("capability mode failed", 1, strerror(errno)); return; } From 5c0b4aeb0572827877654b65bb05fb7b37a3117a Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 Oct 2017 23:31:26 +0100 Subject: [PATCH 0199/1198] Sort Capsicum headers. --- src/core/capsicum.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 5f2556ab..5647a302 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -32,13 +32,14 @@ #include "settings.h" #include "signals.h" -#include +#include #include +#include #include #include #include -#include #include +#include #define OPCODE_CONNECT 1 #define OPCODE_GETHOSTBYNAME 2 From 9895e7b28a3767bbe4430cbffd3662b4ef92b37f Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 Oct 2017 23:52:36 +0100 Subject: [PATCH 0200/1198] Silence down a warning that would appear on "/away" in Capability mode. --- src/core/capsicum.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 5647a302..568b5542 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -183,6 +183,10 @@ void capsicum_mkdir_with_parents(const char *path, int mode) char *component, *copy, *tofree; int error, fd, newfd; + /* The directory already exists, nothing to do. */ + if (strcmp(path, irclogs_path) == 0) + return; + /* +1 is for the slash separating irclogs_path and the rest. */ if (strlen(path) <= irclogs_path_len + 1 || path[irclogs_path_len] != '/' || From 711b2d7df7da4a3010214909ed1b260c55f6befa Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 11 Oct 2017 23:53:41 +0100 Subject: [PATCH 0201/1198] Document that one needs to change the awaylog_file path for "/away" to work with Capsicum. --- docs/capsicum.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/capsicum.txt b/docs/capsicum.txt index 3093bfe5..a3a1b8a7 100644 --- a/docs/capsicum.txt +++ b/docs/capsicum.txt @@ -7,6 +7,7 @@ or the libraries it depends on. To make Irssi enter capability mode on startup, add capsicum = "yes"; +awaylog_file = "~/irclogs/away.log"; to your ~/.irssi/config and restart the client. Alternatively you can enter it "by hand", using the "/capsicum enter" command. From the security From da59fd7c2dd0641f623db2c67a244ddca3013d65 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Fri, 13 Oct 2017 18:28:26 -0700 Subject: [PATCH 0202/1198] Revert "Delete unused function net_ip_compare()" This reverts commit cb5f3cba1f2b5dbad67bcc107f3fe4a1875cc52d. --- src/core/network.c | 12 ++++++++++++ src/core/network.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/core/network.c b/src/core/network.c index 52619e4f..4963a542 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -57,6 +57,18 @@ IPADDR ip4_any = { #endif }; +int net_ip_compare(IPADDR *ip1, IPADDR *ip2) +{ + if (ip1->family != ip2->family) + return 0; + + if (ip1->family == AF_INET6) + return memcmp(&ip1->ip, &ip2->ip, sizeof(ip1->ip)) == 0; + + return memcmp(&ip1->ip, &ip2->ip, 4) == 0; +} + + static void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) { if (ip == NULL) { diff --git a/src/core/network.h b/src/core/network.h index a02f0db9..84f3a56c 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -33,6 +33,9 @@ extern IPADDR ip4_any; GIOChannel *g_io_channel_new(int handle); +/* returns 1 if IPADDRs are the same */ +int net_ip_compare(IPADDR *ip1, IPADDR *ip2); + int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); /* Connect to socket with ip address and SSL*/ From 233be9f580290ff3efa66e6256e46303b01781da Mon Sep 17 00:00:00 2001 From: Will Storey Date: Fri, 13 Oct 2017 18:30:57 -0700 Subject: [PATCH 0203/1198] Mark net_ip_compare() deprecated --- src/core/network.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/network.h b/src/core/network.h index 84f3a56c..e60f607f 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -33,8 +33,9 @@ extern IPADDR ip4_any; GIOChannel *g_io_channel_new(int handle); -/* returns 1 if IPADDRs are the same */ -int net_ip_compare(IPADDR *ip1, IPADDR *ip2); +/* Returns 1 if IPADDRs are the same. */ +/* Deprecated since it is unused. It will be deleted in a later release. */ +int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED; int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); From 7b94015f8f3a7f9f9348a57243632a98cb5e2a56 Mon Sep 17 00:00:00 2001 From: Paul Townsend Date: Sat, 14 Oct 2017 17:42:45 +0100 Subject: [PATCH 0204/1198] Changes based on comments in pull #771. --- src/core/chatnet-rec.h | 1 - src/irc/core/irc-chatnets.c | 7 +++++++ src/irc/core/irc-chatnets.h | 1 + src/irc/core/irc-servers-setup.c | 4 ---- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/chatnet-rec.h b/src/core/chatnet-rec.h index 96ef6914..e3ed8aa0 100644 --- a/src/core/chatnet-rec.h +++ b/src/core/chatnet-rec.h @@ -4,7 +4,6 @@ int chat_type; /* chat_protocol_lookup(xx) */ char *name; char *nick; -char *alternate_nick; char *username; char *realname; diff --git a/src/irc/core/irc-chatnets.c b/src/irc/core/irc-chatnets.c index 0796e0cb..98ce89c3 100644 --- a/src/irc/core/irc-chatnets.c +++ b/src/irc/core/irc-chatnets.c @@ -43,6 +43,9 @@ static void sig_chatnet_read(IRC_CHATNET_REC *rec, CONFIG_NODE *node) value = config_node_get_str(node, "usermode", NULL); rec->usermode = (value != NULL && *value != '\0') ? g_strdup(value) : NULL; + value = config_node_get_str(node, "alternate_nick", NULL); + rec->alternate_nick = (value != NULL && *value != '\0') ? g_strdup(value) : NULL; + rec->max_cmds_at_once = config_node_get_int(node, "cmdmax", 0); rec->cmd_queue_speed = config_node_get_int(node, "cmdspeed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); @@ -65,6 +68,9 @@ static void sig_chatnet_saved(IRC_CHATNET_REC *rec, CONFIG_NODE *node) if (rec->usermode != NULL) iconfig_node_set_str(node, "usermode", rec->usermode); + if (rec->alternate_nick != NULL) + iconfig_node_set_str(node, "alternate_nick", rec->alternate_nick); + if (rec->max_cmds_at_once > 0) iconfig_node_set_int(node, "cmdmax", rec->max_cmds_at_once); if (rec->cmd_queue_speed > 0) @@ -93,6 +99,7 @@ static void sig_chatnet_destroyed(IRC_CHATNET_REC *rec) { if (IS_IRC_CHATNET(rec)) { g_free(rec->usermode); + g_free(rec->alternate_nick); g_free(rec->sasl_mechanism); g_free(rec->sasl_username); g_free(rec->sasl_password); diff --git a/src/irc/core/irc-chatnets.h b/src/irc/core/irc-chatnets.h index 2bb10fa9..3fd44472 100644 --- a/src/irc/core/irc-chatnets.h +++ b/src/irc/core/irc-chatnets.h @@ -18,6 +18,7 @@ struct _IRC_CHATNET_REC { #include "chatnet-rec.h" char *usermode; + char *alternate_nick; char *sasl_mechanism; char *sasl_username; diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index a51ce2e2..bae7d3b4 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -69,10 +69,6 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, return; g_return_if_fail(IS_IRCNET(ircnet)); - if (ircnet->nick != NULL) { - g_free_and_null(conn->nick); - conn->nick = g_strdup(ircnet->nick); - } if (ircnet->alternate_nick != NULL) { g_free_and_null(conn->alternate_nick); conn->alternate_nick = g_strdup(ircnet->alternate_nick); From 45dfe2ba3889c5dc23a9bea3214f158cc651a043 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 19 Oct 2017 11:17:56 +0200 Subject: [PATCH 0205/1198] Prevent a OOB read when parsing IRCNet ! channels Make sure the string has enough data. Fixes #16 --- src/irc/core/channel-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 6cb9b088..b0bddab2 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -37,7 +37,7 @@ static void check_join_failure(IRC_SERVER_REC *server, const char *channel) channel++; /* server didn't understand !channels */ chanrec = channel_find(SERVER(server), channel); - if (chanrec == NULL && channel[0] == '!') { + if (chanrec == NULL && channel[0] == '!' && strlen(channel) > 6) { /* it probably replied with the full !channel name, find the channel with the short name.. */ chan2 = g_strdup_printf("!%s", channel+6); From 9f0dc4766c7aa80e34aa2cde94323fb49971abdf Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 13 Oct 2017 17:54:57 +0200 Subject: [PATCH 0206/1198] fix dcc issue --- src/irc/dcc/dcc-chat.c | 21 +++++++++++++++++++++ src/irc/dcc/dcc-get.c | 17 +++++++++++++++-- src/irc/dcc/dcc-send.c | 10 ++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index ca90b8d8..88c577f7 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -66,6 +66,13 @@ CHAT_DCC_REC *dcc_chat_create(IRC_SERVER_REC *server, dcc->id = dcc_chat_get_new_id(nick); dcc_init_rec(DCC(dcc), server, chat, nick, arg); + if (dcc->module_data == NULL) { + /* failed to successfully init; TODO: change init_rec API */ + g_free(dcc->id); + g_free(dcc); + return NULL; + } + return dcc; } @@ -471,6 +478,7 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server) /* We are accepting a passive DCC CHAT. */ dcc_chat_passive(dcc); } + cmd_params_free(free_arg); return; } @@ -485,6 +493,11 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server) cmd_param_error(CMDERR_NOT_CONNECTED); dcc = dcc_chat_create(server, NULL, nick, "chat"); + if (dcc == NULL) { + cmd_params_free(free_arg); + g_warn_if_reached(); + return; + } if (g_hash_table_lookup(optlist, "passive") == NULL) { /* Standard DCC CHAT... let's listen for incoming connections */ @@ -627,6 +640,9 @@ static void ctcp_msg_dcc_chat(IRC_SERVER_REC *server, const char *data, } passive = paramcount == 4 && g_strcmp0(params[2], "0") == 0; + if (nick == NULL) + nick = ""; + dcc = DCC_CHAT(dcc_find_request(DCC_CHAT_TYPE, nick, NULL)); if (dcc != NULL) { if (dcc_is_listening(dcc)) { @@ -658,6 +674,11 @@ static void ctcp_msg_dcc_chat(IRC_SERVER_REC *server, const char *data, } dcc = dcc_chat_create(server, chat, nick, params[0]); + if (dcc == NULL) { + g_strfreev(params); + g_warn_if_reached(); + return; + } dcc->target = g_strdup(target); dcc->port = atoi(params[2]); diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 107f68fa..cecbb076 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -43,6 +43,12 @@ GET_DCC_REC *dcc_get_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat, dcc->fhandle = -1; dcc_init_rec(DCC(dcc), server, chat, nick, arg); + if (dcc->module_data == NULL) { + /* failed to successfully init; TODO: change API */ + g_free(dcc); + return NULL; + } + return dcc; } @@ -430,9 +436,10 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data, int p_id = -1; int passive = FALSE; - if (addr == NULL) { + if (addr == NULL) addr = ""; - } + if (nick == NULL) + nick = ""; /* SEND
[...] */ /* SEND
0 (DCC SEND passive protocol) */ @@ -512,6 +519,12 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data, dcc_destroy(DCC(dcc)); /* remove the old DCC */ dcc = dcc_get_create(server, chat, nick, fname); + if (dcc == NULL) { + g_free(address); + g_free(fname); + g_warn_if_reached(); + return; + } dcc->target = g_strdup(target); if (passive && port == 0) diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c index ca29b9b9..912129b7 100644 --- a/src/irc/dcc/dcc-send.c +++ b/src/irc/dcc/dcc-send.c @@ -237,6 +237,12 @@ static SEND_DCC_REC *dcc_send_create(IRC_SERVER_REC *server, dcc->queue = -1; dcc_init_rec(DCC(dcc), server, chat, nick, arg); + if (dcc->module_data == NULL) { + /* failed to successfully init; TODO: change API */ + g_free(dcc); + return NULL; + } + return dcc; } @@ -417,6 +423,10 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname, dcc = dcc_send_create(server, chat, target, str); g_free(str); + if (dcc == NULL) { + g_warn_if_reached(); + return FALSE; + } dcc->handle = handle; dcc->port = port; From 73d7b9d7753d35c63f24defe6d26c7c06ffa3cce Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 16 Oct 2017 16:21:10 -0400 Subject: [PATCH 0207/1198] Don't proceed with cmd_msg if there was an error splitting msg There may be cases (such as if target or server->nick is very long) where the split_message function returns NULL, indicating an error. To avoid a potential segfault, we now check to see if splitmsgs is NULL. --- src/core/chat-commands.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index d5a133f8..77f02aa2 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -404,7 +404,10 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) else splitmsgs = singlemsg; - while ((m = splitmsgs[n++])) { + /* splitmsgs may be NULL if there was an error */ + g_warn_if_fail(splitmsgs != NULL); + + while (splitmsgs && (m = splitmsgs[n++])) { signal_emit("server sendmsg", 4, server, target, m, GINT_TO_POINTER(target_type)); signal_emit(target_type == SEND_TARGET_CHANNEL ? From beb2beba3b4802c6969a5595197e25e7a5483fa3 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Wed, 18 Oct 2017 14:33:02 -0400 Subject: [PATCH 0208/1198] Revert "Don't proceed with cmd_msg if there was an error splitting msg" This reverts commit bd83852d646de28f2e0fe01efe7c9236aa4074d4. --- src/core/chat-commands.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 77f02aa2..d5a133f8 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -404,10 +404,7 @@ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) else splitmsgs = singlemsg; - /* splitmsgs may be NULL if there was an error */ - g_warn_if_fail(splitmsgs != NULL); - - while (splitmsgs && (m = splitmsgs[n++])) { + while ((m = splitmsgs[n++])) { signal_emit("server sendmsg", 4, server, target, m, GINT_TO_POINTER(target_type)); signal_emit(target_type == SEND_TARGET_CHANNEL ? From 0840eaec7bf56740029aae614e393f8cf76f6946 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Wed, 18 Oct 2017 14:52:04 -0400 Subject: [PATCH 0209/1198] Make split functions return an array with NULL instead of NULL This avoids undefined behavior in functions that call these split functions and expect an array back instead of just a NULL pointer. --- src/core/recode.c | 7 ++++++- src/irc/core/irc-servers.c | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/recode.c b/src/core/recode.c index d001a46a..d3fc91e7 100644 --- a/src/core/recode.c +++ b/src/core/recode.c @@ -198,7 +198,12 @@ char **recode_split(const SERVER_REC *server, const char *str, int n = 0; char **ret; - g_return_val_if_fail(str != NULL, NULL); + g_warn_if_fail(str != NULL); + if (str == NULL) { + ret = g_new(char *, 1); + ret[0] = NULL; + return ret; + } if (settings_get_bool("recode")) { to = find_conversion(server, target); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 3117e345..4eaab712 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -116,11 +116,14 @@ static char **split_line(const SERVER_REC *server, const char *line, * the code much simpler. It's worth it. */ len -= strlen(recoded_start) + strlen(recoded_end); + g_warn_if_fail(len > 0); if (len <= 0) { /* There is no room for anything. */ g_free(recoded_start); g_free(recoded_end); - return NULL; + lines = g_new(char *, 1); + lines[0] = NULL; + return lines; } lines = recode_split(server, line, target, len, onspace); From 956bc592a94d5f4cce03f5762f1976d98de637ef Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 21 Oct 2017 22:00:11 -0700 Subject: [PATCH 0210/1198] Fix a typo in the readme Also uppercase Irssi in a couple places, and escape an argument not shown due to looking like an HTML tag --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d6577fdf..8d91f4cb 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ think of currently: queries when msgs/notices are received or when you send a msg, closing queries when it's been idle for some time, etc. - - **Multiserver friendy** - I think Irssi has clearly the best support + - **Multiserver friendly** - I think Irssi has clearly the best support for handling multiple server connections. You can have as many as you want in as many ircnets as you want. Having several connections in one server works too, for example when you hit the (ircnet's) 10 @@ -84,7 +84,7 @@ think of currently: search command that jumps around in scrollback in GUI-style is still missing from Irssi, but there's something that's almost as good as it. /LASTLOG always shows timestamps when the line was printed, even if you - didn't have timestamps on. Now doing /SB GOTO jumps + didn't have timestamps on. Now doing /SB GOTO \ jumps directly to the position in scrollback you wanted. Great feature when you want to browse a bit of the discussion what happened when someone said your name (as seen in awaylog) or topic was changed (/last @@ -96,9 +96,9 @@ think of currently: - `startup-HOWTO.txt` - new users should read this - `manual.txt` - manual I started writing but didn't get it very far :) - `perl.txt` - Perl scripting help - - `formats.txt` - How to use colors, etc. with irssi + - `formats.txt` - How to use colors, etc. with Irssi - `faq.txt` - Frequently Asked Questions - - `special_vars.txt` - some predefined $variables you can use with irssi + - `special_vars.txt` - some predefined $variables you can use with Irssi ## Bugs / Suggestions From 816df6d153e937734bdac258ad6bf43173361451 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 22 Oct 2017 15:38:54 +0200 Subject: [PATCH 0211/1198] Merge tag '1.0.5' into integrate/1.0.5 --- NEWS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/NEWS b/NEWS index feb52275..cc301365 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,23 @@ v1.1-head 2017-xx-xx The Irssi team +v1.0.5 2017-10-23 The Irssi team + - Fix missing -sasl_method '' in /NETWORK (#718, #719). + - Fix incorrect restoration of term state when hitting SUSP + inside screen (#737, #733). + - Fix out of bounds read when compressing colour + sequences. Found by Hanno Böck (GL#12, GL!18). + - Fix use after free condition during a race condition when + waiting on channel sync during a rejoin (GL#13, GL!19). + - Fix null pointer dereference when parsing certain malformed + CTCP DCC messages (GL#14, GL!20). + - Fix crash due to null pointer dereference when failing to + split messages due to overlong nick or target (GL#15, GL!21). + - Fix out of bounds read when trying to skip a safe channel ID + without verifying that the ID is long enough (GL#16, GL!22). + - Fix return of random memory when inet_ntop failed (#769). + - Minor statusbar help update. By Robert Bisewski (#758, + #763). + v1.0.4 2017-07-07 The Irssi team - Fix null pointer dereference when parsing invalid timestamp (GL#10, GL!15). Reported by Brian 'geeknik' Carpenter. From 84fc92635acd4d513049794fdbc574b79ac1c5d5 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Tue, 24 Oct 2017 13:27:11 -0400 Subject: [PATCH 0212/1198] Add event_get_params to fe-fuzz --- .gitignore | 1 + configure.ac | 2 + src/fe-fuzz/Makefile.am | 2 + src/fe-fuzz/irc/Makefile.am | 1 + src/fe-fuzz/irc/core/Makefile.am | 46 +++++++++++++ src/fe-fuzz/irc/core/event-get-params.c | 86 +++++++++++++++++++++++++ 6 files changed, 138 insertions(+) create mode 100644 src/fe-fuzz/irc/Makefile.am create mode 100644 src/fe-fuzz/irc/core/Makefile.am create mode 100644 src/fe-fuzz/irc/core/event-get-params.c diff --git a/.gitignore b/.gitignore index 9af0c4b1..2f761710 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ docs/help/in/Makefile.am src/fe-text/irssi src/fe-fuzz/irssi-fuzz +src/fe-fuzz/irc/core/event-get-params-fuzz src/fe-common/irc/irc-modules.c src/irc/irc.c diff --git a/configure.ac b/configure.ac index 9c026c5d..92252672 100644 --- a/configure.ac +++ b/configure.ac @@ -648,6 +648,8 @@ src/fe-common/irc/Makefile src/fe-common/irc/dcc/Makefile src/fe-common/irc/notifylist/Makefile src/fe-fuzz/Makefile +src/fe-fuzz/irc/Makefile +src/fe-fuzz/irc/core/Makefile src/fe-none/Makefile src/fe-text/Makefile src/lib-config/Makefile diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index c11b3dbb..ae49f3df 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = irc + bin_PROGRAMS = irssi-fuzz # Force link with CXX for libfuzzer support diff --git a/src/fe-fuzz/irc/Makefile.am b/src/fe-fuzz/irc/Makefile.am new file mode 100644 index 00000000..52770885 --- /dev/null +++ b/src/fe-fuzz/irc/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = core diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am new file mode 100644 index 00000000..fa614abb --- /dev/null +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -0,0 +1,46 @@ +bin_PROGRAMS = event-get-params-fuzz + +# Force link with CXX for libfuzzer support +CCLD=$(CXX) $(CXXFLAGS) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core/ \ + -I$(top_srcdir)/src/irc/core/ \ + -I$(top_srcdir)/src/fe-common/core/ \ + $(GLIB_CFLAGS) + +AM_DEPENDENCIES = \ + ../../../core/libcore.a \ + ../../../lib-config/libirssi_config.a \ + ../../../irc/libirc.a \ + ../../../irc/core/libirc_core.a \ + ../../../irc/dcc/libirc_dcc.a \ + ../../../irc/flood/libirc_flood.a \ + ../../../irc/notifylist/libirc_notifylist.a \ + ../../../fe-common/core/libfe_common_core.a \ + ../../../fe-common/irc/libfe_common_irc.a \ + ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ + ../../../fe-common/irc/notifylist/libfe_irc_notifylist a + +LDADD = \ + ../../../irc/libirc.a \ + ../../../irc/core/libirc_core.a \ + ../../../irc/dcc/libirc_dcc.a \ + ../../../irc/flood/libirc_flood.a \ + ../../../irc/notifylist/libirc_notifylist.a \ + ../../../fe-common/core/libfe_common_core.a \ + ../../../fe-common/irc/libfe_common_irc.a \ + ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ + ../../../fe-common/irc/notifylist/libfe_irc_notifylist.a \ + ../../../core/libcore.a \ + ../../../lib-config/libirssi_config.a \ + @PROG_LIBS@ \ + $(FUZZER_LIBS) + +event_get_params_fuzz_SOURCES = \ + event-get-params.c \ + $(top_srcdir)/src/fe-text/module-formats.c + +noinst_HEADERS = \ + $(top_srcdir)/src/fe-text/module-formats.h diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c new file mode 100644 index 00000000..89eb89d2 --- /dev/null +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -0,0 +1,86 @@ +/* + event-get-params.c : irssi + + Copyright (C) 2017 Joseph Bisch + + 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 "module.h" +#include "modules-load.h" +#include "levels.h" +#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text +#include "themes.h" +#include "core.h" +#include "fe-common-core.h" +#include "args.h" +#include "printtext.h" +#include "irc.h" + +#include +#include +#include +#include + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + core_register_options(); + fe_common_core_register_options(); + /* no args */ + args_execute(0, NULL); + core_preinit((*argv)[0]); + core_init(); + fe_common_core_init(); + theme_register(gui_text_formats); + module_register("core", "fe-fuzz"); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + if (size < 1) { + return 0; + } + uint8_t count = *data; + char *copy = (char *)malloc(sizeof(char)*(size-1+1)); + memcpy(copy, data+1, size-1); + copy[size-1] = '\0'; + + char *output0; + char *output1; + char *output2; + char *output3; + char *params; + if (count % 8 == 0) { + params = event_get_params(copy, 1 | PARAM_FLAG_GETREST, &output0); + } else if (count % 8 == 1) { + params = event_get_params(copy, 2 | PARAM_FLAG_GETREST, &output0, &output1); + } else if (count % 8 == 2) { + params = event_get_params(copy, 3 | PARAM_FLAG_GETREST, &output0, &output1, &output2); + } else if (count % 8 == 3) { + params = event_get_params(copy, 4 | PARAM_FLAG_GETREST, &output0, &output1, &output2, &output3); + } else if (count % 8 == 4) { + params = event_get_params(copy, 1, &output0); + } else if (count % 8 == 5) { + params = event_get_params(copy, 2, &output0, &output1); + } else if (count % 8 == 6) { + params = event_get_params(copy, 3, &output0, &output1, &output2); + } else if (count % 8 == 7) { + params = event_get_params(copy, 4, &output0, &output1, &output2, &output3); + } else { + params = event_get_params(copy, 4, &output0, &output1, &output2, &output3); + } + g_free(params); + free(copy); + return 0; +} From 87550541e745627cc78507ce573d68b8453959c9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Oct 2017 22:04:13 +0200 Subject: [PATCH 0213/1198] fix key length checker to actually do some work --- autogen.sh | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/autogen.sh b/autogen.sh index 60eb4fb8..a9e354c9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -29,20 +29,6 @@ cat docs/help/in/Makefile.am.gen|sed "s/@HELPFILES@/$files/g"|sed 's/?/\\?/g'|tr files=`echo $files|sed 's/\.in//g'` cat docs/help/Makefile.am.gen|sed "s/@HELPFILES@/$files/g"|sed 's/?/\\?/g'|tr '!?' '\t\n' > docs/help/Makefile.am -# .html -> .txt with lynx or elinks -echo "Documentation: html -> txt..." -if type lynx >/dev/null 2>&1 ; then - LC_ALL=en_IE.utf8 lynx -dump docs/faq.html|perl -pe 's/^ *//; if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = " $_"; };' > docs/faq.txt -elif type elinks >/dev/null 2>&1 ; then - elinks -dump docs/faq.html|perl -pe 's/^ *//; if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = " $_"; };' > docs/faq.txt -elif type links >/dev/null 2>&1 ; then - links -dump docs/faq.html|perl -pe 's/^ *//; if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = " $_"; };' > docs/faq.txt -else - echo "**Error**: No lynx or elinks present" - echo "Install lynx or elinks, then run autogen.sh again" - exit 1 -fi - if test x$NOCONFIGURE = x && test -z "$*"; then echo "**Warning**: I am going to run \`configure' with no arguments." echo "If you wish to pass any to it, please specify them on the" @@ -65,4 +51,4 @@ else fi # make sure perl hashes have correct length -find src/perl -name *.c -o -name *.xs | xargs grep -n hv_store | perl -ne 'if (/"(\w+)",\s*(\d+)/) { print unless $2 == length $1 }' +find src/perl -name '*.c' -o -name '*.xs' -exec grep -n hv_store {} + | perl -l -ne 'if (/"(\w+)",\s*(\d+)/ && $2 != length $1) { $X=1; print "Incorrect key length in $_" } END { exit $X }' From 245bd5579cc680e8eeba4769da87bccb8a4d0de3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Oct 2017 22:12:34 +0200 Subject: [PATCH 0214/1198] remove lynx from autogen and make a separate syncdocs script --- .gitignore | 1 - docs/Makefile.am | 3 +- docs/faq.html | 4 +- docs/faq.txt | 124 +++++++ docs/startup-HOWTO.html | 512 ++++++++++++++------------ docs/startup-HOWTO.txt | 797 ++++++++++++++++++++++++++++++++++++++++ syncdocs.sh | 101 +++++ 7 files changed, 1295 insertions(+), 247 deletions(-) create mode 100644 docs/faq.txt create mode 100644 docs/startup-HOWTO.txt create mode 100755 syncdocs.sh diff --git a/.gitignore b/.gitignore index 9af0c4b1..efc579cb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ config.status configure default-config.h default-theme.h -faq.txt irssi-config irssi-config.h irssi-config.h.in diff --git a/docs/Makefile.am b/docs/Makefile.am index 32722391..8998ffb4 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -11,7 +11,8 @@ doc_DATA = \ perl.txt \ signals.txt \ special_vars.txt \ - startup-HOWTO.html + startup-HOWTO.html \ + startup-HOWTO.txt EXTRA_DIST = $(doc_DATA) $(man_MANS) diff --git a/docs/faq.html b/docs/faq.html index 345060dc..70e90bb5 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -1,4 +1,6 @@ +

Frequently Asked Questions

+

Q: Why doesn’t irssi display colors even when ircii etc. displays them?

A: They force ANSI colors even if terminal doesn’t support them. By default, irssi uses colors only if terminfo/termcap so says. The correct way to fix this would be to change your TERM environment to a value where colors work, like xterm-color or color_xterm (eg. TERM=xterm-color irssi). If this doesn’t help, then use the evil way of /SET term_force_colors ON.

@@ -77,4 +79,4 @@

Q: How to pronounce Irssi?

-

A: Check here

+

A: Check here

\ No newline at end of file diff --git a/docs/faq.txt b/docs/faq.txt new file mode 100644 index 00000000..719fbb9a --- /dev/null +++ b/docs/faq.txt @@ -0,0 +1,124 @@ + Frequently Asked Questions + +Q: Why doesn’t irssi display colors even when ircii etc. displays them? +A: They force ANSI colors even if terminal doesn’t support them. By default, + irssi uses colors only if terminfo/termcap so says. The correct way to fix this + would be to change your TERM environment to a value where colors work, like + xterm-color or color_xterm (eg. TERM=xterm-color irssi). If this doesn’t help, + then use the evil way of /SET term_force_colors ON. + +Q: How do I easily write text to channel that starts with ‘/’ character? +A: / /text + +Q: Why doesn’t irssi update my realname (or whatever) after I change it with / + SET realname and reconnect with /RECONNECT or /SERVER? +A: Irssi is trying to be too smart. This will be fixed in future, but for now + you should use /DISCONNECT and /CONNECT. + +Q: I connected to some server which isn’t responding but now irssi tries to + connect back to it all the time! How can I stop it? +A: Two ways. The “good way” to do it is with /DISCONNECT. Check the server tags + first with /SERVER without giving it any parameters, reconnections are those + that have tag starting with “recon” text. So most probably you’re going to do / + DISCONNECT recon-1. The other way is to remove all the reconnections with / + RMRECONNS, easier but may remove some connections you actually wanted to + reconnect (if you used multiple servers..). + +Q: How do I add seconds to timestamp? +A: /FORMAT timestamp {timestamp %%H:%%M:%%S} - and remember to add the trailing + space :) + +Q: Why does irssi say “Irssi: Channel not fully synchronized yet, try again + after a while” when I try to use /BAN etc? +A: Possibly a bug in irssi, or ircd you’re using does something that irssi + didn’t really notice. The new code should make this happen far less often than + before, but one known reason for this is when irssi doesn’t notice that you + were unable to join some channel. Currently however I don’t know of any such + events irssi doesn’t know about. + + Anyway, if this does happen, do /RAWLOG SAVE ~/rawlog soon after joining to + channel, and either try to figure out yourself why irssi didn’t get reply to + WHO request, or open a Github issue with the full log included. Note that the + rawlog is by default only 200 lines and it may not be enough to show all needed + information, so you might want to do /SET rawlog_lines 1000 or so. + + MODE +b still works fine though. + +Q: Where’s the GUI version? +A: There was one on [1]irssi-import/xirssi but it has not been maintained for a + long time. + +Q: How do I autorejoin channels after being kicked? +A: That’s evil and you shouldn’t do it. If you get kicked, you should stay out, + at least until the channel forgot you existed :) Most channels I’ve joined just + ban you if you autorejoin after kick. If you’re joined to channels who kick + people for fun, try changing channels or something. + + Anyway, if you REALLY want to do that, and you understand that you’re doing + evilness, you can use the autorejoin.pl script that comes with irssi. You’ll + still need to specify the channels you wish to rejoin with /SET + autorejoin_channels #chan1 #chan2 ... + +Q: How do I announce that I’m away/back in all channels I’ve joined? Or how do + I change my nick when setting myself away/back? +A: That’s even worse than autorejoin. Who could possibly care every time you + come and go? Many channels will kick you for using this, and I for example have + added several ignores so I’d never need to see these messages. Learn to use / + AWAY command properly and tell its existence to people who don’t know about it. + /WII yournick shows your away reason much better for people who actually want + to know if you’re there or not. + +Q: Why does irssi autojoin on invite by default? +A: The setting is /SET join_auto_chans_on_invite - it’s not the same as regular + autojoin-on-invite, which irssi doesn’t even have. The only channels that are + joined on invite, are the ones you’ve added to config with /CHANNEL ADD -auto. + This is very useful with +i channels when you need to first send an invite + request to bot, or if you get accidentally kicked from channel, the kicker can + invite you back immediately. + + I don’t see any bad side effects with this feature, so it’s ON by default. I + guess someone could start kicking/inviting you all the time but server + connection shouldn’t drop because of that, and you shouldn’t join channels + whose operators are that evil. + +Q: How to make UTF-8 support work with irssi? +A: Make sure your terminal supports UTF-8 (for example, xterm -u8). If you use + screen, you may have to do screen -U. And in Irssi do /SET term_charset utf-8. + (for 0.8.9 and older: /SET term_type utf-8) + +Q: Will there be /DETACH-like feature? +A: [2]tmux, [3]screen and [4]dtach can be used to do it just fine. + +Q: How do I run scripts automatically at startup? +A: Put them into ~/.irssi/scripts/autorun/ directory. Or better would be if you + placed them in ~/.irssi/scripts/ and created symlinks to autorun directory (eg. + cd ~/.irssi/scripts/autorun/ ; ln -s ../script.pl .) + +Q: How do I execute commands automatically at startup? +A: Put them into ~/.irssi/startup file, each command on its own line. The + preceding slash (/) is not necessary. + +Q: How do I easily edit existing topic? +A: /TOPIC + +Q: How can I have /WHOIS replies to active window? +A: You can disable the status window, or do /WINDOW LEVEL -CRAP in it which + would also make several other messages show up in active window. You can also + use a [5]script. + +Q: How do I add the active network to the statusbar +A: Modify the window-line in statusbar section in config file to window = "{sb + $winref:$tag/$T{sbmode $M}}"; + +Q: How to pronounce Irssi? +A: Check [6]here + + + References: + + [1] https://github.com/irssi-import/xirssi + [2] http://tmux.github.io/ + [3] http://www.gnu.org/software/screen/screen.html + [4] http://dtach.sf.net/ + [5] http://dgl.cx/irssi/hack-whois-in-current-window.pl + [6] https://irssi.org/assets/irssi.wav diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 07a9f47c..aaf9e5fe 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -1,4 +1,6 @@ -

Startup How-To

+ +

Startup How-To

+

To new Irssi users (not to new IRC users ..)

Copyright (c) 2000-2002 by Timo Sirainen, release under GNU FDL 1.1 license.

@@ -6,11 +8,7 @@

Index with some FAQ questions that are answered in the chapter:

    -
  1. For all the ircII people -
      -
    • This window management is just weird, I want it exactly like ircII
    • -
    -
  2. +
  3. First steps
  4. Basic user interface usage
    • Split windows work in weird way
    • @@ -50,7 +48,11 @@
  5. Proxies and IRC bouncers
  6. -
  7. Irssi’s settings
  8. +
  9. Irssi’s settings + +
  10. Statusbar
    • I loaded a statusbar script but it’s not visible anywhere!
    • @@ -58,169 +60,176 @@
-

1. For all the ircII people

+

1. First steps

-

These settings should give you pretty good defaults (the ones I use):

+

IRC Networks are made of servers, and servers have channels. The default config has a few predefined networks, to list them:

-

If colors don’t work, and you know you’re not going to use some weird non-VT compatible terminal (you most probably aren’t), just say:

+
/NETWORK LIST
+
-
 /SET term_force_colors ON
-
+

And to connect to one of those networks and join a channel:

-

I don’t like automatic query windows, I don’t like status window, I do like msgs window where all messages go:

+
/CONNECT Freenode
+/JOIN #irssi
+
-
 /SET autocreate_own_query OFF
- /SET autocreate_query_level DCCMSGS
- /SET use_status_window OFF
- /SET use_msgs_window ON
-
+

To add more networks:

-

Disable automatic window closing when /PARTing channel or /UNQUERYing query:

+
/NETWORK ADD ExampleNet
+
-
 /SET autoclose_windows OFF
- /SET reuse_unused_windows ON
-
+

Then add some servers (with -auto to automatically connect):

-

Here’s the settings that make irssi work exactly like ircII in window management (send me a note if you can think of more):

+
/SERVER ADD -auto -network ExampleNet irc.example.net
+
-
 /SET autocreate_own_query OFF
- /SET autocreate_query_level NONE
- /SET use_status_window OFF
- /SET use_msgs_window OFF
- /SET reuse_unused_windows ON
- /SET windows_auto_renumber OFF
+

Automatically join to channels after connected to server:

- /SET autostick_split_windows OFF - /SET autoclose_windows OFF - /SET print_active_channel ON -
+
/CHANNEL ADD -auto #lounge ExampleNet
+
-

And example how to add servers:

+

To modify existing networks (or servers, or channels) just ADD again using the same name as before. This configures a network to identify with nickserv and wait for 2 seconds before joining channels:

-

(OFTC network, identify with nickserv and wait for 2 seconds before joining channels)

+
/NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" ExampleNet
+
-
 /NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" OFTC
-
+

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-

(NOTE: use /IRCNET with 0.8.9 and older)

+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
+
-

Then add some servers to different networks (network is already set up for them), irc.kpnqwest.fi is used by default for IRCNet but if it fails, irc.funet.fi is tried next:

+

These commands have many more options, see their help for details:

-
 /SERVER ADD -auto -network IRCnet irc.kpnqwest.fi 6667
- /SERVER ADD -network IRCnet irc.funet.fi 6667
- /SERVER ADD -auto -network efnet efnet.cs.hut.fi 6667
-
- -

Automatically join to channels after connected to server, send op request to bot after joined to efnet/#irssi:

- -
 /CHANNEL ADD -auto #irssi IRCnet
- /CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet
-
+
/HELP NETWORK
+/HELP SERVER
+/HELP CHANNEL
+/HELP
+

If you want lines containing your nick to hilight:

-
 /HILIGHT nick
-
+
/HILIGHT nick
+
+ +

Or, for irssi 0.8.18 or higher:

+ +
/SET hilight_nick_matches_everywhere ON
+
+ +

To get beeps on private messages or highlights:

+ +
/SET beep_msg_level MSGS HILIGHT DCCMSGS
+
+ +

No other irssi settings are needed (don’t enable bell_beeps), but there may be settings to change in your terminal multiplexer (screen/tmux), your terminal, or your desktop environment.

2. Basic user interface usage

Windows can be scrolled up/down with PgUp and PgDown keys. If they don’t work for you, use Meta-p and Meta-n keys. For jumping to beginning or end of the buffer, use /SB HOME and /SB END commands.

-

By default, irssi uses “hidden windows” for everything. Hidden window is created every time you /JOIN a channel or /QUERY someone. There’s several ways you can change between these windows:

+

By default, irssi uses “hidden windows” for everything. Hidden windows are created every time you /JOIN a channel or /QUERY someone. There’s several ways you can change between these windows:

-
 Meta-1, Meta-2, .. Meta-0 - Jump directly between windows 1-10
- Meta-q .. Meta-o          - Jump directly between windows 11-19
- /WINDOW <number>          - Jump to any window with specified number
- Ctrl-P, Ctrl-N            - Jump to previous / next window
-
+
Meta-1, Meta-2, .. Meta-0 - Jump directly between windows 1-10
+Meta-q .. Meta-o          - Jump directly between windows 11-19
+/WINDOW <number>          - Jump to any window with specified number
+Ctrl-P, Ctrl-N            - Jump to previous / next window
+
-

Clearly the easiest way is to use Meta-number keys. And what is the Meta key? ESC key always works as Meta, but there’s also easier ways. ALT could work as Meta, or if you have Windows keyboard, left Windows key might work as Meta. If they don’t work directly, you’ll need to set a few X resources (NOTE: these work with both xterm and rxvt):

+

Clearly the easiest way is to use Meta-number keys. Meta usually means the ALT key, but if that doesn’t work, you can use ESC.

-
 XTerm*eightBitInput:   false
+

Mac OS X users with ALT key issues might prefer using iTerm2 instead of the default terminal emulator.

+ +

Alt key as meta, for xterm/rxvt users

+ +

If you use xterm or rxvt, you may need to set a few X resources:

+ +
 XTerm*eightBitInput:   false
  XTerm*metaSendsEscape: true
-
+

With rxvt, you can also specify which key acts as Meta key. So if you want to use ALT instead of Windows key for it, use:

-
 rxvt*modifier: alt
-
+
 rxvt*modifier: alt
+

You could do this by changing the X key mappings:

-
 xmodmap -e "keysym Alt_L = Meta_L Alt_L"
-
+
 xmodmap -e "keysym Alt_L = Meta_L Alt_L"
+

And how exactly do you set these X resources? For Debian, there’s /etc/X11/Xresources/xterm file where you can put them and it’s read automatically when X starts. ~/.Xresources and ~/.Xdefaults files might also work. If you can’t get anything else to work, just copy and paste those lines to ~/.Xresources and directly call xrdb -merge ~/.Xresources in some xterm. The resources affect only the new xterms you start, not existing ones.

-

Many windows SSH clients also don’t allow usage of ALT. One excellent client that does allow is putty, you can download it from http://www.chiark.greenend.org.uk/~sgtatham/putty/.

+

Split windows and window items

+ +

Note: this guide might be a better introduction to window splits

Irssi also supports split windows, they’ve had some problems in past but I think they should work pretty well now :) Here’s some commands related to them:

-
 /WINDOW NEW                    - Create new split window
- /WINDOW NEW HIDE               - Create new hidden window
- /WINDOW CLOSE                  - Close split or hidden window
+
/WINDOW NEW                    - Create new split window
+/WINDOW NEW HIDE               - Create new hidden window
+/WINDOW CLOSE                  - Close split or hidden window
 
- /WINDOW HIDE [<number>|<name>] - Make the split window hidden window
- /WINDOW SHOW <number>|<name>   - Make the hidden window a split window
+/WINDOW HIDE [<number>|<name>] - Make the split window hidden window
+/WINDOW SHOW <number>|<name>   - Make the hidden window a split window
 
- /WINDOW SHRINK [<lines>]       - Shrink the split window
- /WINDOW GROW [<lines>]         - Grow the split window
- /WINDOW BALANCE                - Balance the sizes of all split windows
-
+/WINDOW SHRINK [<lines>] - Shrink the split window +/WINDOW GROW [<lines>] - Grow the split window +/WINDOW BALANCE - Balance the sizes of all split windows +

By default, irssi uses “sticky windowing” for split windows. This means that windows created inside one split window cannot be moved to another split window without some effort. For example you could have following window layout:

-
 Split window 1: win#1 - Status window, win#2 - Messages window
+
 Split window 1: win#1 - Status window, win#2 - Messages window
  Split window 2: win#3 - IRCnet/#channel1, win#4 - IRCnet/#channel2
  Split window 3: win#5 - efnet/#channel1, win#6 - efnet/#channel2
-
+

When you are in win#1 and press ALT-6, irssi jumps to split window #3 and moves the efnet/#channel2 the active window.

With non-sticky windowing the windows don’t have any relationship with split windows, pressing ALT-6 in win#1 moves win#6 to split window 1 and sets it active, except if win#6 was already visible in some other split window irssi just changes to that split window. This it the way windows work with ircii, if you prefer it you can set it with

-
 /SET autostick_split_windows OFF
-
+
/SET autostick_split_windows OFF
+

Each window can have multiple channels, queries and other “window items” inside them. If you don’t like windows at all, you disable automatic creating of them with

-
 /SET autocreate_windows OFF
-
+
/SET autocreate_windows OFF
+

And if you keep all channels in one window, you most probably want the channel name printed in each line:

-
 /SET print_active_channel ON
-
+
/SET print_active_channel ON
+

If you want to group only some channels or queries in one window, use

-
 /JOIN -window #channel
- /QUERY -window nick
-
+
/JOIN -window #channel
+/QUERY -window nick
+

3. Server and channel automation

Irssi’s multiple IRC network support is IMHO very good - at least compared to other clients :) Even if you’re only in one IRC network you should group all your servers to be in the same IRC network as this helps with reconnecting if your primary server breaks and is probably useful in some other ways too :) For information how to actually use irssi correctly with multiple servers see the chapter 6.

-

First you need to have your IRC network set, use /NETWORK command to see if it’s already there. If it isn’t, use /NETWORK ADD yournetwork. If you want to execute some commands automatically when you’re connected to some network, use -autosendcmd option. (NOTE: use /IRCNET with 0.8.9 and older.) Here’s some examples:

+

First you need to have your IRC network set, use /NETWORK command to see if it’s already there. If it isn’t, use /NETWORK ADD yournetwork. If you want to execute some commands automatically when you’re connected to some network, use -autosendcmd option. Here’s some examples:

-
 /NETWORK ADD -autosendcmd '^msg bot invite' IRCnet
- /NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" OFTC
-
+
/NETWORK ADD -autosendcmd '^msg bot invite' IRCnet
+/NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" OFTC
+

After that you need to add your servers. For example:

-
 /SERVER ADD -auto -network IRCnet irc.kpnqwest.fi 6667
- /SERVER ADD -auto -network worknet irc.mycompany.com 6667 password
-
+
/SERVER ADD -auto -network IRCnet irc.kpnqwest.fi 6667
+/SERVER ADD -auto -network worknet irc.mycompany.com 6667 password
+

The -auto option specifies that this server is automatically connected at startup. You don’t need to make more than one server with -auto option to one IRC network, other servers are automatically connected in same network if the -auto server fails.

And finally channels:

-
 /CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet
- /CHANNEL ADD -auto #secret IRCnet password
-
+
/CHANNEL ADD -auto -bots *!*user@host -botcmd "/^msg $0 op pass" #irssi efnet
+/CHANNEL ADD -auto #secret IRCnet password
+

-bots and -botcmd should be the only ones needing a bit of explaining. They’re used to send commands automatically to bot when channel is joined, usually to get ops automatically. You can specify multiple bot masks with -bots option separated with spaces (and remember to quote the string then). The $0 in -botcmd specifies the first found bot in the list. If you don’t need the bot masks (ie. the bot is always with the same nick, like chanserv) you can give only the -botcmd option and the command is always sent.

@@ -228,9 +237,9 @@

First connect to all the servers, join the channels and create the queries you want. If you want to move the windows or channels around use commands:

-
 /WINDOW MOVE LEFT/RIGHT/number    - move window elsewhere
- /WINDOW ITEM MOVE <number>|<name> - move channel/query to another window
-
+
/WINDOW MOVE LEFT/RIGHT/number    - move window elsewhere
+/WINDOW ITEM MOVE <number>|<name> - move channel/query to another window
+

When everything looks the way you like, use /LAYOUT SAVE command (and /SAVE, if you don’t have autosaving enabled) and when you start irssi next time, irssi remembers the positions of the channels, queries and everything. This “remembering” doesn’t mean that simply using /LAYOUT SAVE would automatically make irssi reconnect to all servers and join all channels, you’ll need the /SERVER ADD -auto and /CHANNEL ADD -auto commands to do that.

@@ -240,32 +249,32 @@

By default, all the “extra messages” go to status window. This means pretty much all messages that don’t clearly belong to some channel or query. Some people like it, some don’t. If you want to remove it, use

-
 /SET use_status_window OFF
-
+
/SET use_status_window OFF
+

This doesn’t have any effect until you restart irssi. If you want to remove it immediately, just /WINDOW CLOSE it.

Another common window is “messages window”, where all private messages go. By default it’s disabled and query windows are created instead. To make all private messages go to msgs window, say:

-
 /SET use_msgs_window ON
- /SET autocreate_query_level DCCMSGS  (or if you don't want queries to
+
/SET use_msgs_window ON
+/SET autocreate_query_level DCCMSGS  (or if you don't want queries to
  				      dcc chats either, say NONE)
-
+

use_msgs_window either doesn’t have any effect until restarting irssi. To create it immediately say:

-
 /WINDOW NEW HIDE     - create the window
- /WINDOW NAME (msgs)  - name it to "(msgs)"
- /WINDOW LEVEL MSGS   - make all private messages go to this window
- /WINDOW MOVE 1       - move it to first window
-
+
/WINDOW NEW HIDE     - create the window
+/WINDOW NAME (msgs)  - name it to "(msgs)"
+/WINDOW LEVEL MSGS   - make all private messages go to this window
+/WINDOW MOVE 1       - move it to first window
+

Note that neither use_msgs_window nor use_status_window have any effect at all if /LAYOUT SAVE has been used.

This brings us to message levels.. What are they? All messages that irssi prints have one or more “message levels”. Most common are PUBLIC for public messages in channels, MSGS for private messages and CRAP for all sorts of messages with no real classification. You can get a whole list of levels with

-
 /HELP levels
-
+
/HELP levels
+

Status window has message level ALL -MSGS, meaning that all messages, except private messages, without more specific place go to status window. The -MSGS is there so it doesn’t conflict with messages window.

@@ -273,15 +282,15 @@

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

-
 /CONNECT irc.server.org
-
+
/CONNECT irc.server.org
+

Instead of the /SERVER which disconnects the existing connection. To see list of all active connections, use /SERVER without any parameters. You should see a list of something like:

-
 -!- IRCNet: irc.song.fi:6667 (IRCNet)
+
 -!- IRCNet: irc.song.fi:6667 (IRCNet)
  -!- OFTC: irc.oftc.net:6667 (OFTC)
  -!- RECON-1: 192.168.0.1:6667 () (02:59 left before reconnecting)
-
+

Here you see that we’re connected to IRCNet and OFTC networks. The IRCNet at the beginning is called the “server tag” while the (IRCnet) at the end shows the IRC network. Server tag specifies unique tag to refer to the server, usually it’s the same as the IRC network. When the IRC network isn’t known it’s some part of the server name. When there’s multiple connections to same IRC network or server, irssi adds a number after the tag so there could be network, network2, network3 etc.

@@ -289,63 +298,63 @@

To disconnect one of the servers, or to stop irssi from reconnecting, use

-
 /DISCONNECT network   - disconnect server with tag "network"
- /DISCONNECT recon-1  - stop trying to reconnect to RECON-1 server
- /RMRECONNS           - stop all server reconnections
+
/DISCONNECT network   - disconnect server with tag "network"
+/DISCONNECT recon-1  - stop trying to reconnect to RECON-1 server
+/RMRECONNS           - stop all server reconnections
 
- /RECONNECT recon-1   - immediately try reconnecting back to RECON-1
- /RECONNECT ALL       - immediately try reconnecting back to all
+/RECONNECT recon-1   - immediately try reconnecting back to RECON-1
+/RECONNECT ALL       - immediately try reconnecting back to all
  		       servers in reconnection queue
-
+

Now that you’re connected to all your servers, you’ll have to know how to specify which one of them you want to use. One way is to have an empty window, like status or msgs window. In it, you can specify which server to set active with

-
 /WINDOW SERVER tag    - set server "tag" active
- Ctrl-X                - set the next server in list active
-
+
/WINDOW SERVER tag    - set server "tag" active
+Ctrl-X                - set the next server in list active
+

When the server is active, you can use it normally. When there’s multiple connected servers, irssi adds [servertag] prefix to all messages in non-channel/query messages so you’ll know where it came from.

Several commands also accept -servertag option to specify which server it should use:

-
 /MSG -tag nick message
- /JOIN -tag #channel
- /QUERY -tag nick
-
+
/MSG -tag nick message
+/JOIN -tag #channel
+/QUERY -tag nick
+

/MSG tab completion also automatically adds the -tag option when nick isn’t in active server.

Window’s server can be made sticky. When sticky, it will never automatically change to anything else, and if server gets disconnected, the window won’t have any active server. When the server gets connected again, it is automatically set active in the window. To set the window’s server sticky use

-
 /WINDOW SERVER -sticky tag
-
+
/WINDOW SERVER -sticky tag
+

This is useful if you wish to have multiple status or msgs windows, one for each server. Here’s how to do them (repeat for each server)

-
 /WINDOW NEW HIDE
- /WINDOW NAME (status)
- /WINDOW LEVEL ALL -MSGS
- /WINDOW SERVER -sticky network
+
/WINDOW NEW HIDE
+/WINDOW NAME (status)
+/WINDOW LEVEL ALL -MSGS
+/WINDOW SERVER -sticky network
 
- /WINDOW NEW HIDE
- /WINDOW NAME (msgs)
- /WINDOW LEVEL MSGS
- /WINDOW SERVER -sticky network
-
+/WINDOW NEW HIDE +/WINDOW NAME (msgs) +/WINDOW LEVEL MSGS +/WINDOW SERVER -sticky network +

7. /LASTLOG and jumping around in scrollback

/LASTLOG command can be used for searching texts in scrollback buffer. Simplest usages are

-
 /LASTLOG word     - print all lines with "word" in them
- /LASTLOG word 10  - print last 10 occurances of "word"
- /LASTLOG -topics  - print all topic changes
-
+
/LASTLOG word     - print all lines with "word" in them
+/LASTLOG word 10  - print last 10 occurances of "word"
+/LASTLOG -topics  - print all topic changes
+

If there’s more than 1000 lines to be printed, irssi thinks that you probably made some mistake and won’t print them without -force option. If you want to save the full lastlog to file, use

-
 /LASTLOG -file ~/irc.log
-
+
/LASTLOG -file ~/irc.log
+

With -file option you don’t need -force even if there’s more than 1000 lines. /LASTLOG has a lot of other options too, see /HELP lastlog for details.

@@ -355,29 +364,29 @@

Irssi can automatically log important messages when you’re set away (/AWAY reason). When you set yourself unaway (/AWAY), the new messages in away log are printed to screen. You can configure it with:

-
 /SET awaylog_level MSGS HILIGHT     - Specifies what messages to log
- /SET awaylog_file ~/.irssi/away.log - Specifies the file to use
-
+
/SET awaylog_level MSGS HILIGHT     - Specifies what messages to log
+/SET awaylog_file ~/.irssi/away.log - Specifies the file to use
+

Easiest way to start logging with Irssi is to use autologging. With it Irssi logs all channels and private messages to specified directory. You can turn it on with

-
 /SET autolog ON
-
+
/SET autolog ON
+

By default it logs pretty much everything execept CTCPS or CRAP (/WHOIS requests, etc). You can specify the logging level yourself with

-
 /SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default)
-
+
/SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default)
+

By default irssi logs to ~/irclogs//.log. You can change this with

-
 /SET autolog_path ~/irclogs/$tag/$0.log (this is the default)
-
+
/SET autolog_path ~/irclogs/$tag/$0.log (this is the default)
+

The path is automatically created if it doesn’t exist. $0 specifies the target (channel/nick). You can make irssi automatically rotate the logs by adding date/time formats to the file name. The formats are in “man strftime” format. For example

-
 /SET autolog_path ~/irclogs/%Y/$tag/$0.%m-%d.log
-
+
/SET autolog_path ~/irclogs/%Y/$tag/$0.%m-%d.log
+

For logging only some specific channels or nicks, see /HELP log

@@ -387,16 +396,16 @@

/HELP bind tells pretty much everything there is to know about keyboard bindings. However, there’s the problem of how to bind some non-standard keys. They might differ a bit with each terminal, so you’ll need to find out what exactly the keypress produces. Easiest way to check that would be to see what it prints in cat. Here’s an example for pressing F1 key:

-
 [cras@hurina] ~% cat
+
 [user@host] ~% cat
  ^[OP
-
+

So in irssi you would use /BIND ^[OP /ECHO F1 pressed. If you use multiple terminals which have different bindings for the key, it would be better to use eg.:

-
 /BIND ^[OP key F1
- /BIND ^[11~ key F1
- /BIND F1 /ECHO F1 pressed.
-
+
/BIND ^[OP key F1
+/BIND ^[11~ key F1
+/BIND F1 /ECHO F1 pressed.
+

10. Proxies and IRC bouncers

@@ -404,20 +413,20 @@

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:

-
 /SET use_proxy ON
- /SET proxy_address irc.bouncer.org
- /SET proxy_port 5000
+
/SET use_proxy ON
+/SET proxy_address irc.bouncer.org
+/SET proxy_port 5000
 
- /SET proxy_password YOUR_BNC_PASSWORD_HERE
- /SET -clear proxy_string
- /SET proxy_string_after conn %s %d
-
+/SET proxy_password YOUR_BNC_PASSWORD_HERE +/SET -clear proxy_string +/SET proxy_string_after conn %s %d +

Then you’ll need to add the server connections. These are done exactly as if you’d want to connect directly to them. Nothing special about them:

-
 /SERVER ADD -auto -network dalnet irc.dal.net
- /SERVER ADD -auto -network efnet irc.efnet.org
-
+
/SERVER ADD -auto -network dalnet irc.dal.net
+/SERVER ADD -auto -network efnet irc.efnet.org
+

With the proxy /SETs however, irssi now connects to those servers through your BNC. All server connections are made through them so you can just forget that your bouncer even exists.

@@ -427,36 +436,36 @@

All proxies have these settings in common:

-
 /SET use_proxy ON
- /SET proxy_address <Proxy host address>
- /SET proxy_port <Proxy port>
-
+
/SET use_proxy ON
+/SET proxy_address <Proxy host address>
+/SET proxy_port <Proxy port>
+

HTTP proxy

Use these settings with HTTP proxies:

-
 /SET -clear proxy_password
- /EVAL SET proxy_string CONNECT %s:%d HTTP/1.0\n\n
-
+
/SET -clear proxy_password
+/EVAL SET proxy_string CONNECT %s:%d HTTP/1.0\n\n
+

BNC

-
 /SET proxy_password your_pass
- /SET -clear proxy_string
- /SET proxy_string_after conn %s %d
-
+
/SET proxy_password your_pass
+/SET -clear proxy_string
+/SET proxy_string_after conn %s %d
+

dircproxy

dircproxy separates the server connections by passwords. So, if you for example have network connection with password ircpass and OFTC connection with oftcpass, you would do something like this:

-
 /SET -clear proxy_password
- /SET -clear proxy_string
+
/SET -clear proxy_password
+/SET -clear proxy_string
 
- /SERVER ADD -auto -network IRCnet fake.network 6667 ircpass
- /SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass
-
+/SERVER ADD -auto -network IRCnet fake.network 6667 ircpass +/SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass +

The server name and port you give isn’t used anywhere, so you can put anything you want in there.

@@ -464,19 +473,17 @@

psyBNC has internal support for multiple servers. However, it could be a bit annoying to use, and some people just use different users for connecting to different servers. You can manage this in a bit same way as with dircproxy, by creating fake connections:

-
 /SET -clear proxy_password
- /SET -clear proxy_string
+
/SET -clear proxy_password
+/SET -clear proxy_string
 
- /NETWORK ADD -user networkuser IRCnet
- /SERVER ADD -auto -network IRCnet fake.network 6667 ircpass
- /NETWORK ADD -user oftcuser OFTC
- /SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass
-
+/NETWORK ADD -user networkuser IRCnet +/SERVER ADD -auto -network IRCnet fake.network 6667 ircpass +/NETWORK ADD -user oftcuser OFTC +/SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass +

So, you’ll specify the usernames with /NETWORK ADD command, and the user’s password with /SERVER ADD.

-

(NOTE: use /IRCNET with 0.8.9 and older.)

-

Irssi proxy

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.

@@ -487,65 +494,52 @@

Usage in proxy side:

-
 /LOAD proxy
- /SET irssiproxy_password <password>
- /SET irssiproxy_ports <network>=<port> ... (eg. IRCnet=2777 efnet=2778)
-
+
/LOAD proxy
+/SET irssiproxy_password <password>
+/SET irssiproxy_ports <network>=<port> ... (eg. IRCnet=2777 efnet=2778)
+

NOTE: you MUST add all the servers you are using to server and network lists with /SERVER ADD and /NETWORK ADD. ..Except if you really don’t want to for some reason, and you only use one server connection, you may simply set:

-
 /SET irssiproxy_ports *=2777
-
- -

The special network name ? allows the client to select the -network dynamically on connect (see below):

- -
-/SET irssiproxy_ports ?=2777
-
+
/SET irssiproxy_ports *=2777
+

Usage in client side:

Just connect to the irssi proxy like it is a normal server with password specified in /SET irssiproxy_password. For example:

-
 /SERVER ADD -network IRCnet my.irssi-proxy.org 2777 secret
- /SERVER ADD -network efnet my.irssi-proxy.org 2778 secret
-
- -

Or, if you used ? in irssiproxy_ports:

- -
-/SERVER ADD -network IRCnet my.irssi-proxy.org 2777 IRCnet:secret
-/SERVER ADD -network efnet my.irssi-proxy.org 2777 efnet:secret
-
- -

I.e. the network to connect to is specified as part of the password, -separated by : from the actual proxy password.

+
/SERVER ADD -network IRCnet my.irssi-proxy.org 2777 secret
+/SERVER ADD -network efnet my.irssi-proxy.org 2778 secret
+

Irssi proxy works fine with other IRC clients as well.

SOCKS

-

Irssi can be compiled with socks support (\--with-socks option to configure), but I don’t really know how it works, if at all. /SET proxy settings don’t have anything to do with socks however.

+

Irssi can be compiled with socks support (\--with-socks option to configure), which requires “dante” and routes all connections through the proxy specified in the system-wide /etc/socks.conf. This method is known to have issues in Mac OS X.

+ +

Note that /SET proxy settings don’t have anything to do with socks.

+ +

Using proxychains-ng is recommended over recompiling irssi.

Others

IRC bouncers usually work like IRC servers, and want a password. You can give it with:

-
 /SET proxy_password <password>
-
+
/SET proxy_password <password>
+

Irssi’s defaults for connect strings are

-
 /SET proxy_string CONNECT %s %d
- /SET proxy_string_after
-
+
/SET proxy_string CONNECT %s %d
+/SET proxy_string_after
+

The proxy_string is sent before NICK/USER commands, the proxy_string_after is sent after them. %s and %d can be used with both of them.

11. Irssi’s settings

-

You probably don’t like Irssi’s default settings. I don’t like them. But I’m still convinced that they’re pretty good defaults. Here’s some of them you might want to change (the default value is shown): Also check the Settings Documentation

+

Here’s some settings you might want to change (the default value is shown): Also check the Settings Documentation

Queries

@@ -633,31 +627,61 @@ separated by : from the actual proxy password.

Completion character to use.
+

For all the ircII people

+ +

I don’t like automatic query windows, I don’t like status window, I do like msgs window where all messages go:

+ +
/SET autocreate_own_query OFF
+/SET autocreate_query_level DCCMSGS
+/SET use_status_window OFF
+/SET use_msgs_window ON
+
+ +

Disable automatic window closing when /PARTing channel or /UNQUERYing query:

+ +
/SET autoclose_windows OFF
+/SET reuse_unused_windows ON
+
+ +

Here’s the settings that make irssi work exactly like ircII in window management (send me a note if you can think of more):

+ +
/SET autocreate_own_query OFF
+/SET autocreate_query_level NONE
+/SET use_status_window OFF
+/SET use_msgs_window OFF
+/SET reuse_unused_windows ON
+/SET windows_auto_renumber OFF
+
+/SET autostick_split_windows OFF
+/SET autoclose_windows OFF
+/SET print_active_channel ON
+
+

12. Statusbar

-

/STATUSBAR displays a list of statusbars:

+

/STATUSBAR displays a list of the current statusbars, along with their position and visibility:

-
 Name                           Type   Placement Position Visible
+
 Name                           Type   Placement Position Visible
  window                         window bottom    0        always
  window_inact                   window bottom    1        inactive
  prompt                         root   bottom    100      always
  topic                          root   top       1        always
-
+
-

/STATUSBAR <name> prints the statusbar settings and it’s items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to it’s default settings, or if the statusbar was created by you, it will be removed.

+

/STATUSBAR <name> prints the statusbar settings (type, placement, position, visibility) as well as its items. /STATUSBAR <name> ENABLE|DISABLE enables/disables the statusbar. /STATUSBAR <name> RESET resets the statusbar to its default settings, or if the statusbar was created by you, it will be removed.

-

Type can be window or root, meaning if the statusbar should be created for each split window, or just once. Placement can be top or bottom. Position is a number, the higher the value the lower in screen it is. Visible can be always, active or inactive. Active/inactive is useful only with split windows, one split window is active and the rest are inactive. These settings can be changed with:

+

The statusbar type can be either window or root. If the type is window, then a statusbar will be created for each split window, otherwise it will be created only once. Placement can be top or bottom, which refers to the top or bottom of the screen. Position is a number, the higher the value the lower it will appear in-screen. Visible can be always, active or inactive. Active/inactive is useful only with split windows; one split window is active and the rest are inactive. To adjust these settings, the following commands are available:

-
 /STATUSBAR <name> TYPE window|root
- /STATUSBAR <name> PLACEMENT top|bottom
- /STATUSBAR <name> POSITION <num>
- /STATUSBAR <name> VISIBLE always|active|inactive
-
+
/STATUSBAR <name> TYPE window|root
+/STATUSBAR <name> PLACEMENT top|bottom
+/STATUSBAR <name> POSITION <num>
+/STATUSBAR <name> VISIBLE always|active|inactive
+
-

When loading a new statusbar scripts, you’ll need to also specify where you want to show it. Statusbar items can be modified with:

+

Statusbar items can also be added or removed via command. Note that when loading new statusbar scripts that add items, you will need to specify where you want to show the item and how it is aligned. This can be accomplished using the below commands:

-
 /STATUSBAR <name> ADD [-before | -after <item>] [-priority #] [-alignment left|right] <item>
- /STATUSBAR <name> REMOVE <item>
-
+
/STATUSBAR <name> ADD [-before | -after <item>] [-priority #] [-alignment left|right] <item>
+/STATUSBAR <name> REMOVE <item>
+
-

The item name with statusbar scripts is usually same as the script’s name. Script’s documentation should tell if this isn’t the case. So, to add mail.pl before the window activity item (see the list with /STATUSBAR window), use: /STATUSBAR window ADD -before act mail.

+

For statusbar scripts, the item name is usually equivalent to the script name. The documentation of the script ought to tell you if this is not the case. For example, to add mail.pl before the window activity item, use: /STATUSBAR window ADD -before act mail.

\ No newline at end of file diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt new file mode 100644 index 00000000..23d7cf94 --- /dev/null +++ b/docs/startup-HOWTO.txt @@ -0,0 +1,797 @@ +Startup How-To + +To new Irssi users (not to new IRC users ..) + +Copyright (c) 2000-2002 by Timo Sirainen, release under [1]GNU FDL 1.1 license. + +Index with some FAQ questions that are answered in the chapter: + + 1. First steps + 2. Basic user interface usage + □ Split windows work in weird way + □ How can I easily switch between windows? + □ But alt-1 etc. don’t work! + 3. Server and channel automation + □ How do I automatically connect to servers at startup? + □ How do I automatically join to channels at startup? + □ How do I automatically send commands to server at connect? + 4. Setting up windows and automatically restoring them at startup + 5. Status and msgs windows & message levels + □ I want /WHOIS to print reply to current window + □ I want all messages to go to one window, not create new windows + 6. How support for multiple servers works in irssi + □ I connected to some server that doesn’t respond and now irssi keeps + trying to reconnect to it again and again, how can I stop it?? + □ I want to have own status and/or msgs window for each servers + 7. /LASTLOG and jumping around in scrollback + □ How can I save all texts in a window to file? + 8. Logging + 9. Changing keyboard bindings + □ How do I make F1 key do something? +10. Proxies and IRC bouncers +11. Irssi’s settings + □ For all the ircII people +12. Statusbar + □ I loaded a statusbar script but it’s not visible anywhere! + +1. First steps + +IRC Networks are made of servers, and servers have channels. The default config +has a few predefined networks, to list them: + +/NETWORK LIST + +And to connect to one of those networks and join a channel: + +/CONNECT Freenode +/JOIN #irssi + +To add more networks: + +/NETWORK ADD ExampleNet + +Then add some servers (with -auto to automatically connect): + +/SERVER ADD -auto -network ExampleNet irc.example.net + +Automatically join to channels after connected to server: + +/CHANNEL ADD -auto #lounge ExampleNet + +To modify existing networks (or servers, or channels) just ADD again using the +same name as before. This configures a network to identify with nickserv and +wait for 2 seconds before joining channels: + +/NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" ExampleNet + +If you have irssi 0.8.18 or higher and the irc network supports it, you can use +SASL instead of nickserv, which is more reliable: + +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode + +These commands have many more options, see their help for details: + +/HELP NETWORK +/HELP SERVER +/HELP CHANNEL +/HELP + +If you want lines containing your nick to hilight: + +/HILIGHT nick + +Or, for irssi 0.8.18 or higher: + +/SET hilight_nick_matches_everywhere ON + +To get beeps on private messages or highlights: + +/SET beep_msg_level MSGS HILIGHT DCCMSGS + +No other irssi settings are needed (don’t enable bell_beeps), but there may be +settings to change in your terminal multiplexer (screen/tmux), your terminal, +or your desktop environment. + +2. Basic user interface usage + +Windows can be scrolled up/down with PgUp and PgDown keys. If they don’t work +for you, use Meta-p and Meta-n keys. For jumping to beginning or end of the +buffer, use /SB HOME and /SB END commands. + +By default, irssi uses “hidden windows” for everything. Hidden windows are +created every time you /JOIN a channel or /QUERY someone. There’s several ways +you can change between these windows: + +Meta-1, Meta-2, .. Meta-0 - Jump directly between windows 1-10 +Meta-q .. Meta-o - Jump directly between windows 11-19 +/WINDOW - Jump to any window with specified number +Ctrl-P, Ctrl-N - Jump to previous / next window + +Clearly the easiest way is to use Meta-number keys. Meta usually means the ALT +key, but if that doesn’t work, you can use ESC. + +Mac OS X users with ALT key issues might prefer using [2]iTerm2 instead of the +default terminal emulator. + +Alt key as meta, for xterm/rxvt users + +If you use xterm or rxvt, you may need to set a few X resources: + + XTerm*eightBitInput: false + XTerm*metaSendsEscape: true + +With rxvt, you can also specify which key acts as Meta key. So if you want to +use ALT instead of Windows key for it, use: + + rxvt*modifier: alt + +You could do this by changing the X key mappings: + + xmodmap -e "keysym Alt_L = Meta_L Alt_L" + +And how exactly do you set these X resources? For Debian, there’s /etc/X11/ +Xresources/xterm file where you can put them and it’s read automatically when X +starts. ~/.Xresources and ~/.Xdefaults files might also work. If you can’t get +anything else to work, just copy and paste those lines to ~/.Xresources and +directly call xrdb -merge ~/.Xresources in some xterm. The resources affect +only the new xterms you start, not existing ones. + +Split windows and window items + +Note: [3]this guide might be a better introduction to window splits + +Irssi also supports split windows, they’ve had some problems in past but I +think they should work pretty well now :) Here’s some commands related to them: + +/WINDOW NEW - Create new split window +/WINDOW NEW HIDE - Create new hidden window +/WINDOW CLOSE - Close split or hidden window + +/WINDOW HIDE [|] - Make the split window hidden window +/WINDOW SHOW | - Make the hidden window a split window + +/WINDOW SHRINK [] - Shrink the split window +/WINDOW GROW [] - Grow the split window +/WINDOW BALANCE - Balance the sizes of all split windows + +By default, irssi uses “sticky windowing” for split windows. This means that +windows created inside one split window cannot be moved to another split window +without some effort. For example you could have following window layout: + + Split window 1: win#1 - Status window, win#2 - Messages window + Split window 2: win#3 - IRCnet/#channel1, win#4 - IRCnet/#channel2 + Split window 3: win#5 - efnet/#channel1, win#6 - efnet/#channel2 + +When you are in win#1 and press ALT-6, irssi jumps to split window #3 and moves +the efnet/#channel2 the active window. + +With non-sticky windowing the windows don’t have any relationship with split +windows, pressing ALT-6 in win#1 moves win#6 to split window 1 and sets it +active, except if win#6 was already visible in some other split window irssi +just changes to that split window. This it the way windows work with ircii, if +you prefer it you can set it with + +/SET autostick_split_windows OFF + +Each window can have multiple channels, queries and other “window items” inside +them. If you don’t like windows at all, you disable automatic creating of them +with + +/SET autocreate_windows OFF + +And if you keep all channels in one window, you most probably want the channel +name printed in each line: + +/SET print_active_channel ON + +If you want to group only some channels or queries in one window, use + +/JOIN -window #channel +/QUERY -window nick + +3. Server and channel automation + +Irssi’s multiple IRC network support is IMHO very good - at least compared to +other clients :) Even if you’re only in one IRC network you should group all +your servers to be in the same IRC network as this helps with reconnecting if +your primary server breaks and is probably useful in some other ways too :) For +information how to actually use irssi correctly with multiple servers see the +chapter 6. + +First you need to have your IRC network set, use /NETWORK command to see if +it’s already there. If it isn’t, use /NETWORK ADD yournetwork. If you want to +execute some commands automatically when you’re connected to some network, use +-autosendcmd option. Here’s some examples: + +/NETWORK ADD -autosendcmd '^msg bot invite' IRCnet +/NETWORK ADD -autosendcmd "/^msg nickserv ident pass;wait 2000" OFTC + +After that you need to add your servers. For example: + +/SERVER ADD -auto -network IRCnet irc.kpnqwest.fi 6667 +/SERVER ADD -auto -network worknet irc.mycompany.com 6667 password + +The -auto option specifies that this server is automatically connected at +startup. You don’t need to make more than one server with -auto option to one +IRC network, other servers are automatically connected in same network if the +-auto server fails. + +And finally channels: + +/CHANNEL ADD -auto -bots *!*user@host -botcmd "/^msg $0 op pass" #irssi efnet +/CHANNEL ADD -auto #secret IRCnet password + +-bots and -botcmd should be the only ones needing a bit of explaining. They’re +used to send commands automatically to bot when channel is joined, usually to +get ops automatically. You can specify multiple bot masks with -bots option +separated with spaces (and remember to quote the string then). The $0 in +-botcmd specifies the first found bot in the list. If you don’t need the bot +masks (ie. the bot is always with the same nick, like chanserv) you can give +only the -botcmd option and the command is always sent. + +4. Setting up windows and automatically restoring them at startup + +First connect to all the servers, join the channels and create the queries you +want. If you want to move the windows or channels around use commands: + +/WINDOW MOVE LEFT/RIGHT/number - move window elsewhere +/WINDOW ITEM MOVE | - move channel/query to another window + +When everything looks the way you like, use /LAYOUT SAVE command (and /SAVE, if +you don’t have autosaving enabled) and when you start irssi next time, irssi +remembers the positions of the channels, queries and everything. This +“remembering” doesn’t mean that simply using /LAYOUT SAVE would automatically +make irssi reconnect to all servers and join all channels, you’ll need the / +SERVER ADD -auto and /CHANNEL ADD -auto commands to do that. + +If you want to change the layout, you just rearrange the layout like you want +it and use /LAYOUT SAVE again. If you want to remove the layout for some +reason, use /LAYOUT RESET. + +5. Status and msgs windows & message levels + +By default, all the “extra messages” go to status window. This means pretty +much all messages that don’t clearly belong to some channel or query. Some +people like it, some don’t. If you want to remove it, use + +/SET use_status_window OFF + +This doesn’t have any effect until you restart irssi. If you want to remove it +immediately, just /WINDOW CLOSE it. + +Another common window is “messages window”, where all private messages go. By +default it’s disabled and query windows are created instead. To make all +private messages go to msgs window, say: + +/SET use_msgs_window ON +/SET autocreate_query_level DCCMSGS (or if you don't want queries to + dcc chats either, say NONE) + +use_msgs_window either doesn’t have any effect until restarting irssi. To +create it immediately say: + +/WINDOW NEW HIDE - create the window +/WINDOW NAME (msgs) - name it to "(msgs)" +/WINDOW LEVEL MSGS - make all private messages go to this window +/WINDOW MOVE 1 - move it to first window + +Note that neither use_msgs_window nor use_status_window have any effect at all +if /LAYOUT SAVE has been used. + +This brings us to message levels.. What are they? All messages that irssi +prints have one or more “message levels”. Most common are PUBLIC for public +messages in channels, MSGS for private messages and CRAP for all sorts of +messages with no real classification. You can get a whole list of levels with + +/HELP levels + +Status window has message level ALL -MSGS, meaning that all messages, except +private messages, without more specific place go to status window. The -MSGS is +there so it doesn’t conflict with messages window. + +6. How support for multiple servers works in irssi + +ircii and several other clients support multiple servers by placing the +connection into some window. IRSSI DOES NOT. There is no required relationship +between window and server. You can connect to 10 servers and manage them all in +just one window, or join channel in each one of them to one single window if +you really want to. That being said, here’s how you do connect to new server +without closing the old connection: + +/CONNECT irc.server.org + +Instead of the /SERVER which disconnects the existing connection. To see list +of all active connections, use /SERVER without any parameters. You should see a +list of something like: + + -!- IRCNet: irc.song.fi:6667 (IRCNet) + -!- OFTC: irc.oftc.net:6667 (OFTC) + -!- RECON-1: 192.168.0.1:6667 () (02:59 left before reconnecting) + +Here you see that we’re connected to IRCNet and OFTC networks. The IRCNet at +the beginning is called the “server tag” while the (IRCnet) at the end shows +the IRC network. Server tag specifies unique tag to refer to the server, +usually it’s the same as the IRC network. When the IRC network isn’t known it’s +some part of the server name. When there’s multiple connections to same IRC +network or server, irssi adds a number after the tag so there could be network, +network2, network3 etc. + +Server tags beginning with RECON- mean server reconnections. Above we see that +connection to server at 192.168.0.1 wasn’t successful and irssi will try to +connect it again in 3 minutes. + +To disconnect one of the servers, or to stop irssi from reconnecting, use + +/DISCONNECT network - disconnect server with tag "network" +/DISCONNECT recon-1 - stop trying to reconnect to RECON-1 server +/RMRECONNS - stop all server reconnections + +/RECONNECT recon-1 - immediately try reconnecting back to RECON-1 +/RECONNECT ALL - immediately try reconnecting back to all + servers in reconnection queue + +Now that you’re connected to all your servers, you’ll have to know how to +specify which one of them you want to use. One way is to have an empty window, +like status or msgs window. In it, you can specify which server to set active +with + +/WINDOW SERVER tag - set server "tag" active +Ctrl-X - set the next server in list active + +When the server is active, you can use it normally. When there’s multiple +connected servers, irssi adds [servertag] prefix to all messages in non-channel +/query messages so you’ll know where it came from. + +Several commands also accept -servertag option to specify which server it +should use: + +/MSG -tag nick message +/JOIN -tag #channel +/QUERY -tag nick + +/MSG tab completion also automatically adds the -tag option when nick isn’t in +active server. + +Window’s server can be made sticky. When sticky, it will never automatically +change to anything else, and if server gets disconnected, the window won’t have +any active server. When the server gets connected again, it is automatically +set active in the window. To set the window’s server sticky use + +/WINDOW SERVER -sticky tag + +This is useful if you wish to have multiple status or msgs windows, one for +each server. Here’s how to do them (repeat for each server) + +/WINDOW NEW HIDE +/WINDOW NAME (status) +/WINDOW LEVEL ALL -MSGS +/WINDOW SERVER -sticky network + +/WINDOW NEW HIDE +/WINDOW NAME (msgs) +/WINDOW LEVEL MSGS +/WINDOW SERVER -sticky network + +7. /LASTLOG and jumping around in scrollback + +/LASTLOG command can be used for searching texts in scrollback buffer. Simplest +usages are + +/LASTLOG word - print all lines with "word" in them +/LASTLOG word 10 - print last 10 occurances of "word" +/LASTLOG -topics - print all topic changes + +If there’s more than 1000 lines to be printed, irssi thinks that you probably +made some mistake and won’t print them without -force option. If you want to +save the full lastlog to file, use + +/LASTLOG -file ~/irc.log + +With -file option you don’t need -force even if there’s more than 1000 lines. / +LASTLOG has a lot of other options too, see /HELP lastlog for details. + +Once you’ve found the lines you were interested in, you might want to check the +discussion around them. Irssi has /SCROLLBACK (or alias /SB) command for +jumping around in scrollback buffer. Since /LASTLOG prints the timestamp when +the message was originally printed, you can use /SB GOTO hh:mm to jump directly +there. To get back to the bottom of scrollback, use /SB END command. + +8. Logging + +Irssi can automatically log important messages when you’re set away (/AWAY +reason). When you set yourself unaway (/AWAY), the new messages in away log are +printed to screen. You can configure it with: + +/SET awaylog_level MSGS HILIGHT - Specifies what messages to log +/SET awaylog_file ~/.irssi/away.log - Specifies the file to use + +Easiest way to start logging with Irssi is to use autologging. With it Irssi +logs all channels and private messages to specified directory. You can turn it +on with + +/SET autolog ON + +By default it logs pretty much everything execept CTCPS or CRAP (/WHOIS +requests, etc). You can specify the logging level yourself with + +/SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default) + +By default irssi logs to ~/irclogs//.log. You can change this with + +/SET autolog_path ~/irclogs/$tag/$0.log (this is the default) + +The path is automatically created if it doesn’t exist. $0 specifies the target +(channel/nick). You can make irssi automatically rotate the logs by adding date +/time formats to the file name. The formats are in “man strftime” format. For +example + +/SET autolog_path ~/irclogs/%Y/$tag/$0.%m-%d.log + +For logging only some specific channels or nicks, see /HELP log + +9. Changing keyboard bindings + +You can change any keyboard binding that terminal lets irssi know about. It +doesn’t let irssi know everything, so for example shift-backspace can’t be +bound unless you modify xterm resources somehow. + +/HELP bind tells pretty much everything there is to know about keyboard +bindings. However, there’s the problem of how to bind some non-standard keys. +They might differ a bit with each terminal, so you’ll need to find out what +exactly the keypress produces. Easiest way to check that would be to see what +it prints in cat. Here’s an example for pressing F1 key: + + [user@host] ~% cat + ^[OP + +So in irssi you would use /BIND ^[OP /ECHO F1 pressed. If you use multiple +terminals which have different bindings for the key, it would be better to use +eg.: + +/BIND ^[OP key F1 +/BIND ^[11~ key F1 +/BIND F1 /ECHO F1 pressed. + +10. Proxies and IRC bouncers + +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 /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: + +/SET use_proxy ON +/SET proxy_address irc.bouncer.org +/SET proxy_port 5000 + +/SET proxy_password YOUR_BNC_PASSWORD_HERE +/SET -clear proxy_string +/SET proxy_string_after conn %s %d + +Then you’ll need to add the server connections. These are done exactly as if +you’d want to connect directly to them. Nothing special about them: + +/SERVER ADD -auto -network dalnet irc.dal.net +/SERVER ADD -auto -network efnet irc.efnet.org + +With the proxy /SETs however, irssi now connects to those servers through your +BNC. All server connections are made through them so you can just forget that +your bouncer even exists. + +If you don’t want to use the proxy for some reason, there’s -noproxy option +which you can give to /SERVER and /SERVER ADD commands. + +Proxy specific settings: + +All proxies have these settings in common: + +/SET use_proxy ON +/SET proxy_address +/SET proxy_port + +HTTP proxy + +Use these settings with HTTP proxies: + +/SET -clear proxy_password +/EVAL SET proxy_string CONNECT %s:%d HTTP/1.0\n\n + +BNC + +/SET proxy_password your_pass +/SET -clear proxy_string +/SET proxy_string_after conn %s %d + +dircproxy + +dircproxy separates the server connections by passwords. So, if you for example +have network connection with password ircpass and OFTC connection with +oftcpass, you would do something like this: + +/SET -clear proxy_password +/SET -clear proxy_string + +/SERVER ADD -auto -network IRCnet fake.network 6667 ircpass +/SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass + +The server name and port you give isn’t used anywhere, so you can put anything +you want in there. + +psyBNC + +psyBNC has internal support for multiple servers. However, it could be a bit +annoying to use, and some people just use different users for connecting to +different servers. You can manage this in a bit same way as with dircproxy, by +creating fake connections: + +/SET -clear proxy_password +/SET -clear proxy_string + +/NETWORK ADD -user networkuser IRCnet +/SERVER ADD -auto -network IRCnet fake.network 6667 ircpass +/NETWORK ADD -user oftcuser OFTC +/SERVER ADD -auto -network OFTC fake.oftc 6667 oftcpass + +So, you’ll specify the usernames with /NETWORK ADD command, and the user’s +password with /SERVER ADD. + +Irssi proxy + +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? :) + +Irssi proxy supports sharing multiple server connections in different ports, +like you can share network in port 2777 and efnet in port 2778. + +Usage in proxy side: + +/LOAD proxy +/SET irssiproxy_password +/SET irssiproxy_ports = ... (eg. IRCnet=2777 efnet=2778) + +NOTE: you MUST add all the servers you are using to server and network lists +with /SERVER ADD and /NETWORK ADD. ..Except if you really don’t want to for +some reason, and you only use one server connection, you may simply set: + +/SET irssiproxy_ports *=2777 + +Usage in client side: + +Just connect to the irssi proxy like it is a normal server with password +specified in /SET irssiproxy_password. For example: + +/SERVER ADD -network IRCnet my.irssi-proxy.org 2777 secret +/SERVER ADD -network efnet my.irssi-proxy.org 2778 secret + +Irssi proxy works fine with other IRC clients as well. + +SOCKS + +Irssi can be compiled with socks support (\--with-socks option to configure), +which requires “dante” and routes all connections through the proxy specified +in the system-wide /etc/socks.conf. This method is known to have issues in Mac +OS X. + +Note that /SET proxy settings don’t have anything to do with socks. + +Using [4]proxychains-ng is recommended over recompiling irssi. + +Others + +IRC bouncers usually work like IRC servers, and want a password. You can give +it with: + +/SET proxy_password + +Irssi’s defaults for connect strings are + +/SET proxy_string CONNECT %s %d +/SET proxy_string_after + +The proxy_string is sent before NICK/USER commands, the proxy_string_after is +sent after them. %s and %d can be used with both of them. + +11. Irssi’s settings + +Here’s some settings you might want to change (the default value is shown): +Also check the [5]Settings Documentation + +Queries + +/SET autocreate_own_query ON + Should new query window be created when you send message to someone (with / + MSG). +/SET autocreate_query_level MSGS + New query window should be created when receiving messages with this level. + MSGS, DCCMSGS and NOTICES levels work currently. You can disable this with + /SET -clear autocreate_query_level. +/SET autoclose_query 0 + Query windows can be automatically closed after certain time of inactivity. + Queries with unread messages aren’t closed and active window is neither + never closed. The value is given in seconds. + +Windows + +/SET use_msgs_window OFF + Create messages window at startup. All private messages go to this window. + This only makes sense if you’ve disabled automatic query windows. Message + window can also be created manually with /WINDOW LEVEL MSGS, /WINDOW NAME + (msgs). +/SET use_status_window ON + Create status window at startup. All messages that don’t really have better + place go here, like all /WHOIS replies etc. Status window can also be + created manually with /WINDOW LEVEL ALL -MSGS, /WINDOW NAME (status). +/SET autocreate_windows ON + Should we create new windows for new window items or just place everything + in one window +/SET autoclose_windows ON + Should window be automatically closed when the last item in them is removed + (ie. /PART, /UNQUERY). +/SET reuse_unused_windows OFF + When finding where to place new window item (channel, query) Irssi first + tries to use already existing empty windows. If this is set ON, new window + will always be created for all window items. This setting is ignored if + autoclose_windows is set ON. +/SET window_auto_change OFF + Should Irssi automatically change to automatically created windows - + usually queries when someone sends you a message. To prevent accidentally + sending text meant to some other channel/nick, Irssi clears the input + buffer when changing the window. The text is still in scrollback buffer, + you can get it back with pressing arrow up key. +/SET print_active_channel OFF + When you keep more than one channel in same window, Irssi prints the + messages coming to active channel as text and other channels as + text. If this setting is set ON, the messages to active + channels are also printed in the latter way. +/SET window_history OFF + Should command history be kept separate for each window. + +User information + +/SET nick + Your nick name +/SET alternate_nick + Your alternate nick. +/SET user_name + Your username, if you have ident enabled this doesn’t affect anything +/SET real_name + Your real name. + +Server information + +/SET skip_motd OFF + Should we hide server’s MOTD (Message Of The Day). +/SET server_reconnect_time 300 + Seconds to wait before connecting to same server again. Don’t set this too + low since it usually doesn’t help at all - if the host is down, the few + extra minutes of waiting won’t hurt much. +/SET lag_max_before_disconnect 300 + Maximum server lag in seconds before disconnecting and trying to reconnect. + This happens mostly only when network breaks between you and IRC server. + +Appearance + +/SET timestamps ON + Show timestamps before each message. +/SET hide_text_style OFF + Hide all bolds, underlines, MIRC colors, etc. +/SET show_nickmode ON + Show the nick’s mode before nick in channels, ie. ops have <@nick>, voices + <+nick> and others < nick> +/SET show_nickmode_empty ON + If the nick doesn’t have a mode, use one space. ie. ON: < nick>, OFF: + +/SET show_quit_once OFF + Show quit message only once in some of the channel windows the nick was in + instead of in all windows. +/SET lag_min_show 100 + Show the server lag in status bar if it’s bigger than this, the unit is 1/ + 100 of seconds (ie. the default value of 100 = 1 second). +/SET indent 10 + When lines are longer than screen width they have to be split to multiple + lines. This specifies how much space to put at the beginning of the line + before the text begins. This can be overridden in text formats with %| + format. +/SET activity_hide_targets + If you don’t want to see window activity in some certain channels or + queries, list them here. For example #boringchannel =bot1 =bot2. If any + highlighted text or message for you appears in that window, this setting is + ignored and the activity is shown. + +Nick completion + +/SET completion_auto OFF + Automatically complete the nick if line begins with start of nick and the + completion character. Learn to use the tab-completion instead, it’s a lot + better ;) +/SET completion_char : + Completion character to use. + +For all the ircII people + +I don’t like automatic query windows, I don’t like status window, I do like +msgs window where all messages go: + +/SET autocreate_own_query OFF +/SET autocreate_query_level DCCMSGS +/SET use_status_window OFF +/SET use_msgs_window ON + +Disable automatic window closing when /PARTing channel or /UNQUERYing query: + +/SET autoclose_windows OFF +/SET reuse_unused_windows ON + +Here’s the settings that make irssi work exactly like ircII in window +management (send me a note if you can think of more): + +/SET autocreate_own_query OFF +/SET autocreate_query_level NONE +/SET use_status_window OFF +/SET use_msgs_window OFF +/SET reuse_unused_windows ON +/SET windows_auto_renumber OFF + +/SET autostick_split_windows OFF +/SET autoclose_windows OFF +/SET print_active_channel ON + +12. Statusbar + +/STATUSBAR displays a list of the current statusbars, along with their position +and visibility: + + Name Type Placement Position Visible + window window bottom 0 always + window_inact window bottom 1 inactive + prompt root bottom 100 always + topic root top 1 always + +/STATUSBAR prints the statusbar settings (type, placement, position, +visibility) as well as its items. /STATUSBAR ENABLE|DISABLE enables/ +disables the statusbar. /STATUSBAR RESET resets the statusbar to its +default settings, or if the statusbar was created by you, it will be removed. + +The statusbar type can be either window or root. If the type is window, then a +statusbar will be created for each split window, otherwise it will be created +only once. Placement can be top or bottom, which refers to the top or bottom of +the screen. Position is a number, the higher the value the lower it will appear +in-screen. Visible can be always, active or inactive. Active/inactive is useful +only with split windows; one split window is active and the rest are inactive. +To adjust these settings, the following commands are available: + +/STATUSBAR TYPE window|root +/STATUSBAR PLACEMENT top|bottom +/STATUSBAR POSITION +/STATUSBAR VISIBLE always|active|inactive + +Statusbar items can also be added or removed via command. Note that when +loading new statusbar scripts that add items, you will need to specify where +you want to show the item and how it is aligned. This can be accomplished using +the below commands: + +/STATUSBAR ADD [-before | -after ] [-priority #] [-alignment left|right] +/STATUSBAR REMOVE + +For statusbar scripts, the item name is usually equivalent to the script name. +The documentation of the script ought to tell you if this is not the case. For +example, to add mail.pl before the window activity item, use: /STATUSBAR window +ADD -before act mail. + + +References: + +[1] http://www.gnu.org/licenses/fdl.html +[2] https://www.iterm2.com/ +[3] http://quadpoint.org/articles/irssisplit/ +[4] https://github.com/rofl0r/proxychains-ng +[5] https://irssi.org/documentation/settings/ diff --git a/syncdocs.sh b/syncdocs.sh new file mode 100755 index 00000000..1187eec9 --- /dev/null +++ b/syncdocs.sh @@ -0,0 +1,101 @@ +#!/bin/sh -e +# Run this to download FAQ and startup-HOWTO from irssi.org + +PKG_NAME="Irssi" + +site=https://irssi.org + +faq=$site/documentation/faq/ +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{.*(?=\s*)?(\s*)?)}{\1\2}g;' + +srcdir=`dirname "$0"` +test -z "$srcdir" && srcdir=. + +if test ! -f "$srcdir"/configure.ac; then + echo -n "**Error**: Directory \`$srcdir' does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +fi + +# detect downloader app +downloader=false + +if type curl >/dev/null 2>&1 ; then + downloader="curl -Ssf" +elif type wget >/dev/null 2>&1 ; then + downloader="wget -nv -O-" +else + echo "**Error**: No wget or curl present" + echo "Install wget or curl, then run syncdocs.sh again" +fi + +# detect html converter app +converter=false +if [ "$1" = "-any" ]; then + any=true +else + any=false +fi + +if type w3m >/dev/null 2>&1 ; then + converter="w3m -o display_link_number=1 -dump -T text/html" + any=true +elif type lynx >/dev/null 2>&1 ; then + converter="lynx -dump -stdin -force_html" +elif type elinks >/dev/null 2>&1 ; then + converter="elinks -dump -force-html" +else + echo "**Error**: Neither w3m, nor lynx or elinks present" + echo "Install w3m, then run syncdocs.sh again" + exit 1 +fi + +if ! $any ; then + echo "**Error**: w3m not present" + echo "If you want to use lynx or elinks, run syncdocs.sh -any" + exit 1 +fi + +check_download() { + if test "$1" -ne 0 || test ! -e "$2" || test "$(wc -l "$2" | awk '{print $1}')" -le 1 ; then + rm -f "$2" + echo "... download failed ( $1 )" + exit 2 + fi +} + +download_it() { + echo "Downloading $1 from $2 ..." + ret=0 + $downloader "$2" > "$3".tmp || ret=$? + check_download "$ret" "$3".tmp + perl -i -0777 -p -e "$pageclean_regex" "$3".tmp + perl -i -0777 -p -e 's{\A}{'""'\n}' "$3".tmp + perl -i -0777 -p -e 's{\[email protected\]}{user\@host}g' "$3".tmp + mv "$3".tmp "$3" +} + +download_it "FAQ" "$faq" "$srcdir"/docs/faq.html +download_it "Startup How-To" "$howto" "$srcdir"/docs/startup-HOWTO.html + +# .html -> .txt with lynx or elinks +echo "Documentation: html -> txt..." + +cat "$srcdir"/docs/faq.html \ + | LC_ALL=en_IE.utf8 $converter \ + | perl -pe ' + s/^ *//; + if ($_ eq "\n" && $state eq "Q") { $_ = ""; } + elsif (/^([QA]):/) { $state = $1 } + elsif ($_ ne "\n") { $_ = " $_"; }; +' > docs/faq.txt + +cat "$srcdir"/docs/startup-HOWTO.html \ + | perl -pe "s/\\bhref=([\"\'])#.*?\\1//" \ + | LC_ALL=en_IE.utf8 $converter > "$srcdir"/docs/startup-HOWTO.txt From 9a3c0bce48d3f172d5638ecb37967528812129b1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Oct 2017 22:22:39 +0200 Subject: [PATCH 0215/1198] add a script to sync scripts as well --- syncscripts.sh | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 syncscripts.sh diff --git a/syncscripts.sh b/syncscripts.sh new file mode 100755 index 00000000..eee95a5e --- /dev/null +++ b/syncscripts.sh @@ -0,0 +1,38 @@ +#!/bin/sh -e +# Run this script to sync dual lived scripts from scripts.irssi.org to scripts/ + +PKG_NAME="Irssi" + +scriptbase=https://scripts.irssi.org/scripts + +srcdir=`dirname "$0"` +test -z "$srcdir" && srcdir=. + +if test ! -f "$srcdir"/configure.ac; then + echo -n "**Error**: Directory \`$srcdir' does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +fi + +dl2='curl -Ssf' + +dl_it() { + echo "$1" + $dl2 -o "$srcdir/scripts/$1" "$scriptbase/$1" +} + +for script in \ + autoop.pl \ + autorejoin.pl \ + buf.pl \ + dns.pl \ + kills.pl \ + mail.pl \ + mlock.pl \ + quitmsg.pl \ + scriptassist.pl \ + usercount.pl \ + ; +do + dl_it $script +done From 8843d4f77d8e829135e2ff9b354990134c58c46a Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 21 Oct 2017 20:00:25 -0700 Subject: [PATCH 0216/1198] Strip : from parameters This is to fix #601. The function used to extract the mode string assumed that ":" would only occur in a particular spot. This lead to the possibility that ":" could be treated as part of things like nicknames or mode arguments, where it should have been stripped as part of protocol escaping. --- src/fe-common/irc/fe-events.c | 2 +- src/irc/core/irc.c | 32 ++++++++++++++++++++++++++++++-- src/irc/core/modes.c | 4 ++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index 850174c5..cc83d476 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -224,7 +224,7 @@ static void event_nick(IRC_SERVER_REC *server, const char *data, static void event_mode(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { - char *params, *channel, *mode; + char *params = NULL, *channel = NULL, *mode = NULL; g_return_if_fail(data != NULL); diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 4dce3fcf..790c7122 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -40,6 +40,8 @@ static int signal_server_incoming; # define MAX_SOCKET_READS 5 #endif +static void strip_params_colon(char *const); + /* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd' won't be checked at all if it's 512 bytes or not, or if it contains line feeds or not. Use with extreme caution! */ @@ -269,8 +271,9 @@ char *event_get_params(const char *data, int count, ...) while (count-- > 0) { str = (char **) va_arg(args, char **); if (count == 0 && rest) { - /* put the rest to last parameter */ - tmp = *datad == ':' ? datad+1 : datad; + /* Put the rest into the last parameter. */ + strip_params_colon(datad); + tmp = datad; } else { tmp = event_get_param(&datad); } @@ -281,6 +284,31 @@ char *event_get_params(const char *data, int count, ...) return duprec; } +/* Given a string containing , strip any colon prefixing . */ +static void strip_params_colon(char *const params) +{ + if (!params) { + return; + } + + char *s = params; + while (*s != '\0') { + if (*s == ':') { + memmove(s, s+1, strlen(s+1)+1); + return; + } + + s = strchr(s, ' '); + if (!s) { + return; + } + + while (*s == ' ') { + s++; + } + } +} + static void irc_server_event(IRC_SERVER_REC *server, const char *line, const char *nick, const char *address) { diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index cc3d0faf..ecbf2571 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -480,8 +480,8 @@ static void event_user_mode(IRC_SERVER_REC *server, const char *data) static void event_mode(IRC_SERVER_REC *server, const char *data, const char *nick) { - IRC_CHANNEL_REC *chanrec; - char *params, *channel, *mode; + IRC_CHANNEL_REC *chanrec = NULL; + char *params = NULL, *channel = NULL, *mode = NULL; g_return_if_fail(data != NULL); From ca3498d42d29383024382b0eb983f97ab4e6b614 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 25 Oct 2017 16:22:57 +0200 Subject: [PATCH 0217/1198] move some files into subdirs --- Makefile.am | 21 ++++++----------- autogen.sh | 27 +++++++++++++--------- configure.ac | 2 ++ themes/Makefile.am | 5 ++++ colorless.theme => themes/colorless.theme | 0 default.theme => themes/default.theme | 0 utils/Makefile.am | 4 ++++ file2header.sh => utils/file2header.sh | 0 irssi-version.sh => utils/irssi-version.sh | 0 syncdocs.sh => utils/syncdocs.sh | 3 ++- syncscripts.sh => utils/syncscripts.sh | 1 + syntax.pl => utils/syntax.pl | 0 12 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 themes/Makefile.am rename colorless.theme => themes/colorless.theme (100%) rename default.theme => themes/default.theme (100%) create mode 100644 utils/Makefile.am rename file2header.sh => utils/file2header.sh (100%) rename irssi-version.sh => utils/irssi-version.sh (100%) rename syncdocs.sh => utils/syncdocs.sh (98%) rename syncscripts.sh => utils/syncscripts.sh (97%) rename syntax.pl => utils/syntax.pl (100%) diff --git a/Makefile.am b/Makefile.am index 75d502f1..f52ac92f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,33 +7,26 @@ CLEANFILES = default-config.h default-theme.h @MAINTAINER_MODE_TRUE@.PHONY: irssi-version.h default-config.h: $(srcdir)/irssi.conf - $(srcdir)/file2header.sh $(srcdir)/irssi.conf default_config > default-config.h + $(srcdir)/utils/file2header.sh $(srcdir)/irssi.conf default_config > default-config.h -default-theme.h: $(srcdir)/default.theme - $(srcdir)/file2header.sh $(srcdir)/default.theme default_theme > default-theme.h +default-theme.h: $(srcdir)/themes/default.theme + $(srcdir)/utils/file2header.sh $(srcdir)/themes/default.theme default_theme > default-theme.h irssi-version.h: - VERSION="$(VERSION)" $(srcdir)/irssi-version.sh $(srcdir) | \ - cmp -s - $@ || VERSION="$(VERSION)" $(srcdir)/irssi-version.sh $(srcdir) >$@ + VERSION="$(VERSION)" $(srcdir)/utils/irssi-version.sh $(srcdir) | \ + cmp -s - $@ || VERSION="$(VERSION)" $(srcdir)/utils/irssi-version.sh $(srcdir) >$@ -SUBDIRS = src docs scripts +SUBDIRS = src docs scripts themes utils confdir = $(sysconfdir) conf_DATA = irssi.conf -themedir = $(datadir)/irssi/themes -theme_DATA = default.theme colorless.theme - pkginclude_HEADERS = irssi-config.h irssi-version.h EXTRA_DIST = \ ChangeLog \ autogen.sh \ README.md \ - file2header.sh \ $(conf_DATA) \ - $(theme_DATA) \ irssi-config.in \ - irssi-icon.png \ - irssi-version.sh \ - syntax.pl + irssi-icon.png diff --git a/autogen.sh b/autogen.sh index a9e354c9..9feb0872 100755 --- a/autogen.sh +++ b/autogen.sh @@ -3,21 +3,24 @@ PKG_NAME="Irssi" -srcdir=`dirname $0` +srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. +mydir=`pwd` -if test ! -f $srcdir/configure.ac; then - echo -n "**Error**: Directory \`$srcdir\' does not look like the" +if test ! -f "$srcdir"/configure.ac; then + echo -n "**Error**: Directory \`$srcdir' does not look like the" echo " top-level $PKG_NAME directory" exit 1 fi +cd "$srcdir" + # create help files echo "Creating help files..." -perl syntax.pl +perl utils/syntax.pl echo "Creating ChangeLog..." -git log > $srcdir/ChangeLog +git log > ChangeLog if test "$?" -ne 0; then echo "**Error**: ${PKG_NAME} Autogen must be run in a git clone, cannot proceed." exit 1 @@ -38,17 +41,19 @@ fi rm -f aclocal.m4 echo "Running autoreconf ..." -autoreconf -i || exit 1 +autoreconf -i || exit $? + +# make sure perl hashes have correct length +find src/perl -name '*.c' -o -name '*.xs' -exec grep -n hv_store {} + | perl -l -ne 'if (/"(\w+)",\s*(\d+)/ && $2 != length $1) { $X=1; print "Incorrect key length in $_" } END { exit $X }' + +cd "$mydir" conf_flags="--enable-maintainer-mode" if test x$NOCONFIGURE = x; then - echo Running $srcdir/configure $conf_flags "$@" ... - $srcdir/configure $conf_flags "$@" \ + echo Running "$srcdir"/configure $conf_flags "$@" ... + "$srcdir"/configure $conf_flags "$@" \ && echo Now type \`make\' to compile $PKG_NAME || exit 1 else echo Skipping configure process. fi - -# make sure perl hashes have correct length -find src/perl -name '*.c' -o -name '*.xs' -exec grep -n hv_store {} + | perl -l -ne 'if (/"(\w+)",\s*(\d+)/ && $2 != length $1) { $X=1; print "Incorrect key length in $_" } END { exit $X }' diff --git a/configure.ac b/configure.ac index 9c026c5d..4b65d434 100644 --- a/configure.ac +++ b/configure.ac @@ -661,6 +661,8 @@ scripts/examples/Makefile docs/Makefile docs/help/Makefile docs/help/in/Makefile +utils/Makefile +themes/Makefile irssi-config ]) diff --git a/themes/Makefile.am b/themes/Makefile.am new file mode 100644 index 00000000..ad0707c2 --- /dev/null +++ b/themes/Makefile.am @@ -0,0 +1,5 @@ +themedir = $(datadir)/irssi/themes +theme_DATA = default.theme colorless.theme + +EXTRA_DIST = \ + $(theme_DATA) diff --git a/colorless.theme b/themes/colorless.theme similarity index 100% rename from colorless.theme rename to themes/colorless.theme diff --git a/default.theme b/themes/default.theme similarity index 100% rename from default.theme rename to themes/default.theme diff --git a/utils/Makefile.am b/utils/Makefile.am new file mode 100644 index 00000000..be24c17f --- /dev/null +++ b/utils/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = \ + file2header.sh \ + irssi-version.sh \ + syntax.pl diff --git a/file2header.sh b/utils/file2header.sh similarity index 100% rename from file2header.sh rename to utils/file2header.sh diff --git a/irssi-version.sh b/utils/irssi-version.sh similarity index 100% rename from irssi-version.sh rename to utils/irssi-version.sh diff --git a/syncdocs.sh b/utils/syncdocs.sh similarity index 98% rename from syncdocs.sh rename to utils/syncdocs.sh index 1187eec9..e723edd2 100755 --- a/syncdocs.sh +++ b/utils/syncdocs.sh @@ -16,6 +16,7 @@ s{(<.*?)\sclass="(?:highlighter-rouge|highlight)"(.*?>)}{\1\2}g;' srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. +srcdir="$srcdir"/.. if test ! -f "$srcdir"/configure.ac; then echo -n "**Error**: Directory \`$srcdir' does not look like the" @@ -94,7 +95,7 @@ cat "$srcdir"/docs/faq.html \ if ($_ eq "\n" && $state eq "Q") { $_ = ""; } elsif (/^([QA]):/) { $state = $1 } elsif ($_ ne "\n") { $_ = " $_"; }; -' > docs/faq.txt +' > "$srcdir"/docs/faq.txt cat "$srcdir"/docs/startup-HOWTO.html \ | perl -pe "s/\\bhref=([\"\'])#.*?\\1//" \ diff --git a/syncscripts.sh b/utils/syncscripts.sh similarity index 97% rename from syncscripts.sh rename to utils/syncscripts.sh index eee95a5e..533b77cc 100755 --- a/syncscripts.sh +++ b/utils/syncscripts.sh @@ -7,6 +7,7 @@ scriptbase=https://scripts.irssi.org/scripts srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. +srcdir="$srcdir"/.. if test ! -f "$srcdir"/configure.ac; then echo -n "**Error**: Directory \`$srcdir' does not look like the" diff --git a/syntax.pl b/utils/syntax.pl similarity index 100% rename from syntax.pl rename to utils/syntax.pl From 8c0e0c81ee79684201020f843eeb0a4d656ed14c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 25 Oct 2017 16:23:14 +0200 Subject: [PATCH 0218/1198] run syncscripts.sh --- scripts/autorejoin.pl | 49 ++++++++++++++++++++++++++++--------------- scripts/mail.pl | 1 + scripts/usercount.pl | 1 + 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/scripts/autorejoin.pl b/scripts/autorejoin.pl index 42c97da7..e5be21b2 100644 --- a/scripts/autorejoin.pl +++ b/scripts/autorejoin.pl @@ -1,6 +1,9 @@ -# automatically rejoin to channel after kick +# automatically rejoin to channel after kicked # delayed rejoin: Lam 28.10.2001 (lam@lac.pl) +# /SET autorejoin_channels #channel1 #channel2 ... +# /SET autorejoin_delay 5 + # NOTE: I personally don't like this feature, in most channels I'm in it # will just result as ban. You've probably misunderstood the idea of /KICK # if you kick/get kicked all the time "just for fun" ... @@ -9,31 +12,22 @@ use Irssi; use Irssi::Irc; use strict; use vars qw($VERSION %IRSSI); -$VERSION = "1.0.0"; +$VERSION = "1.1.0"; %IRSSI = ( authors => "Timo 'cras' Sirainen, Leszek Matok", contact => "lam\@lac.pl", name => "autorejoin", - description => "Automatically rejoin to channel after being kick, after a (short) user-defined delay", + description => "Automatically rejoin to channel after being kicked, after a (short) user-defined delay", license => "GPLv2", changed => "10.3.2002 14:00" ); - -# How many seconds to wait before the rejoin? -# TODO: make this a /setting -my $delay = 5; - -my @tags; -my $acttag = 0; - sub rejoin { my ( $data ) = @_; - my ( $tag, $servtag, $channel, $pass ) = split( / +/, $data ); + my ( $servtag, $channel, $pass ) = @{$data}; my $server = Irssi::server_find_tag( $servtag ); $server->send_raw( "JOIN $channel $pass" ) if ( $server ); - Irssi::timeout_remove( $tags[$tag] ); } sub event_rejoin_kick { @@ -48,10 +42,31 @@ sub event_rejoin_kick { my $rejoinchan = $chanrec->{ name } if ( $chanrec ); my $servtag = $server->{ tag }; - Irssi::print "Rejoining $rejoinchan in $delay seconds."; - $tags[$acttag] = Irssi::timeout_add( $delay * 1000, "rejoin", "$acttag $servtag $rejoinchan $password" ); - $acttag++; - $acttag = 0 if ( $acttag > 60 ); + # check if we want to autorejoin this channel + my $chans = Irssi::settings_get_str( 'autorejoin_channels' ); + + if ( $chans ) { + my $found = 0; + foreach my $chan ( split( /[ ,]/, $chans ) ) { + if ( lc( $chan ) eq lc( $channel ) ) { + $found = 1; + last; + } + } + return unless $found; + } + + my @args = ($servtag, $rejoinchan, $password); + my $delay = Irssi::settings_get_int( "autorejoin_delay" ); + + if ($delay) { + Irssi::print "Rejoining $rejoinchan in $delay seconds."; + Irssi::timeout_add_once( $delay * 1000, "rejoin", \@args ); + } else { + rejoin( \@args ); + } } +Irssi::settings_add_int('misc', 'autorejoin_delay', 5); +Irssi::settings_add_str('misc', 'autorejoin_channels', ''); Irssi::signal_add( 'event kick', 'event_rejoin_kick' ); diff --git a/scripts/mail.pl b/scripts/mail.pl index ded02120..23f99c01 100644 --- a/scripts/mail.pl +++ b/scripts/mail.pl @@ -6,6 +6,7 @@ $VERSION = "2.92"; contact => "tss\@iki.fi, matti\@hiljanen.com, joost\@carnique.nl, bart\@dreamflow.nl", name => "mail", description => "Fully customizable mail counter statusbar item with multiple mailbox and multiple Maildir support", + sbitems => "mail", license => "Public Domain", url => "http://irssi.org, http://scripts.irssi.de", ); diff --git a/scripts/usercount.pl b/scripts/usercount.pl index 613da1de..650f9f36 100644 --- a/scripts/usercount.pl +++ b/scripts/usercount.pl @@ -7,6 +7,7 @@ $VERSION = "1.19"; contact => 'dgl@dgl.cx, tss@iki.fi, georg@boerde.de', name => 'usercount', description => 'Adds a usercount for a channel as a statusbar item', + sbitems => 'usercount', license => 'GNU GPLv2 or later', url => 'http://irssi.dgl.cx/', changes => 'Only show halfops if server supports them', From 96c7f68b3579ae5f83b635d946dc705d6322a16c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 26 Oct 2017 16:15:25 +0200 Subject: [PATCH 0219/1198] clean up file path after move --- src/perl/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/Makefile.am b/src/perl/Makefile.am index 427c5492..db52744e 100644 --- a/src/perl/Makefile.am +++ b/src/perl/Makefile.am @@ -59,7 +59,7 @@ perl-signals-list.h: $(top_srcdir)/docs/signals.txt $(srcdir)/get-signals.pl cat $(top_srcdir)/docs/signals.txt | $(perlpath) $(srcdir)/get-signals.pl > perl-signals-list.h irssi-core.pl.h: irssi-core.pl - $(top_srcdir)/file2header.sh $(srcdir)/irssi-core.pl irssi_core_code > irssi-core.pl.h + $(top_srcdir)/utils/file2header.sh $(srcdir)/irssi-core.pl irssi_core_code > irssi-core.pl.h common_sources = \ common/Irssi.xs \ From 7e619ed990503faf45fc1ae1e28a3a6062dc7532 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 30 Oct 2017 16:54:32 +0100 Subject: [PATCH 0220/1198] Update README.md --- README.md | 128 ++++++++++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 8d91f4cb..0f54ccf5 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,73 @@ -# Irssi +# [Irssi](https://irssi.org/) [![Build Status](https://travis-ci.org/irssi/irssi.svg?branch=master)](https://travis-ci.org/irssi/irssi) Irssi is a modular chat client that is most commonly known for its text mode user interface, but 80% of the code isn't text mode -specific. We have a working but currently unmaintained GTK2 frontend -called xirssi. Irssi comes with IRC support built in, and there are +specific. Irssi comes with IRC support built in, and there are third party [ICB](https://github.com/jperkin/irssi-icb), [SILC](http://www.silcnet.org/), [XMPP](http://cybione.org/~irssi-xmpp/) (Jabber), -[PSYC](https://github.com/electric-blue/irssyc) and +[PSYC](http://about.psyc.eu/Irssyc) and [Quassel](https://github.com/phhusson/quassel-irssi) protocol modules available. -## Installation +![irssi](https://user-images.githubusercontent.com/5665186/32180643-cf127f60-bd92-11e7-8aa2-882313ce1d8e.png) -See the `INSTALL` file. +## [Download information](https://irssi.org/download/) -## Features +#### Development source installation -So what's so great about Irssi? Here's a list of some features I can -think of currently: +``` +git clone https://github.com/irssi/irssi +cd irssi +./autogen.sh +make && sudo make install +``` - - **Optional automation** - There's lots of things Irssi does for you - automatically that some people like and others just hate. Things like: - nick completion, creating new window for newly joined channel, creating - queries when msgs/notices are received or when you send a msg, closing - queries when it's been idle for some time, etc. +#### Release source installation - - **Multiserver friendly** - I think Irssi has clearly the best support - for handling multiple server connections. You can have as many as you - want in as many ircnets as you want. Having several connections in one - server works too, for example when you hit the (ircnet's) 10 - channels/connection limit you can just create another connection and - you hardly notice it. If connection to server is lost, Irssi tries to - connect back until it's successful. Also channels you were joined - before disconnection are restored, even if they're "temporarily - unavailable" because of netsplits, Irssi keeps rejoining back to them. - Also worth noticing - there's not that stupid "server is bound to this - window, if this window gets closed the connection closes" thing that - ircII based clients have. +* Download [release](https://github.com/irssi/irssi/releases) +* [Verify](https://irssi.org/download/#release-sources) signature +``` +tar xJf irssi-*.tar.xz +cd irssi-* +./configure +make && sudo make install +``` - - **Channel automation** - You can specify what channels to join to - immediately after connected to some server or IRC network. After joined - to channel, Irssi can automatically request ops for you (or do - anything, actually) from channel's bots. +### Requirements - - **Window content saving** - Say /LAYOUT SAVE when you've put all the - channels and queries to their correct place, and after restarting - Irssi, the channels will be joined back into windows where they were - saved. +- [glib-2.28](https://wiki.gnome.org/Projects/GLib) or greater +- [openssl](https://www.openssl.org/) +- [perl-5.6](https://www.perl.org/) or greater (for perl support) +- terminfo or ncurses (for text frontend) - - **Tab completing anything** - You can complete lots of things with tab: - nicks, commands, command -options, file names, settings, text format - names, channels and server names. There's also an excellent /msg - completion that works transparently with multiple IRC networks. - Completing channel nicks is also pretty intelligent, it first goes - through the people who have talked to you recently, then the people who - have talked to anyone recently and only then it fallbacks to rest of - the nicks. You can also complete a set of words you've specified, for - example homepage changes it to your actual home page URL. +#### See the [INSTALL](INSTALL) file for details - - **Excellent logging** - You can log any way you want and as easily or - hard as you want. With autologging Irssi logs everything to specified - directory, one file per channel/nick. ircII style /WINDOW LOG ON is - also supported. There's also the "hard way" of logging - /LOG command - which lets you specify exactly what you wish to log and where. Log - rotating is supported with all the different logging methods, you can - specify how often you want it to rotate and what kind of time stamp to - use. +## [Documentation](https://irssi.org/documentation/) - - **Excellent ignoring** - You can most probably ignore anything any way - you want. Nick masks, words, regular expressions. You can add - exceptions to ignores. You can ignore other people's replies in - channels to nicks you have ignored. You can also specify that the - specific ignores work only in specific channel(s). +* [Frequently Asked Questions](https://irssi.org/documentation/faq) +* [Startup How-To](https://irssi.org/documentation/startup) +* Check the built-in `/HELP`, it has all the details on command syntax - - **Lastlog and scrollback handling** - /LASTLOG command has some new - features: -new option checks only lines that came since you last did - /LASTLOG command, -away option checks new lines since you last went - away. Regular expression matches work also, of course. Going to some - wanted place at scrollback has always been hard with non-GUI clients. A - search command that jumps around in scrollback in GUI-style is still - missing from Irssi, but there's something that's almost as good as it. - /LASTLOG always shows timestamps when the line was printed, even if you - didn't have timestamps on. Now doing /SB GOTO \ jumps - directly to the position in scrollback you wanted. Great feature when - you want to browse a bit of the discussion what happened when someone - said your name (as seen in awaylog) or topic was changed (/last - -topics) +## [Themes](https://irssi-import.github.io/themes/) -## Files +## [Scripts](http://scripts.irssi.org/) - - The `docs/` directory contains several documents: - - `startup-HOWTO.txt` - new users should read this - - `manual.txt` - manual I started writing but didn't get it very far :) - - `perl.txt` - Perl scripting help - - `formats.txt` - How to use colors, etc. with Irssi - - `faq.txt` - Frequently Asked Questions - - `special_vars.txt` - some predefined $variables you can use with Irssi +## [Modules](https://irssi.org/modules/) -## Bugs / Suggestions +## [Security information](https://irssi.org/security/) -See the `TODO` file, http://bugs.irssi.org and the GitHub issues if it is -already listed in there; if not, open an issue on GitHub or send a mail to -[staff@irssi.org](mailto:staff@irssi.org). +Please report security issues to staff@irssi.org. Thanks! -You can also contact the Irssi developers in #irssi on freenode. +## [Bugs](https://github.com/irssi/irssi/issues) / Suggestions / [Contributing](https://irssi.org/development/) + +Check the GitHub issues if it is already listed in there; if not, open +an issue on GitHub or send a mail to [staff@irssi.org](mailto:staff@irssi.org). + +Irssi is always looking for developers. Feel free to submit patches through +GitHub pull requests. + +You can also contact the Irssi developers in +[#irssi](https://irssi.org/support/irc/) on freenode. From b0fa4dd46d8bf1cf63880fabf2105dd9134100df Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 1 Nov 2017 15:48:35 +0100 Subject: [PATCH 0221/1198] show initial nick and name on first start --- src/core/settings.c | 10 +++++++ src/fe-common/core/Makefile.am | 1 + src/fe-common/core/fe-settings.c | 7 ++++- src/fe-common/core/fe-settings.h | 6 ++++ src/fe-text/irssi.c | 49 ++++++++++++++++---------------- src/fe-text/module-formats.c | 21 ++++++++++++++ src/fe-text/module-formats.h | 6 ++++ src/irc/core/irc-servers-setup.c | 11 ++++++- 8 files changed, 85 insertions(+), 26 deletions(-) create mode 100644 src/fe-common/core/fe-settings.h diff --git a/src/core/settings.c b/src/core/settings.c index 4e0717cd..48d6640e 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -39,6 +39,7 @@ static GString *last_errors; static GSList *last_invalid_modules; static int fe_initialized; static int config_changed; /* FIXME: remove after .98 (unless needed again) */ +static int user_settings_changed; static GHashTable *settings; static int timeout_tag; @@ -464,6 +465,11 @@ SETTINGS_REC *settings_get_record(const char *key) return g_hash_table_lookup(settings, key); } +static void sig_init_userinfo_changed(gpointer changedp) +{ + user_settings_changed = GPOINTER_TO_INT(changedp); +} + static void sig_init_finished(void) { fe_initialized = TRUE; @@ -479,6 +485,8 @@ static void sig_init_finished(void) "updated, please /SAVE"); signal_emit("setup changed", 0); } + + signal_emit("settings userinfo changed", 1, GINT_TO_POINTER(user_settings_changed)); } static void settings_clean_invalid_module(const char *module) @@ -875,6 +883,7 @@ void settings_init(void) timeout_tag = g_timeout_add(SETTINGS_AUTOSAVE_TIMEOUT, (GSourceFunc) sig_autosave, NULL); signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished); + signal_add("irssi init userinfo changed", (SIGNAL_FUNC) sig_init_userinfo_changed); signal_add("gui exit", (SIGNAL_FUNC) sig_autosave); } @@ -887,6 +896,7 @@ void settings_deinit(void) { g_source_remove(timeout_tag); signal_remove("irssi init finished", (SIGNAL_FUNC) sig_init_finished); + signal_remove("irssi init userinfo changed", (SIGNAL_FUNC) sig_init_userinfo_changed); signal_remove("gui exit", (SIGNAL_FUNC) sig_autosave); g_slist_foreach(last_invalid_modules, (GFunc) g_free, NULL); diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 29cc941a..cf4e8ee3 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -55,6 +55,7 @@ pkginc_fe_common_core_HEADERS = \ fe-exec.h \ fe-messages.h \ fe-queries.h \ + fe-settings.h \ fe-tls.h \ formats.h \ hilight-text.h \ diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index abbd45a8..de9f67a1 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -26,7 +26,7 @@ #include "misc.h" #include "lib-config/iconfig.h" #include "settings.h" - +#include "fe-settings.h" #include "levels.h" #include "printtext.h" #include "keyboard.h" @@ -41,6 +41,11 @@ static void set_print(SETTINGS_REC *rec) g_free(value); } +void fe_settings_set_print(const char *key) +{ + set_print(settings_get_record(key)); +} + static void set_print_pattern(const char *pattern) { GSList *sets, *tmp; diff --git a/src/fe-common/core/fe-settings.h b/src/fe-common/core/fe-settings.h new file mode 100644 index 00000000..dd33f223 --- /dev/null +++ b/src/fe-common/core/fe-settings.h @@ -0,0 +1,6 @@ +#ifndef __FE_CHANNELS_H +#define __FE_CHANNELS_H + +void fe_settings_set_print(const char *key); + +#endif diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index b5df47c9..6349ae2a 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -31,6 +31,7 @@ #include "printtext.h" #include "fe-common-core.h" +#include "fe-settings.h" #include "themes.h" #include "term.h" @@ -79,25 +80,8 @@ static int dirty, full_redraw; static GMainLoop *main_loop; int quitting; -static const char *banner_text = - " ___ _\n" - "|_ _|_ _ _____(_)\n" - " | || '_(_-<_-< |\n" - "|___|_| /__/__/_|\n" - "Irssi v" PACKAGE_VERSION " - http://www.irssi.org"; - -static const char *firsttimer_text = - "- - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" - "Hi there! If this is your first time using Irssi, you\n" - "might want to go to our website and read the startup\n" - "documentation to get you going.\n\n" - "Our community and staff are available to assist you or\n" - "to answer any questions you may have.\n\n" - "Use the /HELP command to get detailed information about\n" - "the available commands.\n" - "- - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - static int display_firsttimer = FALSE; +static int user_settings_changed = 0; static void sig_exit(void) @@ -105,6 +89,11 @@ static void sig_exit(void) quitting = TRUE; } +static void sig_settings_userinfo_changed(gpointer changedp) +{ + user_settings_changed = GPOINTER_TO_INT(changedp); +} + /* redraw irssi's screen.. */ void irssi_redraw(void) { @@ -161,6 +150,7 @@ static void textui_init(void) fe_common_irc_init(); theme_register(gui_text_formats); + signal_add("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed); signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit); } @@ -199,14 +189,24 @@ static void textui_finish_init(void) statusbar_redraw(NULL, TRUE); if (servers == NULL && lookup_servers == NULL) { - printtext(NULL, NULL, MSGLEVEL_CRAP|MSGLEVEL_NO_ACT, - "%s", banner_text); + printformat(NULL, NULL, MSGLEVEL_CRAP|MSGLEVEL_NO_ACT, TXT_IRSSI_BANNER); } if (display_firsttimer) { - printtext(NULL, NULL, MSGLEVEL_CRAP|MSGLEVEL_NO_ACT, - "%s", firsttimer_text); + printformat(NULL, NULL, MSGLEVEL_CRAP|MSGLEVEL_NO_ACT, TXT_WELCOME_FIRSTTIME); } + + /* see irc-servers-setup.c:init_userinfo */ + if (user_settings_changed) + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_WELCOME_INIT_SETTINGS); + if (user_settings_changed & (1<<0)) + fe_settings_set_print("real_name"); + if (user_settings_changed & (1<<1)) + fe_settings_set_print("user_name"); + if (user_settings_changed & (1<<2)) + fe_settings_set_print("nick"); + if (user_settings_changed & (1<<3)) + fe_settings_set_print("hostname"); } static void textui_deinit(void) @@ -223,6 +223,7 @@ static void textui_deinit(void) #endif dirty_check(); /* one last time to print any quit messages */ + signal_remove("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed); signal_remove("gui exit", (SIGNAL_FUNC) sig_exit); lastlog_deinit(); @@ -249,6 +250,7 @@ static void textui_deinit(void) core_deinit(); } + static void check_files(void) { struct stat statbuf; @@ -259,12 +261,11 @@ static void check_files(void) } } - int main(int argc, char **argv) { static int version = 0; static GOptionEntry options[] = { - { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display irssi version", NULL }, + { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display Irssi version", NULL }, { NULL } }; int loglev; diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index 899827c2..c4606197 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -78,5 +78,26 @@ FORMAT_REC gui_text_formats[] = { "paste_warning", "Pasting $0 lines to $1. Press Ctrl-K if you wish to do this or Ctrl-C to cancel.", 2, { 1, 0 } }, { "paste_prompt", "Hit Ctrl-K to paste, Ctrl-C to abort?", 0 }, + /* ---- */ + { NULL, "Welcome", 0 }, + + { "irssi_banner", + " ___ _%:" + "|_ _|_ _ _____(_)%:" + " | || '_(_-<_-< |%:" + "|___|_| /__/__/_|%:" + "Irssi v$J - http://www.irssi.org", 0 }, + { "welcome_firsttime", + "- - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" + "Hi there! If this is your first time using Irssi, you%:" + "might want to go to our website and read the startup%:" + "documentation to get you going.%:%:" + "Our community and staff are available to assist you or%:" + "to answer any questions you may have.%:%:" + "Use the /HELP command to get detailed information about%:" + "the available commands.%:" + "- - - - - - - - - - - - - - - - - - - - - - - - - - - -", 0 }, + { "welcome_init_settings", "The following settings were initialized", 0 }, + { NULL, NULL, 0 } }; diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h index 3fa8c511..05e9438d 100644 --- a/src/fe-text/module-formats.h +++ b/src/fe-text/module-formats.h @@ -52,6 +52,12 @@ enum { TXT_PASTE_WARNING, TXT_PASTE_PROMPT, + TXT_FILL_5, /* Welcome */ + + TXT_IRSSI_BANNER, + TXT_WELCOME_FIRSTTIME, + TXT_WELCOME_INIT_SETTINGS, + TXT_COUNT }; diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index bae7d3b4..22c86f57 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -116,14 +116,17 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, static void init_userinfo(void) { + int changed; const char *set, *nick, *user_name, *str; + changed = 0; /* check if nick/username/realname wasn't read from setup.. */ set = settings_get_str("real_name"); if (set == NULL || *set == '\0') { str = g_getenv("IRCNAME"); settings_set_str("real_name", str != NULL ? str : g_get_real_name()); + changed |= 1<<0; } /* username */ @@ -134,6 +137,7 @@ static void init_userinfo(void) str != NULL ? str : g_get_user_name()); user_name = settings_get_str("user_name"); + changed |= 1<<1; } /* nick */ @@ -143,15 +147,20 @@ static void init_userinfo(void) settings_set_str("nick", str != NULL ? str : user_name); nick = settings_get_str("nick"); + changed |= 1<<2; } /* host name */ set = settings_get_str("hostname"); if (set == NULL || *set == '\0') { str = g_getenv("IRCHOST"); - if (str != NULL) + if (str != NULL) { settings_set_str("hostname", str); + changed |= 1<<3; + } } + + signal_emit("irssi init userinfo changed", 1, GINT_TO_POINTER(changed)); } static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) From 4d6822b1c43d876856a5df07ce69fb4e67c3591a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 1 Nov 2017 15:52:45 +0100 Subject: [PATCH 0222/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 159f7124..a7eaa7cf 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 11 +#define IRSSI_ABI_VERSION 12 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 56013367983b61d8ee4d2e905767ce50b25ffb82 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 30 Oct 2017 09:39:16 +0100 Subject: [PATCH 0223/1198] Turn the style guide into a clang-format file --- .clang-format | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..5501478f --- /dev/null +++ b/.clang-format @@ -0,0 +1,37 @@ +# IndentPPDirectives: None +# SpaceInParentheses: false +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +ColumnLimit: 100 +IndentCaseLabels: true +IndentWidth: 8 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 1 +PointerAlignment: Right +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpacesInSquareBrackets: false +TabWidth: 8 +UseTab: ForIndentation From 60c31219a278330498e695e4d7fca05ea69962e4 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Tue, 24 Oct 2017 12:02:30 +0200 Subject: [PATCH 0224/1198] Allow selection of what kind of activity targets to ignore Initialize tagtarget on declaration move code around for better flow, extra checks for uninitialized values remove unnecessary item->type checks don't strdup sign add braces around if statements, use strcmp0 with single characters and remove g_str_has_prefix refactoring changed g_ascii_strcasecmp to g_strcmp0 Add networktag/ shorthand fixed memory leaks changed from #@= to ::channels, ::queries and ::dccqueries check for empty string and continue; if found fixed bug with empty string check Clean up code --- src/fe-common/core/fe-common-core.c | 53 +++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 512fc84c..bce9ab4e 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -461,26 +461,43 @@ void fe_common_core_finish_init(void) gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) { + int channel_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL"); + int query_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); + char **tmp; + g_return_val_if_fail(array != NULL, FALSE); + g_return_val_if_fail(dest != NULL, FALSE); + g_return_val_if_fail(dest->window != NULL, FALSE); + g_return_val_if_fail(dest->target != NULL, FALSE); - if (strarray_find(array, "*") != -1) - return TRUE; - - if (strarray_find(array, dest->target) != -1) - return TRUE; - - if (dest->server_tag != NULL) { - char *tagtarget = g_strdup_printf("%s/%s", dest->server_tag, "*"); - int ret = strarray_find(array, tagtarget); - g_free(tagtarget); - if (ret != -1) - return TRUE; - - tagtarget = g_strdup_printf("%s/%s", dest->server_tag, dest->target); - ret = strarray_find(array, tagtarget); - g_free(tagtarget); - if (ret != -1) - return TRUE; + WI_ITEM_REC *item = window_item_find_window(dest->window, dest->server, dest->target); + if (item == NULL) { + return FALSE; } + + int server_tag_len = dest->server_tag ? strlen(dest->server_tag) : 0; + for (tmp = array; *tmp != NULL; tmp++) { + char *str = *tmp; + if (*str == '\0') { + continue; + } + + if (server_tag_len && !g_ascii_strncasecmp(str, dest->server_tag, server_tag_len) && str[server_tag_len] == '/') { + str += server_tag_len + 1; + } + + if (!g_strcmp0(str, "") || !g_strcmp0(str, "::all")) { + return TRUE; + } else if (!g_ascii_strcasecmp(str, dest->target)) { + return TRUE; + } else if (item->type == query_type && + !g_strcmp0(str, (dest->target[0] == '=') ? "::dccqueries" : "::queries")) { + return TRUE; + } else if (item->type == channel_type && + !g_strcmp0(str, "::channels")) { + return TRUE; + } + } + return FALSE; } From f9d69597ef1e204640d5ce104061717aca0d213a Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 2 Nov 2017 11:44:57 -0400 Subject: [PATCH 0225/1198] Remove unnecessary malloc cast in fe-fuzz We compile this as C code, so the cast is unnecessary. --- src/fe-fuzz/irc/core/event-get-params.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index 89eb89d2..fc21bbeb 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -52,7 +52,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } uint8_t count = *data; - char *copy = (char *)malloc(sizeof(char)*(size-1+1)); + char *copy = malloc(sizeof(char)*(size-1+1)); memcpy(copy, data+1, size-1); copy[size-1] = '\0'; From f4b89044f075038d29089435f7620a068507d80e Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 2 Nov 2017 11:48:30 -0400 Subject: [PATCH 0226/1198] Fix malloc parameter in fe-fuzz It is fairly safe to assume that sizeof(char) will always be 1 anyway and replace the size calculation with a comment explaining the calculation. --- src/fe-fuzz/irc/core/event-get-params.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index fc21bbeb..f8060ffe 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -52,7 +52,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } uint8_t count = *data; - char *copy = malloc(sizeof(char)*(size-1+1)); + /* malloc(size) instead of size+1, because we already used one byte of data */ + char *copy = malloc(size); memcpy(copy, data+1, size-1); copy[size-1] = '\0'; From 532527ffa6a5eaccdbf607a2dc3d0e6ef884fce9 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 2 Nov 2017 11:56:53 -0400 Subject: [PATCH 0227/1198] Use gchar and g_strndup in fe-fuzz --- src/fe-fuzz/irc/core/event-get-params.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index f8060ffe..6266ffb6 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -53,9 +53,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } uint8_t count = *data; /* malloc(size) instead of size+1, because we already used one byte of data */ - char *copy = malloc(size); - memcpy(copy, data+1, size-1); - copy[size-1] = '\0'; + gchar *copy = g_strndup((const gchar *)data+1, size-1); char *output0; char *output1; @@ -82,6 +80,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { params = event_get_params(copy, 4, &output0, &output1, &output2, &output3); } g_free(params); - free(copy); + g_free(copy); return 0; } From 66b2c9bc91a3b6e34ba59491c95747db75d21c6b Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 3 Nov 2017 16:37:04 +0100 Subject: [PATCH 0228/1198] Keep a copy of the strings coming from the config The "HILIGHT_REC" structure used to keep a pointer to the "servertag" string, owned by the "CONFIG_NODE", causing a double-free. --- src/fe-common/core/hilight-text.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 62e6f0de..b9912457 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -106,6 +106,7 @@ static void hilight_destroy(HILIGHT_REC *rec) if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); + g_free_not_null(rec->servertag); g_free(rec->text); g_free(rec); } @@ -424,7 +425,7 @@ static void read_hilight_config(void) CONFIG_NODE *node; HILIGHT_REC *rec; GSList *tmp; - char *text, *color; + char *text, *color, *servertag; hilights_destroy_all(); @@ -467,7 +468,9 @@ static void read_hilight_config(void) rec->nickmask = config_node_get_bool(node, "mask", FALSE); rec->fullword = config_node_get_bool(node, "fullword", FALSE); rec->regexp = config_node_get_bool(node, "regexp", FALSE); - rec->servertag = config_node_get_str(node, "servertag", NULL); + servertag = config_node_get_str(node, "servertag", NULL); + rec->servertag = servertag == NULL || *servertag == '\0' ? NULL : + g_strdup(servertag); hilight_init_rec(rec); node = iconfig_node_section(node, "channels", -1); From 02c677f467b398f8b91b1e90544502ff98a6e0da Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 10 Nov 2017 22:02:36 +0100 Subject: [PATCH 0229/1198] use enum --- src/core/settings.c | 6 +++--- src/core/settings.h | 7 +++++++ src/fe-text/irssi.c | 15 +++++++-------- src/irc/core/irc-servers-setup.c | 12 ++++++------ 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/core/settings.c b/src/core/settings.c index 48d6640e..3ebb9e4a 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -39,7 +39,7 @@ static GString *last_errors; static GSList *last_invalid_modules; static int fe_initialized; static int config_changed; /* FIXME: remove after .98 (unless needed again) */ -static int user_settings_changed; +static unsigned int user_settings_changed; static GHashTable *settings; static int timeout_tag; @@ -467,7 +467,7 @@ SETTINGS_REC *settings_get_record(const char *key) static void sig_init_userinfo_changed(gpointer changedp) { - user_settings_changed = GPOINTER_TO_INT(changedp); + user_settings_changed |= GPOINTER_TO_UINT(changedp); } static void sig_init_finished(void) @@ -486,7 +486,7 @@ static void sig_init_finished(void) signal_emit("setup changed", 0); } - signal_emit("settings userinfo changed", 1, GINT_TO_POINTER(user_settings_changed)); + signal_emit("settings userinfo changed", 1, GUINT_TO_POINTER(user_settings_changed)); } static void settings_clean_invalid_module(const char *module) diff --git a/src/core/settings.h b/src/core/settings.h index d174f250..b67a9e44 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -30,6 +30,13 @@ typedef struct { char **choices; } SETTINGS_REC; +enum { + USER_SETTINGS_REAL_NAME = 0x1, + USER_SETTINGS_USER_NAME = 0x2, + USER_SETTINGS_NICK = 0x4, + USER_SETTINGS_HOSTNAME = 0x8, +}; + /* macros for handling the default Irssi configuration */ #define iconfig_get_str(a, b, c) config_get_str(mainconfig, a, b, c) #define iconfig_get_int(a, b, c) config_get_int(mainconfig, a, b, c) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 6349ae2a..ef443670 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -81,7 +81,7 @@ static GMainLoop *main_loop; int quitting; static int display_firsttimer = FALSE; -static int user_settings_changed = 0; +static unsigned int user_settings_changed = 0; static void sig_exit(void) @@ -91,7 +91,7 @@ static void sig_exit(void) static void sig_settings_userinfo_changed(gpointer changedp) { - user_settings_changed = GPOINTER_TO_INT(changedp); + user_settings_changed = GPOINTER_TO_UINT(changedp); } /* redraw irssi's screen.. */ @@ -199,13 +199,13 @@ static void textui_finish_init(void) /* see irc-servers-setup.c:init_userinfo */ if (user_settings_changed) printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_WELCOME_INIT_SETTINGS); - if (user_settings_changed & (1<<0)) + if (user_settings_changed & USER_SETTINGS_REAL_NAME) fe_settings_set_print("real_name"); - if (user_settings_changed & (1<<1)) + if (user_settings_changed & USER_SETTINGS_USER_NAME) fe_settings_set_print("user_name"); - if (user_settings_changed & (1<<2)) + if (user_settings_changed & USER_SETTINGS_NICK) fe_settings_set_print("nick"); - if (user_settings_changed & (1<<3)) + if (user_settings_changed & USER_SETTINGS_HOSTNAME) fe_settings_set_print("hostname"); } @@ -222,7 +222,7 @@ static void textui_deinit(void) fe_perl_deinit(); #endif - dirty_check(); /* one last time to print any quit messages */ + dirty_check(); /* one last time to print any quit messages */ signal_remove("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed); signal_remove("gui exit", (SIGNAL_FUNC) sig_exit); @@ -250,7 +250,6 @@ static void textui_deinit(void) core_deinit(); } - static void check_files(void) { struct stat statbuf; diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 22c86f57..e79557ab 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -116,7 +116,7 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, static void init_userinfo(void) { - int changed; + unsigned int changed; const char *set, *nick, *user_name, *str; changed = 0; @@ -126,7 +126,7 @@ static void init_userinfo(void) str = g_getenv("IRCNAME"); settings_set_str("real_name", str != NULL ? str : g_get_real_name()); - changed |= 1<<0; + changed |= USER_SETTINGS_REAL_NAME; } /* username */ @@ -137,7 +137,7 @@ static void init_userinfo(void) str != NULL ? str : g_get_user_name()); user_name = settings_get_str("user_name"); - changed |= 1<<1; + changed |= USER_SETTINGS_USER_NAME; } /* nick */ @@ -147,7 +147,7 @@ static void init_userinfo(void) settings_set_str("nick", str != NULL ? str : user_name); nick = settings_get_str("nick"); - changed |= 1<<2; + changed |= USER_SETTINGS_NICK; } /* host name */ @@ -156,11 +156,11 @@ static void init_userinfo(void) str = g_getenv("IRCHOST"); if (str != NULL) { settings_set_str("hostname", str); - changed |= 1<<3; + changed |= USER_SETTINGS_HOSTNAME; } } - signal_emit("irssi init userinfo changed", 1, GINT_TO_POINTER(changed)); + signal_emit("irssi init userinfo changed", 1, GUINT_TO_POINTER(changed)); } static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) From 596fa6b51ed2ab6be80041684ad805f7b22256ac Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 11 Nov 2017 09:14:41 +0100 Subject: [PATCH 0230/1198] Take into account Nei's suggestions --- .clang-format | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index 5501478f..295356df 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ -# IndentPPDirectives: None +# IndentPPDirectives: AfterHash # SpaceInParentheses: false AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false @@ -12,22 +12,23 @@ AllowShortFunctionsOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakBeforeMultilineStrings: false BinPackArguments: true BinPackParameters: true BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeTernaryOperators: true +BreakBeforeBraces: Linux +BreakBeforeTernaryOperators: false ColumnLimit: 100 IndentCaseLabels: true IndentWidth: 8 IndentWrappedFunctionNames: true KeepEmptyLinesAtTheStartOfBlocks: false Language: Cpp +Cpp11BracedListStyle: false MaxEmptyLinesToKeep: 1 PointerAlignment: Right SortIncludes: true -SpaceAfterCStyleCast: false +SpaceAfterCStyleCast: true SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false From 7605f67f95b6ee1ac26dd8fb7f3121f319497943 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 11 Nov 2017 12:37:51 +0100 Subject: [PATCH 0231/1198] Prevent a UAF error during the execution of some commands Some arguments were free'd first and then printed, leading to gibberish being output to screen or a crash. Found by Joseph Bisch. Closes: !GL17 --- src/fe-common/core/fe-channels.c | 2 +- src/fe-common/core/fe-server.c | 2 +- src/fe-common/irc/fe-ircnet.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-channels.c b/src/fe-common/core/fe-channels.c index 8e434ab5..5cad51a7 100644 --- a/src/fe-common/core/fe-channels.c +++ b/src/fe-common/core/fe-channels.c @@ -278,9 +278,9 @@ static void cmd_channel_add_modify(const char *data, gboolean add) rec = channel_setup_find(channel, chatnet); if (rec == NULL) { if (add == FALSE) { - cmd_params_free(free_arg); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CHANSETUP_NOT_FOUND, channel, chatnet); + cmd_params_free(free_arg); return; } diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 810afe83..074a83f3 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -136,9 +136,9 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (rec == NULL) { if (add == FALSE) { - cmd_params_free(free_arg); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_NOT_FOUND, addr, port); + cmd_params_free(free_arg); return; } diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index 8f1d2efd..5ae5ac05 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -106,9 +106,9 @@ static void cmd_network_add_modify(const char *data, gboolean add) rec = ircnet_find(name); if (rec == NULL) { if (add == FALSE) { - cmd_params_free(free_arg); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_NETWORK_NOT_FOUND, name); + cmd_params_free(free_arg); return; } From 3acc72f842a021ffcff8809c1f245ca614f68598 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 15 Nov 2017 16:33:06 +0100 Subject: [PATCH 0232/1198] reset colour at comma, like mIRC Fixes #742 and #740 --- src/fe-common/core/formats.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 005e6fb7..a340bffa 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1072,7 +1072,8 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) fg = fg_ret == NULL ? -1 : *fg_ret; bg = bg_ret == NULL ? -1 : *bg_ret; - if (!i_isdigit(**str) && **str != ',') { + if (!i_isdigit(**str)) { + /* turn off color */ fg = -1; bg = -1; } else { @@ -1085,11 +1086,8 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) (*str)++; } } - if (**str == ',') { + if ((*str)[0] == ',' && i_isdigit((*str)[1])) { /* background color */ - if (!i_isdigit((*str)[1])) - bg = -1; - else { (*str)++; bg = **str-'0'; (*str)++; @@ -1097,7 +1095,6 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) bg = bg*10 + (**str-'0'); (*str)++; } - } } } From ba3c5801a4bb175fe1e0d0fd273ae15318dd2b03 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 16 Nov 2017 13:50:48 +0100 Subject: [PATCH 0233/1198] Update .clang-format do not indent case deeper --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index 295356df..1180910e 100644 --- a/.clang-format +++ b/.clang-format @@ -19,7 +19,7 @@ BreakBeforeBinaryOperators: None BreakBeforeBraces: Linux BreakBeforeTernaryOperators: false ColumnLimit: 100 -IndentCaseLabels: true +IndentCaseLabels: false IndentWidth: 8 IndentWrappedFunctionNames: true KeepEmptyLinesAtTheStartOfBlocks: false From 47400d405a0680bfe4d69ce8b06ecbfd09931999 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 20 Nov 2017 14:17:15 +0100 Subject: [PATCH 0234/1198] Update formats.c remove now useless check for , --- src/fe-common/core/formats.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index a340bffa..37db6f7c 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1078,23 +1078,22 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) bg = -1; } else { /* foreground color */ - if (**str != ',') { - fg = **str-'0'; + fg = **str-'0'; + (*str)++; + if (i_isdigit(**str)) { + fg = fg*10 + (**str-'0'); (*str)++; - if (i_isdigit(**str)) { - fg = fg*10 + (**str-'0'); - (*str)++; - } } + if ((*str)[0] == ',' && i_isdigit((*str)[1])) { /* background color */ + (*str)++; + bg = **str-'0'; + (*str)++; + if (i_isdigit(**str)) { + bg = bg*10 + (**str-'0'); (*str)++; - bg = **str-'0'; - (*str)++; - if (i_isdigit(**str)) { - bg = bg*10 + (**str-'0'); - (*str)++; - } + } } } From 1a49787ef25103d1a393c81e35fb949322fe0523 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 27 Nov 2017 19:37:11 -0800 Subject: [PATCH 0235/1198] Revert initializing pointers to NULL To maintain C89 compatibility --- src/fe-common/irc/fe-events.c | 2 +- src/irc/core/modes.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index cc83d476..850174c5 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -224,7 +224,7 @@ static void event_nick(IRC_SERVER_REC *server, const char *data, static void event_mode(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { - char *params = NULL, *channel = NULL, *mode = NULL; + char *params, *channel, *mode; g_return_if_fail(data != NULL); diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index ecbf2571..cc3d0faf 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -480,8 +480,8 @@ static void event_user_mode(IRC_SERVER_REC *server, const char *data) static void event_mode(IRC_SERVER_REC *server, const char *data, const char *nick) { - IRC_CHANNEL_REC *chanrec = NULL; - char *params = NULL, *channel = NULL, *mode = NULL; + IRC_CHANNEL_REC *chanrec; + char *params, *channel, *mode; g_return_if_fail(data != NULL); From b2ca8c04778866bd07cf1b612adf0df55f45b78e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 29 Nov 2017 15:53:12 +0100 Subject: [PATCH 0236/1198] check for declaration-after-statement on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b4b93919..1d8786c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ before_install: install: - ./configure --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build - - make CFLAGS="-Wall -Werror" + - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - make install before_script: From b332d448f7e3c7e4b40ea4a08932d0bd46007bbf Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 30 Nov 2017 11:15:47 +0100 Subject: [PATCH 0237/1198] fix comments --- src/core/ignore.h | 6 +++--- src/core/network-openssl.c | 20 ++++++++++---------- src/fe-fuzz/irssi.c | 2 +- src/fe-text/statusbar-items.c | 4 ++-- src/irc/core/sasl.c | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/ignore.h b/src/core/ignore.h index e18be3c4..31171b58 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -27,14 +27,14 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); enum { - IGNORE_FIND_PATTERN = 0x01, // Match the pattern - IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level + IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ + IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ }; 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 +/* 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); diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 7ec902fb..26496f47 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -600,7 +600,7 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger tls_rec_set_certificate_fingerprint(tls, cert_fingerprint_hex); tls_rec_set_certificate_fingerprint_algorithm(tls, "SHA256"); - // Show algorithm. + /* Show algorithm. */ switch (EVP_PKEY_id(pubkey)) { case EVP_PKEY_RSA: tls_rec_set_public_key_algorithm(tls, "RSA"); @@ -624,7 +624,7 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger tls_rec_set_public_key_size(tls, EVP_PKEY_bits(pubkey)); tls_rec_set_public_key_fingerprint_algorithm(tls, "SHA256"); - // Read the NotBefore timestamp. + /* Read the NotBefore timestamp. */ bio = BIO_new(BIO_s_mem()); ASN1_TIME_print(bio, X509_get_notBefore(cert)); length = BIO_read(bio, buffer, sizeof(buffer)); @@ -632,7 +632,7 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger BIO_free(bio); tls_rec_set_not_before(tls, buffer); - // Read the NotAfter timestamp. + /* Read the NotAfter timestamp. */ bio = BIO_new(BIO_s_mem()); ASN1_TIME_print(bio, X509_get_notAfter(cert)); length = BIO_read(bio, buffer, sizeof(buffer)); @@ -670,7 +670,7 @@ static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) for (i = 0; i < sk_X509_num(chain); i++) { cert_rec = tls_cert_create_rec(); - // Subject. + /* Subject. */ name = X509_get_subject_name(sk_X509_value(chain, i)); for (j = 0; j < X509_NAME_entry_count(name); j++) { @@ -689,7 +689,7 @@ static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) tls_cert_rec_append_subject_entry(cert_rec, tls_cert_entry_rec); } - // Issuer. + /* Issuer. */ name = X509_get_issuer_name(sk_X509_value(chain, i)); for (j = 0; j < X509_NAME_entry_count(name); j++) { @@ -718,10 +718,10 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) g_return_if_fail(ssl != NULL); #ifdef SSL_get_server_tmp_key - // Show ephemeral key information. + /* Show ephemeral key information. */ EVP_PKEY *ephemeral_key = NULL; - // OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 + /* OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 */ #ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; #endif @@ -759,7 +759,7 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) EVP_PKEY_free(ephemeral_key); } -#endif // SSL_get_server_tmp_key. +#endif /* SSL_get_server_tmp_key. */ } GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server) @@ -866,7 +866,7 @@ int irssi_ssl_handshake(GIOChannel *handle) set_peer_cert_chain_info(tls, chan->ssl); set_server_temporary_key_info(tls, chan->ssl); - // Emit the TLS rec. + /* Emit the TLS rec. */ signal_emit("tls handshake finished", 2, chan->server, tls); ret = 1; @@ -893,7 +893,7 @@ int irssi_ssl_handshake(GIOChannel *handle) ret = irssi_ssl_verify(chan->ssl, chan->ctx, chan->server->connrec->address, chan->port, cert, chan->server, tls); if (! ret) { - // irssi_ssl_verify emits a warning itself. + /* irssi_ssl_verify emits a warning itself. */ goto done; } } diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c index 77892aaf..c1b2ca9b 100644 --- a/src/fe-fuzz/irssi.c +++ b/src/fe-fuzz/irssi.c @@ -21,7 +21,7 @@ #include "module.h" #include "modules-load.h" #include "levels.h" -#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text +#include "../fe-text/module-formats.h" /* need to explicitly grab from fe-text */ #include "themes.h" #include "core.h" #include "fe-common-core.h" diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index de4499b4..c7d6bcfb 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -369,8 +369,8 @@ static void item_lag(SBAR_ITEM_REC *item, int get_size_only) last_lag_unknown = lag_unknown; if (lag_unknown) { - // "??)" in C becomes ']' - // See: https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C + /* "??)" in C becomes ']' + See: https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C */ g_snprintf(str, sizeof(str), "%d (?""?)", lag / 100); } else { if (lag % 100 == 0) diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 635b7dfb..2b589579 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -30,16 +30,16 @@ * Based on IRCv3 SASL Extension Specification: * http://ircv3.net/specs/extensions/sasl-3.1.html */ -#define AUTHENTICATE_CHUNK_SIZE 400 // bytes +#define AUTHENTICATE_CHUNK_SIZE 400 /* bytes */ /* * Maximum size to allow the buffer to grow to before the next fragment comes in. Note that * due to the way fragmentation works, the maximum message size will actually be: * floor(AUTHENTICATE_MAX_SIZE / AUTHENTICATE_CHUNK_SIZE) + AUTHENTICATE_CHUNK_SIZE - 1 */ -#define AUTHENTICATE_MAX_SIZE 8192 // bytes +#define AUTHENTICATE_MAX_SIZE 8192 /* bytes */ -#define SASL_TIMEOUT (20 * 1000) // ms +#define SASL_TIMEOUT (20 * 1000) /* ms */ static gboolean sasl_timeout(IRC_SERVER_REC *server) { From 2b918fd9b8438eeef8f33556723140263e36f731 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 30 Nov 2017 11:17:05 +0100 Subject: [PATCH 0238/1198] move decls before code --- src/core/network-openssl.c | 18 +++++++++--------- src/fe-common/core/fe-windows.c | 4 +++- src/perl/common/Expando.xs | 3 ++- src/perl/textui/Statusbar.xs | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 26496f47..c7ce4b43 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -583,9 +583,6 @@ static void set_cipher_info(TLS_REC *tls, SSL *ssl) static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_fingerprint, size_t cert_fingerprint_size, unsigned char *public_key_fingerprint, size_t public_key_fingerprint_size) { - g_return_if_fail(tls != NULL); - g_return_if_fail(cert != NULL); - EVP_PKEY *pubkey = NULL; char *cert_fingerprint_hex = NULL; char *public_key_fingerprint_hex = NULL; @@ -594,6 +591,9 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger char buffer[128]; size_t length; + g_return_if_fail(tls != NULL); + g_return_if_fail(cert != NULL); + pubkey = X509_get_pubkey(cert); cert_fingerprint_hex = binary_to_hex(cert_fingerprint, cert_fingerprint_size); @@ -647,9 +647,6 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) { - g_return_if_fail(tls != NULL); - g_return_if_fail(ssl != NULL); - int nid; char *key = NULL; char *value = NULL; @@ -662,6 +659,9 @@ static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) TLS_CERT_ENTRY_REC *tls_cert_entry_rec = NULL; ASN1_STRING *data = NULL; + g_return_if_fail(tls != NULL); + g_return_if_fail(ssl != NULL); + chain = SSL_get_peer_cert_chain(ssl); if (chain == NULL) @@ -714,9 +714,6 @@ static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) { - g_return_if_fail(tls != NULL); - g_return_if_fail(ssl != NULL); - #ifdef SSL_get_server_tmp_key /* Show ephemeral key information. */ EVP_PKEY *ephemeral_key = NULL; @@ -729,6 +726,9 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) char *cname = NULL; int nid; + g_return_if_fail(tls != NULL); + g_return_if_fail(ssl != NULL); + if (SSL_get_server_tmp_key(ssl, &ephemeral_key)) { switch (EVP_PKEY_id(ephemeral_key)) { case EVP_PKEY_DH: diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 0afa2914..93f2e3f3 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -563,8 +563,10 @@ GSList *windows_get_sorted(void) begin = windows_seq_begin(); while (iter != begin) { + WINDOW_REC *rec; + iter = g_sequence_iter_prev(iter); - WINDOW_REC *rec = g_sequence_get(iter); + rec = g_sequence_get(iter); sorted = g_slist_prepend(sorted, rec); } diff --git a/src/perl/common/Expando.xs b/src/perl/common/Expando.xs index 26800b05..84853a02 100644 --- a/src/perl/common/Expando.xs +++ b/src/perl/common/Expando.xs @@ -74,6 +74,7 @@ static char *perl_expando_event(PerlExpando *rec, SERVER_REC *server, ret = NULL; if (SvTRUE(ERRSV)) { + char *error; PERL_SCRIPT_REC *script = rec->script; (void) POPs; @@ -85,7 +86,7 @@ static char *perl_expando_event(PerlExpando *rec, SERVER_REC *server, script_unregister_expandos(script); /* rec has been freed now */ - char *error = g_strdup(SvPV_nolen(ERRSV)); + error = g_strdup(SvPV_nolen(ERRSV)); signal_emit("script error", 2, script, error); g_free(error); } else if (retcount > 0) { diff --git a/src/perl/textui/Statusbar.xs b/src/perl/textui/Statusbar.xs index 8b0e5f65..111deaa7 100644 --- a/src/perl/textui/Statusbar.xs +++ b/src/perl/textui/Statusbar.xs @@ -67,7 +67,7 @@ static void perl_statusbar_event(char *function, SBAR_ITEM_REC *item, if (SvTRUE(ERRSV)) { PERL_SCRIPT_REC *script; - char *package; + char *package, *error; package = perl_function_get_package(function); script = perl_script_find_package(package); @@ -78,7 +78,7 @@ static void perl_statusbar_event(char *function, SBAR_ITEM_REC *item, script_unregister_statusbars(script); } - char *error = g_strdup(SvPV_nolen(ERRSV)); + error = g_strdup(SvPV_nolen(ERRSV)); signal_emit("script error", 2, script, error); g_free(error); } else { From b0637ad6ea8784d3b2be829ca40f9dddf0c049fc Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 2 Dec 2017 10:09:52 -0800 Subject: [PATCH 0239/1198] Update NULL comparison style and be C89 compatible --- src/irc/core/irc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 790c7122..a740b0da 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -287,11 +287,13 @@ char *event_get_params(const char *data, int count, ...) /* Given a string containing , strip any colon prefixing . */ static void strip_params_colon(char *const params) { - if (!params) { + char *s; + + if (params == NULL) { return; } - char *s = params; + s = params; while (*s != '\0') { if (*s == ':') { memmove(s, s+1, strlen(s+1)+1); @@ -299,7 +301,7 @@ static void strip_params_colon(char *const params) } s = strchr(s, ' '); - if (!s) { + if (s == NULL) { return; } From 1328e1ba08430b0eaa589919272d732bb84a6921 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 21 Oct 2017 20:01:04 -0700 Subject: [PATCH 0240/1198] Add a test program to test mode parsing This uses GLib's testing framework. It is to test the changes to the mode parsing for #603. --- .gitignore | 3 + .travis.yml | 4 +- Makefile.am | 2 +- configure.ac | 3 + tests/Makefile.am | 1 + tests/irc/Makefile.am | 1 + tests/irc/core/Makefile.am | 36 ++++++ tests/irc/core/test-irc.c | 230 +++++++++++++++++++++++++++++++++++++ 8 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 tests/Makefile.am create mode 100644 tests/irc/Makefile.am create mode 100644 tests/irc/core/Makefile.am create mode 100644 tests/irc/core/test-irc.c diff --git a/.gitignore b/.gitignore index efc579cb..cf1cf72e 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,9 @@ src/perl/*/Makefile.old src/fe-fuzz/crash-* src/fe-fuzz/oom-* +tests/irc/core/test-irc +tests/irc/core/test-irc.trs + *.a *.bs *.la diff --git a/.travis.yml b/.travis.yml index 1d8786c4..1e04d943 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,5 +49,7 @@ before_script: - echo ^quit >> irssi-test/startup - irssi-build/bin/irssi --home irssi-test - cat irc.log.* + - cd $TRAVIS_BUILD_DIR -script: true +script: + - make check diff --git a/Makefile.am b/Makefile.am index f52ac92f..ba45d8ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,7 @@ irssi-version.h: VERSION="$(VERSION)" $(srcdir)/utils/irssi-version.sh $(srcdir) | \ cmp -s - $@ || VERSION="$(VERSION)" $(srcdir)/utils/irssi-version.sh $(srcdir) >$@ -SUBDIRS = src docs scripts themes utils +SUBDIRS = src tests docs scripts themes utils confdir = $(sysconfdir) conf_DATA = irssi.conf diff --git a/configure.ac b/configure.ac index 4b65d434..bf15e6ae 100644 --- a/configure.ac +++ b/configure.ac @@ -658,6 +658,9 @@ src/perl/ui/Makefile.PL src/perl/textui/Makefile.PL scripts/Makefile scripts/examples/Makefile +tests/Makefile +tests/irc/Makefile +tests/irc/core/Makefile docs/Makefile docs/help/Makefile docs/help/in/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 00000000..58c348df --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = irc diff --git a/tests/irc/Makefile.am b/tests/irc/Makefile.am new file mode 100644 index 00000000..52770885 --- /dev/null +++ b/tests/irc/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = core diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am new file mode 100644 index 00000000..fff2a246 --- /dev/null +++ b/tests/irc/core/Makefile.am @@ -0,0 +1,36 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + $(GLIB_CFLAGS) + +TESTS = test-irc +check_PROGRAMS = test-irc + +test_irc_CPPFLAGS = \ + -I$(top_srcdir)/src/irc/core \ + $(AM_CPPFLAGS) + +test_irc_DEPENDENCIES = \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a + +test_irc_LDADD = \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a \ + @GLIB_LIBS@ \ + @OPENSSL_LIBS@ + +test_irc_SOURCES = \ + test-irc.c \ + ../../../src/irc/core/irc-cap.c \ + ../../../src/irc/core/irc-nicklist.c \ + ../../../src/irc/core/irc-queries.c \ + ../../../src/irc/core/irc-servers-reconnect.c \ + ../../../src/irc/core/irc-servers-setup.c \ + ../../../src/irc/core/irc-servers.c \ + ../../../src/irc/core/irc.c \ + ../../../src/irc/core/mode-lists.c \ + ../../../src/irc/core/modes.c \ + ../../../src/irc/core/servers-idle.c \ + ../../../src/irc/core/servers-redirect.c diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c new file mode 100644 index 00000000..7e85c9ba --- /dev/null +++ b/tests/irc/core/test-irc.c @@ -0,0 +1,230 @@ +/* + test-irc.c : irssi + + Copyright (C) 2017 Will Storey + + 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 +#include +#include + +static void test_event_get_param(void); +static void test_event_get_params(void); + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/test/event_get_param", test_event_get_param); + g_test_add_func("/test/event_get_params", test_event_get_params); + + return g_test_run(); +} + +static void test_event_get_param(void) +{ + struct test_case { + char const *const description; + char const *const input; + char const *const input_after; + char const *const output; + }; + + struct test_case const tests[] = { + { + .description = "Zero parameters", + .input = "", + .input_after = "", + .output = "", + }, + { + .description = "One parameter", + .input = "#test", + .input_after = "", + .output = "#test", + }, + { + .description = "One parameter, trailing space", + .input = "#test ", + .input_after = "", + .output = "#test", + }, + { + .description = "One parameter, more trailing space", + .input = "#test ", + .input_after = " ", + .output = "#test", + }, + { + .description = "Two parameters", + .input = "#test +o", + .input_after = "+o", + .output = "#test", + }, + { + .description = "Two parameters continued", + .input = "+o", + .input_after = "", + .output = "+o", + }, + { + .description = "Two parameters with trailing space", + .input = "#test +o ", + .input_after = "+o ", + .output = "#test", + }, + { + .description = "Two parameters with trailing space continued", + .input = "+o ", + .input_after = "", + .output = "+o", + }, + { + .description = "Two parameters with inline and trailing space", + .input = "#test +o ", + .input_after = " +o ", + .output = "#test", + }, + /* TODO: It seems not ideal that the caller has to deal with inline space. + */ + { + .description = "Two parameters with inline and trailing space continued", + .input = " +o ", + .input_after = "+o ", + .output = "", + }, + }; + + char *buf = g_malloc0(1024); + + int i = 0; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + struct test_case const test = tests[i]; + + memcpy(buf, test.input, strlen(test.input)+1); + char *input = buf; + + char *const output = event_get_param(&input); + + g_assert_cmpstr(input, ==, test.input_after); + g_assert_cmpstr(output, ==, test.output); + } + + g_free(buf); +} + +static void test_event_get_params(void) +{ + struct test_case { + char const *const description; + char const *const input; + char const *const output0; + char const *const output1; + }; + + struct test_case const tests[] = { + { + .description = "Only a channel", + .input = "#test", + .output0 = "#test", + .output1 = "", + }, + { + .description = "Only a channel with trailing space", + .input = "#test ", + .output0 = "#test", + .output1 = "", + }, + { + .description = "No :, channel mode with one parameter after channel name", + .input = "#test +i", + .output0 = "#test", + .output1 = "+i", + }, + { + .description = "No :, channel mode with two parameters after channel name", + .input = "#test +o tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "No :, channel mode with three parameters afer channel name", + .input = "#test +ov tester tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "No :, channel mode with three parameters afer channel name, bunch of extra space", + .input = "#test +ov tester tester2 ", + .output0 = "#test", + .output1 = " +ov tester tester2 ", + }, + { + .description = "Channel mode with one parameter after channel name, : at the start of modes", + .input = "#test :+i", + .output0 = "#test", + .output1 = "+i", + }, + { + .description = "Channel mode with two parameters after channel name, : at the start of modes", + .input = "#test :+o tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "Channel mode with three parameters after channel name, : at the start of modes", + .input = "#test :+ov tester tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "Channel mode with two parameters after channel name, : on the final parameter", + .input = "#test +o :tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "Channel mode with three parameters after channel name, : on the final parameter", + .input = "#test +ov tester :tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "Channel mode with three parameters after channel name, : on the final parameter, also a second : present", + .input = "#test +ov tester :tester2 hi:there", + .output0 = "#test", + .output1 = "+ov tester tester2 hi:there", + }, + }; + + int i = 0; + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + struct test_case const test = tests[i]; + + char *output0 = NULL; + char *output1 = NULL; + char *const params = event_get_params(test.input, 2 | PARAM_FLAG_GETREST, + &output0, &output1); + + /* params happens to always point at the first output */ + g_assert_cmpstr(params, ==, test.output0); + g_assert_cmpstr(output0, ==, test.output0); + g_assert_cmpstr(output1, ==, test.output1); + + g_free(params); + } +} From c20eddeb385974d6f46494e71ab63d4493df119b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 26 Nov 2017 16:19:31 +0100 Subject: [PATCH 0241/1198] add glib testing TAP utilities --- configure.ac | 2 + m4/glibtests.m4 | 28 ++ tests/irc/core/Makefile.am | 5 +- tests/irc/core/test-irc.c | 1 + utils/Makefile.am | 4 +- utils/glib-tap.mk | 134 ++++++++ utils/tap-driver.sh | 652 +++++++++++++++++++++++++++++++++++++ utils/tap-test | 5 + 8 files changed, 828 insertions(+), 3 deletions(-) create mode 100644 m4/glibtests.m4 create mode 100644 utils/glib-tap.mk create mode 100755 utils/tap-driver.sh create mode 100755 utils/tap-test diff --git a/configure.ac b/configure.ac index bf15e6ae..c780b9b8 100644 --- a/configure.ac +++ b/configure.ac @@ -295,6 +295,8 @@ fi LIBS="$LIBS $GLIB_LIBS" +GLIB_TESTS + dnl ** dnl ** OpenSSL checks dnl ** diff --git a/m4/glibtests.m4 b/m4/glibtests.m4 new file mode 100644 index 00000000..7d5920a4 --- /dev/null +++ b/m4/glibtests.m4 @@ -0,0 +1,28 @@ +dnl GLIB_TESTS +dnl + +AC_DEFUN([GLIB_TESTS], +[ + AC_ARG_ENABLE(installed-tests, + AS_HELP_STRING([--enable-installed-tests], + [Enable installation of some test cases]), + [case ${enableval} in + yes) ENABLE_INSTALLED_TESTS="1" ;; + no) ENABLE_INSTALLED_TESTS="" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;; + esac]) + AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1") + AC_ARG_ENABLE(always-build-tests, + AS_HELP_STRING([--enable-always-build-tests], + [Enable always building tests during 'make all']), + [case ${enableval} in + yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;; + no) ENABLE_ALWAYS_BUILD_TESTS="" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;; + esac]) + AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1") + if test "$ENABLE_INSTALLED_TESTS" = "1"; then + AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME) + AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME) + fi +]) diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index fff2a246..b5345067 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -1,11 +1,12 @@ +include $(top_srcdir)/utils/glib-tap.mk + AM_CPPFLAGS = \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/core \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) -TESTS = test-irc -check_PROGRAMS = test-irc +test_programs = test-irc test_irc_CPPFLAGS = \ -I$(top_srcdir)/src/irc/core \ diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c index 7e85c9ba..4c62e6a7 100644 --- a/tests/irc/core/test-irc.c +++ b/tests/irc/core/test-irc.c @@ -32,6 +32,7 @@ int main(int argc, char **argv) g_test_add_func("/test/event_get_param", test_event_get_param); g_test_add_func("/test/event_get_params", test_event_get_params); + g_test_set_nonfatal_assertions(); return g_test_run(); } diff --git a/utils/Makefile.am b/utils/Makefile.am index be24c17f..8af5c8f7 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -1,4 +1,6 @@ EXTRA_DIST = \ file2header.sh \ irssi-version.sh \ - syntax.pl + syntax.pl \ + tap-driver.sh \ + tap-test diff --git a/utils/glib-tap.mk b/utils/glib-tap.mk new file mode 100644 index 00000000..582f6d29 --- /dev/null +++ b/utils/glib-tap.mk @@ -0,0 +1,134 @@ +# GLIB - Library of useful C routines + +TESTS_ENVIRONMENT= \ + G_TEST_SRCDIR="$(abs_srcdir)" \ + G_TEST_BUILDDIR="$(abs_builddir)" \ + G_DEBUG=gc-friendly \ + MALLOC_CHECK_=2 \ + MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) +LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/utils/tap-driver.sh +LOG_COMPILER = $(top_srcdir)/utils/tap-test + +NULL = + +# initialize variables for unconditional += appending +BUILT_SOURCES = +BUILT_EXTRA_DIST = +CLEANFILES = *.log *.trs +DISTCLEANFILES = +MAINTAINERCLEANFILES = +EXTRA_DIST = +TESTS = + +installed_test_LTLIBRARIES = +installed_test_PROGRAMS = +installed_test_SCRIPTS = +nobase_installed_test_DATA = + +noinst_LTLIBRARIES = +noinst_PROGRAMS = +noinst_SCRIPTS = +noinst_DATA = + +check_LTLIBRARIES = +check_PROGRAMS = +check_SCRIPTS = +check_DATA = + +# We support a fairly large range of possible variables. It is expected that all types of files in a test suite +# will belong in exactly one of the following variables. +# +# First, we support the usual automake suffixes, but in lowercase, with the customary meaning: +# +# test_programs, test_scripts, test_data, test_ltlibraries +# +# The above are used to list files that are involved in both uninstalled and installed testing. The +# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite. +# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is +# installed in the same way as it appears in the package layout. +# +# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled', +# like so: +# +# installed_test_programs, uninstalled_test_programs +# installed_test_scripts, uninstalled_test_scripts +# installed_test_data, uninstalled_test_data +# installed_test_ltlibraries, uninstalled_test_ltlibraries +# +# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts +# that should not themselves be run as testcases (but exist to be used from other testcases): +# +# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs +# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts +# +# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data +# file automatically end up in the tarball. +# +# dist_test_scripts, dist_test_data, dist_test_extra_scripts +# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts +# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts +# +# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the +# standard automake convention of not disting programs scripts or data by default. +# +# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted +# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under +# gtester. That's a bit strange for scripts, but it's possible. + +TESTS += $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \ + $(dist_test_scripts) $(dist_uninstalled_test_scripts) + +# Note: build even the installed-only targets during 'make check' to ensure that they still work. +# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to +# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were +# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'. +all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \ + $(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs) +all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) $(installed_test_scripts) \ + $(test_extra_scripts) $(uninstalled_test_extra_scripts) $(installed_test_extra_scripts) +all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \ + $(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts) +all_test_scripts += $(all_dist_test_scripts) +EXTRA_DIST += $(all_dist_test_scripts) +all_test_data = $(test_data) $(uninstalled_test_data) $(installed_test_data) +all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data) +all_test_data += $(all_dist_test_data) +EXTRA_DIST += $(all_dist_test_data) +all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries) + +if ENABLE_ALWAYS_BUILD_TESTS +noinst_LTLIBRARIES += $(all_test_ltlibs) +noinst_PROGRAMS += $(all_test_programs) +noinst_SCRIPTS += $(all_test_scripts) +noinst_DATA += $(all_test_data) +else +check_LTLIBRARIES += $(all_test_ltlibs) +check_PROGRAMS += $(all_test_programs) +check_SCRIPTS += $(all_test_scripts) +check_DATA += $(all_test_data) +endif + +if ENABLE_INSTALLED_TESTS +installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \ + $(test_extra_programs) $(installed_test_extra_programs) +installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \ + $(test_extra_scripts) $(test_installed_extra_scripts) +installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \ + $(dist_installed_test_scripts) $(dist_installed_test_extra_scripts) +nobase_installed_test_DATA += $(test_data) $(installed_test_data) +nobase_installed_test_DATA += $(dist_test_data) $(dist_installed_test_data) +installed_test_LTLIBRARIES += $(test_ltlibraries) $(installed_test_ltlibraries) +installed_testcases = $(test_programs) $(installed_test_programs) \ + $(test_scripts) $(installed_test_scripts) \ + $(dist_test_scripts) $(dist_installed_test_scripts) + +installed_test_meta_DATA = $(installed_testcases:=.test) + +%.test: %$(EXEEXT) Makefile + $(AM_V_GEN) (echo '[Test]' > $@.tmp; \ + echo 'Type=session' >> $@.tmp; \ + echo 'Exec=$(installed_testdir)/$<' >> $@.tmp; \ + mv $@.tmp $@) + +CLEANFILES += $(installed_test_meta_DATA) +endif diff --git a/utils/tap-driver.sh b/utils/tap-driver.sh new file mode 100755 index 00000000..19aa531d --- /dev/null +++ b/utils/tap-driver.sh @@ -0,0 +1,652 @@ +#! /bin/sh +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# 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, 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +scriptversion=2011-12-27.17; # UTC + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +me=tap-driver.sh + +fatal () +{ + echo "$me: fatal: $*" >&2 + exit 1 +} + +usage_error () +{ + echo "$me: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat < + # + trap : 1 3 2 13 15 + if test $merge -gt 0; then + exec 2>&1 + else + exec 2>&3 + fi + "$@" + echo $? + ) | LC_ALL=C ${AM_TAP_AWK-awk} \ + -v me="$me" \ + -v test_script_name="$test_name" \ + -v log_file="$log_file" \ + -v trs_file="$trs_file" \ + -v expect_failure="$expect_failure" \ + -v merge="$merge" \ + -v ignore_exit="$ignore_exit" \ + -v comments="$comments" \ + -v diag_string="$diag_string" \ +' +# FIXME: the usages of "cat >&3" below could be optimized when using +# FIXME: GNU awk, and/on on systems that supports /dev/fd/. + +# Implementation note: in what follows, `result_obj` will be an +# associative array that (partly) simulates a TAP result object +# from the `TAP::Parser` perl module. + +## ----------- ## +## FUNCTIONS ## +## ----------- ## + +function fatal(msg) +{ + print me ": " msg | "cat >&2" + exit 1 +} + +function abort(where) +{ + fatal("internal error " where) +} + +# Convert a boolean to a "yes"/"no" string. +function yn(bool) +{ + return bool ? "yes" : "no"; +} + +function add_test_result(result) +{ + if (!test_results_index) + test_results_index = 0 + test_results_list[test_results_index] = result + test_results_index += 1 + test_results_seen[result] = 1; +} + +# Whether the test script should be re-run by "make recheck". +function must_recheck() +{ + for (k in test_results_seen) + if (k != "XFAIL" && k != "PASS" && k != "SKIP") + return 1 + return 0 +} + +# Whether the content of the log file associated to this test should +# be copied into the "global" test-suite.log. +function copy_in_global_log() +{ + for (k in test_results_seen) + if (k != "PASS") + return 1 + return 0 +} + +# FIXME: this can certainly be improved ... +function get_global_test_result() +{ + if ("ERROR" in test_results_seen) + return "ERROR" + if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) + return "FAIL" + all_skipped = 1 + for (k in test_results_seen) + if (k != "SKIP") + all_skipped = 0 + if (all_skipped) + return "SKIP" + return "PASS"; +} + +function stringify_result_obj(result_obj) +{ + if (result_obj["is_unplanned"] || result_obj["number"] != testno) + return "ERROR" + + if (plan_seen == LATE_PLAN) + return "ERROR" + + if (result_obj["directive"] == "TODO") + return result_obj["is_ok"] ? "XPASS" : "XFAIL" + + if (result_obj["directive"] == "SKIP") + return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; + + if (length(result_obj["directive"])) + abort("in function stringify_result_obj()") + + return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL +} + +function decorate_result(result) +{ + color_name = color_for_result[result] + if (color_name) + return color_map[color_name] "" result "" color_map["std"] + # If we are not using colorized output, or if we do not know how + # to colorize the given result, we should return it unchanged. + return result +} + +function report(result, details) +{ + if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) + { + msg = ": " test_script_name + add_test_result(result) + } + else if (result == "#") + { + msg = " " test_script_name ":" + } + else + { + abort("in function report()") + } + if (length(details)) + msg = msg " " details + # Output on console might be colorized. + print decorate_result(result) msg + # Log the result in the log file too, to help debugging (this is + # especially true when said result is a TAP error or "Bail out!"). + print result msg | "cat >&3"; +} + +function testsuite_error(error_message) +{ + report("ERROR", "- " error_message) +} + +function handle_tap_result() +{ + details = result_obj["number"]; + if (length(result_obj["description"])) + details = details " " result_obj["description"] + + if (plan_seen == LATE_PLAN) + { + details = details " # AFTER LATE PLAN"; + } + else if (result_obj["is_unplanned"]) + { + details = details " # UNPLANNED"; + } + else if (result_obj["number"] != testno) + { + details = sprintf("%s # OUT-OF-ORDER (expecting %d)", + details, testno); + } + else if (result_obj["directive"]) + { + details = details " # " result_obj["directive"]; + if (length(result_obj["explanation"])) + details = details " " result_obj["explanation"] + } + + report(stringify_result_obj(result_obj), details) +} + +# `skip_reason` should be empty whenever planned > 0. +function handle_tap_plan(planned, skip_reason) +{ + planned += 0 # Avoid getting confused if, say, `planned` is "00" + if (length(skip_reason) && planned > 0) + abort("in function handle_tap_plan()") + if (plan_seen) + { + # Error, only one plan per stream is acceptable. + testsuite_error("multiple test plans") + return; + } + planned_tests = planned + # The TAP plan can come before or after *all* the TAP results; we speak + # respectively of an "early" or a "late" plan. If we see the plan line + # after at least one TAP result has been seen, assume we have a late + # plan; in this case, any further test result seen after the plan will + # be flagged as an error. + plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) + # If testno > 0, we have an error ("too many tests run") that will be + # automatically dealt with later, so do not worry about it here. If + # $plan_seen is true, we have an error due to a repeated plan, and that + # has already been dealt with above. Otherwise, we have a valid "plan + # with SKIP" specification, and should report it as a particular kind + # of SKIP result. + if (planned == 0 && testno == 0) + { + if (length(skip_reason)) + skip_reason = "- " skip_reason; + report("SKIP", skip_reason); + } +} + +function extract_tap_comment(line) +{ + if (index(line, diag_string) == 1) + { + # Strip leading `diag_string` from `line`. + line = substr(line, length(diag_string) + 1) + # And strip any leading and trailing whitespace left. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + # Return what is left (if any). + return line; + } + return ""; +} + +# When this function is called, we know that line is a TAP result line, +# so that it matches the (perl) RE "^(not )?ok\b". +function setup_result_obj(line) +{ + # Get the result, and remove it from the line. + result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) + sub("^(not )?ok[ \t]*", "", line) + + # If the result has an explicit number, get it and strip it; otherwise, + # automatically assing the next progresive number to it. + if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) + { + match(line, "^[0-9]+") + # The final `+ 0` is to normalize numbers with leading zeros. + result_obj["number"] = substr(line, 1, RLENGTH) + 0 + line = substr(line, RLENGTH + 1) + } + else + { + result_obj["number"] = testno + } + + if (plan_seen == LATE_PLAN) + # No further test results are acceptable after a "late" TAP plan + # has been seen. + result_obj["is_unplanned"] = 1 + else if (plan_seen && testno > planned_tests) + result_obj["is_unplanned"] = 1 + else + result_obj["is_unplanned"] = 0 + + # Strip trailing and leading whitespace. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + + # This will have to be corrected if we have a "TODO"/"SKIP" directive. + result_obj["description"] = line + result_obj["directive"] = "" + result_obj["explanation"] = "" + + if (index(line, "#") == 0) + return # No possible directive, nothing more to do. + + # Directives are case-insensitive. + rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" + + # See whether we have the directive, and if yes, where. + pos = match(line, rx "$") + if (!pos) + pos = match(line, rx "[^a-zA-Z0-9_]") + + # If there was no TAP directive, we have nothing more to do. + if (!pos) + return + + # Let`s now see if the TAP directive has been escaped. For example: + # escaped: ok \# SKIP + # not escaped: ok \\# SKIP + # escaped: ok \\\\\# SKIP + # not escaped: ok \ # SKIP + if (substr(line, pos, 1) == "#") + { + bslash_count = 0 + for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) + bslash_count += 1 + if (bslash_count % 2) + return # Directive was escaped. + } + + # Strip the directive and its explanation (if any) from the test + # description. + result_obj["description"] = substr(line, 1, pos - 1) + # Now remove the test description from the line, that has been dealt + # with already. + line = substr(line, pos) + # Strip the directive, and save its value (normalized to upper case). + sub("^[ \t]*#[ \t]*", "", line) + result_obj["directive"] = toupper(substr(line, 1, 4)) + line = substr(line, 5) + # Now get the explanation for the directive (if any), with leading + # and trailing whitespace removed. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + result_obj["explanation"] = line +} + +function get_test_exit_message(status) +{ + if (status == 0) + return "" + if (status !~ /^[1-9][0-9]*$/) + abort("getting exit status") + if (status < 127) + exit_details = "" + else if (status == 127) + exit_details = " (command not found?)" + else if (status >= 128 && status <= 255) + exit_details = sprintf(" (terminated by signal %d?)", status - 128) + else if (status > 256 && status <= 384) + # We used to report an "abnormal termination" here, but some Korn + # shells, when a child process die due to signal number n, can leave + # in $? an exit status of 256+n instead of the more standard 128+n. + # Apparently, both behaviours are allowed by POSIX (2008), so be + # prepared to handle them both. See also Austing Group report ID + # 0000051 + exit_details = sprintf(" (terminated by signal %d?)", status - 256) + else + # Never seen in practice. + exit_details = " (abnormal termination)" + return sprintf("exited with status %d%s", status, exit_details) +} + +function write_test_results() +{ + print ":global-test-result: " get_global_test_result() > trs_file + print ":recheck: " yn(must_recheck()) > trs_file + print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file + for (i = 0; i < test_results_index; i += 1) + print ":test-result: " test_results_list[i] > trs_file + close(trs_file); +} + +BEGIN { + +## ------- ## +## SETUP ## +## ------- ## + +'"$init_colors"' + +# Properly initialized once the TAP plan is seen. +planned_tests = 0 + +COOKED_PASS = expect_failure ? "XPASS": "PASS"; +COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; + +# Enumeration-like constants to remember which kind of plan (if any) +# has been seen. It is important that NO_PLAN evaluates "false" as +# a boolean. +NO_PLAN = 0 +EARLY_PLAN = 1 +LATE_PLAN = 2 + +testno = 0 # Number of test results seen so far. +bailed_out = 0 # Whether a "Bail out!" directive has been seen. + +# Whether the TAP plan has been seen or not, and if yes, which kind +# it is ("early" is seen before any test result, "late" otherwise). +plan_seen = NO_PLAN + +## --------- ## +## PARSING ## +## --------- ## + +is_first_read = 1 + +while (1) + { + # Involutions required so that we are able to read the exit status + # from the last input line. + st = getline + if (st < 0) # I/O error. + fatal("I/O error while reading from input stream") + else if (st == 0) # End-of-input + { + if (is_first_read) + abort("in input loop: only one input line") + break + } + if (is_first_read) + { + is_first_read = 0 + nextline = $0 + continue + } + else + { + curline = nextline + nextline = $0 + $0 = curline + } + # Copy any input line verbatim into the log file. + print | "cat >&3" + # Parsing of TAP input should stop after a "Bail out!" directive. + if (bailed_out) + continue + + # TAP test result. + if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) + { + testno += 1 + setup_result_obj($0) + handle_tap_result() + } + # TAP plan (normal or "SKIP" without explanation). + else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) + { + # The next two lines will put the number of planned tests in $0. + sub("^1\\.\\.", "") + sub("[^0-9]*$", "") + handle_tap_plan($0, "") + continue + } + # TAP "SKIP" plan, with an explanation. + else if ($0 ~ /^1\.\.0+[ \t]*#/) + { + # The next lines will put the skip explanation in $0, stripping + # any leading and trailing whitespace. This is a little more + # tricky in truth, since we want to also strip a potential leading + # "SKIP" string from the message. + sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") + sub("[ \t]*$", ""); + handle_tap_plan(0, $0) + } + # "Bail out!" magic. + # Older versions of prove and TAP::Harness (e.g., 3.17) did not + # recognize a "Bail out!" directive when preceded by leading + # whitespace, but more modern versions (e.g., 3.23) do. So we + # emulate the latter, "more modern" behaviour. + else if ($0 ~ /^[ \t]*Bail out!/) + { + bailed_out = 1 + # Get the bailout message (if any), with leading and trailing + # whitespace stripped. The message remains stored in `$0`. + sub("^[ \t]*Bail out![ \t]*", ""); + sub("[ \t]*$", ""); + # Format the error message for the + bailout_message = "Bail out!" + if (length($0)) + bailout_message = bailout_message " " $0 + testsuite_error(bailout_message) + } + # Maybe we have too look for dianogtic comments too. + else if (comments != 0) + { + comment = extract_tap_comment($0); + if (length(comment)) + report("#", comment); + } + } + +## -------- ## +## FINISH ## +## -------- ## + +# A "Bail out!" directive should cause us to ignore any following TAP +# error, as well as a non-zero exit status from the TAP producer. +if (!bailed_out) + { + if (!plan_seen) + { + testsuite_error("missing test plan") + } + else if (planned_tests != testno) + { + bad_amount = testno > planned_tests ? "many" : "few" + testsuite_error(sprintf("too %s tests run (expected %d, got %d)", + bad_amount, planned_tests, testno)) + } + if (!ignore_exit) + { + # Fetch exit status from the last line. + exit_message = get_test_exit_message(nextline) + if (exit_message) + testsuite_error(exit_message) + } + } + +write_test_results() + +exit 0 + +} # End of "BEGIN" block. +' + +# TODO: document that we consume the file descriptor 3 :-( +} 3>"$log_file" + +test $? -eq 0 || fatal "I/O or internal error" + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/utils/tap-test b/utils/tap-test new file mode 100755 index 00000000..481e333e --- /dev/null +++ b/utils/tap-test @@ -0,0 +1,5 @@ +#! /bin/sh + +# run a GTest in tap mode. The test binary is passed as $1 + +$1 -k --tap From 43d06369bf8e5c5e470dc2b00656ddcdb9ee0480 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 26 Nov 2017 21:10:07 +0100 Subject: [PATCH 0242/1198] move fixtures to outer scope --- tests/irc/core/Makefile.am | 16 +- tests/irc/core/test-irc.c | 372 ++++++++++++++++++------------------- 2 files changed, 190 insertions(+), 198 deletions(-) diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index b5345067..ccc6aa97 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -1,5 +1,7 @@ include $(top_srcdir)/utils/glib-tap.mk +PACKAGE_STRING=irc/core + AM_CPPFLAGS = \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/core \ @@ -17,21 +19,11 @@ test_irc_DEPENDENCIES = \ ../../../src/lib-config/libirssi_config.a test_irc_LDADD = \ + ../../../src/irc/core/libirc_core.a \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a \ @GLIB_LIBS@ \ @OPENSSL_LIBS@ test_irc_SOURCES = \ - test-irc.c \ - ../../../src/irc/core/irc-cap.c \ - ../../../src/irc/core/irc-nicklist.c \ - ../../../src/irc/core/irc-queries.c \ - ../../../src/irc/core/irc-servers-reconnect.c \ - ../../../src/irc/core/irc-servers-setup.c \ - ../../../src/irc/core/irc-servers.c \ - ../../../src/irc/core/irc.c \ - ../../../src/irc/core/mode-lists.c \ - ../../../src/irc/core/modes.c \ - ../../../src/irc/core/servers-idle.c \ - ../../../src/irc/core/servers-redirect.c + test-irc.c diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c index 4c62e6a7..90ce856b 100644 --- a/tests/irc/core/test-irc.c +++ b/tests/irc/core/test-irc.c @@ -22,210 +22,210 @@ #include #include -static void test_event_get_param(void); -static void test_event_get_params(void); +typedef struct { + char const *const description; + char const *const input; + char const *const input_after; + char const *const output; +} event_get_param_test_case; + +event_get_param_test_case const event_get_param_fixtures[] = { + { + .description = "Zero parameters", + .input = "", + .input_after = "", + .output = "", + }, + { + .description = "One parameter", + .input = "#test", + .input_after = "", + .output = "#test", + }, + { + .description = "One parameter, trailing space", + .input = "#test ", + .input_after = "", + .output = "#test", + }, + { + .description = "One parameter, more trailing space", + .input = "#test ", + .input_after = " ", + .output = "#test", + }, + { + .description = "Two parameters", + .input = "#test +o", + .input_after = "+o", + .output = "#test", + }, + { + .description = "Two parameters continued", + .input = "+o", + .input_after = "", + .output = "+o", + }, + { + .description = "Two parameters with trailing space", + .input = "#test +o ", + .input_after = "+o ", + .output = "#test", + }, + { + .description = "Two parameters with trailing space continued", + .input = "+o ", + .input_after = "", + .output = "+o", + }, + { + .description = "Two parameters with inline and trailing space", + .input = "#test +o ", + .input_after = " +o ", + .output = "#test", + }, + /* TODO: It seems not ideal that the caller has to deal with inline space. + */ + { + .description = "Two parameters with inline and trailing space continued", + .input = " +o ", + .input_after = "+o ", + .output = "", + }, +}; + +static void test_event_get_param(const event_get_param_test_case *test); + +typedef struct { + char const *const description; + char const *const input; + char const *const output0; + char const *const output1; +} event_get_params_test_case; + +event_get_params_test_case const event_get_params_fixtures[] = { + { + .description = "Only a channel", + .input = "#test", + .output0 = "#test", + .output1 = "", + }, + { + .description = "Only a channel with trailing space", + .input = "#test ", + .output0 = "#test", + .output1 = "", + }, + { + .description = "No :, channel mode with one parameter after channel name", + .input = "#test +i", + .output0 = "#test", + .output1 = "+i", + }, + { + .description = "No :, channel mode with two parameters after channel name", + .input = "#test +o tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "No :, channel mode with three parameters afer channel name", + .input = "#test +ov tester tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "No :, channel mode with three parameters afer channel name, bunch of extra space", + .input = "#test +ov tester tester2 ", + .output0 = "#test", + .output1 = " +ov tester tester2 ", + }, + { + .description = "Channel mode with one parameter after channel name, : at the start of modes", + .input = "#test :+i", + .output0 = "#test", + .output1 = "+i", + }, + { + .description = "Channel mode with two parameters after channel name, : at the start of modes", + .input = "#test :+o tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "Channel mode with three parameters after channel name, : at the start of modes", + .input = "#test :+ov tester tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "Channel mode with two parameters after channel name, : on the final parameter", + .input = "#test +o :tester", + .output0 = "#test", + .output1 = "+o tester", + }, + { + .description = "Channel mode with three parameters after channel name, : on the final parameter", + .input = "#test +ov tester :tester2", + .output0 = "#test", + .output1 = "+ov tester tester2", + }, + { + .description = "Channel mode with three parameters after channel name, : on the final parameter, also a second : present", + .input = "#test +ov tester :tester2 hi:there", + .output0 = "#test", + .output1 = "+ov tester tester2 hi:there", + }, +}; + +static void test_event_get_params(const event_get_params_test_case *test); int main(int argc, char **argv) { + int i; + g_test_init(&argc, &argv, NULL); - g_test_add_func("/test/event_get_param", test_event_get_param); - g_test_add_func("/test/event_get_params", test_event_get_params); + for (i = 0; i < G_N_ELEMENTS(event_get_param_fixtures); i++) { + char *name = g_strdup_printf("/test/event_get_params/%d", i); + g_test_add_data_func(name, &event_get_params_fixtures[i], (GTestDataFunc)test_event_get_params); + g_free(name); + } + for (i = 0; i < G_N_ELEMENTS(event_get_param_fixtures); i++) { + char *name = g_strdup_printf("/test/event_get_param/%d", i); + g_test_add_data_func(name, &event_get_param_fixtures[i], (GTestDataFunc)test_event_get_param); + g_free(name); + } g_test_set_nonfatal_assertions(); return g_test_run(); } -static void test_event_get_param(void) +static void test_event_get_param(const event_get_param_test_case *test) { - struct test_case { - char const *const description; - char const *const input; - char const *const input_after; - char const *const output; - }; + char *buf, *input, *output; - struct test_case const tests[] = { - { - .description = "Zero parameters", - .input = "", - .input_after = "", - .output = "", - }, - { - .description = "One parameter", - .input = "#test", - .input_after = "", - .output = "#test", - }, - { - .description = "One parameter, trailing space", - .input = "#test ", - .input_after = "", - .output = "#test", - }, - { - .description = "One parameter, more trailing space", - .input = "#test ", - .input_after = " ", - .output = "#test", - }, - { - .description = "Two parameters", - .input = "#test +o", - .input_after = "+o", - .output = "#test", - }, - { - .description = "Two parameters continued", - .input = "+o", - .input_after = "", - .output = "+o", - }, - { - .description = "Two parameters with trailing space", - .input = "#test +o ", - .input_after = "+o ", - .output = "#test", - }, - { - .description = "Two parameters with trailing space continued", - .input = "+o ", - .input_after = "", - .output = "+o", - }, - { - .description = "Two parameters with inline and trailing space", - .input = "#test +o ", - .input_after = " +o ", - .output = "#test", - }, - /* TODO: It seems not ideal that the caller has to deal with inline space. - */ - { - .description = "Two parameters with inline and trailing space continued", - .input = " +o ", - .input_after = "+o ", - .output = "", - }, - }; + input = buf = g_strdup(test->input); + output = event_get_param(&input); - char *buf = g_malloc0(1024); - - int i = 0; - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - struct test_case const test = tests[i]; - - memcpy(buf, test.input, strlen(test.input)+1); - char *input = buf; - - char *const output = event_get_param(&input); - - g_assert_cmpstr(input, ==, test.input_after); - g_assert_cmpstr(output, ==, test.output); - } + g_assert_cmpstr(input, ==, test->input_after); + g_assert_cmpstr(output, ==, test->output); g_free(buf); } -static void test_event_get_params(void) +static void test_event_get_params(const event_get_params_test_case *test) { - struct test_case { - char const *const description; - char const *const input; - char const *const output0; - char const *const output1; - }; + char *output0, *output1, *params; + output0 = NULL; + output1 = NULL; + params = event_get_params(test->input, 2 | PARAM_FLAG_GETREST, + &output0, &output1); - struct test_case const tests[] = { - { - .description = "Only a channel", - .input = "#test", - .output0 = "#test", - .output1 = "", - }, - { - .description = "Only a channel with trailing space", - .input = "#test ", - .output0 = "#test", - .output1 = "", - }, - { - .description = "No :, channel mode with one parameter after channel name", - .input = "#test +i", - .output0 = "#test", - .output1 = "+i", - }, - { - .description = "No :, channel mode with two parameters after channel name", - .input = "#test +o tester", - .output0 = "#test", - .output1 = "+o tester", - }, - { - .description = "No :, channel mode with three parameters afer channel name", - .input = "#test +ov tester tester2", - .output0 = "#test", - .output1 = "+ov tester tester2", - }, - { - .description = "No :, channel mode with three parameters afer channel name, bunch of extra space", - .input = "#test +ov tester tester2 ", - .output0 = "#test", - .output1 = " +ov tester tester2 ", - }, - { - .description = "Channel mode with one parameter after channel name, : at the start of modes", - .input = "#test :+i", - .output0 = "#test", - .output1 = "+i", - }, - { - .description = "Channel mode with two parameters after channel name, : at the start of modes", - .input = "#test :+o tester", - .output0 = "#test", - .output1 = "+o tester", - }, - { - .description = "Channel mode with three parameters after channel name, : at the start of modes", - .input = "#test :+ov tester tester2", - .output0 = "#test", - .output1 = "+ov tester tester2", - }, - { - .description = "Channel mode with two parameters after channel name, : on the final parameter", - .input = "#test +o :tester", - .output0 = "#test", - .output1 = "+o tester", - }, - { - .description = "Channel mode with three parameters after channel name, : on the final parameter", - .input = "#test +ov tester :tester2", - .output0 = "#test", - .output1 = "+ov tester tester2", - }, - { - .description = "Channel mode with three parameters after channel name, : on the final parameter, also a second : present", - .input = "#test +ov tester :tester2 hi:there", - .output0 = "#test", - .output1 = "+ov tester tester2 hi:there", - }, - }; + /* params happens to always point at the first output */ + g_assert_cmpstr(params, ==, test->output0); + g_assert_cmpstr(output0, ==, test->output0); + g_assert_cmpstr(output1, ==, test->output1); - int i = 0; - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - struct test_case const test = tests[i]; - - char *output0 = NULL; - char *output1 = NULL; - char *const params = event_get_params(test.input, 2 | PARAM_FLAG_GETREST, - &output0, &output1); - - /* params happens to always point at the first output */ - g_assert_cmpstr(params, ==, test.output0); - g_assert_cmpstr(output0, ==, test.output0); - g_assert_cmpstr(output1, ==, test.output1); - - g_free(params); - } + g_free(params); } From d932e6e4b78383e0874721a76a8480a9a7e03667 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 26 Nov 2017 21:10:49 +0100 Subject: [PATCH 0243/1198] add test case for format_real_length --- configure.ac | 2 ++ tests/Makefile.am | 2 +- tests/fe-common/Makefile.am | 1 + tests/fe-common/core/Makefile.am | 28 ++++++++++++++++ tests/fe-common/core/test-formats.c | 50 +++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/fe-common/Makefile.am create mode 100644 tests/fe-common/core/Makefile.am create mode 100644 tests/fe-common/core/test-formats.c diff --git a/configure.ac b/configure.ac index c780b9b8..76ada09f 100644 --- a/configure.ac +++ b/configure.ac @@ -661,6 +661,8 @@ src/perl/textui/Makefile.PL scripts/Makefile scripts/examples/Makefile tests/Makefile +tests/fe-common/Makefile +tests/fe-common/core/Makefile tests/irc/Makefile tests/irc/core/Makefile docs/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index 58c348df..e16d190e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1 +1 @@ -SUBDIRS = irc +SUBDIRS = fe-common irc diff --git a/tests/fe-common/Makefile.am b/tests/fe-common/Makefile.am new file mode 100644 index 00000000..52770885 --- /dev/null +++ b/tests/fe-common/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = core diff --git a/tests/fe-common/core/Makefile.am b/tests/fe-common/core/Makefile.am new file mode 100644 index 00000000..070b6052 --- /dev/null +++ b/tests/fe-common/core/Makefile.am @@ -0,0 +1,28 @@ +include $(top_srcdir)/utils/glib-tap.mk + +PACKAGE_STRING=fe-common/core + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core \ + $(GLIB_CFLAGS) + +test_programs = test-formats + +test_formats_CPPFLAGS = \ + -I$(top_srcdir)/src/fe-common/core \ + $(AM_CPPFLAGS) + +test_formats_DEPENDENCIES = \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a + +test_formats_LDADD = \ + ../../../src/fe-common/core/libfe_common_core.a \ + ../../../src/core/libcore.a \ + ../../../src/lib-config/libirssi_config.a \ + @GLIB_LIBS@ \ + @OPENSSL_LIBS@ + +test_formats_SOURCES = \ + test-formats.c diff --git a/tests/fe-common/core/test-formats.c b/tests/fe-common/core/test-formats.c new file mode 100644 index 00000000..9ef23fd6 --- /dev/null +++ b/tests/fe-common/core/test-formats.c @@ -0,0 +1,50 @@ +#include "common.h" +#include "formats.h" + +#define MAX_LENGTH 5 + +typedef struct { + char const *const description; + char const *const input; + int const result[ MAX_LENGTH ]; +} format_real_length_test_case; + +static void test_format_real_length(const format_real_length_test_case *test); + +format_real_length_test_case const format_real_length_fixtures[] = { + { + .description = "", + .input = "%4%w ", + .result = { 0, 5, 5, -1 }, + }, +}; + +int main(int argc, char **argv) +{ + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS(format_real_length_fixtures); i++) { + char *name = g_strdup_printf("/test/format_real_length/%d", i); + g_test_add_data_func(name, &format_real_length_fixtures[i], (GTestDataFunc)test_format_real_length); + g_free(name); + } + + g_test_set_nonfatal_assertions(); + return g_test_run(); +} + +static void test_format_real_length(const format_real_length_test_case *test) +{ + int j, len; + + g_test_message("Testing format %s", test->input); + + for (j = 0; test->result[j] != -1; j++) { + len = format_real_length(test->input, j); + g_assert_cmpint(len, ==, test->result[j]); + } + + return; +} From d6458304d7dba0644fb4b682e09baf0acebdbb97 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 26 Nov 2017 21:23:51 +0100 Subject: [PATCH 0244/1198] mess with travis --- .travis.yml | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e04d943..a6ff601f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,13 @@ perl: # - "5.18-shrplib" - "system-perl" env: - - CC=clang - - CC=gcc + - CC=clang UNITTESTS=false + - CC=gcc UNITTESTS=false + - CC=clang UNITTESTS=true +matrix: + exclude: + - env: CC=clang UNITTESTS=true + perl: "system-perl" addons: apt: @@ -31,11 +36,12 @@ before_install: install: - ./configure --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build + $( $UNITTESTS && echo --enable-always-build-tests ) - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - make install before_script: - - cd + - pushd ~ - mkdir irssi-test - echo echo automated irssi launch test > irssi-test/startup; echo ^set settings_autosave off >> irssi-test/startup; @@ -47,9 +53,12 @@ before_script: - echo load perl >> irssi-test/startup - echo load proxy >> irssi-test/startup - echo ^quit >> irssi-test/startup - - irssi-build/bin/irssi --home irssi-test - - cat irc.log.* - - cd $TRAVIS_BUILD_DIR script: - - make check + - irssi-build/bin/irssi --home irssi-test + - popd + - if $UNITTESTS; then make -C tests -sk check; fi + +after_script: + - cat ~/irc.log.*; + find -name test-suite.log -exec cat {} + From eb9e2ed6fdacc3fa262b4907de51dea3f12be5fe Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 28 Nov 2017 11:00:46 +0100 Subject: [PATCH 0245/1198] Update test-irc.c Fix wrong array (missing an s) --- tests/irc/core/test-irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c index 90ce856b..c96956df 100644 --- a/tests/irc/core/test-irc.c +++ b/tests/irc/core/test-irc.c @@ -186,7 +186,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); - for (i = 0; i < G_N_ELEMENTS(event_get_param_fixtures); i++) { + for (i = 0; i < G_N_ELEMENTS(event_get_params_fixtures); i++) { char *name = g_strdup_printf("/test/event_get_params/%d", i); g_test_add_data_func(name, &event_get_params_fixtures[i], (GTestDataFunc)test_event_get_params); g_free(name); From 8b34871ea67c420b045ead9e317b67a247c02aae Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 29 Nov 2017 14:40:40 +0100 Subject: [PATCH 0246/1198] make travis pass despite failures --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index a6ff601f..b0bc78e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,8 @@ matrix: exclude: - env: CC=clang UNITTESTS=true perl: "system-perl" + allow_failures: + - env: CC=clang UNITTESTS=true addons: apt: From 58557d18c49c11cd4a4de44c5a9e7c00f2d8f880 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 7 Dec 2017 12:08:20 +0100 Subject: [PATCH 0247/1198] add separator in travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0bc78e8..e2b3f57c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,5 +62,5 @@ script: - if $UNITTESTS; then make -C tests -sk check; fi after_script: - - cat ~/irc.log.*; - find -name test-suite.log -exec cat {} + + - cat ~/irc.log.* + - find -name test-suite.log -exec cat {} + From ef07b3c60c80a828f529a2075246185d7d0b5b25 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Tue, 2 Jan 2018 20:21:07 -0500 Subject: [PATCH 0248/1198] Remove redundant if case --- src/fe-fuzz/irc/core/event-get-params.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index 6266ffb6..beeca6ba 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -74,8 +74,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { params = event_get_params(copy, 2, &output0, &output1); } else if (count % 8 == 6) { params = event_get_params(copy, 3, &output0, &output1, &output2); - } else if (count % 8 == 7) { - params = event_get_params(copy, 4, &output0, &output1, &output2, &output3); } else { params = event_get_params(copy, 4, &output0, &output1, &output2, &output3); } From 15705432e1fb88d9f784cb3fc12c89f8f9164043 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Tue, 2 Jan 2018 20:22:38 -0500 Subject: [PATCH 0249/1198] Remove outdated comment --- src/fe-fuzz/irc/core/event-get-params.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index beeca6ba..c50b6205 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -52,7 +52,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } uint8_t count = *data; - /* malloc(size) instead of size+1, because we already used one byte of data */ gchar *copy = g_strndup((const gchar *)data+1, size-1); char *output0; From 54d453623d879ea83d0818a80bd14151192953ec Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 3 Jan 2018 12:45:43 +0100 Subject: [PATCH 0250/1198] do not record topic change time when sender is blank --- src/irc/core/channel-events.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index b0bddab2..46bbd5fa 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -138,7 +138,13 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, g_free_not_null(chanrec->topic_by); chanrec->topic_by = g_strdup(setby); - chanrec->topic_time = settime; + if (chanrec->topic_by == NULL) { + /* ensure invariant topic_time > 0 <=> topic_by != NULL. + this could be triggered by a topic command without sender */ + chanrec->topic_time = 0; + } else { + chanrec->topic_time = settime; + } signal_emit("channel topic changed", 1, chanrec); } From 7a83c63701b7395ee6cc606905314318eef77971 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 3 Jan 2018 14:09:48 +0100 Subject: [PATCH 0251/1198] check if \\c is complete in eval --- src/core/misc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index e589b8c5..4e9f4bbe 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -703,8 +703,11 @@ int expand_escape(const char **data) *data += 2; return strtol(digit, NULL, 16); case 'c': - /* control character (\cA = ^A) */ - (*data)++; + /* check for end of string */ + if ((*data)[1] == '\0') + return 0; + /* control character (\cA = ^A) */ + (*data)++; return i_toupper(**data) - 64; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': From 2361d4b1e5d38701f35146219ceddd318ac4e645 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 3 Jan 2018 15:35:18 +0100 Subject: [PATCH 0252/1198] rewrite completion code and check for direct match of separator --- src/fe-common/core/completion.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index e78fe7d5..fd452e5c 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -187,12 +187,18 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i char *old; old = linestart; - linestart = *linestart == '\0' ? - g_strdup(word) : - g_strdup_printf("%s%c%s", - /* do not accidentally duplicate the word separator */ - line == wordstart - 1 ? "" : linestart, - old_wordstart[-1], word); + /* we want to move word into linestart */ + if (*linestart == '\0') { + linestart = g_strdup(word); + } else { + GString *str = g_string_new(linestart); + if (old_wordstart[-1] != str->str[str->len - 1]) { + /* do not accidentally duplicate the word separator */ + g_string_append_c(str, old_wordstart[-1]); + } + g_string_append(str, word); + linestart = g_string_free(str, FALSE); + } g_free(old); g_free(word); From cc17837a9b326ec9100a35981348fa0f5d6316fa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 3 Jan 2018 15:51:51 +0100 Subject: [PATCH 0253/1198] disable variable arguments code --- src/core/special-vars.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/special-vars.c b/src/core/special-vars.c index aaf8da8f..f254c200 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -384,6 +384,7 @@ char *parse_special(char **cmd, SERVER_REC *server, void *item, } nest_free = FALSE; nest_value = NULL; +#if 0 /* this code is disabled due to security issues until it is fixed */ if (**cmd == '(' && (*cmd)[1] != '\0') { /* subvariable */ int toplevel = nested_orig_cmd == NULL; @@ -412,6 +413,9 @@ char *parse_special(char **cmd, SERVER_REC *server, void *item, if (toplevel) nested_orig_cmd = NULL; } +#else + if (nested_orig_cmd) nested_orig_cmd = NULL; +#endif if (**cmd != '{') brackets = FALSE; From 5bddfe7b7336f6b48408c72955dbcb664cc4dc97 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Jan 2018 14:29:57 +0100 Subject: [PATCH 0254/1198] add new test skeleton --- configure.ac | 1 + tests/irc/Makefile.am | 4 +++- tests/irc/flood/Makefile.am | 32 ++++++++++++++++++++++++++++++++ tests/irc/flood/test-796.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/irc/flood/Makefile.am create mode 100644 tests/irc/flood/test-796.c diff --git a/configure.ac b/configure.ac index 76ada09f..61e96149 100644 --- a/configure.ac +++ b/configure.ac @@ -665,6 +665,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/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..4bc4a93c --- /dev/null +++ b/tests/irc/flood/Makefile.am @@ -0,0 +1,32 @@ +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/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/flood/libirc_flood.a \ + ../../../src/irc/core/libirc_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..9ca29489 --- /dev/null +++ b/tests/irc/flood/test-796.c @@ -0,0 +1,29 @@ +/* + 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" + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_set_nonfatal_assertions(); + return g_test_run(); +} From c7cd49f8d7e83302c0f21f4449cddac528d28eea Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Jan 2018 16:18:07 +0100 Subject: [PATCH 0255/1198] first bug case, exposes broken server object in chat-completion --- tests/irc/flood/Makefile.am | 8 +++ tests/irc/flood/test-796.c | 122 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am index 4bc4a93c..85b52eab 100644 --- a/tests/irc/flood/Makefile.am +++ b/tests/irc/flood/Makefile.am @@ -12,6 +12,7 @@ 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) @@ -21,8 +22,15 @@ test_796_DEPENDENCIES = \ ../../../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@ \ diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 9ca29489..293e87d7 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -19,11 +19,133 @@ */ #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 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_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("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; + + g_test_bug("796"); + + 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(); + + signal_emit("server connected", 1, 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; + + signal_emit("event privmsg", 4, server, "#someroom :test message", "nick", "user@host"); +} 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(); } From 3b7b868bb11faf74c872ecf606c4eef189e31725 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Jan 2018 16:43:58 +0100 Subject: [PATCH 0256/1198] finish test case --- tests/irc/flood/test-796.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 293e87d7..24a5d4be 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -110,6 +110,7 @@ static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const voi server = proto->server_init_connect(conn); server->session_reconnect = TRUE; server->tag = g_strdup("testserver"); + server_ref(server); g_test_message("created server: %p", server); @@ -118,7 +119,8 @@ static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const voi irc_session_deinit(); irc_irc_deinit(); - signal_emit("server connected", 1, server); + + server_connect_finished(server); /* make up for the skipped session init */ irc_server_init_bare_minimum(IRC_SERVER(server)); @@ -130,6 +132,16 @@ static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const voi /* simulate failing irc_server_send_data() */ server->connection_lost = TRUE; + /* + chat_completion_deinit(); + fe_messages_deinit(); + irc_notifylist_deinit(); + */ + + /* for the purpose of this exercise, we are ignoring the + errors of g_hash_table_lookup failure */ + g_log_set_always_fatal(G_LOG_FATAL_MASK); + signal_emit("event privmsg", 4, server, "#someroom :test message", "nick", "user@host"); } From bffced54981c191f5bac4f9611e4691fe442e58c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Jan 2018 21:11:00 +0100 Subject: [PATCH 0257/1198] Update test-796.c odd space --- tests/irc/flood/test-796.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 24a5d4be..ae94c5ab 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -33,7 +33,7 @@ /* irc.c */ void irc_init(void); -void irc_deinit(void) ; +void irc_deinit(void); /* irc-session.c */ void irc_session_init(void); From 6b0e14099655bf4d94a19dff252cce89b2858c93 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Jan 2018 23:01:28 +0100 Subject: [PATCH 0258/1198] show destroyed event --- tests/irc/flood/test-796.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index ae94c5ab..2e4affa0 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -63,6 +63,11 @@ 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); @@ -73,12 +78,14 @@ static void server_destroy_flood_set_up(ServerDestroyFloodData *fixture, const v 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(); @@ -90,27 +97,31 @@ static void server_destroy_flood_tear_down(ServerDestroyFloodData *fixture, cons 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); + (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)@%+")); + /* 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; + 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"); - server_ref(server); g_test_message("created server: %p", server); @@ -138,11 +149,11 @@ static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const voi irc_notifylist_deinit(); */ - /* for the purpose of this exercise, we are ignoring the - errors of g_hash_table_lookup failure */ - g_log_set_always_fatal(G_LOG_FATAL_MASK); - + 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) From c9b3d87eb7ef2ce99f659d7e567fc83629439142 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 3 Jan 2018 12:26:02 +0100 Subject: [PATCH 0259/1198] Postpone server cleanup until after unref Add a new signal, server destroyed, that is supposed to run the clean up tasks of server disconnected. This is so that some structures will stay around longer. --- src/core/servers.c | 1 + src/fe-common/core/fe-common-core.c | 6 +++--- src/irc/core/irc-servers.c | 6 +++--- src/irc/flood/flood.c | 4 ++-- src/irc/notifylist/notifylist.c | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/core/servers.c b/src/core/servers.c index b9faab81..b1da9b7e 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -524,6 +524,7 @@ int server_unref(SERVER_REC *server) return TRUE; } + signal_emit("server destroyed", 1, server); 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 a3b7364c..d0d36490 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/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 4eaab712..5076a688 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; @@ -1031,7 +1031,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); @@ -1058,7 +1058,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); From c8012b2e574c6e1e25cf20ed31182323a492a98e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 5 Jan 2018 00:32:03 +0100 Subject: [PATCH 0260/1198] Merge tag '1.0.6' into integrate/1.0.6 --- NEWS | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cc301365..1054bb62 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,16 @@ -v1.1-head 2017-xx-xx The Irssi team +v1.1-head 2018-xx-xx The Irssi team + +v1.0.6 2018-01-07 The Irssi team + - Fix invalid memory access when reading hilight configuration + (#787, #788). + - Fix null pointer dereference when the channel topic is set + without specifying a sender (GL#20, GL!25). + - Fix return of random memory when using incomplete escape + codes (GL#21, GL!26). + - Fix heap buffer overflow when completing certain strings + (GL#19, GL!27). + - Fix return of random memory when using an incomplete + variable argument (GL#18, GL!28). v1.0.5 2017-10-23 The Irssi team - Fix missing -sasl_method '' in /NETWORK (#718, #719). From 3c7185c5ad61de24f9d1bc39240c8145665fba44 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Jan 2018 00:38:54 +0100 Subject: [PATCH 0261/1198] Update irc-nicklist.c move altnick check before the nick correction code --- src/irc/core/irc-nicklist.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index a006a3cb..1f8c1fc9 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -345,6 +345,7 @@ static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) { char *str, *cmd, *params, *nick; int n; + gboolean try_alternate_nick; g_return_if_fail(data != NULL); @@ -352,6 +353,10 @@ static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) /* Already connected, no need to handle this anymore. */ return; } + + try_alternate_nick = g_ascii_strcasecmp(server->nick, server->connrec->nick) == 0 && + server->connrec->alternate_nick != NULL && + g_ascii_strcasecmp(server->connrec->alternate_nick, server->nick) != 0; params = event_get_params(data, 2, NULL, &nick); if (g_ascii_strcasecmp(server->nick, nick) != 0) { @@ -362,9 +367,7 @@ static void event_nick_in_use(IRC_SERVER_REC *server, const char *data) 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 && - g_ascii_strcasecmp(server->connrec->alternate_nick, server->nick) != 0) { + if (try_alternate_nick) { /* first try, so try the alternative nick.. */ g_free(server->nick); server->nick = g_strdup(server->connrec->alternate_nick); From eb18904840cc7d4a6830bf0711f4682af50f1abc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Jan 2018 22:13:23 +0100 Subject: [PATCH 0262/1198] fix crash in notifylist --- src/core/servers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/servers.c b/src/core/servers.c index b1da9b7e..0abfdfb0 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -524,7 +524,12 @@ int server_unref(SERVER_REC *server) return TRUE; } - signal_emit("server destroyed", 1, 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); + MODULE_DATA_DEINIT(server); server_connect_unref(server->connrec); if (server->rawlog != NULL) rawlog_destroy(server->rawlog); From b111f038ddb7b5079f9901dd282fd4733390b1ba Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Jan 2018 23:15:24 +0100 Subject: [PATCH 0263/1198] fix /exec -o for blank lines since it is not allowed to send nothing, instead of spamming the status window with error, send " " instead Fixes FS#902 --- src/fe-common/core/fe-exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index 36990866..c1739d39 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -613,7 +613,7 @@ static void sig_exec_input(PROCESS_REC *rec, const char *text) str = g_strconcat(rec->target_nick ? "-nick " : rec->target_channel ? "-channel " : "", - rec->target, " ", text, NULL); + rec->target, " ", *text == '\0' ? " " : text, NULL); signal_emit(rec->notice ? "command notice" : "command msg", 3, str, server, item); g_free(str); From 6e6a96d8c1eb8a51404d34809382e54eea46a9f7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Jan 2018 23:05:39 +0100 Subject: [PATCH 0264/1198] fix uaf in signal path --- src/core/servers.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/core/servers.c b/src/core/servers.c index 0abfdfb0..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,11 +512,28 @@ 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) + 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); From 451019d05dfabbac2463f0d835c5113ac140c5c4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 May 2017 14:45:13 +0200 Subject: [PATCH 0265/1198] make format_real_length left-collecting --- src/fe-common/core/formats.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 37db6f7c..4c819c2d 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -480,27 +480,30 @@ int format_real_length(const char *str, int len) start = str; tmp = g_string_new(NULL); - while (*str != '\0' && len > 0) { + while (*str != '\0') { + oldstr = str; if (*str == '%' && str[1] != '\0') { str++; if (*str != '%') { adv = format_expand_styles(tmp, &str, NULL); - str += adv; - if (adv) - continue; - } - - /* %% or unknown %code, written as-is */ - if (*str != '%') { - if (--len == 0) - break; + if (adv) { + str += adv; + continue; + } + /* discount for unknown % */ + if (--len < 0) { + str = oldstr; + break; + } + oldstr = str; } } - oldstr = str; len -= string_advance(&str, utf8); - if (len < 0) + if (len < 0) { str = oldstr; + break; + } } g_string_free(tmp, TRUE); From 4e71a1f485d9a546cb92ad94e8918a2363a88b03 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 25 Apr 2017 00:42:53 +0200 Subject: [PATCH 0266/1198] sideways split support for Irssi warning: * may be buggy This commit adds support for sideways splits into Irssi. To that regard, there are a number of new commands available the "R" commands: /window new rsplit - make a new sideways split /window rshow - show an existing window to the right /window rgrow/rshrink/rsize/rbalance - manipulate the size of your sideways split windows the "D" commands: /window dup/ddown/dleft/dright - navigate the windows directionally, as an alternative to /window up/down that you can bind to some key /window move dleft/dright - the same for moving Enjoy! --- docs/help/in/window.in | 15 +- src/fe-common/core/fe-windows.h | 8 + src/fe-common/core/window-commands.c | 7 +- src/fe-common/core/window-items.c | 2 +- src/fe-text/gui-printtext.c | 43 +- src/fe-text/gui-printtext.h | 1 + src/fe-text/gui-windows.c | 14 +- src/fe-text/mainwindows-layout.c | 159 +++- src/fe-text/mainwindows.c | 1144 +++++++++++++++++++++----- src/fe-text/mainwindows.h | 22 +- src/fe-text/module-formats.c | 4 +- src/fe-text/statusbar-items.c | 19 +- src/fe-text/statusbar.c | 72 +- src/fe-text/statusbar.h | 6 + src/fe-text/term-terminfo.c | 79 +- src/fe-text/term.h | 2 + src/fe-text/textbuffer-view.c | 120 +-- themes/default.theme | 1 + 18 files changed, 1373 insertions(+), 345 deletions(-) diff --git a/docs/help/in/window.in b/docs/help/in/window.in index 6dde6c50..0e7ed637 100644 --- a/docs/help/in/window.in +++ b/docs/help/in/window.in @@ -35,10 +35,19 @@ SHRINK: %|Decrease the size of the active split window by the specified number of lines. SIZE: %|Set the current split window size to the specified numer of lines. BALANCE: %|Balance the heights of all split windows. + RGROW: %|Increase the width of the active split window by the specified number of columns. + RSHRINK: %|Decrease the wodth of the active split window by the specified number of columns. + RSIZE: %|Set the current split window width to the specified numer of columns. + RBALANCE: %|Balance the widths of all split windows in this line. HIDE: %|Hides the current split window, or the split window specified by number or item name. SHOW: %|Show the window specified by number or item name as a new split windows. It is made sticky when autostick_split_windows is turned on. - UP: %|Set the split window above the current one active. At the top, wraps to the bottom. - DOWN: %|Set the split window below the current one active. At the bottom, wraps to the top. + RSHOW: %|Show the window specified by number or item name as a new windows split to the right of the current window. It is made sticky when autostick_split_windows is turned on. + UP: %|Set the split window left or above the current one active. At the top, wraps to the bottom. + DOWN: %|Set the split window right or below the current one active. At the bottom, wraps to the top. + DUP: %|Set the split window above the current one active. At the top, wraps to the bottom. + DDOWN: %|Set the split window below the current one active. At the bottom, wraps to the top. + DLEFT: %|Set the split window left to the current one active. At the left, wraps to the right. + DRIGHT: %|Set the split window right to the current one active. At the right, wraps to the left. LEFT: %|Go to the previous window numerically that is part of the current sticky group (or not part of any sticky group). RIGHT: %|Go to the next window numerically that is part of the current sticky group (or not part of any sticky group). STICK: %|Make the currently active window sticky, or stick the window specified by number to the currently visible split window. Or turn off stickyness of the currently active window or the window specified by number. @@ -46,6 +55,8 @@ MOVE RIGHT: %|Move the window to the numerically next location inside the current sticky group. MOVE UP: %|Move the current window to the sticky group of the split window above. If no sticky group remains, the split window collapses. MOVE DOWN: %|Move the current window to the sticky group of the split window below. If no sticky group remains, the split window collapses. + MOVE DLEFT: %|Move the current window to the sticky group of the split window to the left. If no sticky group remains, the split window collapses. + MOVE DRIGHT: %|Move the current window to the sticky group of the split window to the right. If no sticky group remains, the split window collapses. %|Add the required arguments for the given command. Without arguments, the details (size, immortality, levels, server, name and sticky group) of the currently active window are displayed. If used with a number as argument, same as WINDOW REFNUM. diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 32d6cfcd..aaa773c8 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -11,6 +11,14 @@ enum { DATA_LEVEL_HILIGHT }; +enum { + MAIN_WINDOW_TYPE_NONE = -1, + MAIN_WINDOW_TYPE_DEFAULT = 0, + MAIN_WINDOW_TYPE_HIDDEN = 1, + MAIN_WINDOW_TYPE_SPLIT = 2, + MAIN_WINDOW_TYPE_RSPLIT = 3 +}; + typedef struct { char *servertag; char *name; diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index 57c81ac2..a81c0180 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -169,7 +169,7 @@ static void cmd_window(const char *data, void *server, WI_ITEM_REC *item) command_runsub("window", data, server, item); } -/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT] */ +/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT|RSPLIT] */ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) { WINDOW_REC *window; @@ -177,8 +177,9 @@ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) g_return_if_fail(data != NULL); - type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? 1 : - (g_ascii_strcasecmp(data, "split") == 0 ? 2 : 0); + type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? MAIN_WINDOW_TYPE_HIDDEN : + g_ascii_strcasecmp(data, "split") == 0 ? MAIN_WINDOW_TYPE_SPLIT : + g_ascii_strncasecmp(data, "rs", 2) == 0 ? MAIN_WINDOW_TYPE_RSPLIT : MAIN_WINDOW_TYPE_DEFAULT; signal_emit("gui window create override", 1, GINT_TO_POINTER(type)); window = window_create(NULL, FALSE); diff --git a/src/fe-common/core/window-items.c b/src/fe-common/core/window-items.c index bd6ae5e9..8eab7124 100644 --- a/src/fe-common/core/window-items.c +++ b/src/fe-common/core/window-items.c @@ -314,7 +314,7 @@ void window_item_create(WI_ITEM_REC *item, int automatic) /* create new window to use */ if (settings_get_bool("autocreate_split_windows")) { signal_emit("gui window create override", 1, - GINT_TO_POINTER(0)); + GINT_TO_POINTER(MAIN_WINDOW_TYPE_SPLIT)); } window = window_create(item, automatic); } else { diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index a07451fa..c52f9ced 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -24,6 +24,7 @@ #include "formats.h" #include "printtext.h" +#include "themes.h" #include "term.h" #include "gui-printtext.h" @@ -138,6 +139,39 @@ void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str) gui_printtext_after_time(dest, prev, str, 0); } +void gui_printtext_window_border(int x, int y) +{ + char *v0, *v1; + int len; + if (current_theme != NULL) { + v1 = theme_format_expand(current_theme, "{window_border} "); + len = format_real_length(v1, 1); + v1[len] = '\0'; + } + else { + v1 = g_strdup(" "); + } + + if (*v1 == '\0') { + g_free(v1); + v1 = g_strdup(" "); + } + + if (clrtoeol_info->color != NULL) { + char *color = g_strdup(clrtoeol_info->color); + len = format_real_length(color, 0); + color[len] = '\0'; + v0 = g_strconcat(color, v1, NULL); + g_free(color); + g_free(v1); + } else { + v0 = v1; + } + + gui_printtext(x, y, v0); + g_free(v0); +} + static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) { LINE_REC *line; @@ -236,8 +270,13 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, 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); + 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); return; } diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index d2671497..64595bbe 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -20,5 +20,6 @@ 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); +void gui_printtext_window_border(int xpos, int ypos); #endif diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index c63c495c..966c5138 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -73,17 +73,18 @@ static void gui_window_created(WINDOW_REC *window, void *automatic) g_return_if_fail(window != NULL); - new_parent = window_create_override == 0 || - window_create_override == 2 || + new_parent = window_create_override == MAIN_WINDOW_TYPE_DEFAULT || + window_create_override == MAIN_WINDOW_TYPE_SPLIT || + window_create_override == MAIN_WINDOW_TYPE_RSPLIT || active_win == NULL || WINDOW_GUI(active_win) == NULL; - parent = !new_parent ? WINDOW_MAIN(active_win) : mainwindow_create(); + parent = !new_parent ? WINDOW_MAIN(active_win) : mainwindow_create(window_create_override == MAIN_WINDOW_TYPE_RSPLIT); if (parent == NULL) { /* not enough space for new window, but we really can't abort creation of the window anymore, so create hidden window instead. */ parent = WINDOW_MAIN(active_win); } - window_create_override = -1; + window_create_override = MAIN_WINDOW_TYPE_NONE; if (parent->active == NULL) parent->active = window; window->gui_data = gui_window_init(window, parent); @@ -281,13 +282,14 @@ static void read_settings(void) void gui_windows_init(void) { - settings_add_bool("lookandfeel", "autostick_split_windows", TRUE); + settings_add_bool("lookandfeel", "autostick_split_windows", FALSE); + settings_add_bool("lookandfeel", "autounstick_windows", TRUE); settings_add_int("lookandfeel", "indent", 10); settings_add_bool("lookandfeel", "indent_always", FALSE); settings_add_bool("lookandfeel", "break_wide", FALSE); settings_add_bool("lookandfeel", "scroll", TRUE); - window_create_override = -1; + window_create_override = MAIN_WINDOW_TYPE_NONE; read_settings(); signal_add("gui window create override", (SIGNAL_FUNC) sig_window_create_override); diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index fae02539..734c9acb 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -48,9 +48,9 @@ static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) { WINDOW_REC *parent; - GUI_WINDOW_REC *gui; + GUI_WINDOW_REC *gui; - gui = WINDOW_GUI(window); + gui = WINDOW_GUI(window); parent = window_find_refnum(config_node_get_int(node, "parent", -1)); if (parent != NULL) @@ -61,7 +61,7 @@ static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) if (config_node_get_str(node, "scroll", NULL) != NULL) { gui->use_scroll = TRUE; gui->scroll = config_node_get_bool(node, "scroll", TRUE); - textbuffer_view_set_scroll(gui->view, gui->scroll); + textbuffer_view_set_scroll(gui->view, gui->scroll); } } @@ -74,6 +74,8 @@ static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node) iconfig_node_set_int(node, "first_line", window->first_line); iconfig_node_set_int(node, "lines", window->height); + iconfig_node_set_int(node, "first_column", window->first_column); + iconfig_node_set_int(node, "columns", window->width); } static void sig_layout_save(void) @@ -88,8 +90,16 @@ static void sig_layout_save(void) static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2) { - return config_node_get_int(n1, "first_line", 0) > - config_node_get_int(n2, "first_line", 0) ? -1 : 1; + return (config_node_get_int(n1, "first_line", 0) == + config_node_get_int(n2, "first_line", 0) + && + config_node_get_int(n1, "first_column", 0) > + config_node_get_int(n2, "first_column", 0) + ) || + config_node_get_int(n1, "first_line", 0) > + config_node_get_int(n2, "first_line", 0) + ? -1 + : 1; } /* Returns list of mainwindow nodes sorted by first_line @@ -108,14 +118,45 @@ static GSList *get_sorted_windows_config(CONFIG_NODE *node) return output; } +static GSList *get_windows_config_filter_line(GSList *in) +{ + GSList *tmp, *output; + + output = NULL; + for (tmp = in; tmp != NULL; tmp = tmp->next) { + CONFIG_NODE *node = tmp->data; + if (config_node_get_int(node, "first_column", 0) == 0) + output = g_slist_append(output, node); + } + + return output; +} + +static GSList *get_windows_config_filter_column(GSList *in, int first_line, int last_line) +{ + GSList *tmp, *output; + + output = NULL; + for (tmp = in; tmp != NULL; tmp = tmp->next) { + int l1, l2; + CONFIG_NODE *node = tmp->data; + l1 = config_node_get_int(node, "first_line", -1); + l2 = l1 + config_node_get_int(node, "lines", 0) - 1; + if (l1 >= first_line && l2 <= last_line) + output = g_slist_prepend(output, node); + } + + return output; +} + static void sig_layout_restore(void) { - MAIN_WINDOW_REC *lower_window; - WINDOW_REC *window; + MAIN_WINDOW_REC *lower_window; + WINDOW_REC *window, *first; CONFIG_NODE *node; - GSList *tmp, *sorted_config; - int avail_height, height, *heights; - int i, lower_size, windows_count, diff; + GSList *tmp, *sorted_config, *lines_config; + int avail_height, height, *heights, *widths, max_wins_line; + int i, lower_size, lines_count, columns_count, diff; node = iconfig_node_traverse("mainwindows", FALSE); if (node == NULL) return; @@ -123,51 +164,56 @@ static void sig_layout_restore(void) sorted_config = get_sorted_windows_config(node); if (sorted_config == NULL) return; - windows_count = g_slist_length(sorted_config); + lines_config = get_windows_config_filter_line(sorted_config); + lines_count = g_slist_length(lines_config); - /* calculate the saved terminal height */ + /* calculate the saved terminal height */ avail_height = term_height - screen_reserved_top - screen_reserved_bottom; height = 0; - heights = g_new0(int, windows_count); - for (i = 0, tmp = sorted_config; tmp != NULL; tmp = tmp->next, i++) { + heights = g_new0(int, lines_count); + for (i = 0, tmp = lines_config; tmp != NULL; tmp = tmp->next, i++) { CONFIG_NODE *node = tmp->data; - heights[i] = config_node_get_int(node, "lines", 0); + heights[i] = config_node_get_int(node, "lines", 0); height += heights[i]; } + max_wins_line = (term_width + 1) / (NEW_WINDOW_WIDTH + 1); + if (max_wins_line < 1) + max_wins_line = 1; + if (avail_height <= (WINDOW_MIN_SIZE*2)+1) { /* we can fit only one window to screen - give it all the height we can */ - windows_count = 1; - heights[0] = avail_height; + lines_count = 1; + heights[0] = avail_height; } else if (height != avail_height) { /* Terminal's height is different from the saved one. Resize the windows so they fit to screen. */ while (height > avail_height && - windows_count*(WINDOW_MIN_SIZE+1) > avail_height) { + lines_count*(WINDOW_MIN_SIZE+1) > avail_height) { /* all windows can't fit into screen, remove the lowest ones */ - windows_count--; + lines_count--; } - /* try to keep the windows' size about the same in percents */ - for (i = 0; i < windows_count; i++) { + /* try to keep the windows' size about the same in percents */ + for (i = 0; i < lines_count; i++) { int size = avail_height*heights[i]/height; if (size < WINDOW_MIN_SIZE+1) - size = WINDOW_MIN_SIZE+1; + size = WINDOW_MIN_SIZE+1; heights[i] = size; } /* give/remove the last bits */ - height = 0; - for (i = 0; i < windows_count; i++) - height += heights[i]; + height = 0; + for (i = 0; i < lines_count; i++) + height += heights[i]; diff = height < avail_height ? 1 : -1; for (i = 0; height != avail_height; i++) { - if (i == windows_count) + if (i == lines_count) i = 0; if (heights[i] > WINDOW_MIN_SIZE+1) { @@ -178,25 +224,59 @@ static void sig_layout_restore(void) } /* create all the visible windows with correct size */ - lower_window = NULL; lower_size = 0; - for (i = 0, tmp = sorted_config; i < windows_count; tmp = tmp->next, i++) { + lower_window = NULL; lower_size = 0; first = NULL; + for (i = 0, tmp = lines_config; i < lines_count; tmp = tmp->next, i++) { + GSList *tmp2, *columns_config, *line; + int j, l1, l2; CONFIG_NODE *node = tmp->data; if (node->key == NULL) continue; - /* create a new window + mainwindow */ - signal_emit("gui window create override", 1, - GINT_TO_POINTER(0)); + l1 = config_node_get_int(node, "first_line", -1); + l2 = l1 + config_node_get_int(node, "lines", 0) - 1; + columns_config = get_windows_config_filter_column(sorted_config, l1, l2); - window = window_create(NULL, TRUE); - window_set_refnum(window, atoi(node->key)); + window = NULL; columns_count = 0; + widths = g_new0(int, max_wins_line); + for (j = 0, tmp2 = columns_config; j < max_wins_line && tmp2 != NULL; tmp2 = tmp2->next, j++) { + int width; + WINDOW_REC *new_win; + CONFIG_NODE *node2 = tmp2->data; + if (node2->key == NULL) continue; + + /* create a new window + mainwindow */ + signal_emit("gui window create override", 1, + GINT_TO_POINTER(window == NULL ? MAIN_WINDOW_TYPE_SPLIT : MAIN_WINDOW_TYPE_RSPLIT)); + + new_win = window_create(NULL, TRUE); + + window_set_refnum(new_win, atoi(node2->key)); + width = config_node_get_int(node2, "columns", NEW_WINDOW_WIDTH); + widths[j] = width; + columns_count += width + (window == NULL ? 0 : 1); + + if (window == NULL) + window = new_win; + if (first == NULL) + first = new_win; + + window_set_active(new_win); + active_mainwin = WINDOW_MAIN(new_win); + } + if (window == NULL) + continue; + line = g_slist_reverse(mainwindows_get_line(WINDOW_MAIN(window))); + for (j = g_slist_length(line), tmp2 = line; tmp2 != NULL; tmp2 = tmp2->next, j--) { + int width = MAX(NEW_WINDOW_WIDTH, widths[j-1] * term_width / columns_count); + MAIN_WINDOW_REC *rec = tmp2->data; + mainwindow_set_rsize(rec, width); + } + g_slist_free(line); + g_free(widths); if (lower_size > 0) mainwindow_set_size(lower_window, lower_size, FALSE); - window_set_active(window); - active_mainwin = WINDOW_MAIN(window); - - lower_window = WINDOW_MAIN(window); + lower_window = WINDOW_MAIN(window); lower_size = heights[i]; if (lower_size < WINDOW_MIN_SIZE+1) lower_size = WINDOW_MIN_SIZE+1; @@ -206,6 +286,11 @@ static void sig_layout_restore(void) if (lower_size > 0) mainwindow_set_size(lower_window, lower_size, FALSE); + + if (first != NULL) { + window_set_active(first); + active_mainwin = WINDOW_MAIN(first); + } } static void sig_layout_reset(void) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 5f58c25f..deab8de8 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -34,24 +34,27 @@ GSList *mainwindows; MAIN_WINDOW_REC *active_mainwin; +MAIN_WINDOW_BORDER_REC *clrtoeol_info; int screen_reserved_top, screen_reserved_bottom; -static int old_screen_width, old_screen_height; +int screen_reserved_left, screen_reserved_right; +static int screen_width, screen_height; #define mainwindow_create_screen(window) \ - term_window_create(0, \ + term_window_create((window)->first_column + (window)->statusbar_columns_left, \ (window)->first_line + (window)->statusbar_lines_top, \ - (window)->width, \ + (window)->width - (window)->statusbar_columns, \ (window)->height - (window)->statusbar_lines) #define mainwindow_set_screen_size(window) \ - term_window_move((window)->screen_win, 0, \ + term_window_move((window)->screen_win, \ + (window)->first_column + (window)->statusbar_columns_left, \ (window)->first_line + (window)->statusbar_lines_top, \ - (window)->width, \ + (window)->width - (window)->statusbar_columns, \ (window)->height - (window)->statusbar_lines); -static MAIN_WINDOW_REC *find_window_with_room(void) +static MAIN_WINDOW_REC *find_window_with_room() { MAIN_WINDOW_REC *biggest_rec; GSList *tmp; @@ -71,14 +74,34 @@ static MAIN_WINDOW_REC *find_window_with_room(void) return biggest_rec; } +static MAIN_WINDOW_REC *find_window_with_room_right(void) +{ + MAIN_WINDOW_REC *biggest_rec; + GSList *tmp; + int space, biggest; + + biggest = 0; biggest_rec = NULL; + for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + + space = MAIN_WINDOW_TEXT_WIDTH(rec); + if (space >= 2 * NEW_WINDOW_WIDTH && space > biggest) { + biggest = space; + biggest_rec = rec; + } + } + + return biggest_rec; +} + #define window_size_equals(window, mainwin) \ - ((window)->width == (mainwin)->width && \ + ((window)->width == MAIN_WINDOW_TEXT_WIDTH(mainwin) && \ (window)->height == MAIN_WINDOW_TEXT_HEIGHT(mainwin)) static void mainwindow_resize_windows(MAIN_WINDOW_REC *window) { GSList *tmp; - int resized; + int resized; mainwindow_set_screen_size(window); @@ -89,24 +112,31 @@ static void mainwindow_resize_windows(MAIN_WINDOW_REC *window) if (rec->gui_data != NULL && WINDOW_GUI(rec)->parent == window && !window_size_equals(rec, window)) { - resized = TRUE; - gui_window_resize(rec, window->width, + resized = TRUE; + gui_window_resize(rec, MAIN_WINDOW_TEXT_WIDTH(window), MAIN_WINDOW_TEXT_HEIGHT(window)); } } - if (resized) + if (resized) signal_emit("mainwindow resized", 1, window); } static void mainwindow_resize(MAIN_WINDOW_REC *window, int xdiff, int ydiff) { + int height, width; if (quitting || (xdiff == 0 && ydiff == 0)) - return; + return; - window->width += xdiff; + height = window->height + ydiff; + width = window->width + xdiff; + window->width = window->last_column-window->first_column+1; window->height = window->last_line-window->first_line+1; - window->size_dirty = TRUE; + if (height != window->height || width != window->width) { + g_warning("Resizing window %p W:%d expected:%d H:%d expected:%d", + window, window->width, width, window->height, height); + } + window->size_dirty = TRUE; } static GSList *get_sticky_windows_sorted(MAIN_WINDOW_REC *mainwin) @@ -178,14 +208,13 @@ void mainwindows_recreate(void) } } -MAIN_WINDOW_REC *mainwindow_create(void) +MAIN_WINDOW_REC *mainwindow_create(int right) { MAIN_WINDOW_REC *rec, *parent; int space; rec = g_new0(MAIN_WINDOW_REC, 1); rec->dirty = TRUE; - rec->width = term_width; if (mainwindows == NULL) { active_mainwin = rec; @@ -193,21 +222,53 @@ MAIN_WINDOW_REC *mainwindow_create(void) rec->first_line = screen_reserved_top; rec->last_line = term_height-1 - screen_reserved_bottom; rec->height = rec->last_line-rec->first_line+1; + rec->first_column = screen_reserved_left; + rec->last_column = screen_width-1 - screen_reserved_right; + rec->width = rec->last_column-rec->first_column+1; } else { parent = WINDOW_MAIN(active_win); - if (MAIN_WINDOW_TEXT_HEIGHT(parent) < - WINDOW_MIN_SIZE+NEW_WINDOW_SIZE) - parent = find_window_with_room(); - if (parent == NULL) - return NULL; /* not enough space */ - space = parent->height / 2; - rec->first_line = parent->first_line; - rec->last_line = rec->first_line + space; - rec->height = rec->last_line-rec->first_line+1; + if (!right) { + GSList *tmp, *line; + if (MAIN_WINDOW_TEXT_HEIGHT(parent) < + WINDOW_MIN_SIZE+NEW_WINDOW_SIZE) + parent = find_window_with_room(); + if (parent == NULL) + return NULL; /* not enough space */ - parent->first_line += space+1; - mainwindow_resize(parent, 0, -space-1); + space = parent->height / 2; + rec->first_line = parent->first_line; + rec->last_line = rec->first_line + space; + rec->height = rec->last_line-rec->first_line+1; + rec->first_column = screen_reserved_left; + rec->last_column = screen_width-1 - screen_reserved_right; + rec->width = rec->last_column-rec->first_column+1; + + line = mainwindows_get_line(parent); + for (tmp = line; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + rec->first_line += space+1; + mainwindow_resize(rec, 0, -space-1); + } + g_slist_free(line); + } else { + if (MAIN_WINDOW_TEXT_WIDTH(parent) < + 2* NEW_WINDOW_WIDTH) + parent = find_window_with_room_right(); + if (parent == NULL) + return NULL; /* not enough space */ + + space = parent->width / 2; + rec->first_line = parent->first_line; + rec->last_line = parent->last_line; + rec->height = parent->height; + rec->first_column = parent->last_column - space + 1; + rec->last_column = parent->last_column; + rec->width = rec->last_column-rec->first_column+1; + + parent->last_column -= space+1; + mainwindow_resize(parent, -space-1, 0); + } } rec->screen_win = mainwindow_create_screen(rec); @@ -218,16 +279,22 @@ MAIN_WINDOW_REC *mainwindow_create(void) return rec; } -static MAIN_WINDOW_REC *mainwindows_find_lower(int line) +static MAIN_WINDOW_REC *mainwindows_find_lower(MAIN_WINDOW_REC *window) { + int last_line; MAIN_WINDOW_REC *best; GSList *tmp; + if (window != NULL) + last_line = window->last_line; + else + last_line = -1; + best = NULL; for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; - if (rec->first_line > line && + if (rec->first_line > last_line && (best == NULL || rec->first_line < best->first_line)) best = rec; } @@ -235,16 +302,64 @@ static MAIN_WINDOW_REC *mainwindows_find_lower(int line) return best; } -static MAIN_WINDOW_REC *mainwindows_find_upper(int line) +static MAIN_WINDOW_REC *mainwindows_find_right(MAIN_WINDOW_REC *window, int find_first) { + int first_line, last_line, last_column; MAIN_WINDOW_REC *best; GSList *tmp; + if (window != NULL) { + first_line = window->first_line; + last_line = window->last_line; + last_column = window->last_column; + } else { + first_line = last_line = last_column = -1; + } + + if (find_first) + last_column = -1; + best = NULL; for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; - if (rec->last_line < line && + if (rec->first_line >= first_line && + rec->last_line <= last_line && + rec->first_column > last_column && + (best == NULL || rec->first_column < best->first_column)) + best = rec; + } + + return best; +} + +static MAIN_WINDOW_REC *mainwindows_find_lower_right(MAIN_WINDOW_REC *window) +{ + MAIN_WINDOW_REC *best; + + best = mainwindows_find_right(window, FALSE); + if (best == NULL) + best = mainwindows_find_lower(window); + + return best; +} + +static MAIN_WINDOW_REC *mainwindows_find_upper(MAIN_WINDOW_REC *window) +{ + int first_line; + MAIN_WINDOW_REC *best; + GSList *tmp; + + if (window != NULL) + first_line = window->first_line; + else + first_line = screen_height; + + best = NULL; + for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + + if (rec->last_line < first_line && (best == NULL || rec->last_line > best->last_line)) best = rec; } @@ -252,27 +367,142 @@ static MAIN_WINDOW_REC *mainwindows_find_upper(int line) return best; } -static void mainwindows_add_space(int first_line, int last_line) +static MAIN_WINDOW_REC *mainwindows_find_left(MAIN_WINDOW_REC *window, int find_last) +{ + int first_line, last_line, first_column; + MAIN_WINDOW_REC *best; + GSList *tmp; + + if (window != NULL) { + first_line = window->first_line; + last_line = window->last_line; + first_column = window->first_column; + } else { + first_line = last_line = screen_height; + first_column = screen_width; + } + + if (find_last) + first_column = screen_width; + + best = NULL; + for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + + if (rec->first_line >= first_line && + rec->last_line <= last_line && + rec->last_column < first_column && + (best == NULL || rec->last_column > best->last_column)) + best = rec; + } + + return best; +} + +static MAIN_WINDOW_REC *mainwindows_find_upper_left(MAIN_WINDOW_REC *window) +{ + MAIN_WINDOW_REC *best; + + best = mainwindows_find_left(window, FALSE); + if (best == NULL) + best = mainwindows_find_upper(window); + + return best; +} + +static MAIN_WINDOW_REC *mainwindows_find_left_upper(MAIN_WINDOW_REC *window) +{ + MAIN_WINDOW_REC *best; + + best = mainwindows_find_left(window, FALSE); + if (best == NULL) + best = mainwindows_find_left(mainwindows_find_upper(window), TRUE); + + return best; +} + +GSList *mainwindows_get_line(MAIN_WINDOW_REC *rec) +{ + MAIN_WINDOW_REC *win; + GSList *list; + + list = NULL; + + for (win = mainwindows_find_left(rec, FALSE); + win != NULL; + win = mainwindows_find_left(win, FALSE)) { + list = g_slist_append(list, win); + } + + if (rec != NULL) + list = g_slist_append(list, rec); + + for (win = mainwindows_find_right(rec, FALSE); + win != NULL; + win = mainwindows_find_right(win, FALSE)) { + list = g_slist_append(list, win); + } + + return list; +} + +/* add back the space which was occupied by destroyed mainwindow first_line .. last_line */ +static void mainwindows_add_space(MAIN_WINDOW_REC *destroy_win) { MAIN_WINDOW_REC *rec; - int size; + int size, rsize; - if (last_line < first_line) + if (destroy_win->last_line < destroy_win->first_line) return; - size = last_line-first_line+1; + if (destroy_win->last_column < destroy_win->first_column) + return; - rec = mainwindows_find_lower(last_line); + rsize = destroy_win->last_column-destroy_win->first_column+1; + rec = mainwindows_find_left(destroy_win, FALSE); if (rec != NULL) { - rec->first_line = first_line; - mainwindow_resize(rec, 0, size); + rec->last_column = destroy_win->last_column; + mainwindow_resize(rec, rsize+1, 0); return; } - rec = mainwindows_find_upper(first_line); + rec = mainwindows_find_right(destroy_win, FALSE); if (rec != NULL) { - rec->last_line = last_line; - mainwindow_resize(rec, 0, size); + rec->first_column = destroy_win->first_column; + mainwindow_resize(rec, rsize+1, 0); + return; + } + + size = destroy_win->last_line-destroy_win->first_line+1; + + rec = mainwindows_find_lower(destroy_win); + if (rec != NULL) { + GSList *tmp, *list; + list = mainwindows_get_line(rec); + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + rec->first_line = destroy_win->first_line; + mainwindow_resize(rec, 0, size); + } + + g_slist_free(list); + return; + } + + rec = mainwindows_find_upper(destroy_win); + if (rec != NULL) { + GSList *tmp, *list; + list = mainwindows_get_line(rec); + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + rec->last_line = destroy_win->last_line; + mainwindow_resize(rec, 0, size); + } + + g_slist_free(list); + return; } } @@ -302,8 +532,7 @@ void mainwindow_destroy(MAIN_WINDOW_REC *window) if (mainwindows != NULL) { gui_windows_remove_parent(window); if (!quitting) { - mainwindows_add_space(window->first_line, - window->last_line); + mainwindows_add_space(window); mainwindows_redraw(); } } @@ -313,6 +542,14 @@ void mainwindow_destroy(MAIN_WINDOW_REC *window) if (active_mainwin == window) active_mainwin = NULL; } +void mainwindow_destroy_half(MAIN_WINDOW_REC *window) +{ + int really_quitting = quitting; + quitting = TRUE; + mainwindow_destroy(window); + quitting = really_quitting; +} + void mainwindows_redraw(void) { GSList *tmp; @@ -327,12 +564,20 @@ void mainwindows_redraw(void) static int mainwindows_compare(MAIN_WINDOW_REC *w1, MAIN_WINDOW_REC *w2) { - return w1->first_line < w2->first_line ? -1 : 1; + return w1->first_line < w2->first_line ? -1 + : w1->first_line > w2->first_line ? 1 + : w1->first_column < w2->first_column ? -1 + : w1->first_column > w2->first_column ? 1 + : 0; } static int mainwindows_compare_reverse(MAIN_WINDOW_REC *w1, MAIN_WINDOW_REC *w2) { - return w1->first_line < w2->first_line ? 1 : -1; + return w1->first_line < w2->first_line ? 1 + : w1->first_line > w2->first_line ? -1 + : w1->first_column < w2->first_column ? 1 + : w1->first_column > w2->first_column ? -1 + : 0; } GSList *mainwindows_get_sorted(int reverse) @@ -348,123 +593,235 @@ GSList *mainwindows_get_sorted(int reverse) return list; } -static void mainwindows_resize_smaller(int xdiff, int ydiff) +static void mainwindows_resize_smaller(int ydiff) { - MAIN_WINDOW_REC *rec; + MAIN_WINDOW_REC *rec; GSList *sorted, *tmp; - int space; + int space; - sorted = mainwindows_get_sorted(TRUE); + sorted = NULL; + for (rec = mainwindows_find_lower(NULL); + rec != NULL; + rec = mainwindows_find_lower(rec)) { + sorted = g_slist_prepend(sorted, rec); + } if (sorted == NULL) return; for (;;) { + int skip_active = FALSE; space = 0; - for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { + /* for each line of windows, calculate the space that can be reduced still */ + for (tmp = sorted; tmp != NULL; tmp = tmp->next) { + int min; + GSList *line, *ltmp; rec = tmp->data; - space += MAIN_WINDOW_TEXT_HEIGHT(rec)-WINDOW_MIN_SIZE; + line = mainwindows_get_line(rec); + min = screen_height - ydiff; + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + int lmin; + MAIN_WINDOW_REC *win = ltmp->data; + if (win == active_mainwin && tmp == sorted) + skip_active = TRUE; + + lmin = MAIN_WINDOW_TEXT_HEIGHT(win)-WINDOW_MIN_SIZE; + if (lmin < min) + min = lmin; + } + g_slist_free(line); + space += min; } if (space >= -ydiff) break; rec = sorted->data; - if (rec == active_mainwin && sorted->next != NULL) + if (skip_active && sorted->next != NULL) rec = sorted->next->data; sorted = g_slist_remove(sorted, rec); if (sorted != NULL) { /* terminal is too small - destroy the uppest window and try again */ - mainwindow_destroy(rec); + GSList *line, *ltmp; + line = mainwindows_get_line(rec); + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + MAIN_WINDOW_REC *win = ltmp->data; + mainwindow_destroy(win); + } + g_slist_free(line); } else { - /* only one window in screen.. just force the resize */ - rec->last_line += ydiff; - mainwindow_resize(rec, xdiff, ydiff); - return; + /* only one line of window in screen.. just force the resize */ + GSList *line, *ltmp; + line = mainwindows_get_line(rec); + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + MAIN_WINDOW_REC *win = ltmp->data; + win->last_line += ydiff; + mainwindow_resize(win, 0, ydiff); + } + g_slist_free(line); + return; } } /* resize windows that have space */ for (tmp = sorted; tmp != NULL && ydiff < 0; tmp = tmp->next) { + int min; + GSList *line, *ltmp; + rec = tmp->data; + line = mainwindows_get_line(rec); + min = screen_height - ydiff; + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + int lmin; + MAIN_WINDOW_REC *win = ltmp->data; + lmin = MAIN_WINDOW_TEXT_HEIGHT(win)-WINDOW_MIN_SIZE; + if (lmin < min) + min = lmin; + } + space = min; - space = MAIN_WINDOW_TEXT_HEIGHT(rec)-WINDOW_MIN_SIZE; if (space == 0) { - mainwindow_resize(rec, xdiff, 0); + /* move the line */ + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + MAIN_WINDOW_REC *win = ltmp->data; + mainwindow_resize(win, 0, 0); + win->size_dirty = TRUE; + win->first_line += ydiff; + win->last_line += ydiff; + signal_emit("mainwindow moved", 1, win); + } + } else { + if (space > -ydiff) space = -ydiff; + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + MAIN_WINDOW_REC *win = ltmp->data; + win->last_line += ydiff; + win->first_line += ydiff + space; - rec->first_line += ydiff; - rec->last_line += ydiff; - signal_emit("mainwindow moved", 1, rec); - continue; - } - - if (space > -ydiff) space = -ydiff; - rec->last_line += ydiff; - ydiff += space; - rec->first_line += ydiff; - - mainwindow_resize(rec, xdiff, -space); - } - - if (xdiff != 0) { - while (tmp != NULL) { - mainwindow_resize(tmp->data, xdiff, 0); - tmp = tmp->next; + mainwindow_resize(win, 0, -space); + } + ydiff += space; } + g_slist_free(line); } g_slist_free(sorted); } -static void mainwindows_resize_bigger(int xdiff, int ydiff) +static void mainwindows_rresize_line(int xdiff, MAIN_WINDOW_REC *win) { - GSList *sorted, *tmp; + int windows, i, extra_width, next_column, shrunk; + int *widths; + GSList *line, *tmp; - sorted = mainwindows_get_sorted(FALSE); - for (tmp = sorted; tmp != NULL; tmp = tmp->next) { + line = mainwindows_get_line(win); + windows = g_slist_length(line); + widths = g_new0(int, windows); + + extra_width = screen_width - windows + 1; + for (tmp = line, i = 0; tmp != NULL; tmp = tmp->next, i++) { MAIN_WINDOW_REC *rec = tmp->data; - - if (ydiff == 0 || tmp->next != NULL) { - mainwindow_resize(rec, xdiff, 0); - continue; + widths[i] = (MAIN_WINDOW_TEXT_WIDTH(rec) * (screen_width - windows + 1)) / (screen_width - xdiff - windows + 1); + extra_width -= widths[i] + rec->statusbar_columns; + } + shrunk = FALSE; + for (i = windows; extra_width < 0; i = i > 1 ? i - 1 : windows) { + if (widths[i-1] > NEW_WINDOW_WIDTH || (i == 1 && !shrunk)) { + widths[i-1]--; + extra_width++; + shrunk = i == 1; } - - /* lowest window - give all the extra space for it */ - rec->last_line += ydiff; - mainwindow_resize(rec, xdiff, ydiff); } - g_slist_free(sorted); -} -static void mainwindows_resize_horiz(int xdiff) -{ - GSList *tmp; + next_column = 0; - for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { +#define extra ( (i >= screen_width % windows && i < extra_width + (screen_width % windows)) \ + || i + windows < extra_width + (screen_width % windows) ? 1 : 0 ) + + for (tmp = line, i = 0; tmp != NULL; tmp = tmp->next, i++) { MAIN_WINDOW_REC *rec = tmp->data; - - mainwindow_resize(rec, xdiff, 0); + rec->first_column = next_column; + rec->last_column = rec->first_column + widths[i] + rec->statusbar_columns + extra - 1; + next_column = rec->last_column + 2; + mainwindow_resize(rec, widths[i] + rec->statusbar_columns + extra - rec->width, 0); + rec->size_dirty = TRUE; } +#undef extra + + g_free(widths); + g_slist_free(line); } void mainwindows_resize(int width, int height) { int xdiff, ydiff; - xdiff = width-old_screen_width; - ydiff = height-old_screen_height; - old_screen_width = width; - old_screen_height = height; + xdiff = width-screen_width; + ydiff = height-screen_height; + screen_width = width; + screen_height = height; - if (ydiff < 0) - mainwindows_resize_smaller(xdiff, ydiff); - else if (ydiff > 0) - mainwindows_resize_bigger(xdiff, ydiff); - else if (xdiff != 0) - mainwindows_resize_horiz(xdiff); + if (ydiff > 0) { + /* algorithm: enlarge bottom window */ + MAIN_WINDOW_REC *rec; + GSList *line, *tmp; + line = mainwindows_get_line(mainwindows_find_upper(NULL)); + for (tmp = line; tmp != NULL; tmp = tmp->next) { + rec = tmp->data; + rec->last_line += ydiff; + mainwindow_resize(rec, 0, ydiff); + } + g_slist_free(line); + } - signal_emit("terminal resized", 0); + if (xdiff > 0) { + /* algorithm: distribute new space on each line */ + MAIN_WINDOW_REC *win; + + for (win = mainwindows_find_lower(NULL); + win != NULL; + win = mainwindows_find_lower(win)) { + mainwindows_rresize_line(xdiff, win); + } + } + + if (xdiff < 0) { + /* algorithm: shrink each window, + destroy windows on the right if no room */ + MAIN_WINDOW_REC *win; + + for (win = mainwindows_find_lower(NULL); + win != NULL; + win = mainwindows_find_lower(win)) { + int max_windows, i, last_column; + GSList *line, *tmp; + + line = mainwindows_get_line(win); + max_windows = (screen_width + 1) / (NEW_WINDOW_WIDTH + 1); + if (max_windows < 1) + max_windows = 1; + last_column = screen_width - 1; + for (tmp = line, i = 0; tmp != NULL; tmp = tmp->next, i++) { + MAIN_WINDOW_REC *rec = tmp->data; + if (i >= max_windows) + mainwindow_destroy_half(rec); + else + last_column = rec->last_column; + } + win = line->data; + g_slist_free(line); + + mainwindows_rresize_line(screen_width - last_column + 1, win); + } + } + + if (ydiff < 0) { + /* algorithm: shrink windows starting from bottom, + destroy windows starting from top if no room */ + mainwindows_resize_smaller(ydiff); + } + + signal_emit("terminal resized", 0); irssi_redraw(); } @@ -474,31 +831,37 @@ int mainwindows_reserve_lines(int top, int bottom) MAIN_WINDOW_REC *window; int ret; - ret = -1; + ret = -1; if (top != 0) { + GSList *list, *tmp; g_return_val_if_fail(top > 0 || screen_reserved_top > top, -1); ret = screen_reserved_top; screen_reserved_top += top; - window = mainwindows_find_lower(-1); - if (window != NULL) { + list = mainwindows_get_line(mainwindows_find_lower(NULL)); + for (tmp = list; tmp != NULL; tmp = tmp->next) { + window = tmp->data; window->first_line += top; mainwindow_resize(window, 0, -top); } + g_slist_free(list); } if (bottom != 0) { + GSList *list, *tmp; g_return_val_if_fail(bottom > 0 || screen_reserved_bottom > bottom, -1); ret = screen_reserved_bottom; screen_reserved_bottom += bottom; - window = mainwindows_find_upper(term_height); - if (window != NULL) { + list = mainwindows_get_line(mainwindows_find_upper(NULL)); + for (tmp = list; tmp != NULL; tmp = tmp->next) { + window = tmp->data; window->last_line -= bottom; mainwindow_resize(window, 0, -bottom); } + g_slist_free(list); } return ret; @@ -528,47 +891,109 @@ int mainwindow_set_statusbar_lines(MAIN_WINDOW_REC *window, return ret; } -static void mainwindows_resize_two(MAIN_WINDOW_REC *grow_win, - MAIN_WINDOW_REC *shrink_win, int count) +static void mainwindows_resize_two(GSList *grow_list, + GSList *shrink_list, int count) { - irssi_set_dirty(); + GSList *tmp; + MAIN_WINDOW_REC *win; - mainwindow_resize(grow_win, 0, count); - mainwindow_resize(shrink_win, 0, -count); - grow_win->dirty = TRUE; - shrink_win->dirty = TRUE; + irssi_set_dirty(); + + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + mainwindow_resize(win, 0, -count); + win->dirty = TRUE; + } + for (tmp = grow_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + mainwindow_resize(win, 0, count); + win->dirty = TRUE; + } } static int try_shrink_lower(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; - shrink_win = mainwindows_find_lower(window->last_line); - if (shrink_win != NULL && - MAIN_WINDOW_TEXT_HEIGHT(shrink_win)-count >= WINDOW_MIN_SIZE) { - window->last_line += count; - shrink_win->first_line += count; - mainwindows_resize_two(window, shrink_win, count); - return TRUE; + shrink_win = mainwindows_find_lower(window); + if (shrink_win != NULL) { + int ok; + GSList *shrink_list, *tmp; + MAIN_WINDOW_REC *win; + + ok = TRUE; + shrink_list = mainwindows_get_line(shrink_win); + + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + if (MAIN_WINDOW_TEXT_HEIGHT(win)-count < WINDOW_MIN_SIZE) { + ok = FALSE; + break; + } + } + if (ok) { + GSList *grow_list; + grow_list = mainwindows_get_line(window); + + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->first_line += count; + } + for (tmp = grow_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->last_line += count; + } + + mainwindows_resize_two(grow_list, shrink_list, count); + g_slist_free(grow_list); + } + + g_slist_free(shrink_list); + return ok; } - return FALSE; + return FALSE; } static int try_shrink_upper(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; - shrink_win = mainwindows_find_upper(window->first_line); - if (shrink_win != NULL && - MAIN_WINDOW_TEXT_HEIGHT(shrink_win)-count >= WINDOW_MIN_SIZE) { - window->first_line -= count; - shrink_win->last_line -= count; - mainwindows_resize_two(window, shrink_win, count); - return TRUE; + shrink_win = mainwindows_find_upper(window); + if (shrink_win != NULL) { + int ok; + GSList *shrink_list, *tmp; + MAIN_WINDOW_REC *win; + + ok = TRUE; + shrink_list = mainwindows_get_line(shrink_win); + + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + if (MAIN_WINDOW_TEXT_HEIGHT(win)-count < WINDOW_MIN_SIZE) { + ok = FALSE; + break; + } + } + if (ok) { + GSList *grow_list; + grow_list = mainwindows_get_line(window); + for (tmp = grow_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->first_line -= count; + } + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->last_line -= count; + } + mainwindows_resize_two(grow_list, shrink_list, count); + g_slist_free(grow_list); + } + g_slist_free(shrink_list); + return ok; } - return FALSE; + return FALSE; } static int mainwindow_grow(MAIN_WINDOW_REC *window, int count, @@ -588,28 +1013,52 @@ static int try_grow_lower(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *grow_win; - grow_win = mainwindows_find_lower(window->last_line); + grow_win = mainwindows_find_lower(window); if (grow_win != NULL) { - window->last_line -= count; - grow_win->first_line -= count; - mainwindows_resize_two(grow_win, window, count); + MAIN_WINDOW_REC *win; + GSList *grow_list, *shrink_list, *tmp; + grow_list = mainwindows_get_line(grow_win); + shrink_list = mainwindows_get_line(window); + for (tmp = grow_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->first_line -= count; + } + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->last_line -= count; + } + mainwindows_resize_two(grow_list, shrink_list, count); + g_slist_free(shrink_list); + g_slist_free(grow_list); } - return grow_win != NULL; + return grow_win != NULL; } static int try_grow_upper(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *grow_win; - grow_win = mainwindows_find_upper(window->first_line); + grow_win = mainwindows_find_upper(window); if (grow_win != NULL) { - window->first_line += count; - grow_win->last_line += count; - mainwindows_resize_two(grow_win, window, count); + MAIN_WINDOW_REC *win; + GSList *grow_list, *shrink_list, *tmp; + grow_list = mainwindows_get_line(grow_win); + shrink_list = mainwindows_get_line(window); + for (tmp = grow_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->last_line += count; + } + for (tmp = shrink_list; tmp != NULL; tmp = tmp->next) { + win = tmp->data; + win->first_line += count; + } + mainwindows_resize_two(grow_list, shrink_list, count); + g_slist_free(shrink_list); + g_slist_free(grow_list); } - return grow_win != NULL; + return grow_win != NULL; } static int mainwindow_shrink(MAIN_WINDOW_REC *window, int count, int resize_lower) @@ -627,6 +1076,109 @@ static int mainwindow_shrink(MAIN_WINDOW_REC *window, int count, int resize_lowe return TRUE; } +static void mainwindows_rresize_two(MAIN_WINDOW_REC *grow_win, + MAIN_WINDOW_REC *shrink_win, int count) +{ + irssi_set_dirty(); + + mainwindow_resize(grow_win, count, 0); + mainwindow_resize(shrink_win, -count, 0); + grow_win->dirty = TRUE; + shrink_win->dirty = TRUE; +} + +static int try_rshrink_right(MAIN_WINDOW_REC *window, int count) +{ + MAIN_WINDOW_REC *shrink_win; + + shrink_win = mainwindows_find_right(window, FALSE); + if (shrink_win != NULL) { + if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { + return FALSE; + } + + shrink_win->first_column += count; + window->last_column += count; + + mainwindows_rresize_two(window, shrink_win, count); + return TRUE; + } + + return FALSE; +} + +static int try_rshrink_left(MAIN_WINDOW_REC *window, int count) +{ + MAIN_WINDOW_REC *shrink_win; + + shrink_win = mainwindows_find_left(window, FALSE); + if (shrink_win != NULL) { + if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { + return FALSE; + } + window->first_column -= count; + shrink_win->last_column -= count; + + mainwindows_rresize_two(window, shrink_win, count); + return TRUE; + } + + return FALSE; +} + +static int mainwindow_rgrow(MAIN_WINDOW_REC *window, int count) +{ + if (!try_rshrink_right(window, count)) { + if (!try_rshrink_left(window, count)) + return FALSE; + } + + return TRUE; +} + +static int try_rgrow_right(MAIN_WINDOW_REC *window, int count) +{ + MAIN_WINDOW_REC *grow_win; + + grow_win = mainwindows_find_right(window, FALSE); + if (grow_win != NULL) { + grow_win->first_column -= count; + window->last_column -= count; + mainwindows_rresize_two(grow_win, window, count); + return TRUE; + } + + return FALSE; +} + +static int try_rgrow_left(MAIN_WINDOW_REC *window, int count) +{ + MAIN_WINDOW_REC *grow_win; + + grow_win = mainwindows_find_left(window, FALSE); + if (grow_win != NULL) { + grow_win->last_column += count; + window->first_column += count; + mainwindows_rresize_two(grow_win, window, count); + return TRUE; + } + + return FALSE; +} + +static int mainwindow_rshrink(MAIN_WINDOW_REC *window, int count) +{ + if (MAIN_WINDOW_TEXT_WIDTH(window)-count < NEW_WINDOW_WIDTH) + return FALSE; + + if (!try_rgrow_right(window, count)) { + if (!try_rgrow_left(window, count)) + return FALSE; + } + + return TRUE; +} + /* Change the window height - the height includes the lines needed for statusbars. If resize_lower is TRUE, the lower window is first tried to be resized instead of upper window. */ @@ -639,6 +1191,15 @@ void mainwindow_set_size(MAIN_WINDOW_REC *window, int height, int resize_lower) mainwindow_grow(window, height, resize_lower); } +void mainwindow_set_rsize(MAIN_WINDOW_REC *window, int width) +{ + width -= window->width; + if (width < 0) + mainwindow_rshrink(window, -width); + else + mainwindow_rgrow(window, width); +} + void mainwindows_redraw_dirty(void) { GSList *tmp; @@ -707,35 +1268,52 @@ static void cmd_window_size(const char *data) /* SYNTAX: WINDOW BALANCE */ static void cmd_window_balance(void) { - GSList *sorted, *tmp; + GSList *sorted, *stmp, *line, *ltmp; int avail_size, unit_size, bigger_units; int windows, last_line, old_size; + MAIN_WINDOW_REC *win; windows = g_slist_length(mainwindows); if (windows == 1) return; + sorted = NULL; + windows = 0; + for (win = mainwindows_find_lower(NULL); + win != NULL; + win = mainwindows_find_lower(win)) { + windows++; + sorted = g_slist_append(sorted, win); + } + avail_size = term_height - screen_reserved_top-screen_reserved_bottom; unit_size = avail_size/windows; bigger_units = avail_size%windows; - sorted = mainwindows_get_sorted(FALSE); - last_line = screen_reserved_top; - for (tmp = sorted; tmp != NULL; tmp = tmp->next) { - MAIN_WINDOW_REC *rec = tmp->data; + last_line = screen_reserved_top; + for (stmp = sorted; stmp != NULL; stmp = stmp->next) { + win = stmp->data; + line = mainwindows_get_line(win); - old_size = rec->height; - rec->first_line = last_line; - rec->last_line = rec->first_line + unit_size-1; + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + MAIN_WINDOW_REC *rec = ltmp->data; + old_size = rec->height; + rec->first_line = last_line; + rec->last_line = rec->first_line + unit_size-1; - if (bigger_units > 0) { - rec->last_line++; - bigger_units--; + if (bigger_units > 0) { + rec->last_line++; + } + + rec->height = rec->last_line-rec->first_line+1; + + mainwindow_resize(rec, 0, rec->height-old_size); } + if (line != NULL && bigger_units > 0) { + bigger_units--; + } + last_line = win->last_line+1; - rec->height = rec->last_line-rec->first_line+1; - last_line = rec->last_line+1; - - mainwindow_resize(rec, 0, rec->height-old_size); + g_slist_free(line); } g_slist_free(sorted); @@ -769,29 +1347,30 @@ static void cmd_window_hide(const char *data) return; if (WINDOW_MAIN(window)->sticky_windows) { - printformat_window(active_win, MSGLEVEL_CLIENTERROR, - TXT_CANT_HIDE_STICKY_WINDOWS); - return; + if (!settings_get_bool("autounstick_windows")) { + printformat_window(active_win, MSGLEVEL_CLIENTERROR, + TXT_CANT_HIDE_STICKY_WINDOWS); + return; + } } mainwindow_destroy(WINDOW_MAIN(window)); if (active_mainwin == NULL) { active_mainwin = WINDOW_MAIN(active_win); - window_set_active(active_mainwin->active); + window_set_active(active_mainwin->active); } } -/* SYNTAX: WINDOW SHOW | */ -static void cmd_window_show(const char *data) +static void _cmd_window_show_opt(const char *data, int right) { - MAIN_WINDOW_REC *parent; + MAIN_WINDOW_REC *parent; WINDOW_REC *window; if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); if (is_numeric(data, '\0')) { - window = window_find_refnum(atoi(data)); + window = window_find_refnum(atoi(data)); if (window == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_REFNUM_NOT_FOUND, data); @@ -804,30 +1383,150 @@ static void cmd_window_show(const char *data) return; if (WINDOW_GUI(window)->sticky) { - printformat_window(active_win, MSGLEVEL_CLIENTERROR, - TXT_CANT_SHOW_STICKY_WINDOWS); - return; + if (!settings_get_bool("autounstick_windows")) { + printformat_window(active_win, MSGLEVEL_CLIENTERROR, + TXT_CANT_SHOW_STICKY_WINDOWS); + return; + } } - parent = mainwindow_create(); + parent = mainwindow_create(right); parent->active = window; - gui_window_reparent(window, parent); + gui_window_reparent(window, parent); if (settings_get_bool("autostick_split_windows")) - gui_window_set_sticky(window); + gui_window_set_sticky(window); active_mainwin = NULL; window_set_active(window); } +/* SYNTAX: WINDOW SHOW | */ +static void cmd_window_show(const char *data) +{ + _cmd_window_show_opt(data, FALSE); +} + +/* SYNTAX: WINDOW RSHOW | */ +static void cmd_window_rshow(const char *data) +{ + _cmd_window_show_opt(data, TRUE); +} + +/* SYNTAX: WINDOW RGROW [] */ +static void cmd_window_rgrow(const char *data) +{ + int count; + + count = *data == '\0' ? 1 : atoi(data); + if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, + TXT_WINDOW_TOO_SMALL); + } +} + +/* SYNTAX: WINDOW RSHRINK [] */ +static void cmd_window_rshrink(const char *data) +{ + int count; + + count = *data == '\0' ? 1 : atoi(data); + if (!mainwindow_rshrink(WINDOW_MAIN(active_win), count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, + TXT_WINDOW_TOO_SMALL); + } +} + +/* SYNTAX: WINDOW RSIZE */ +static void cmd_window_rsize(const char *data) +{ + char rsizestr[MAX_INT_STRLEN]; + int rsize; + + if (!is_numeric(data, 0)) return; + rsize = atoi(data); + + rsize -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win)); + if (rsize == 0) return; + + ltoa(rsizestr, rsize < 0 ? -rsize : rsize); + if (rsize < 0) + cmd_window_rshrink(rsizestr); + else + cmd_window_rgrow(rsizestr); +} + +/* SYNTAX: WINDOW RBALANCE */ +static void cmd_window_rbalance(void) +{ + GSList *line, *ltmp; + int avail_width, unit_width, bigger_units; + int windows, last_column, old_width; + MAIN_WINDOW_REC *win; + + line = mainwindows_get_line(WINDOW_MAIN(active_win)); + windows = g_slist_length(line); + if (windows == 1) { + g_slist_free(line); + return; + } + + avail_width = term_width - screen_reserved_left-screen_reserved_right - windows + 1; + unit_width = avail_width/windows; + bigger_units = avail_width%windows; + + last_column = screen_reserved_left; + for (ltmp = line; ltmp != NULL; ltmp = ltmp->next) { + win = ltmp->data; + old_width = win->width; + win->first_column = last_column; + win->last_column = win->first_column + unit_width-1; + + if (bigger_units > 0) { + win->last_column++; + bigger_units--; + } + + mainwindow_resize(win, win->last_column - win->first_column + 1 - old_width, 0); + last_column = win->last_column+2; + } + g_slist_free(line); + + mainwindows_redraw(); +} + /* SYNTAX: WINDOW UP */ static void cmd_window_up(void) { MAIN_WINDOW_REC *rec; - rec = mainwindows_find_upper(active_mainwin->first_line); + rec = mainwindows_find_left_upper(active_mainwin); if (rec == NULL) - rec = mainwindows_find_upper(term_height); + rec = mainwindows_find_left_upper(NULL); + if (rec != NULL) + window_set_active(rec->active); +} + +/* SYNTAX: WINDOW DUP */ +static void cmd_window_dup(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_upper(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_upper(NULL); + if (rec != NULL) + window_set_active(rec->active); +} + +/* SYNTAX: WINDOW DLEFT */ +static void cmd_window_dleft(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_left(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_left(active_mainwin, TRUE); if (rec != NULL) window_set_active(rec->active); } @@ -837,9 +1536,33 @@ static void cmd_window_down(void) { MAIN_WINDOW_REC *rec; - rec = mainwindows_find_lower(active_mainwin->last_line); + rec = mainwindows_find_lower_right(active_mainwin); if (rec == NULL) - rec = mainwindows_find_lower(-1); + rec = mainwindows_find_lower_right(NULL); + if (rec != NULL) + window_set_active(rec->active); +} + +/* SYNTAX: WINDOW DDOWN */ +static void cmd_window_ddown(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_lower(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_lower(NULL); + if (rec != NULL) + window_set_active(rec->active); +} + +/* SYNTAX: WINDOW DRIGHT */ +static void cmd_window_dright(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_right(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_right(active_mainwin, TRUE); if (rec != NULL) window_set_active(rec->active); } @@ -997,13 +1720,37 @@ static void cmd_window_move_right(void) window_set_refnum(active_win, refnum); } +/* SYNTAX: WINDOW MOVE DLEFT */ +static void cmd_window_move_dleft(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_left(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_left(active_mainwin, TRUE); + if (rec != NULL) + window_reparent(active_win, rec); +} + +/* SYNTAX: WINDOW MOVE DRIGHT */ +static void cmd_window_move_dright(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_right(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_right(active_mainwin, TRUE); + if (rec != NULL) + window_reparent(active_win, rec); +} + /* SYNTAX: WINDOW MOVE UP */ static void cmd_window_move_up(void) { MAIN_WINDOW_REC *rec; - rec = mainwindows_find_upper(active_mainwin->first_line); - if (rec != NULL) + rec = mainwindows_find_upper_left(active_mainwin); + if (rec != NULL) window_reparent(active_win, rec); } @@ -1012,7 +1759,7 @@ static void cmd_window_move_down(void) { MAIN_WINDOW_REC *rec; - rec = mainwindows_find_lower(active_mainwin->last_line); + rec = mainwindows_find_lower_right(active_mainwin); if (rec != NULL) window_reparent(active_win, rec); } @@ -1058,12 +1805,14 @@ static void sig_window_print_info(WINDOW_REC *win) void mainwindows_init(void) { - old_screen_width = term_width; - old_screen_height = term_height; + screen_width = term_width; + screen_height = term_height; mainwindows = NULL; active_mainwin = NULL; + clrtoeol_info = g_new0(MAIN_WINDOW_BORDER_REC, 1); screen_reserved_top = screen_reserved_bottom = 0; + screen_reserved_left = screen_reserved_right = 0; command_bind("window grow", NULL, (SIGNAL_FUNC) cmd_window_grow); command_bind("window shrink", NULL, (SIGNAL_FUNC) cmd_window_shrink); @@ -1075,18 +1824,30 @@ void mainwindows_init(void) command_bind("window down", NULL, (SIGNAL_FUNC) cmd_window_down); command_bind("window left", NULL, (SIGNAL_FUNC) cmd_window_left); command_bind("window right", NULL, (SIGNAL_FUNC) cmd_window_right); + command_bind("window dup", NULL, (SIGNAL_FUNC) cmd_window_dup); + command_bind("window ddown", NULL, (SIGNAL_FUNC) cmd_window_ddown); + command_bind("window dleft", NULL, (SIGNAL_FUNC) cmd_window_dleft); + command_bind("window dright", NULL, (SIGNAL_FUNC) cmd_window_dright); command_bind("window stick", NULL, (SIGNAL_FUNC) cmd_window_stick); command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left); command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right); command_bind("window move up", NULL, (SIGNAL_FUNC) cmd_window_move_up); command_bind("window move down", NULL, (SIGNAL_FUNC) cmd_window_move_down); - signal_add("window print info", (SIGNAL_FUNC) sig_window_print_info); + command_bind("window move dleft", NULL, (SIGNAL_FUNC) cmd_window_move_dleft); + command_bind("window move dright", NULL, (SIGNAL_FUNC) cmd_window_move_dright); + command_bind("window rgrow", NULL, (SIGNAL_FUNC) cmd_window_rgrow); + command_bind("window rshrink", NULL, (SIGNAL_FUNC) cmd_window_rshrink); + command_bind("window rsize", NULL, (SIGNAL_FUNC) cmd_window_rsize); + command_bind("window rbalance", NULL, (SIGNAL_FUNC) cmd_window_rbalance); + command_bind("window rshow", NULL, (SIGNAL_FUNC) cmd_window_rshow); + signal_add("window print info", (SIGNAL_FUNC) sig_window_print_info); } void mainwindows_deinit(void) { while (mainwindows != NULL) mainwindow_destroy(mainwindows->data); + g_free(clrtoeol_info); command_unbind("window grow", (SIGNAL_FUNC) cmd_window_grow); command_unbind("window shrink", (SIGNAL_FUNC) cmd_window_shrink); @@ -1098,10 +1859,21 @@ void mainwindows_deinit(void) command_unbind("window down", (SIGNAL_FUNC) cmd_window_down); command_unbind("window left", (SIGNAL_FUNC) cmd_window_left); command_unbind("window right", (SIGNAL_FUNC) cmd_window_right); + command_unbind("window dup", (SIGNAL_FUNC) cmd_window_dup); + command_unbind("window ddown", (SIGNAL_FUNC) cmd_window_ddown); + command_unbind("window dleft", (SIGNAL_FUNC) cmd_window_dleft); + command_unbind("window dright", (SIGNAL_FUNC) cmd_window_dright); command_unbind("window stick", (SIGNAL_FUNC) cmd_window_stick); command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left); command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right); command_unbind("window move up", (SIGNAL_FUNC) cmd_window_move_up); command_unbind("window move down", (SIGNAL_FUNC) cmd_window_move_down); - signal_remove("window print info", (SIGNAL_FUNC) sig_window_print_info); + command_unbind("window move dleft", (SIGNAL_FUNC) cmd_window_move_dleft); + command_unbind("window move dright", (SIGNAL_FUNC) cmd_window_move_dright); + command_unbind("window rgrow", (SIGNAL_FUNC) cmd_window_rgrow); + command_unbind("window rshrink", (SIGNAL_FUNC) cmd_window_rshrink); + command_unbind("window rsize", (SIGNAL_FUNC) cmd_window_rsize); + command_unbind("window rbalance", (SIGNAL_FUNC) cmd_window_rbalance); + command_unbind("window rshow", (SIGNAL_FUNC) cmd_window_rshow); + signal_remove("window print info", (SIGNAL_FUNC) sig_window_print_info); } diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 1bca333d..414275bf 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -5,36 +5,48 @@ #include "term.h" #define WINDOW_MIN_SIZE 2 +#define NEW_WINDOW_WIDTH 10 #define MAIN_WINDOW_TEXT_HEIGHT(window) \ ((window)->height-(window)->statusbar_lines) +#define MAIN_WINDOW_TEXT_WIDTH(window) \ + ((window)->width-(window)->statusbar_columns) + typedef struct { WINDOW_REC *active; TERM_WINDOW *screen_win; - int sticky_windows; /* number of sticky windows */ + int sticky_windows; /* number of sticky windows */ int first_line, last_line; /* first/last line used by this window (0..x) (includes statusbars) */ + int first_column, last_column; /* first/last column used by this window (0..x) (includes statusbars) */ int width, height; /* width/height of the window (includes statusbars) */ GSList *statusbars; - int statusbar_lines_top; - int statusbar_lines_bottom; + int statusbar_lines_top, statusbar_lines_bottom; int statusbar_lines; /* top+bottom */ + int statusbar_columns_left, statusbar_columns_right; + int statusbar_columns; /* left+right */ unsigned int dirty:1; /* This window needs a redraw */ unsigned int size_dirty:1; /* We'll need to resize the window, but haven't got around doing it just yet. */ } MAIN_WINDOW_REC; +typedef struct { + char *color; + TERM_WINDOW *window; +} MAIN_WINDOW_BORDER_REC; + extern GSList *mainwindows; extern MAIN_WINDOW_REC *active_mainwin; +extern MAIN_WINDOW_BORDER_REC *clrtoeol_info; extern int screen_reserved_top, screen_reserved_bottom; void mainwindows_init(void); void mainwindows_deinit(void); -MAIN_WINDOW_REC *mainwindow_create(void); +MAIN_WINDOW_REC *mainwindow_create(int); void mainwindow_destroy(MAIN_WINDOW_REC *window); void mainwindows_redraw(void); @@ -45,6 +57,7 @@ void mainwindows_recreate(void); to be resized instead of upper window. */ void mainwindow_set_size(MAIN_WINDOW_REC *window, int height, int resize_lower); +void mainwindow_set_rsize(MAIN_WINDOW_REC *window, int width); void mainwindows_resize(int width, int height); void mainwindow_change_active(MAIN_WINDOW_REC *mainwin, @@ -56,5 +69,6 @@ int mainwindow_set_statusbar_lines(MAIN_WINDOW_REC *window, void mainwindows_redraw_dirty(void); GSList *mainwindows_get_sorted(int reverse); +GSList *mainwindows_get_line(MAIN_WINDOW_REC *rec); #endif diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index c4606197..c37d5c62 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -41,8 +41,8 @@ FORMAT_REC gui_text_formats[] = { "refnum_not_found", "Window number $0 not found", 1, { 0 } }, { "window_too_small", "Not enough room to resize this window", 0 }, { "cant_hide_last", "You can't hide the last window", 0 }, - { "cant_hide_sticky_windows", "You can't hide sticky windows (use /WINDOW STICK OFF)", 0 }, - { "cant_show_sticky_windows", "You can't show sticky windows (use /WINDOW STICK OFF)", 0 }, + { "cant_hide_sticky_windows", "You can't hide sticky windows (use /SET autounstick_windows ON)", 0 }, + { "cant_show_sticky_windows", "You can't show sticky windows (use /SET autounstick_windows ON)", 0 }, { "window_not_sticky", "Window is not sticky", 0 }, { "window_set_sticky", "Window set sticky", 0 }, { "window_unset_sticky", "Window is not sticky anymore", 0 }, diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index c7d6bcfb..5740a40b 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -418,7 +418,7 @@ static void item_input(SBAR_ITEM_REC *item, int get_size_only) rec = g_hash_table_lookup(input_entries, item->bar->config->name); if (rec == NULL) { - rec = gui_entry_create(item->xpos, item->bar->real_ypos, + rec = gui_entry_create(ITEM_WINDOW_REAL_XPOS(item), item->bar->real_ypos, item->size, term_type == TERM_TYPE_UTF8); gui_entry_set_active(rec); g_hash_table_insert(input_entries, @@ -426,12 +426,21 @@ static void item_input(SBAR_ITEM_REC *item, int get_size_only) } if (get_size_only) { - item->min_size = 2+term_width/10; - item->max_size = term_width; - return; + int max_width; + WINDOW_REC *window; + + window = item->bar->parent_window != NULL + ? item->bar->parent_window->active + : NULL; + + max_width = window != NULL ? window->width : term_width; + + item->min_size = 2+max_width/10; + item->max_size = max_width; + return; } - gui_entry_move(rec, item->xpos, item->bar->real_ypos, + gui_entry_move(rec, ITEM_WINDOW_REAL_XPOS(item), item->bar->real_ypos, item->size); gui_entry_redraw(rec); /* FIXME: this is only necessary with ^L.. */ } diff --git a/src/fe-text/statusbar.c b/src/fe-text/statusbar.c index f0dff828..40837eea 100644 --- a/src/fe-text/statusbar.c +++ b/src/fe-text/statusbar.c @@ -242,17 +242,24 @@ static void statusbar_resize_items(STATUSBAR_REC *bar, int max_width) static void statusbar_calc_item_positions(STATUSBAR_REC *bar) { - WINDOW_REC *old_active_win; + WINDOW_REC *window; + WINDOW_REC *old_active_win; GSList *tmp, *right_items; int xpos, rxpos; + int max_width; old_active_win = active_win; - if (bar->parent_window != NULL) + if (bar->parent_window != NULL) active_win = bar->parent_window->active; - statusbar_resize_items(bar, term_width); + window = bar->parent_window != NULL + ? bar->parent_window->active + : NULL; - /* left-aligned items */ + max_width = window != NULL ? window->width : term_width; + statusbar_resize_items(bar, max_width); + + /* left-aligned items */ xpos = 0; for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { SBAR_ITEM_REC *rec = tmp->data; @@ -260,11 +267,11 @@ static void statusbar_calc_item_positions(STATUSBAR_REC *bar) if (!rec->config->right_alignment && (rec->size > 0 || rec->current_size > 0)) { if (SBAR_ITEM_REDRAW_NEEDED(bar, rec, xpos)) { - /* redraw the item */ + /* redraw the item */ rec->dirty = TRUE; if (bar->dirty_xpos == -1 || xpos < bar->dirty_xpos) { - irssi_set_dirty(); + irssi_set_dirty(); bar->dirty = TRUE; bar->dirty_xpos = xpos; } @@ -277,12 +284,12 @@ static void statusbar_calc_item_positions(STATUSBAR_REC *bar) /* right-aligned items - first copy them to a new list backwards, easier to draw them in right order */ - right_items = NULL; + right_items = NULL; for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { SBAR_ITEM_REC *rec = tmp->data; if (rec->config->right_alignment) { - if (rec->size > 0) + if (rec->size > 0) right_items = g_slist_prepend(right_items, rec); else if (rec->current_size > 0 && (bar->dirty_xpos == -1 || @@ -291,12 +298,12 @@ static void statusbar_calc_item_positions(STATUSBAR_REC *bar) to begin from the item's old xpos */ irssi_set_dirty(); bar->dirty = TRUE; - bar->dirty_xpos = rec->xpos; + bar->dirty_xpos = rec->xpos; } } } - rxpos = term_width; + rxpos = max_width; for (tmp = right_items; tmp != NULL; tmp = tmp->next) { SBAR_ITEM_REC *rec = tmp->data; @@ -312,7 +319,7 @@ static void statusbar_calc_item_positions(STATUSBAR_REC *bar) rec->xpos = rxpos; } } - g_slist_free(right_items); + g_slist_free(right_items); active_win = old_active_win; } @@ -451,8 +458,13 @@ static void mainwindow_recalc_ypos(MAIN_WINDOW_REC *window, int placement) static void sig_mainwindow_resized(MAIN_WINDOW_REC *window) { - mainwindow_recalc_ypos(window, STATUSBAR_TOP); - mainwindow_recalc_ypos(window, STATUSBAR_BOTTOM); + GSList *tmp; + mainwindow_recalc_ypos(window, STATUSBAR_TOP); + mainwindow_recalc_ypos(window, STATUSBAR_BOTTOM); + for (tmp = window->statusbars; tmp != NULL; tmp = tmp->next) { + STATUSBAR_REC *bar = tmp->data; + statusbar_redraw(bar, TRUE); + } } STATUSBAR_REC *statusbar_create(STATUSBAR_GROUP_REC *group, @@ -728,7 +740,7 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, g_string_append_c(out, ' '); } - gui_printtext(item->xpos, item->bar->real_ypos, out->str); + gui_printtext(ITEM_WINDOW_REAL_XPOS(item), item->bar->real_ypos, out->str); g_string_free(out, TRUE); } g_free(tmpstr); @@ -960,20 +972,42 @@ void statusbar_item_destroy(SBAR_ITEM_REC *item) g_free(item); } +static MAIN_WINDOW_BORDER_REC *set_border_info(STATUSBAR_REC *bar) +{ + MAIN_WINDOW_BORDER_REC *orig_border, *new_border; + orig_border = clrtoeol_info; + new_border = g_new0(MAIN_WINDOW_BORDER_REC, 1); + new_border->window = bar->parent_window != NULL ? bar->parent_window->screen_win : NULL; + new_border->color = bar->color; + clrtoeol_info = new_border; + return orig_border; +} + +static void restore_border_info(MAIN_WINDOW_BORDER_REC *border_info) +{ + MAIN_WINDOW_BORDER_REC *old_border; + old_border = clrtoeol_info; + clrtoeol_info = border_info; + g_free(old_border); +} + static void statusbar_redraw_needed_items(STATUSBAR_REC *bar) { - WINDOW_REC *old_active_win; + WINDOW_REC *old_active_win; GSList *tmp; char *str; old_active_win = active_win; - if (bar->parent_window != NULL) + if (bar->parent_window != NULL) active_win = bar->parent_window->active; if (bar->dirty_xpos >= 0) { + MAIN_WINDOW_BORDER_REC *orig_border; + orig_border = set_border_info(bar); str = g_strconcat(bar->color, "%>", NULL); - gui_printtext(bar->dirty_xpos, bar->real_ypos, str); + gui_printtext(BAR_WINDOW_REAL_DIRTY_XPOS(bar), bar->real_ypos, str); g_free(str); + restore_border_info(orig_border); } for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { @@ -982,13 +1016,13 @@ static void statusbar_redraw_needed_items(STATUSBAR_REC *bar) if (rec->dirty || (bar->dirty_xpos != -1 && rec->xpos >= bar->dirty_xpos)) { - rec->current_size = rec->size; + rec->current_size = rec->size; rec->func(rec, FALSE); rec->dirty = FALSE; } } - active_win = old_active_win; + active_win = old_active_win; } void statusbar_redraw_dirty(void) diff --git a/src/fe-text/statusbar.h b/src/fe-text/statusbar.h index 309294b0..b0048cc4 100644 --- a/src/fe-text/statusbar.h +++ b/src/fe-text/statusbar.h @@ -23,6 +23,12 @@ typedef struct SBAR_ITEM_REC SBAR_ITEM_REC; #define STATUSBAR_VISIBLE_ACTIVE 2 #define STATUSBAR_VISIBLE_INACTIVE 3 +#define ITEM_WINDOW_REAL_XPOS(item) ( ( (item)->bar->parent_window != NULL ? \ + (item)->bar->parent_window->first_column + (item)->bar->parent_window->statusbar_columns_left : 0 ) + (item)->xpos ) + +#define BAR_WINDOW_REAL_DIRTY_XPOS(bar) ( ( (bar)->parent_window != NULL ? \ + (bar)->parent_window->first_column + (bar)->parent_window->statusbar_columns_left : 0 ) + (bar)->dirty_xpos ) + typedef struct { char *name; GSList *config_bars; diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 6645cfb0..0b2c7cb0 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -23,6 +23,7 @@ #include "term.h" #include "terminfo-core.h" #include "fe-windows.h" +#include "gui-printtext.h" #include "utf8.h" #include @@ -284,10 +285,10 @@ void term_window_clear(TERM_WINDOW *window) { int y; - terminfo_set_normal(); - if (window->y == 0 && window->height == term_height) { - term_clear(); - } else { + terminfo_set_normal(); + if (window->y == 0 && window->height == term_height && window->width == term_width) { + term_clear(); + } else { for (y = 0; y < window->height; y++) { term_move(window, 0, y); term_clrtoeol(window); @@ -452,14 +453,14 @@ void term_set_color(TERM_WINDOW *window, int col) void term_move(TERM_WINDOW *window, int x, int y) { if (x >= 0 && y >= 0) { - vcmove = TRUE; - vcx = x+window->x; - vcy = y+window->y; + vcmove = TRUE; + vcx = x+window->x; + vcy = y+window->y; - if (vcx >= term_width) - vcx = term_width-1; - if (vcy >= term_height) - vcy = term_height-1; + if (vcx >= term_width) + vcx = term_width-1; + if (vcy >= term_height) + vcy = term_height-1; } } @@ -552,7 +553,7 @@ int term_addstr(TERM_WINDOW *window, const char *str) while (*ptr != '\0') { tmp = g_utf8_get_char_validated(ptr, -1); /* On utf8 error, treat as single byte and try to - continue interpretting rest of string as utf8 */ + continue interpreting rest of string as utf8 */ if (tmp == (gunichar)-1 || tmp == (gunichar)-2) { len++; ptr++; @@ -574,21 +575,47 @@ int term_addstr(TERM_WINDOW *window, const char *str) void term_clrtoeol(TERM_WINDOW *window) { - /* clrtoeol() doesn't necessarily understand colors */ - if (last_fg == -1 && last_bg == -1 && - (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_ITALIC)) == 0) { - if (!term_lines_empty[vcy]) { - if (vcmove) term_move_real(); - terminfo_clrtoeol(); - if (vcx == 0) term_lines_empty[vcy] = TRUE; - } - } else if (vcx < term_width) { - /* we'll need to fill the line ourself. */ - if (vcmove) term_move_real(); - terminfo_repeat(' ', term_width-vcx); - terminfo_move(vcx, vcy); - term_lines_empty[vcy] = FALSE; + if (vcx < window->x) { + /* we just wrapped outside of the split, put the cursor back into the window */ + vcx += window->x; } + if (window->x + window->width < term_width) { + /* we need to fill a vertical split */ + if (vcmove) term_move_real(); + terminfo_repeat(' ', window->x + window->width - vcx + 1); + terminfo_move(vcx, vcy); + term_lines_empty[vcy] = FALSE; + } else { + /* clrtoeol() doesn't necessarily understand colors */ + if (last_fg == -1 && last_bg == -1 && + (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_ITALIC)) == 0) { + if (!term_lines_empty[vcy]) { + if (vcmove) term_move_real(); + terminfo_clrtoeol(); + if (vcx == 0) term_lines_empty[vcy] = TRUE; + } + } else if (vcx < term_width) { + /* we'll need to fill the line ourself. */ + if (vcmove) term_move_real(); + terminfo_repeat(' ', term_width-vcx); + terminfo_move(vcx, vcy); + term_lines_empty[vcy] = FALSE; + } + } +} + +void term_window_clrtoeol(TERM_WINDOW* window, int ypos) +{ + term_clrtoeol(window); + if (window->x + window->width < term_width) { + gui_printtext_window_border(window->x + window->width, window->y + ypos); + term_set_color(window, ATTR_RESET); + } +} + +void term_window_clrtoeol_abs(TERM_WINDOW* window, int ypos) +{ + term_window_clrtoeol(window, ypos - window->y); } void term_move_cursor(int x, int y) diff --git a/src/fe-text/term.h b/src/fe-text/term.h index 0c7847f6..70012bea 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -85,6 +85,8 @@ void term_addch(TERM_WINDOW *window, char chr); void term_add_unichar(TERM_WINDOW *window, unichar chr); int term_addstr(TERM_WINDOW *window, const char *str); void term_clrtoeol(TERM_WINDOW *window); +void term_window_clrtoeol(TERM_WINDOW* window, int ypos); +void term_window_clrtoeol_abs(TERM_WINDOW* window, int ypos_abs); void term_move_cursor(int x, int y); diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index cb066f5e..b503ec73 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -388,9 +388,9 @@ static void view_reset_cache(TEXT_BUFFER_VIEW_REC *view) static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, int subline, int ypos, int max) { - INDENT_FUNC indent_func; + INDENT_FUNC indent_func; LINE_CACHE_REC *cache; - const unsigned char *text, *end, *text_newline; + const unsigned char *text, *end, *text_newline; unsigned char *tmp; unichar chr; int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width; @@ -399,54 +399,54 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, #endif if (view->dirty) /* don't bother drawing anything - redraw is coming */ - return 0; + return 0; cache = textbuffer_view_get_line_cache(view, line); if (subline >= cache->count) - return 0; + return 0; - color = ATTR_RESET; - need_move = TRUE; need_clrtoeol = FALSE; + color = ATTR_RESET; + need_move = TRUE; need_clrtoeol = FALSE; xpos = drawcount = 0; first = TRUE; text_newline = text = subline == 0 ? line->text : cache->lines[subline-1].start; for (;;) { if (text == text_newline) { - if (need_clrtoeol && xpos < term_width) { + if (need_clrtoeol && xpos < view->width + (view->width == term_width ? 0 : 1)) { term_set_color(view->window, ATTR_RESET); - term_clrtoeol(view->window); + term_window_clrtoeol(view->window, ypos); } if (first) first = FALSE; else { ypos++; - if (--max == 0) + if (--max == 0) break; } if (subline > 0) { - /* continuing previous line - indent it */ + /* continuing previous line - indent it */ indent_func = cache->lines[subline-1].indent_func; if (indent_func == NULL) xpos = cache->lines[subline-1].indent; - color = cache->lines[subline-1].color; + color = cache->lines[subline-1].color; #ifdef TERM_TRUECOLOR - fg24 = cache->lines[subline-1].fg24; - bg24 = cache->lines[subline-1].bg24; + fg24 = cache->lines[subline-1].fg24; + bg24 = cache->lines[subline-1].bg24; #endif } else { indent_func = NULL; } if (xpos == 0 && indent_func == NULL) - need_clrtoeol = TRUE; + need_clrtoeol = TRUE; else { /* line was indented - need to clear the - indented area first */ + indented area first */ term_set_color(view->window, ATTR_RESET); term_move(view->window, 0, ypos); - term_clrtoeol(view->window); + term_window_clrtoeol(view->window, ypos); if (indent_func != NULL) xpos = indent_func(view, line, ypos); @@ -463,9 +463,17 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, } else { /* get the beginning of the next subline */ text_newline = cache->lines[subline].start; - need_move = !cache->lines[subline].continues; + if (view->width == term_width) { + /* ensure that links / long words are not broken */ + need_move = !cache->lines[subline].continues; + } else { + /* we cannot use the need_move + optimisation unless the split spans + the whole width */ + need_move = TRUE; + } } - drawcount++; + drawcount++; subline++; } @@ -473,10 +481,10 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, /* command */ text++; if (*text == LINE_CMD_EOL) - break; + break; if (*text == LINE_CMD_CONTINUE) { - /* jump to next block */ + /* jump to next block */ memcpy(&tmp, text+1, sizeof(unsigned char *)); text = tmp; continue; @@ -511,13 +519,13 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, } xpos += char_width; - if (xpos <= term_width) { + if (xpos <= view->width) { if (unichar_isprint(chr)) { if (view->utf8) - term_add_unichar(view->window, chr); + term_add_unichar(view->window, chr); else - for (; text < end; text++) - term_addch(view->window, *text); + for (; text < end; text++) + term_addch(view->window, *text); } else { /* low-ascii */ term_set_color(view->window, ATTR_RESET|ATTR_REVERSE); @@ -528,12 +536,12 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, text = end; } - if (need_clrtoeol && xpos < term_width) { + if (need_clrtoeol && xpos < view->width + (view->width == term_width ? 0 : 1)) { term_set_color(view->window, ATTR_RESET); - term_clrtoeol(view->window); + term_window_clrtoeol(view->window, ypos); } - return drawcount; + return drawcount; } /* Recalculate view's bottom line information - try to keep the @@ -738,7 +746,7 @@ static void view_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, term_set_color(view->window, ATTR_RESET); while (lines > 0) { term_move(view->window, 0, ypos); - term_clrtoeol(view->window); + term_window_clrtoeol(view->window, ypos); ypos++; lines--; } } @@ -775,51 +783,51 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines, int linecount, realcount, scroll_visible; if (*lines == NULL) - return 0; + return 0; /* scroll down */ scroll_visible = lines == &view->startline; realcount = -*subline; scrollcount += *subline; - *subline = 0; + *subline = 0; while (scrollcount > 0) { linecount = view_get_linecount(view, *lines); if ((scroll_visible && *lines == view->bottom_startline) && (scrollcount >= view->bottom_subline)) { *subline = view->bottom_subline; - realcount += view->bottom_subline; - scrollcount = 0; - break; + realcount += view->bottom_subline; + scrollcount = 0; + break; } - realcount += linecount; + realcount += linecount; scrollcount -= linecount; if (scrollcount < 0) { - realcount += scrollcount; + realcount += scrollcount; *subline = linecount+scrollcount; - scrollcount = 0; - break; + scrollcount = 0; + break; } if ((*lines)->next == NULL) break; - *lines = (*lines)->next; + *lines = (*lines)->next; } - /* scroll up */ + /* scroll up */ while (scrollcount < 0 && (*lines)->prev != NULL) { *lines = (*lines)->prev; linecount = view_get_linecount(view, *lines); - realcount -= linecount; + realcount -= linecount; scrollcount += linecount; if (scrollcount > 0) { - realcount += scrollcount; + realcount += scrollcount; *subline = scrollcount; - break; + break; } } @@ -827,19 +835,27 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines, if (realcount <= -view->height || realcount >= view->height) { /* scrolled more than screenful, redraw the whole view */ - textbuffer_view_redraw(view); + textbuffer_view_redraw(view); } else { - term_set_color(view->window, ATTR_RESET); - term_window_scroll(view->window, realcount); + if (view->width == term_width) { + /* we can try to use vt100 scroll regions */ + term_set_color(view->window, ATTR_RESET); + term_window_scroll(view->window, realcount); - if (draw_nonclean) { - if (realcount < 0) - view_draw_top(view, -realcount, TRUE); - else - view_draw_bottom(view, realcount); + if (draw_nonclean) { + if (realcount < 0) + view_draw_top(view, -realcount, TRUE); + else + view_draw_bottom(view, realcount); + } + + term_refresh(view->window); + } else { + /* do not bother with vt400 scroll + rectangles for now, redraw the + whole view */ + textbuffer_view_redraw(view); } - - term_refresh(view->window); } } diff --git a/themes/default.theme b/themes/default.theme index 956d7c4f..79b1af55 100644 --- a/themes/default.theme +++ b/themes/default.theme @@ -251,6 +251,7 @@ abstracts = { # default background for all statusbars. You can also give # the default foreground color for statusbar items. sb_background = "%4%w"; + window_border = "%4%w"; # default backround for "default" statusbar group #sb_default_bg = "%4"; From 63d8e884ddb970d6a8b5c6a7a546f0283d38a055 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 9 May 2017 15:05:03 +0200 Subject: [PATCH 0267/1198] fix some more --- src/fe-text/term-terminfo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 0b2c7cb0..4d5ca65b 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -576,8 +576,9 @@ int term_addstr(TERM_WINDOW *window, const char *str) void term_clrtoeol(TERM_WINDOW *window) { if (vcx < window->x) { - /* we just wrapped outside of the split, put the cursor back into the window */ + /* we just wrapped outside of the split, warp the cursor back into the window */ vcx += window->x; + vcmove = TRUE; } if (window->x + window->width < term_width) { /* we need to fill a vertical split */ @@ -606,6 +607,10 @@ void term_clrtoeol(TERM_WINDOW *window) void term_window_clrtoeol(TERM_WINDOW* window, int ypos) { + if (ypos >= 0 && window->y + ypos != vcy) { + /* the line is already full */ + return; + } term_clrtoeol(window); if (window->x + window->width < term_width) { gui_printtext_window_border(window->x + window->width, window->y + ypos); From ded4e4d98df3c8df20119574c145fe1a736ee994 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 6 Jan 2018 01:05:35 +0100 Subject: [PATCH 0268/1198] fix redraw --- src/fe-text/mainwindows.c | 2 ++ src/fe-text/textbuffer-view.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index deab8de8..5f24674f 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -1214,6 +1214,8 @@ void mainwindows_redraw_dirty(void) if (rec->dirty) { rec->dirty = FALSE; gui_window_redraw(rec->active); + } else if (WINDOW_GUI(rec->active)->view->dirty) { + gui_window_redraw(rec->active); } } } diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index b503ec73..b7fdcb7d 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -854,7 +854,8 @@ static int view_scroll(TEXT_BUFFER_VIEW_REC *view, LINE_REC **lines, /* do not bother with vt400 scroll rectangles for now, redraw the whole view */ - textbuffer_view_redraw(view); + view->dirty = TRUE; + irssi_set_dirty(); } } } From 4d5982f07d7f32585c00f1d6cca3fb425183140f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 6 Jan 2018 20:02:31 +0100 Subject: [PATCH 0269/1198] Update fe-common-core.c --- src/fe-common/core/fe-common-core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index bce9ab4e..4f2d210a 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -475,26 +475,29 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) return FALSE; } - int server_tag_len = dest->server_tag ? strlen(dest->server_tag) : 0; + int server_tag_len = dest->server_tag != NULL ? strlen(dest->server_tag) : 0; for (tmp = array; *tmp != NULL; tmp++) { char *str = *tmp; if (*str == '\0') { continue; } - if (server_tag_len && !g_ascii_strncasecmp(str, dest->server_tag, server_tag_len) && str[server_tag_len] == '/') { + if (server_tag_len && + g_ascii_strncasecmp(str, dest->server_tag, server_tag_len) == 0 && + str[server_tag_len] == '/') { str += server_tag_len + 1; } - if (!g_strcmp0(str, "") || !g_strcmp0(str, "::all")) { + if (g_strcmp0(str, "") == 0 || g_strcmp0(str, "::all") == 0) { return TRUE; - } else if (!g_ascii_strcasecmp(str, dest->target)) { + } else if (g_ascii_strcasecmp(str, dest->target) == 0) { return TRUE; } else if (item->type == query_type && - !g_strcmp0(str, (dest->target[0] == '=') ? "::dccqueries" : "::queries")) { + g_strcmp0(str, dest->target[0] == '=' ? "::dccqueries" : + "::queries") == 0) { return TRUE; } else if (item->type == channel_type && - !g_strcmp0(str, "::channels")) { + g_strcmp0(str, "::channels") == 0) { return TRUE; } } From 121a4971e61176e326ee3d2f71867e87732f4519 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 6 Jan 2018 20:17:51 +0100 Subject: [PATCH 0270/1198] Update fe-common-core.c fix mixed decls --- src/fe-common/core/fe-common-core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 4f2d210a..a8726314 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -461,16 +461,19 @@ void fe_common_core_finish_init(void) gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) { - int channel_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL"); - int query_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); + WI_ITEM_REC *item; + int server_tag_len, channel_type, query_type; char **tmp; + channel_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL"); + query_type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); + g_return_val_if_fail(array != NULL, FALSE); g_return_val_if_fail(dest != NULL, FALSE); g_return_val_if_fail(dest->window != NULL, FALSE); g_return_val_if_fail(dest->target != NULL, FALSE); - WI_ITEM_REC *item = window_item_find_window(dest->window, dest->server, dest->target); + item = window_item_find_window(dest->window, dest->server, dest->target); if (item == NULL) { return FALSE; } From 0aafd011c0adc58ddf43783764b96fdd74578243 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 23 Jun 2017 21:53:16 -0300 Subject: [PATCH 0271/1198] Add a startup warning if the TERM var is wrong inside tmux/screen One of the most common and confusing issues we get in #irssi, this should help identifying and mitigating it. --- src/fe-text/irssi.c | 2 ++ src/fe-text/term-terminfo.c | 28 ++++++++++++++++++++++++++++ src/fe-text/term.h | 2 ++ 3 files changed, 32 insertions(+) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index ef443670..0288e4f1 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -207,6 +207,8 @@ static void textui_finish_init(void) fe_settings_set_print("nick"); if (user_settings_changed & USER_SETTINGS_HOSTNAME) fe_settings_set_print("hostname"); + + term_environment_check(); } static void textui_deinit(void) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 6645cfb0..d96e235d 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -733,3 +733,31 @@ void term_gets(GArray *buffer, int *line_count) } } } + +static const char* term_env_warning = + "The TERM environment variable is set to '%s' which can cause display " + "glitches when running under %s.\n" + "Consider changing TERM to 'screen' or 'screen-256color' instead."; + +void term_environment_check(void) +{ + const char *term, *sty, *tmux, *multiplexer; + + term = g_getenv("TERM"); + sty = g_getenv("STY"); + tmux = g_getenv("TMUX"); + + multiplexer = (sty && *sty) ? "screen" : + (tmux && *tmux) ? "tmux" : NULL; + + if (!multiplexer) { + return; + } + + if (term && (g_str_has_prefix(term, "screen") || + g_str_has_prefix(term, "tmux"))) { + return; + } + + g_warning(term_env_warning, term, multiplexer); +} diff --git a/src/fe-text/term.h b/src/fe-text/term.h index 0c7847f6..4b1e2874 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -105,4 +105,6 @@ void term_gets(GArray *buffer, int *line_count); void term_common_init(void); void term_common_deinit(void); +void term_environment_check(void); + #endif From f9c8365999c5319be6970dcf27f21190b0481314 Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 7 Jan 2018 01:44:48 -0300 Subject: [PATCH 0272/1198] fe-common-core: fix redeclaration of server_tag_len --- src/fe-common/core/fe-common-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index a8726314..791f56d4 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -478,7 +478,7 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) return FALSE; } - int server_tag_len = dest->server_tag != NULL ? strlen(dest->server_tag) : 0; + server_tag_len = dest->server_tag != NULL ? strlen(dest->server_tag) : 0; for (tmp = array; *tmp != NULL; tmp++) { char *str = *tmp; if (*str == '\0') { From 0d5e353ef1be253106ed66417b270d03b2b91ed3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 7 Jan 2018 11:43:13 +0100 Subject: [PATCH 0273/1198] Reword warning message Include multiplexer name in TERM recommendation --- src/fe-text/term-terminfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index d96e235d..f4c4d17c 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -735,9 +735,9 @@ void term_gets(GArray *buffer, int *line_count) } static const char* term_env_warning = - "The TERM environment variable is set to '%s' which can cause display " - "glitches when running under %s.\n" - "Consider changing TERM to 'screen' or 'screen-256color' instead."; + "You seem to be running Irssi inside %2$s, but the TERM environment variable" + "is set to '%1$s', which can cause display glitches.\n" + "Consider changing TERM to '%2$s' or '%2$s-256color' instead."; void term_environment_check(void) { From 98836f8b7ee058c32d54562903676c4d16f83aa4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 10:21:03 +0200 Subject: [PATCH 0274/1198] Parse the K/V form in CAP LS This is a prerequisite for the IRC v3.2 compliance. --- src/irc/core/irc-cap.c | 43 ++++++++++++++++++++++++++++++++++---- src/irc/core/irc-servers.c | 2 +- src/irc/core/irc-servers.h | 2 +- src/perl/irc/Irc.xs | 15 +++++++++---- 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 5464e493..eac6f239 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -45,7 +45,7 @@ int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) if (enable && !gslist_find_string(server->cap_active, cap)) { /* Make sure the required cap is supported by the server */ - if (!gslist_find_string(server->cap_supported, cap)) + if (!g_hash_table_lookup_extended(server->cap_supported, cap, NULL, NULL)) return FALSE; irc_send_cmdv(server, "CAP REQ %s", cap); @@ -96,9 +96,44 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add caps_length = g_strv_length(caps); if (!g_strcmp0(evt, "LS")) { + if (server->cap_supported) { + g_hash_table_destroy(server->cap_supported); + } + /* Start with a fresh table */ + server->cap_supported = g_hash_table_new_full(g_str_hash, + g_str_equal, + g_free, g_free); + /* Create a list of the supported caps */ - for (i = 0; i < caps_length; i++) - server->cap_supported = g_slist_prepend(server->cap_supported, g_strdup(caps[i])); + for (i = 0; i < caps_length; i++) { + const char *name = caps[i]; + const char *eq = strchr(name, '='); + int fresh = TRUE; + + if (!eq) { + fresh = g_hash_table_insert(server->cap_supported, + g_strdup(name), + NULL); + } + /* Some values are in a KEY=VALUE form, parse them */ + else if (eq[1] != '\0') { + char *key = g_strndup(name, (int)(eq - name)); + char *val = g_strdup(eq + 1); + fresh = g_hash_table_insert(server->cap_supported, + key, val); + } + /* If the string ends after the '=' consider the value + * as invalid */ + else { + g_warning("Invalid CAP key/value pair"); + } + + /* The specification doesn't say anything about + * duplicated values, let's just warn the user */ + if (fresh == FALSE) { + g_warning("Duplicate value"); + } + } /* Request the required caps, if any */ if (server->cap_queue == NULL) { @@ -111,7 +146,7 @@ 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)) { + if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, NULL)) { if (avail_caps > 0) g_string_append_c(cmd, ' '); g_string_append(cmd, tmp->data); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 4eaab712..7fd83045 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -443,7 +443,7 @@ static void sig_disconnected(IRC_SERVER_REC *server) gslist_free_full(server->cap_active, (GDestroyNotify) g_free); server->cap_active = NULL; - gslist_free_full(server->cap_supported, (GDestroyNotify) g_free); + g_hash_table_destroy(server->cap_supported); server->cap_supported = NULL; gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 09f3f81d..6c6002c8 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -75,7 +75,7 @@ struct _IRC_SERVER_REC { int max_whois_in_cmd; /* max. number of nicks in one /WHOIS command */ int max_msgs_in_cmd; /* max. number of targets in one /MSG */ - GSList *cap_supported; /* A list of caps supported by the server */ + GHashTable *cap_supported; /* A list of caps supported by the server */ GSList *cap_active; /* A list of caps active for this session */ GSList *cap_queue; /* A list of caps to request on connection */ diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 41690010..bb2d27bb 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -12,7 +12,10 @@ 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) { AV *av; + HV *hv_; GSList *tmp; + GHashTableIter iter; + gpointer key_, val_; perl_irc_connect_fill_hash(hv, server->connrec); perl_server_fill_hash(hv, (SERVER_REC *) server); @@ -34,10 +37,14 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server) (void) hv_store(hv, "cap_complete", 12, newSViv(server->cap_complete), 0); (void) hv_store(hv, "sasl_success", 12, newSViv(server->sasl_success), 0); - av = newAV(); - for (tmp = server->cap_supported; tmp != NULL; tmp = tmp->next) - av_push(av, new_pv(tmp->data)); - (void) hv_store(hv, "cap_supported", 13, newRV_noinc((SV*)av), 0); + hv_ = newHV(); + g_hash_table_iter_init(&iter, server->cap_supported); + while (g_hash_table_iter_next(&iter, &key_, &val_)) { + char *key = (char *)key_; + char *val = (char *)val_; + hv_store(hv_, key, strlen(key), new_pv(val), 0); + } + (void) hv_store(hv, "cap_supported", 13, newRV_noinc((SV*)hv_), 0); av = newAV(); for (tmp = server->cap_active; tmp != NULL; tmp = tmp->next) From d21706e1cc78284d5e7b2d69ebe4873e459d0e9b Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 10:35:49 +0200 Subject: [PATCH 0275/1198] Factor out the parsing function This is also needed for CAP NEW and CAP DEL. --- src/irc/core/irc-cap.c | 56 ++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index eac6f239..9ac232b5 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -79,6 +79,33 @@ static void cap_emit_signal (IRC_SERVER_REC *server, char *cmd, char *args) g_free(signal_name); } +static gboolean parse_cap_name(char *name, char **key, char **val) +{ + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(name[0] != '\0', FALSE); + + const char *eq = strchr(name, '='); + /* KEY only value */ + if (!eq) { + *key = g_strdup(name); + *val = NULL; + return TRUE; + } + /* Some values are in a KEY=VALUE form, parse them */ + else if (eq[1] != '\0') { + *key = g_strndup(name, (int)(eq - name)); + *val = g_strdup(eq + 1); + return TRUE; + } + /* If the string ends after the '=' consider the value + * as invalid */ + else { + *key = NULL; + *val = NULL; + return FALSE; + } +} + static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *address) { GSList *tmp; @@ -106,33 +133,20 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* Create a list of the supported caps */ for (i = 0; i < caps_length; i++) { - const char *name = caps[i]; - const char *eq = strchr(name, '='); - int fresh = TRUE; + char *key, *val; - if (!eq) { - fresh = g_hash_table_insert(server->cap_supported, - g_strdup(name), - NULL); + if (parse_cap_name(caps[i], &key, &val)) { + if (!g_hash_table_insert(server->cap_supported, + key, val)) { + /* The specification doesn't say anything about + * duplicated values, let's just warn the user */ + g_warning("Duplicate value"); + } } - /* Some values are in a KEY=VALUE form, parse them */ - else if (eq[1] != '\0') { - char *key = g_strndup(name, (int)(eq - name)); - char *val = g_strdup(eq + 1); - fresh = g_hash_table_insert(server->cap_supported, - key, val); - } - /* If the string ends after the '=' consider the value - * as invalid */ else { g_warning("Invalid CAP key/value pair"); } - /* The specification doesn't say anything about - * duplicated values, let's just warn the user */ - if (fresh == FALSE) { - g_warning("Duplicate value"); - } } /* Request the required caps, if any */ From 57827ca743e95a6b6ad830fab03f46efaf1d9069 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 10:44:53 +0200 Subject: [PATCH 0276/1198] Don't free the hash table if there's none Glib doesn't like that and shows a harmless warning. --- src/irc/core/irc-servers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 7fd83045..3b4e1a52 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -443,8 +443,10 @@ static void sig_disconnected(IRC_SERVER_REC *server) gslist_free_full(server->cap_active, (GDestroyNotify) g_free); server->cap_active = NULL; - g_hash_table_destroy(server->cap_supported); - server->cap_supported = NULL; + if (server->cap_supported) { + g_hash_table_destroy(server->cap_supported); + server->cap_supported = NULL; + } gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); server->cap_queue = NULL; From 8c87766132b7dbb75d8a49548ff7c97037ea983b Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 11:23:44 +0200 Subject: [PATCH 0277/1198] Parse multiline responses to CAP LS The parsing logic isn't too elegant because of the optional parameter used for signaling if a response has a continuation one. --- src/irc/core/irc-cap.c | 89 +++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 9ac232b5..602a7b06 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -110,13 +110,31 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add { GSList *tmp; GString *cmd; - char *params, *evt, *list, **caps; - int i, caps_length, disable, avail_caps; + char *params, *evt, *list, *star, **caps; + int i, caps_length, disable, avail_caps, multiline; - params = event_get_params(args, 3, NULL, &evt, &list); + params = event_get_params(args, 4, NULL, &evt, &star, &list); if (params == NULL) return; + /* Multiline responses have an additional parameter and we have to do + * this stupid dance to parse them */ + if (evt[0] == 'L' && !strcmp(star, "*")) { + multiline = TRUE; + } + /* This branch covers the '*' parameter isn't present, adjust the + * parameter pointer to compensate for this */ + else if (list[0] == '\0') { + multiline = FALSE; + list = star; + } + /* Malformed request, terminate the negotiation */ + else { + cap_finish_negotiation(server); + g_warn_if_reached(); + return; + } + /* Strip the trailing whitespaces before splitting the string, some servers send responses with * superfluous whitespaces that g_strsplit the interprets as tokens */ caps = g_strsplit(g_strchomp(list), " ", -1); @@ -149,37 +167,41 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } - /* Request the required caps, if any */ - if (server->cap_queue == NULL) { - cap_finish_negotiation(server); - } - else { - cmd = g_string_new("CAP REQ :"); - - avail_caps = 0; - - /* Check whether the cap is supported by the server */ - for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { - if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, NULL)) { - if (avail_caps > 0) - g_string_append_c(cmd, ' '); - g_string_append(cmd, tmp->data); - - avail_caps++; - } - } - - /* Clear the queue here */ - gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); - server->cap_queue = NULL; - - /* If the server doesn't support any cap we requested close the negotiation here */ - if (avail_caps > 0) - irc_send_cmd_now(server, cmd->str); - else + /* A multiline response is always terminated by a normal one, + * wait until we receive that one to require any CAP */ + if (multiline == FALSE) { + /* No CAP has been requested */ + if (server->cap_queue == NULL) { cap_finish_negotiation(server); + } + else { + cmd = g_string_new("CAP REQ :"); - g_string_free(cmd, TRUE); + avail_caps = 0; + + /* Check whether the cap is supported by the server */ + for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { + if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, NULL)) { + if (avail_caps > 0) + g_string_append_c(cmd, ' '); + g_string_append(cmd, tmp->data); + + avail_caps++; + } + } + + /* Clear the queue here */ + gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); + server->cap_queue = NULL; + + /* If the server doesn't support any cap we requested close the negotiation here */ + if (avail_caps > 0) + irc_send_cmd_now(server, cmd->str); + else + cap_finish_negotiation(server); + + g_string_free(cmd, TRUE); + } } } else if (!g_strcmp0(evt, "ACK")) { @@ -214,6 +236,9 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) cap_emit_signal(server, "nak", caps[i]); } + else { + g_warning("Unhandled CAP subcommand %s", evt); + } g_strfreev(caps); g_free(params); From f4d811ddf51ce03e90e0417a6c25baeb9aa48353 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 17:11:43 +0200 Subject: [PATCH 0278/1198] Handle CAP {ADD,DEL} from cap-notify This is the last piece of the puzzle. --- src/irc/core/irc-cap.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 602a7b06..2378d640 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -135,6 +135,8 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add return; } + g_warning("%s -> %s", evt, list); + /* Strip the trailing whitespaces before splitting the string, some servers send responses with * superfluous whitespaces that g_strsplit the interprets as tokens */ caps = g_strsplit(g_strchomp(list), " ", -1); @@ -158,11 +160,11 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add key, val)) { /* The specification doesn't say anything about * duplicated values, let's just warn the user */ - g_warning("Duplicate value"); + g_warning("Duplicate value %s", key); } } else { - g_warning("Invalid CAP key/value pair"); + g_warning("Invalid CAP %s key/value pair", evt); } } @@ -236,6 +238,36 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) cap_emit_signal(server, "nak", caps[i]); } + else if (!strcmp(evt, "NEW")) { + for (i = 0; i < caps_length; i++) { + char *key, *val; + + if (parse_cap_name(caps[i], &key, &val)) { + g_hash_table_insert(server->cap_supported, + key, val); + } + else { + g_warning("Invalid CAP %s key/value pair", evt); + } + cap_emit_signal(server, "new", key); + } + } + else if (!strcmp(evt, "DEL")) { + for (i = 0; i < caps_length; i++) { + char *key, *val; + + if (parse_cap_name(caps[i], &key, &val)) { + g_hash_table_remove(server->cap_supported, key); + } + else { + g_warning("Invalid CAP %s key/value pair", evt); + } + cap_emit_signal(server, "delete", key); + /* The server removed this CAP, remove it from the list + * of the active ones if we had requested it */ + server->cap_active = gslist_remove_string(server->cap_active, key); + } + } else { g_warning("Unhandled CAP subcommand %s", evt); } From cfc8c9f8e2d982ee3ebff7afa1d1bdeb04003029 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 17:38:06 +0200 Subject: [PATCH 0279/1198] Properly dispose the GSList chains We forgot to free the link and the data, oops. --- src/core/misc.c | 13 +++++++++++++ src/core/misc.h | 1 + src/irc/core/irc-cap.c | 8 +++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 4e9f4bbe..27741220 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -218,6 +218,19 @@ GSList *gslist_remove_string (GSList *list, const char *str) return list; } +GSList *gslist_delete_string (GSList *list, const char *str, GDestroyNotify free_func) +{ + GSList *l; + + l = g_slist_find_custom(list, str, (GCompareFunc) g_strcmp0); + if (l != NULL) { + free_func(l->data); + return g_slist_delete_link(list, l); + } + + return list; +} + /* `list' contains pointer to structure with a char* to string. */ char *gslistptr_to_string(GSList *list, int offset, const char *delimiter) { diff --git a/src/core/misc.h b/src/core/misc.h index 375744db..689cf5c2 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -22,6 +22,7 @@ GSList *gslist_find_icase_string(GSList *list, const char *key); GList *glist_find_string(GList *list, const char *key); GList *glist_find_icase_string(GList *list, const char *key); GSList *gslist_remove_string (GSList *list, const char *str); +GSList *gslist_delete_string (GSList *list, const char *str, GDestroyNotify free_func); void gslist_free_full (GSList *list, GDestroyNotify free_func); diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 2378d640..a5ae07aa 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -36,7 +36,7 @@ int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) return TRUE; } else if (!enable && gslist_find_string(server->cap_queue, cap)) { - server->cap_queue = gslist_remove_string(server->cap_queue, cap); + server->cap_queue = gslist_delete_string(server->cap_queue, cap, g_free); return TRUE; } @@ -135,8 +135,6 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add return; } - g_warning("%s -> %s", evt, list); - /* Strip the trailing whitespaces before splitting the string, some servers send responses with * superfluous whitespaces that g_strsplit the interprets as tokens */ caps = g_strsplit(g_strchomp(list), " ", -1); @@ -214,7 +212,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add disable = (*caps[i] == '-'); if (disable) - server->cap_active = gslist_remove_string(server->cap_active, caps[i] + 1); + server->cap_active = gslist_delete_string(server->cap_active, caps[i] + 1, g_free); else server->cap_active = g_slist_prepend(server->cap_active, g_strdup(caps[i])); @@ -265,7 +263,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add cap_emit_signal(server, "delete", key); /* The server removed this CAP, remove it from the list * of the active ones if we had requested it */ - server->cap_active = gslist_remove_string(server->cap_active, key); + server->cap_active = gslist_delete_string(server->cap_active, key, g_free); } } else { From 432368bdc6b941c1ff6319748b357bd5bae1bb6e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 21 Oct 2017 17:40:45 +0200 Subject: [PATCH 0280/1198] Use strcmp instead of g_strcmp0 There's no need to use the latter. --- src/irc/core/irc-cap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index a5ae07aa..f448ef83 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -140,7 +140,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add caps = g_strsplit(g_strchomp(list), " ", -1); caps_length = g_strv_length(caps); - if (!g_strcmp0(evt, "LS")) { + if (!strcmp(evt, "LS")) { if (server->cap_supported) { g_hash_table_destroy(server->cap_supported); } @@ -204,7 +204,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } } } - else if (!g_strcmp0(evt, "ACK")) { + else if (!strcmp(evt, "ACK")) { int got_sasl = FALSE; /* Emit a signal for every ack'd cap */ @@ -216,7 +216,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add else server->cap_active = g_slist_prepend(server->cap_active, g_strdup(caps[i])); - if (!g_strcmp0(caps[i], "sasl")) + if (!strcmp(caps[i], "sasl")) got_sasl = TRUE; cap_emit_signal(server, "ack", caps[i]); @@ -228,7 +228,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add if (got_sasl == FALSE) cap_finish_negotiation(server); } - else if (!g_strcmp0(evt, "NAK")) { + else if (!strcmp(evt, "NAK")) { g_warning("The server answered with a NAK to our CAP request, this should not happen"); /* A NAK'd request means that a required cap can't be enabled or disabled, don't update the From f683e81880ac4408693582df3ec11d640684c78d Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 23 Oct 2017 12:42:37 +0200 Subject: [PATCH 0281/1198] Prevent a NULL pointer deference Always create the cap_supported table when a CAP event is received. --- src/irc/core/irc-cap.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index f448ef83..46276243 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -135,19 +135,21 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add return; } + /* The table is created only when needed */ + if (server->cap_supported == NULL) { + server->cap_supported = g_hash_table_new_full(g_str_hash, + g_str_equal, + g_free, g_free); + } + /* Strip the trailing whitespaces before splitting the string, some servers send responses with * superfluous whitespaces that g_strsplit the interprets as tokens */ caps = g_strsplit(g_strchomp(list), " ", -1); caps_length = g_strv_length(caps); if (!strcmp(evt, "LS")) { - if (server->cap_supported) { - g_hash_table_destroy(server->cap_supported); - } - /* Start with a fresh table */ - server->cap_supported = g_hash_table_new_full(g_str_hash, - g_str_equal, - g_free, g_free); + /* Throw away everything and start from scratch */ + g_hash_table_remove_all(server->cap_supported); /* Create a list of the supported caps */ for (i = 0; i < caps_length; i++) { From 74409aa85071390a3969fffa21c08a6736efe314 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 23 Oct 2017 20:08:19 +0200 Subject: [PATCH 0282/1198] Miscellaneous fixes Stylistic stuff, please ignore. --- src/irc/core/irc-cap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 46276243..9af55130 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -86,14 +86,14 @@ static gboolean parse_cap_name(char *name, char **key, char **val) const char *eq = strchr(name, '='); /* KEY only value */ - if (!eq) { + if (eq == NULL) { *key = g_strdup(name); *val = NULL; return TRUE; } /* Some values are in a KEY=VALUE form, parse them */ else if (eq[1] != '\0') { - *key = g_strndup(name, (int)(eq - name)); + *key = g_strndup(name, (gsize)(eq - name)); *val = g_strdup(eq + 1); return TRUE; } From cd107deb463934f7a8611cdc8d17b861a93d97f9 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 23 Oct 2017 21:19:51 +0200 Subject: [PATCH 0283/1198] Prevent a memory leak When a CAP DEL is received the key/val pair is not stored in the hashtable at all so just free them when we're done. --- src/irc/core/irc-cap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 9af55130..8be9d33f 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -266,6 +266,10 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* The server removed this CAP, remove it from the list * of the active ones if we had requested it */ server->cap_active = gslist_delete_string(server->cap_active, key, g_free); + /* We don't transfer the ownership of those two + * variables this time, just free them when we're done. */ + g_free(key); + g_free(val); } } else { From 9160ddaffd45b03c523320ef8f71bb3a8a9fb87a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 23 Oct 2017 21:23:59 +0200 Subject: [PATCH 0284/1198] Keep processing the CAPs on error If an invalid CAP is found we keep going by parsing the next one. --- src/irc/core/irc-cap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 8be9d33f..d93dfac4 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -165,8 +165,8 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } else { g_warning("Invalid CAP %s key/value pair", evt); + continue; } - } /* A multiline response is always terminated by a normal one, @@ -248,6 +248,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } else { g_warning("Invalid CAP %s key/value pair", evt); + continue; } cap_emit_signal(server, "new", key); } @@ -261,6 +262,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } else { g_warning("Invalid CAP %s key/value pair", evt); + continue; } cap_emit_signal(server, "delete", key); /* The server removed this CAP, remove it from the list From c00132ac4cf78702b4f72fc6a0085432bcef2fac Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 24 Oct 2017 15:47:06 +0200 Subject: [PATCH 0285/1198] Simplify the code Early exit, simpler code. --- src/irc/core/irc-cap.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index d93dfac4..5d033bbf 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -155,18 +155,16 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) { char *key, *val; - if (parse_cap_name(caps[i], &key, &val)) { - if (!g_hash_table_insert(server->cap_supported, - key, val)) { - /* The specification doesn't say anything about - * duplicated values, let's just warn the user */ - g_warning("Duplicate value %s", key); - } - } - else { + if (!parse_cap_name(caps[i], &key, &val)) { g_warning("Invalid CAP %s key/value pair", evt); continue; } + + if (!g_hash_table_insert(server->cap_supported, key, val)) { + /* The specification doesn't say anything about + * duplicated values, let's just warn the user */ + g_warning("Duplicate value %s", key); + } } /* A multiline response is always terminated by a normal one, @@ -242,14 +240,12 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) { char *key, *val; - if (parse_cap_name(caps[i], &key, &val)) { - g_hash_table_insert(server->cap_supported, - key, val); - } - else { + if (!parse_cap_name(caps[i], &key, &val)) { g_warning("Invalid CAP %s key/value pair", evt); continue; } + + g_hash_table_insert(server->cap_supported, key, val); cap_emit_signal(server, "new", key); } } @@ -257,13 +253,12 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) { char *key, *val; - if (parse_cap_name(caps[i], &key, &val)) { - g_hash_table_remove(server->cap_supported, key); - } - else { + if (!parse_cap_name(caps[i], &key, &val)) { g_warning("Invalid CAP %s key/value pair", evt); continue; } + + g_hash_table_remove(server->cap_supported, key); cap_emit_signal(server, "delete", key); /* The server removed this CAP, remove it from the list * of the active ones if we had requested it */ From 6c45ab0493e42bca08016ad70a54bb523282b7b8 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 29 Oct 2017 15:59:51 +0100 Subject: [PATCH 0286/1198] Command names may be in lower-case Do not take the string case into account when comparing the command name. --- src/irc/core/irc-cap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 5d033bbf..1a76fc8e 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -147,7 +147,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add caps = g_strsplit(g_strchomp(list), " ", -1); caps_length = g_strv_length(caps); - if (!strcmp(evt, "LS")) { + if (!g_ascii_strcasecmp(evt, "LS")) { /* Throw away everything and start from scratch */ g_hash_table_remove_all(server->cap_supported); @@ -204,7 +204,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } } } - else if (!strcmp(evt, "ACK")) { + else if (!g_ascii_strcasecmp(evt, "ACK")) { int got_sasl = FALSE; /* Emit a signal for every ack'd cap */ @@ -228,7 +228,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add if (got_sasl == FALSE) cap_finish_negotiation(server); } - else if (!strcmp(evt, "NAK")) { + else if (!g_ascii_strcasecmp(evt, "NAK")) { g_warning("The server answered with a NAK to our CAP request, this should not happen"); /* A NAK'd request means that a required cap can't be enabled or disabled, don't update the @@ -236,7 +236,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add for (i = 0; i < caps_length; i++) cap_emit_signal(server, "nak", caps[i]); } - else if (!strcmp(evt, "NEW")) { + else if (!g_ascii_strcasecmp(evt, "NEW")) { for (i = 0; i < caps_length; i++) { char *key, *val; @@ -249,7 +249,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add cap_emit_signal(server, "new", key); } } - else if (!strcmp(evt, "DEL")) { + else if (!g_ascii_strcasecmp(evt, "DEL")) { for (i = 0; i < caps_length; i++) { char *key, *val; From f3a535564880d73b75263b685794a7165e56f9bd Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 29 Oct 2017 16:03:28 +0100 Subject: [PATCH 0287/1198] Match LS instead of checking the first letter only --- src/irc/core/irc-cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 1a76fc8e..a9d79c24 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -119,7 +119,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* Multiline responses have an additional parameter and we have to do * this stupid dance to parse them */ - if (evt[0] == 'L' && !strcmp(star, "*")) { + if (!g_ascii_strcasecmp(evt, "LS") && !strcmp(star, "*")) { multiline = TRUE; } /* This branch covers the '*' parameter isn't present, adjust the From 4b9fcbc15ae3561c34944e30e24fd1d54346bb99 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 29 Oct 2017 16:06:36 +0100 Subject: [PATCH 0288/1198] Nicer error message when a duplicate CAP in LS --- src/irc/core/irc-cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index a9d79c24..880a15b6 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -163,7 +163,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add if (!g_hash_table_insert(server->cap_supported, key, val)) { /* The specification doesn't say anything about * duplicated values, let's just warn the user */ - g_warning("Duplicate value %s", key); + g_warning("The server sent the %s capability twice", key); } } From fed791ed9100552edbe643d8b3d0e0bc271e88d4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 30 Oct 2017 17:41:16 +0100 Subject: [PATCH 0289/1198] Fix a problem with multiline responses Do not clear the whole table every time a response is received. --- src/irc/core/irc-cap.c | 8 ++++++-- src/irc/core/irc-servers.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 880a15b6..90bffd80 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -148,8 +148,12 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add caps_length = g_strv_length(caps); if (!g_ascii_strcasecmp(evt, "LS")) { - /* Throw away everything and start from scratch */ - g_hash_table_remove_all(server->cap_supported); + if (!server->cap_in_multiline) { + /* Throw away everything and start from scratch */ + g_hash_table_remove_all(server->cap_supported); + } + + server->cap_in_multiline = multiline; /* Create a list of the supported caps */ for (i = 0; i < caps_length; i++) { diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 6c6002c8..1374e846 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -68,6 +68,7 @@ struct _IRC_SERVER_REC { unsigned int motd_got:1; /* We've received MOTD */ unsigned int isupport_sent:1; /* Server has sent us an isupport reply */ unsigned int cap_complete:1; /* We've done the initial CAP negotiation */ + unsigned int cap_in_multiline:1; /* We're waiting for the multiline response to end */ unsigned int sasl_success:1; /* Did we authenticate successfully ? */ int max_kicks_in_cmd; /* max. number of people to kick with one /KICK command */ From 063c85da6c4e73a292525aa01b5cad70ed6bf82b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 7 Jan 2018 20:01:00 +0100 Subject: [PATCH 0290/1198] Fix space in message --- src/fe-text/term-terminfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index f4c4d17c..ba8bdcaf 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -735,7 +735,7 @@ void term_gets(GArray *buffer, int *line_count) } static const char* term_env_warning = - "You seem to be running Irssi inside %2$s, but the TERM environment variable" + "You seem to be running Irssi inside %2$s, but the TERM environment variable " "is set to '%1$s', which can cause display glitches.\n" "Consider changing TERM to '%2$s' or '%2$s-256color' instead."; From b8e3c5d00e80a2bf24cfbb063e2e4916ef01147d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 8 Jan 2018 13:33:40 +0100 Subject: [PATCH 0291/1198] only use nonfatal assertions for GLib that actually supports it Fixes tests on Debian 7 and RHEL 6 --- tests/fe-common/core/test-formats.c | 2 ++ tests/irc/core/test-irc.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/fe-common/core/test-formats.c b/tests/fe-common/core/test-formats.c index 9ef23fd6..08d706ac 100644 --- a/tests/fe-common/core/test-formats.c +++ b/tests/fe-common/core/test-formats.c @@ -31,7 +31,9 @@ int main(int argc, char **argv) g_free(name); } +#if GLIB_CHECK_VERSION(2,38,0) g_test_set_nonfatal_assertions(); +#endif return g_test_run(); } diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c index c96956df..3eaf7020 100644 --- a/tests/irc/core/test-irc.c +++ b/tests/irc/core/test-irc.c @@ -197,7 +197,9 @@ int main(int argc, char **argv) g_free(name); } +#if GLIB_CHECK_VERSION(2,38,0) g_test_set_nonfatal_assertions(); +#endif return g_test_run(); } From 3b1ee8e7e7e9d01190d906ae5af6d3dd7dbd9a63 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 8 Jan 2018 13:47:25 +0100 Subject: [PATCH 0292/1198] change expected format_real_length test result This change from 0 -> 4 was introduced by #697 and is thus expected --- tests/fe-common/core/test-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fe-common/core/test-formats.c b/tests/fe-common/core/test-formats.c index 9ef23fd6..b3b15886 100644 --- a/tests/fe-common/core/test-formats.c +++ b/tests/fe-common/core/test-formats.c @@ -15,7 +15,7 @@ format_real_length_test_case const format_real_length_fixtures[] = { { .description = "", .input = "%4%w ", - .result = { 0, 5, 5, -1 }, + .result = { 4, 5, 5, -1 }, }, }; From f2e73a7046358ed948b14180c70bab5dba5364cc Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Tue, 9 Jan 2018 23:15:08 +0100 Subject: [PATCH 0293/1198] Add perl access to hidden_level in TEXT_BUFFER_VIEW_REC --- src/perl/textui/TextUI.xs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 5d2c8a7f..ff94ad5f 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -40,6 +40,7 @@ static void perl_text_buffer_view_fill_hash(HV *hv, TEXT_BUFFER_VIEW_REC *view) (void) hv_store(hv, "startline", 9, plain_bless(view->startline, "Irssi::TextUI::Line"), 0); (void) hv_store(hv, "subline", 7, newSViv(view->subline), 0); + (void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0); (void) hv_store(hv, "bottom_startline", 16, plain_bless(view->bottom_startline, "Irssi::TextUI::Line"), 0); (void) hv_store(hv, "bottom_subline", 14, newSViv(view->bottom_subline), 0); From 4041f29711e5a6745175d0ae046e68e34f034bf4 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Tue, 9 Jan 2018 23:16:26 +0100 Subject: [PATCH 0294/1198] Changed spaces to tab --- src/perl/textui/TextUI.xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index ff94ad5f..12732e3f 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -40,7 +40,7 @@ static void perl_text_buffer_view_fill_hash(HV *hv, TEXT_BUFFER_VIEW_REC *view) (void) hv_store(hv, "startline", 9, plain_bless(view->startline, "Irssi::TextUI::Line"), 0); (void) hv_store(hv, "subline", 7, newSViv(view->subline), 0); - (void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0); + (void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0); (void) hv_store(hv, "bottom_startline", 16, plain_bless(view->bottom_startline, "Irssi::TextUI::Line"), 0); (void) hv_store(hv, "bottom_subline", 14, newSViv(view->bottom_subline), 0); From fa8508404f4c4a02749cae5148662e2322c2abf0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 10 Jan 2018 20:08:15 +0100 Subject: [PATCH 0295/1198] revert netsplit print optimisation this reverts part of #465 unfortunately we need to further refine the initial patch - when filtering by channel, the whole split is cleaned up nevertheless - something similar happens for the netjoins - furthermore, we cannot wait only for PUBLIC msgs, j/p/q are equivalently relevant for temporal integrity --- src/fe-common/irc/fe-netjoin.c | 5 +---- src/fe-common/irc/fe-netsplit.c | 9 +++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index 8272093f..bc39b27c 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -253,15 +253,12 @@ static void sig_print_starting(TEXT_DEST_REC *dest) if (!IS_IRC_SERVER(dest->server)) return; - if (!(dest->level & MSGLEVEL_PUBLIC)) - return; - if (!server_ischannel(dest->server, dest->target)) return; rec = netjoin_find_server(IRC_SERVER(dest->server)); if (rec != NULL && rec->netjoins != NULL) - print_netjoins(rec, dest->target); + print_netjoins(rec, NULL); } static int sig_check_netjoins(void) diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 4c69dd10..ac3330e5 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -199,7 +199,7 @@ static void temp_split_chan_free(TEMP_SPLIT_CHAN_REC *rec) g_free(rec); } -static void print_splits(IRC_SERVER_REC *server, const char *channel) +static void print_splits(IRC_SERVER_REC *server, const char *filter_channel) { TEMP_SPLIT_REC temp; GSList *servers; @@ -218,7 +218,7 @@ static void print_splits(IRC_SERVER_REC *server, const char *channel) g_hash_table_foreach(server->splits, (GHFunc) get_server_splits, &temp); - print_server_splits(server, &temp, channel); + print_server_splits(server, &temp, filter_channel); g_slist_foreach(temp.channels, (GFunc) temp_split_chan_free, NULL); @@ -255,15 +255,12 @@ static void sig_print_starting(TEXT_DEST_REC *dest) if (!IS_IRC_SERVER(dest->server)) return; - if (!(dest->level & MSGLEVEL_PUBLIC)) - return; - if (!server_ischannel(dest->server, dest->target)) return; rec = IRC_SERVER(dest->server); if (rec->split_servers != NULL) - print_splits(rec, dest->target); + print_splits(rec, NULL); } static int sig_check_splits(void) From 182673ed05a5b5cb79d104df83f34fcc163a9c7e Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Mon, 15 Jan 2018 11:59:01 -0500 Subject: [PATCH 0296/1198] Add theme_load to fe-fuzz --- .gitignore | 1 + configure.ac | 2 + src/fe-fuzz/Makefile.am | 2 +- src/fe-fuzz/fe-common/Makefile.am | 1 + src/fe-fuzz/fe-common/core/Makefile.am | 46 +++++++++++++++++ src/fe-fuzz/fe-common/core/theme-load.c | 66 +++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/fe-fuzz/fe-common/Makefile.am create mode 100644 src/fe-fuzz/fe-common/core/Makefile.am create mode 100644 src/fe-fuzz/fe-common/core/theme-load.c diff --git a/.gitignore b/.gitignore index b707e9ec..916457f8 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ docs/help/in/Makefile.am src/fe-text/irssi src/fe-fuzz/irssi-fuzz src/fe-fuzz/irc/core/event-get-params-fuzz +src/fe-fuzz/fe-common/core/theme-load-fuzz src/fe-common/irc/irc-modules.c src/irc/irc.c diff --git a/configure.ac b/configure.ac index 4a499b1d..e8df7d9e 100644 --- a/configure.ac +++ b/configure.ac @@ -652,6 +652,8 @@ src/fe-common/irc/notifylist/Makefile src/fe-fuzz/Makefile src/fe-fuzz/irc/Makefile src/fe-fuzz/irc/core/Makefile +src/fe-fuzz/fe-common/Makefile +src/fe-fuzz/fe-common/core/Makefile src/fe-none/Makefile src/fe-text/Makefile src/lib-config/Makefile diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index ae49f3df..40abd5ba 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = irc +SUBDIRS = irc fe-common bin_PROGRAMS = irssi-fuzz diff --git a/src/fe-fuzz/fe-common/Makefile.am b/src/fe-fuzz/fe-common/Makefile.am new file mode 100644 index 00000000..52770885 --- /dev/null +++ b/src/fe-fuzz/fe-common/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = core diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am new file mode 100644 index 00000000..4fe5937c --- /dev/null +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -0,0 +1,46 @@ +bin_PROGRAMS = theme-load-fuzz + +# Force link with CXX for libfuzzer support +CCLD=$(CXX) $(CXXFLAGS) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core/ \ + -I$(top_srcdir)/src/irc/core/ \ + -I$(top_srcdir)/src/fe-common/core/ \ + $(GLIB_CFLAGS) + +AM_DEPENDENCIES = \ + ../../../core/libcore.a \ + ../../../lib-config/libirssi_config.a \ + ../../../irc/libirc.a \ + ../../../irc/core/libirc_core.a \ + ../../../irc/dcc/libirc_dcc.a \ + ../../../irc/flood/libirc_flood.a \ + ../../../irc/notifylist/libirc_notifylist.a \ + ../../../fe-common/core/libfe_common_core.a \ + ../../../fe-common/irc/libfe_common_irc.a \ + ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ + ../../../fe-common/irc/notifylist/libfe_irc_notifylist.a + +LDADD = \ + ../../../irc/libirc.a \ + ../../../irc/core/libirc_core.a \ + ../../../irc/dcc/libirc_dcc.a \ + ../../../irc/flood/libirc_flood.a \ + ../../../irc/notifylist/libirc_notifylist.a \ + ../../../fe-common/core/libfe_common_core.a \ + ../../../fe-common/irc/libfe_common_irc.a \ + ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ + ../../../fe-common/irc/notifylist/libfe_irc_notifylist.a \ + ../../../core/libcore.a \ + ../../../lib-config/libirssi_config.a \ + @PROG_LIBS@ \ + $(FUZZER_LIBS) + +theme_load_fuzz_SOURCES = \ + theme-load.c \ + $(top_srcdir)/src/fe-text/module-formats.c + +noinst_HEADERS = \ + $(top_srcdir)/src/fe-text/module-formats.h diff --git a/src/fe-fuzz/fe-common/core/theme-load.c b/src/fe-fuzz/fe-common/core/theme-load.c new file mode 100644 index 00000000..14df74c6 --- /dev/null +++ b/src/fe-fuzz/fe-common/core/theme-load.c @@ -0,0 +1,66 @@ +/* + theme-load.c : irssi + + Copyright (C) 2018 Joseph Bisch + + 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 "module.h" +#include "modules-load.h" +#include "levels.h" +#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text +#include "themes.h" +#include "core.h" +#include "fe-common-core.h" +#include "args.h" +#include "printtext.h" +#include "irc.h" +#include "themes.h" + +#include +#include +#include +#include + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + core_register_options(); + fe_common_core_register_options(); + char *irssi_argv[] = {*argv[0], "--home", "/tmp/irssi", NULL}; + int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1; + args_execute(irssi_argc, irssi_argv); + core_preinit((*argv)[0]); + core_init(); + fe_common_core_init(); + theme_register(gui_text_formats); + module_register("core", "fe-fuzz"); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + gchar *copy = g_strndup((const gchar *)data, size); + + FILE *fp = fopen("/tmp/irssi/fuzz.theme", "wb"); + if (fp) { + fwrite(copy, strlen(copy), 1, fp); + fclose(fp); + } + + THEME_REC *theme = theme_load("fuzz"); + theme_destroy(theme); + + g_free(copy); + return 0; +} From ef8111eebe3c9d35ef9754f68c9f7df0aea7058e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 15 Jan 2018 21:54:52 +0100 Subject: [PATCH 0297/1198] Merge branch 'maint/1.1.0' into integrate/1.1.0 --- NEWS | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1054bb62..4b171852 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,83 @@ -v1.1-head 2018-xx-xx The Irssi team +v1.2-head 2018-xx-xx The Irssi team + +v1.1.0 2018-01-15 The Irssi team + * Colour is now re-set when reaching a comma, matching mIRC + behaviour (#742, #740, #790) + * Irssi now shows the initial nick and name on first start + (#785, #786) + * lynx is no longer required to run autogen.sh (#81, #781) + * The command history no longer permits wrapping around (#686) + * /foreach now correctly sends arguments as commands, stopping + you from embarassing AMSGs (#659) + * /server does not connect to servers anymore, use /server + connect to change servers (#559, #649). + * The net_ip_compare API function is now deprecated, and the + previously deprecated net_connect has been removed + (#770). By Will Storey (#770) + + Add an option to ignore all channels or ignore all queries + using /set activity_hide_targets. By Jari Matilainen (#612, + #779) + + Add a startup warning if the TERM var is wrong inside + tmux/screen (#726) + + Add option to hide certain levels from the textbuffer using + /window hidelevel (#746, #808) + + Irssi now has its first unit test (for mode parsing). By + Will Storey (#793) + + Added access to global command history when using window + history, and a binding to erase entries from the command + history (erase_history_entry) (#762) + + -alternate_nick is now available as a network specific + property. By Paul Townsend (#120, #771) + + On FreeBSD, Irssi now supports Capsicum sandbox (/capsicum + enter). By Edward Tomasz Napierala (#735, #755, #772) + + Filenames (directories) ending with a / now tab-complete + (#741) + + UTF-8 should now work in regular expressions when using + GRegex (the default) (#636, #653) + + Nicks are now properly escaped on completion. By Oscar + Linderholm (#693, #709) + + /server add -port now works. By Jari Matilainen (#703) + + Add a setting key_timeout to make key sequences + automatically re-set when not finished (#644, #645) + + Warn users about expired client certificates, as servers may + refuse them (#211, #627) + + Add a new net_start_ssl function for StartTLS. This is + available from ABI 8 and can be used by protocol modules + (#615, #622). + + The %# code is now stored in the textbuffer, so for example + web scripts can make use of it (#626) + + Add new setting break_wide which can be used to enable + breaking of wide characters (for east-asian + users). Originally from FreeBSD ports. (#625) + + Add fuzzing code (#610, #620, #701, #713) + - Netsplits show properly again (#812) + - Do not error on blank lines when using /exec -o. By Fabian + Kurz (FS#902, #805) + - Detect used nickname as reported by server. By Alexandre + Morignot (#219, #804) + - Prevent use after free error during the execution of some + commands. Found by Joseph Bisch. (GL#17, GL!24) + - Fix MODE parameter parsing when colon was used at a place + Irssi didn't expect (#601, #766) + - Fixed code to compile with + -Werror=declaration-after-statement (#795) + - Clang-format is now supported for git-clang-format (#784) + - Fix use after free when changing the network of + hilights. Reported by Rui Mathias. (#787, #788) + - Fix positioning error when tab-completing non-ascii + strings. (#752, #754) + - In-development issues (#750, #751) + - Clarify Alis in /help list (#699, #712) + - Improve /lastlog performance from O(N^2) to O(N) (#715) + - Fix a segfault on "script destroyed" signal. By Stephen + Oberholtzer (#660, #661). + - Fix early ISON error (#596, #647) + - Documentation improvements. By Paolo Martini (#639). + By Tristan Pepin (#731). By Paul Townsend (#684, #736). + By Will Storey (#777) + - Minor cleanups (#590). By Edward Tomasz Napierala (#734, + #738) + - Fix space issue in glib-2.0.m4 (#621) v1.0.6 2018-01-07 The Irssi team - Fix invalid memory access when reading hilight configuration From e7c9b3afb82f4db3958f4f08cb706aadcbd12d2c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 16 Jan 2018 11:05:47 +0100 Subject: [PATCH 0298/1198] fix test builds on some platforms --- tests/fe-common/core/Makefile.am | 3 +-- tests/irc/core/Makefile.am | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/fe-common/core/Makefile.am b/tests/fe-common/core/Makefile.am index 070b6052..f048e95c 100644 --- a/tests/fe-common/core/Makefile.am +++ b/tests/fe-common/core/Makefile.am @@ -21,8 +21,7 @@ test_formats_LDADD = \ ../../../src/fe-common/core/libfe_common_core.a \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a \ - @GLIB_LIBS@ \ - @OPENSSL_LIBS@ + @PROG_LIBS@ test_formats_SOURCES = \ test-formats.c diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index ccc6aa97..86f1d547 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -22,8 +22,7 @@ test_irc_LDADD = \ ../../../src/irc/core/libirc_core.a \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a \ - @GLIB_LIBS@ \ - @OPENSSL_LIBS@ + @PROG_LIBS@ test_irc_SOURCES = \ test-irc.c From d983ad1a878103448231c8fd56fbc9c4b8f7f501 Mon Sep 17 00:00:00 2001 From: Zero King Date: Tue, 16 Jan 2018 15:23:54 +0000 Subject: [PATCH 0299/1198] Update Irssi website URLs --- README.md | 2 +- docs/help/in/hash.in | 2 +- docs/help/in/help.in | 2 +- docs/irssi.1 | 2 +- docs/manual.txt | 2 +- irssi.conf | 4 ++-- src/fe-text/module-formats.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0f54ccf5..3550b640 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ make && sudo make install ## [Themes](https://irssi-import.github.io/themes/) -## [Scripts](http://scripts.irssi.org/) +## [Scripts](https://scripts.irssi.org/) ## [Modules](https://irssi.org/modules/) diff --git a/docs/help/in/hash.in b/docs/help/in/hash.in index 32dfc9c7..2d5a355d 100644 --- a/docs/help/in/hash.in +++ b/docs/help/in/hash.in @@ -15,7 +15,7 @@ %9References:%9 - http://www.irssi.org + https://irssi.org https://github.com/irssi %9See also:%9 DIE, KILL, OPER diff --git a/docs/help/in/help.in b/docs/help/in/help.in index 555e20e1..35ab9b75 100644 --- a/docs/help/in/help.in +++ b/docs/help/in/help.in @@ -20,7 +20,7 @@ %9References:%9 - http://www.irssi.org + https://irssi.org https://github.com/irssi %9See also:%9 CONNECT, MSG, NETWORK, SERVER diff --git a/docs/irssi.1 b/docs/irssi.1 index e1fab0d8..08be69f5 100644 --- a/docs/irssi.1 +++ b/docs/irssi.1 @@ -59,7 +59,7 @@ show a help message .SH SEE ALSO .B Irssi has a solid amount of documentation available; check /HELP or look online -at http://www.irssi.org +at https://irssi.org .SH FILES .TP .I ~/.irssi/config diff --git a/docs/manual.txt b/docs/manual.txt index b2d0de14..db40e5d3 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -1,5 +1,5 @@ - Irssi 0.8 documentation - http://www.irssi.org/ + Irssi 0.8 documentation - https://irssi.org/ Copyright(c) 2000 Timo Sirainen diff --git a/irssi.conf b/irssi.conf index 0e486807..61d2e81f 100644 --- a/irssi.conf +++ b/irssi.conf @@ -145,7 +145,7 @@ aliases = { SB = "SCROLLBACK"; SBAR = "STATUSBAR"; SIGNOFF = "QUIT"; - SV = "MSG * Irssi $J ($V) - http://www.irssi.org"; + SV = "MSG * Irssi $J ($V) - https://irssi.org"; T = "TOPIC"; UB = "UNBAN"; UMODE = "MODE $N"; @@ -281,7 +281,7 @@ statusbar = { prompt_empty = "{prompt $winname}"; topic = " $topic"; - topic_empty = " Irssi v$J - http://www.irssi.org"; + topic_empty = " Irssi v$J - https://irssi.org"; lag = "{sb Lag: $0-}"; act = "{sb Act: $0-}"; diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index 8fa31a0e..b234f46c 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -87,7 +87,7 @@ FORMAT_REC gui_text_formats[] = "|_ _|_ _ _____(_)%:" " | || '_(_-<_-< |%:" "|___|_| /__/__/_|%:" - "Irssi v$J - http://www.irssi.org", 0 }, + "Irssi v$J - https://irssi.org", 0 }, { "welcome_firsttime", "- - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" "Hi there! If this is your first time using Irssi, you%:" From 925ae6e6adfae0b8924cfeca2a2b0ac99b042bce Mon Sep 17 00:00:00 2001 From: GinjaNinja32 Date: Fri, 6 Oct 2017 18:36:42 +0100 Subject: [PATCH 0300/1198] Add color support for input bar --- src/fe-text/gui-entry.c | 133 +++++++++++++++++++++++++++++++------- src/fe-text/gui-entry.h | 2 + src/perl/textui/TextUI.xs | 8 +++ 3 files changed, 121 insertions(+), 22 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index e91fcfb3..3e275e34 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -65,6 +65,8 @@ static void entry_text_grow(GUI_ENTRY_REC *entry, int grow_size) entry->text_alloc = nearest_power(entry->text_alloc+grow_size); entry->text = g_realloc(entry->text, sizeof(unichar) * entry->text_alloc); + entry->colors = g_realloc(entry->colors, + sizeof(int) * entry->text_alloc); } GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) @@ -74,11 +76,12 @@ GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) rec = g_new0(GUI_ENTRY_REC, 1); rec->xpos = xpos; rec->ypos = ypos; - rec->width = width; - rec->text_alloc = 1024; + rec->width = width; + rec->text_alloc = 1024; rec->text = g_new(unichar, rec->text_alloc); - rec->text[0] = '\0'; - rec->utf8 = utf8; + rec->colors = g_new(int, rec->text_alloc); + rec->text[0] = '\0'; + rec->utf8 = utf8; return rec; } @@ -100,9 +103,10 @@ void gui_entry_destroy(GUI_ENTRY_REC *entry) } g_slist_free(entry->kill_ring); - g_free(entry->text); + g_free(entry->text); + g_free(entry->colors); g_free(entry->prompt); - g_free(entry); + g_free(entry); } /* big5 functions */ @@ -238,7 +242,8 @@ static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry) static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { int i; - int xpos, end_xpos; + const int *col; + int xpos, end_xpos, color; xpos = entry->xpos + entry->promptlen + pos2scrpos(entry, pos + entry->scrstart) - @@ -248,10 +253,13 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (xpos > end_xpos) return; + color = ATTR_RESET; term_set_color(root_window, ATTR_RESET); term_move(root_window, xpos, entry->ypos); - for (i = entry->scrstart + pos; i < entry->text_len; i++) { + col = entry->scrstart + pos < entry->text_len ? + entry->colors + entry->scrstart + pos : 0; + for (i = entry->scrstart + pos; i < entry->text_len; i++, col++) { unichar c = entry->text[i]; if (entry->hidden) @@ -266,6 +274,11 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (xpos > end_xpos) break; + if (*col != color) { + term_set_color(root_window, *col); + color = *col; + } + if (entry->hidden) term_addch(root_window, ' '); else if (unichar_isprint(c)) @@ -273,7 +286,7 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) else { term_set_color(root_window, ATTR_RESET|ATTR_REVERSE); term_addch(root_window, (c & 127)+'A'-1); - term_set_color(root_window, ATTR_RESET); + term_set_color(root_window, color); } } @@ -488,6 +501,10 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) g_memmove(entry->text + entry->pos + len, entry->text + entry->pos, (entry->text_len-entry->pos + 1) * sizeof(unichar)); + /* make space for the color */ + g_memmove(entry->colors + entry->pos + len, entry->colors + entry->pos, + (entry->text_len-entry->pos) * sizeof(int)); + if (!entry->utf8) { if (term_type == TERM_TYPE_BIG5) { chr = entry->text[entry->pos + len]; @@ -505,6 +522,10 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) } } + for(i = 0; i < len; i++) { + entry->colors[entry->pos + i] = ATTR_RESET; + } + entry->text_len += len; entry->pos += len; @@ -514,7 +535,7 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) { - g_return_if_fail(entry != NULL); + g_return_if_fail(entry != NULL); if (chr == 0 || chr == 13 || chr == 10) return; /* never insert NUL, CR or LF characters */ @@ -522,7 +543,7 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) if (entry->utf8 && entry->pos == 0 && mk_wcwidth(chr) == 0) return; - gui_entry_redraw_from(entry, entry->pos); + gui_entry_redraw_from(entry, entry->pos); entry_text_grow(entry, 1); @@ -530,9 +551,14 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) g_memmove(entry->text + entry->pos + 1, entry->text + entry->pos, (entry->text_len-entry->pos + 1) * sizeof(unichar)); + g_memmove(entry->colors + entry->pos + 1, entry->colors + entry->pos, + (entry->text_len-entry->pos) * sizeof(int)); + + entry->text[entry->pos] = chr; + entry->colors[entry->pos] = ATTR_RESET; entry->text_len++; - entry->pos++; + entry->pos++; gui_entry_fix_cursor(entry); gui_entry_draw(entry); @@ -700,6 +726,9 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ g_memmove(entry->text + entry->pos - size, entry->text + entry->pos, (entry->text_len-entry->pos+1) * sizeof(unichar)); + g_memmove(entry->colors + entry->pos - size, entry->colors + entry->pos, + (entry->text_len - entry->pos) * sizeof(int)); + entry->pos -= size; entry->text_len -= size; @@ -719,7 +748,10 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) mk_wcwidth(entry->text[entry->pos+size]) == 0) size++; g_memmove(entry->text + entry->pos, entry->text + entry->pos + size, - (entry->text_len-entry->pos-size+1) * sizeof(unichar)); + (entry->text_len-entry->pos-size+1) * sizeof(unichar)); + + g_memmove(entry->colors + entry->pos, entry->colors + entry->pos + size, + (entry->text_len-entry->pos-size) * sizeof(int)); entry->text_len -= size; @@ -782,6 +814,7 @@ void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPD void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) { unichar chr; + int color; if (entry->pos == 0 || entry->text_len < 2) return; @@ -794,6 +827,10 @@ void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) entry->text[entry->pos] = entry->text[entry->pos-1]; entry->text[entry->pos-1] = chr; + color = entry->colors[entry->pos]; + entry->colors[entry->pos] = entry->colors[entry->pos-1]; + entry->colors[entry->pos-1] = color; + entry->pos++; gui_entry_redraw_from(entry, entry->pos-2); @@ -830,31 +867,55 @@ void gui_entry_transpose_words(GUI_ENTRY_REC *entry) /* do wordswap if any found */ if (spos1 < epos1 && epos1 < spos2 && spos2 < epos2) { unichar *first, *sep, *second; + int *first_color, *sep_color, *second_color; int i; first = (unichar *) g_malloc( (epos1 - spos1) * sizeof(unichar) ); sep = (unichar *) g_malloc( (spos2 - epos1) * sizeof(unichar) ); second = (unichar *) g_malloc( (epos2 - spos2) * sizeof(unichar) ); - for (i = spos1; i < epos1; i++) + first_color = (int *) g_malloc( (epos1 - spos1) * sizeof(int) ); + sep_color = (int *) g_malloc( (spos2 - epos1) * sizeof(int) ); + second_color = (int *) g_malloc( (epos2 - spos2) * sizeof(int) ); + + for (i = spos1; i < epos1; i++) { first[i-spos1] = entry->text[i]; - for (i = epos1; i < spos2; i++) + first_color[i-spos1] = entry->colors[i]; + } + for (i = epos1; i < spos2; i++) { sep[i-epos1] = entry->text[i]; - for (i = spos2; i < epos2; i++) + sep_color[i-epos1] = entry->colors[i]; + } + for (i = spos2; i < epos2; i++) { second[i-spos2] = entry->text[i]; + second_color[i-spos2] = entry->colors[i]; + } entry->pos = spos1; - for (i = 0; i < epos2-spos2; i++) - entry->text[entry->pos++] = second[i]; - for (i = 0; i < spos2-epos1; i++) - entry->text[entry->pos++] = sep[i]; - for (i = 0; i < epos1-spos1; i++) - entry->text[entry->pos++] = first[i]; + for (i = 0; i < epos2-spos2; i++) { + entry->text[entry->pos] = second[i]; + entry->colors[entry->pos] = second_color[i]; + entry->pos++; + } + for (i = 0; i < spos2-epos1; i++) { + entry->text[entry->pos] = sep[i]; + entry->colors[entry->pos] = sep_color[i]; + entry->pos++; + } + for (i = 0; i < epos1-spos1; i++) { + entry->text[entry->pos] = first[i]; + entry->colors[entry->pos] = first_color[i]; + entry->pos++; + } g_free(first); g_free(sep); g_free(second); + g_free(first_color); + g_free(sep_color); + g_free(second_color); + } gui_entry_redraw_from(entry, spos1); @@ -1042,3 +1103,31 @@ void gui_entry_redraw(GUI_ENTRY_REC *entry) gui_entry_fix_cursor(entry); gui_entry_draw(entry); } + +void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) +{ + int i, end, update = 0; + + g_return_if_fail(entry != NULL); + + if (pos > entry->text_len) + return; + + end = pos + len; + + if (end > entry->text_len) + end = entry->text_len; + + for (i = pos; i < end; i++) { + if (entry->colors[i] != color) { + entry->colors[i] = color; + update = 1; + } + } + + if (update) { + gui_entry_redraw_from(entry, pos); + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); + } +} diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 000c5f03..18cc5a4d 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -9,6 +9,7 @@ typedef struct { typedef struct { int text_len, text_alloc; /* as shorts, not chars */ unichar *text; + int *colors; GSList *kill_ring; @@ -77,5 +78,6 @@ void gui_entry_move_words(GUI_ENTRY_REC *entry, int count, int to_space); void gui_entry_redraw(GUI_ENTRY_REC *entry); +void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color); #endif diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 12732e3f..02ef6c73 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -124,6 +124,14 @@ gui_input_set(str) CODE: gui_entry_set_text(active_entry, str); +void +gui_input_color(pos, len, color) + int pos + int len + int color +CODE: + gui_entry_set_color(active_entry, pos, len, color); + int gui_input_get_pos() CODE: From 13b93c8c05dafd4f45ca7153ae165d6afd0ba157 Mon Sep 17 00:00:00 2001 From: GinjaNinja32 Date: Fri, 6 Oct 2017 20:35:29 +0100 Subject: [PATCH 0301/1198] Apply changes based on review feedback --- src/fe-text/gui-entry.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 3e275e34..27eaa540 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -242,7 +242,6 @@ static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry) static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { int i; - const int *col; int xpos, end_xpos, color; xpos = entry->xpos + entry->promptlen + @@ -257,10 +256,9 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) term_set_color(root_window, ATTR_RESET); term_move(root_window, xpos, entry->ypos); - col = entry->scrstart + pos < entry->text_len ? - entry->colors + entry->scrstart + pos : 0; - for (i = entry->scrstart + pos; i < entry->text_len; i++, col++) { + for (i = entry->scrstart + pos; i < entry->text_len; i++) { unichar c = entry->text[i]; + int col = entry->colors[i]; if (entry->hidden) xpos++; @@ -274,9 +272,9 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (xpos > end_xpos) break; - if (*col != color) { - term_set_color(root_window, *col); - color = *col; + if (col != color) { + term_set_color(root_window, col); + color = col; } if (entry->hidden) @@ -522,7 +520,7 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) } } - for(i = 0; i < len; i++) { + for (i = 0; i < len; i++) { entry->colors[entry->pos + i] = ATTR_RESET; } @@ -915,7 +913,6 @@ void gui_entry_transpose_words(GUI_ENTRY_REC *entry) g_free(first_color); g_free(sep_color); g_free(second_color); - } gui_entry_redraw_from(entry, spos1); @@ -1106,7 +1103,7 @@ void gui_entry_redraw(GUI_ENTRY_REC *entry) void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) { - int i, end, update = 0; + int i, end, update = FALSE; g_return_if_fail(entry != NULL); @@ -1121,7 +1118,7 @@ void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) for (i = pos; i < end; i++) { if (entry->colors[i] != color) { entry->colors[i] = color; - update = 1; + update = TRUE; } } From 0f1b3873fe5b99cf8af9bc58d1a982dd5f0f66bd Mon Sep 17 00:00:00 2001 From: GinjaNinja32 Date: Sat, 7 Oct 2017 13:59:46 +0100 Subject: [PATCH 0302/1198] Don't accept pos<0 or len<0 in gui_entry_set_color --- 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 27eaa540..bef76a96 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -1107,7 +1107,7 @@ void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) g_return_if_fail(entry != NULL); - if (pos > entry->text_len) + if (pos < 0 || len < 0 || pos > entry->text_len) return; end = pos + len; From 5bae9a94c83b8ce21e21b18963db1aa43807c932 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 18 Jan 2018 12:02:29 +0100 Subject: [PATCH 0303/1198] add backwards compatible code for running tap tests --- utils/tap-test | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/utils/tap-test b/utils/tap-test index 481e333e..b3ef8b04 100755 --- a/utils/tap-test +++ b/utils/tap-test @@ -2,4 +2,22 @@ # run a GTest in tap mode. The test binary is passed as $1 -$1 -k --tap +t="$1"; shift +if ${PKG_CONFIG:-pkg-config} --atleast-version 2.40 glib-2.0; then +exec "$t" -k --tap "$@" +else # GTest does not support tap yet + (((("$t" "$@"; echo $? >&3) | ${AM_TAP_AWK:-awk} ' +{ + if (/: /) { + i++ + ok = /: OK/ + sub(/:/, " #") + print (ok ? "ok " : "not ok ") i " " $0 + } else { + print "# " $0 + } +} END { + print 1 ".." i +} +' >&4) 3>&1) | (read xs; exit $xs)) 4>&1 +fi From 12d08f79bbec3582fe079ec5a5d0f91002f62037 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 19 Jan 2018 18:34:30 +0530 Subject: [PATCH 0304/1198] Insert colons after completing nicks preceded by a list of other autocompleted nicks When pinging two people, typing `nick1 nick2 message` for autocompletion will get you `nick1: nick2 message`, which is kinda confusing. We only insert the colon after the first autocompleted nick, because if a nick is used in the middle of the sentence it's mentioning the person but not targeting the message at them. However, this breaks down when we try to ping a list of people. There should be a colon in front of each separating the names from the message. only having a colon at the end of the nick list works too, but it seems like the IRC convention is to just use multiple colons. This patch makes it so that autocompleting a nick after a list of existing autocompleted nicks at the beginning of the message will include a colon. --- src/fe-common/core/chat-completion.c | 55 +++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 97cd0565..7ecdd4a2 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -639,6 +639,59 @@ static void complete_window_nicks(GList **list, WINDOW_REC *window, } } +/* Checks if a line is only nicks from autocompletion. + This lets us insert colons only at the beginning of a list + of nicks */ +static int only_nicks(const char *linestart) +{ + int i = 1; + char prev; + + // at the beginning of the line + if (*linestart == '\0') { + return TRUE; + } + + /* completion_char being a whole string introduces loads of edge cases + and can't be handled generally. Skip this case; we handled the + "beginning of line" case already */ + if (completion_char[1] != '\0') + return FALSE; + + /* This would make the completion char get inserted everywhere otherwise */ + if (*completion_char == ' ') + return FALSE; + + /* First ensure that the line is of the format "foo: bar: baz" + we check this by ensuring each space is preceded by a colon or + another space */ + while (linestart[i] != '\0') { + if (linestart[i] == ' ') { + prev = linestart[i - 1]; + if (prev != *completion_char && prev != ' ') + return FALSE; + } + i += 1; + } + + /* There's an edge case here, if we're completing something + like `foo: bar ba`, then the `linestart` line will end + at "bar", and we'll miss the space. Ensure that the end + of the line is a colon followed by an optional series of spaces */ + i -= 1; + while (i >= 0) { + if (linestart[i] == ' ') { + i--; + continue; + } else if (linestart[i] == *completion_char) { + return TRUE; + } else { + break; + } + } + return FALSE; +} + static void sig_complete_word(GList **list, WINDOW_REC *window, const char *word, const char *linestart, int *want_space) @@ -691,7 +744,7 @@ static void sig_complete_word(GList **list, WINDOW_REC *window, } else if (channel != NULL) { /* nick completion .. we could also be completing a nick after /MSG from nicks in channel */ - const char *suffix = *linestart != '\0' ? NULL : completion_char; + const char *suffix = only_nicks(linestart) ? completion_char : NULL; complete_window_nicks(list, window, word, suffix); } else if (window->level & MSGLEVEL_MSGS) { /* msgs window, complete /MSG nicks */ From d14dbbd09338f5cd8d14c1ec15bcf3c7fd43a3c7 Mon Sep 17 00:00:00 2001 From: Niklas Luokkala Date: Wed, 24 Jan 2018 00:15:29 +0200 Subject: [PATCH 0305/1198] Add Shift-Tab completion to gui-readline --- 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 b3a78396..c7cf6369 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -1174,6 +1174,7 @@ void gui_readline_init(void) key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo); + key_bind("key", NULL, "meta2-Z", "shifttab", (SIGNAL_FUNC) key_combo); /* meta */ key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo); @@ -1280,6 +1281,7 @@ void gui_readline_init(void) key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line); key_bind("word_completion_backward", "", NULL, NULL, (SIGNAL_FUNC) key_word_completion_backward); key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion); + key_bind("word_completion_backward", "Completes the previous word", "shifttab", NULL, (SIGNAL_FUNC) key_word_completion_backward); key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion); key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces); From 0ba1b1f2a4f0b2be6bb1077d54dda546f3db46ad Mon Sep 17 00:00:00 2001 From: Niklas Luokkala Date: Wed, 24 Jan 2018 01:49:28 +0200 Subject: [PATCH 0306/1198] removed unnecessary repetition --- src/fe-text/gui-readline.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index c7cf6369..d425739d 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -1279,9 +1279,8 @@ void gui_readline_init(void) /* line transmitting */ key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line); - key_bind("word_completion_backward", "", NULL, NULL, (SIGNAL_FUNC) key_word_completion_backward); - key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion); key_bind("word_completion_backward", "Completes the previous word", "shifttab", NULL, (SIGNAL_FUNC) key_word_completion_backward); + key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion); key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion); key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces); From 474ee8ee70c9ff9c69487746a9740355f38a01b2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 7 Jan 2018 12:44:28 +0100 Subject: [PATCH 0307/1198] Address some minor stylish nits --- src/irc/core/irc-cap.c | 10 +++++----- src/irc/core/irc-servers.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 90bffd80..95a051f0 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -81,25 +81,25 @@ static void cap_emit_signal (IRC_SERVER_REC *server, char *cmd, char *args) static gboolean parse_cap_name(char *name, char **key, char **val) { + const char *eq; + g_return_val_if_fail(name != NULL, FALSE); g_return_val_if_fail(name[0] != '\0', FALSE); - const char *eq = strchr(name, '='); + eq = strchr(name, '='); /* KEY only value */ if (eq == NULL) { *key = g_strdup(name); *val = NULL; return TRUE; - } /* Some values are in a KEY=VALUE form, parse them */ - else if (eq[1] != '\0') { + } else if (eq[1] != '\0') { *key = g_strndup(name, (gsize)(eq - name)); *val = g_strdup(eq + 1); return TRUE; - } /* If the string ends after the '=' consider the value * as invalid */ - else { + } else { *key = NULL; *val = NULL; return FALSE; diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 3b4e1a52..e154d17f 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -444,8 +444,8 @@ static void sig_disconnected(IRC_SERVER_REC *server) server->cap_active = NULL; if (server->cap_supported) { - g_hash_table_destroy(server->cap_supported); - server->cap_supported = NULL; + g_hash_table_destroy(server->cap_supported); + server->cap_supported = NULL; } gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); From b0b40be82e046785562fdb18dca3b1afb1b08a2b Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 24 Jan 2018 10:47:40 +0100 Subject: [PATCH 0308/1198] Deprecate gslist_remove_string It is not used anymore and it leaks memory. --- src/core/misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/misc.h b/src/core/misc.h index 689cf5c2..a46a1432 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -21,7 +21,7 @@ GSList *gslist_find_string(GSList *list, const char *key); GSList *gslist_find_icase_string(GSList *list, const char *key); GList *glist_find_string(GList *list, const char *key); GList *glist_find_icase_string(GList *list, const char *key); -GSList *gslist_remove_string (GSList *list, const char *str); +GSList *gslist_remove_string (GSList *list, const char *str) G_GNUC_DEPRECATED; GSList *gslist_delete_string (GSList *list, const char *str, GDestroyNotify free_func); void gslist_free_full (GSList *list, GDestroyNotify free_func); From 260733475c2b701c35024a3b4fbe900751b45341 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 24 Jan 2018 10:55:20 +0100 Subject: [PATCH 0309/1198] Accept CAPs with an empty value (KEY=) --- src/irc/core/irc-cap.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 95a051f0..dd720841 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -91,19 +91,13 @@ static gboolean parse_cap_name(char *name, char **key, char **val) if (eq == NULL) { *key = g_strdup(name); *val = NULL; - return TRUE; /* Some values are in a KEY=VALUE form, parse them */ - } else if (eq[1] != '\0') { + } else { *key = g_strndup(name, (gsize)(eq - name)); *val = g_strdup(eq + 1); - return TRUE; - /* If the string ends after the '=' consider the value - * as invalid */ - } else { - *key = NULL; - *val = NULL; - return FALSE; } + + return TRUE; } static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *address) From 6dfe5bc8361dab212653f19d611286ac93a32638 Mon Sep 17 00:00:00 2001 From: Niklas Luokkala Date: Wed, 24 Jan 2018 22:12:09 +0200 Subject: [PATCH 0310/1198] modified gui-readline based on the suggestions made to the pull request --- src/fe-text/gui-readline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index d425739d..88e827a7 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -1174,7 +1174,7 @@ void gui_readline_init(void) key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo); key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo); - key_bind("key", NULL, "meta2-Z", "shifttab", (SIGNAL_FUNC) key_combo); + key_bind("key", NULL, "meta2-Z", "stab", (SIGNAL_FUNC) key_combo); /* meta */ key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo); @@ -1279,7 +1279,7 @@ void gui_readline_init(void) /* line transmitting */ key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line); - key_bind("word_completion_backward", "Completes the previous word", "shifttab", NULL, (SIGNAL_FUNC) key_word_completion_backward); + key_bind("word_completion_backward", "Choose previous completion suggestion", "stab", NULL, (SIGNAL_FUNC) key_word_completion_backward); key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion); key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion); key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces); From f5aa829bd084d279f9ae7eb27a52ea674adfed5d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 25 Jan 2018 15:01:34 +0100 Subject: [PATCH 0311/1198] Do not use X509_STORE on OpenSSL < 1.0.2 --- src/core/network-openssl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index c7ce4b43..9e15d5c7 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -46,6 +46,7 @@ #endif /* OpenSSL 1.1.0 also introduced some useful additions to the api */ +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER) static int X509_STORE_up_ref(X509_STORE *vfy) { @@ -57,6 +58,7 @@ static int X509_STORE_up_ref(X509_STORE *vfy) return (n > 1) ? 1 : 0; } #endif +#endif /* ssl i/o channel object */ typedef struct @@ -72,7 +74,10 @@ typedef struct } GIOSSLChannel; static int ssl_inited = FALSE; +/* https://github.com/irssi/irssi/issues/820 */ +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) static X509_STORE *store = NULL; +#endif static void irssi_ssl_free(GIOChannel *handle) { @@ -391,6 +396,8 @@ gboolean irssi_ssl_init(void) SSL_load_error_strings(); OpenSSL_add_all_algorithms(); #endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) store = X509_STORE_new(); if (store == NULL) { g_error("Could not initialize OpenSSL: X509_STORE_new() failed"); @@ -404,6 +411,9 @@ gboolean irssi_ssl_init(void) store = NULL; /* Don't return an error; the user might have their own cafile/capath. */ } +#else + success = success = TRUE; +#endif ssl_inited = TRUE; @@ -522,13 +532,21 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ g_free(scafile); g_free(scapath); verify = TRUE; - } else if (store != NULL) { + } +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) + else if (store != NULL) { /* Make sure to increment the refcount every time the store is * used, that's essential not to get it free'd by OpenSSL when * the SSL_CTX is destroyed. */ X509_STORE_up_ref(store); SSL_CTX_set_cert_store(ctx, store); } +#else + else { + if (!SSL_CTX_set_default_verify_paths(ctx)) + g_warning("Could not load default certificates"); + } +#endif if(!(ssl = SSL_new(ctx))) { From af087e110373090e65184aebc3515555f64f4a33 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 25 Jan 2018 15:08:26 +0100 Subject: [PATCH 0312/1198] fix sequence error --- src/core/network-openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 9e15d5c7..9fddf073 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -384,7 +384,9 @@ static GIOFuncs irssi_ssl_channel_funcs = { gboolean irssi_ssl_init(void) { +#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) int success; +#endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) if (!OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL)) { @@ -411,8 +413,6 @@ gboolean irssi_ssl_init(void) store = NULL; /* Don't return an error; the user might have their own cafile/capath. */ } -#else - success = success = TRUE; #endif ssl_inited = TRUE; From e91da9e4098e449dc36eaa15354aff67650e7703 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 25 Jan 2018 16:05:47 +0100 Subject: [PATCH 0313/1198] please give us nicks --- src/fe-common/core/chat-completion.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 97cd0565..c62d760d 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -173,6 +173,7 @@ static void sig_message_public(SERVER_REC *server, const char *msg, { CHANNEL_REC *channel; int own; + g_return_if_fail(nick != NULL); channel = channel_find(server, target); if (channel != NULL) { @@ -185,6 +186,7 @@ static void sig_message_join(SERVER_REC *server, const char *channel, const char *nick, const char *address) { CHANNEL_REC *chanrec; + g_return_if_fail(nick != NULL); chanrec = channel_find(server, channel); if (chanrec != NULL) From 0909d47e5b5ab08cd07970a374e311f7f54be547 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 25 Jan 2018 16:10:21 +0100 Subject: [PATCH 0314/1198] Check that server is still existent when using /oper --- src/fe-common/irc/fe-irc-commands.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index 11a911d2..7a6b17a6 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -345,16 +345,18 @@ static void cmd_ts(const char *data) } typedef struct { - IRC_SERVER_REC *server; + char *server_tag; char *nick; } OPER_PASS_REC; static void cmd_oper_got_pass(const char *password, OPER_PASS_REC *rec) { - if (*password != '\0') - irc_send_cmdv(rec->server, "OPER %s %s", rec->nick, password); + SERVER_REC *server_rec = server_find_tag(rec->server_tag); + if (*password != '\0' && IS_IRC_SERVER(server_rec)) + irc_send_cmdv((IRC_SERVER_REC *) server_rec, "OPER %s %s", rec->nick, password); g_free(rec->nick); - g_free(rec); + g_free(rec->server_tag); + g_free(rec); } static void cmd_oper(const char *data, IRC_SERVER_REC *server) @@ -374,7 +376,7 @@ static void cmd_oper(const char *data, IRC_SERVER_REC *server) OPER_PASS_REC *rec; rec = g_new(OPER_PASS_REC, 1); - rec->server = server; + rec->server_tag = g_strdup(server->tag); rec->nick = g_strdup(*nick != '\0' ? nick : server->nick); format = format_get_text(MODULE_NAME, NULL, server, NULL, From a4f99ae746efb121185fe76c392a64d743a9eb92 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 20 Jan 2018 19:58:05 -0300 Subject: [PATCH 0315/1198] Revert more of the netsplit print optimisation to fix crashes Now iterating over all servers to avoid crashes on server_ischannel(), which is a macro for server->ischannel(), so it dies horribly when it's null. Doesn't help that IS_IRC_SERVER() always returns true on null. --- src/fe-common/irc/fe-netjoin.c | 16 +++++++--------- src/fe-common/irc/fe-netsplit.c | 15 ++++++--------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index bc39b27c..a7a2e4fe 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -245,20 +245,18 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - NETJOIN_SERVER_REC *rec; + GSList *tmp, *next; if (printing_joins) return; - if (!IS_IRC_SERVER(dest->server)) - return; + for (tmp = joinservers; tmp != NULL; tmp = next) { + NETJOIN_SERVER_REC *server = tmp->data; - if (!server_ischannel(dest->server, dest->target)) - return; - - rec = netjoin_find_server(IRC_SERVER(dest->server)); - if (rec != NULL && rec->netjoins != NULL) - print_netjoins(rec, NULL); + next = tmp->next; + if (server->netjoins != NULL) + print_netjoins(server, NULL); + } } static int sig_check_netjoins(void) diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index ac3330e5..edd3fc34 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -247,20 +247,17 @@ static int check_server_splits(IRC_SERVER_REC *server) message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - IRC_SERVER_REC *rec; + GSList *tmp; if (printing_splits) return; - if (!IS_IRC_SERVER(dest->server)) - return; + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; - if (!server_ischannel(dest->server, dest->target)) - return; - - rec = IRC_SERVER(dest->server); - if (rec->split_servers != NULL) - print_splits(rec, NULL); + if (IS_IRC_SERVER(rec) && rec->split_servers != NULL) + print_splits(rec, NULL); + } } static int sig_check_splits(void) From 126189bb374d436280885f0f878a5075feed2fbc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 25 Jan 2018 15:54:20 +0100 Subject: [PATCH 0316/1198] we probably should not try to replace replaces Credit to OSS-Fuzz --- src/fe-common/core/themes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index cb1cce8f..6692985b 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -130,7 +130,7 @@ static char *theme_replace_expand(THEME_REC *theme, int index, abstract = rec->data; abstract = theme_format_expand_data(theme, (const char **) &abstract, default_fg, default_bg, - last_fg, last_bg, flags); + last_fg, last_bg, (flags | EXPAND_FLAG_IGNORE_REPLACES)); ret = parse_special_string(abstract, NULL, NULL, data, NULL, PARSE_FLAG_ONLY_ARGS); g_free(abstract); From 7f4de37fbfc3a052f46619b629d7a2ea8b03ebb3 Mon Sep 17 00:00:00 2001 From: William Jackson Date: Tue, 30 Jan 2018 10:31:13 -0600 Subject: [PATCH 0317/1198] Fix typo in help text for /ISON command --- docs/help/in/ison.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/ison.in b/docs/help/in/ison.in index c77e4c59..e9e54ee9 100644 --- a/docs/help/in/ison.in +++ b/docs/help/in/ison.in @@ -16,5 +16,5 @@ /ISON mike /ISON sarah bob -%9See also:%9 NOTIFY, WHOAS, WHOIS +%9See also:%9 NOTIFY, WHOWAS, WHOIS From 12360fb2c06b8f11db6a7348426851fac8de8a93 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 1 Feb 2018 10:21:31 +0100 Subject: [PATCH 0318/1198] protect theme recursion --- src/fe-common/core/themes.c | 54 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 6692985b..99dc90bc 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -400,12 +400,15 @@ char *theme_format_expand_get(THEME_REC *theme, const char **format) return ret; } +static char *theme_format_expand_data_rec(THEME_REC *theme, const char **format, + theme_rm_col default_fg, theme_rm_col default_bg, + theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, + int flags, GTree *block_list); + /* expand a single {abstract ...data... } */ -static char *theme_format_expand_abstract(THEME_REC *theme, - const char **formatp, - theme_rm_col *last_fg, - theme_rm_col *last_bg, - int flags) +static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp, + theme_rm_col *last_fg, theme_rm_col *last_bg, int flags, + GTree *block_list) { GString *str; const char *p, *format; @@ -439,12 +442,20 @@ static char *theme_format_expand_abstract(THEME_REC *theme, } *formatp = format+len; + if (block_list == NULL) { + block_list = g_tree_new_full((GCompareDataFunc) g_strcmp0, NULL, g_free, NULL); + } else { + g_tree_ref(block_list); + } + /* get the abstract data */ data = g_hash_table_lookup(theme->abstracts, abstract); - g_free(abstract); - if (data == NULL) { + if (data == NULL || g_tree_lookup(block_list, abstract) != NULL) { /* unknown abstract, just display the data */ data = "$0-"; + g_free(abstract); + } else { + g_tree_insert(block_list, abstract, abstract); } abstract = g_strdup(data); @@ -488,18 +499,17 @@ static char *theme_format_expand_abstract(THEME_REC *theme, /* abstract may itself contain abstracts or replaces */ p = abstract; - ret = theme_format_expand_data(theme, &p, default_fg, default_bg, - last_fg, last_bg, - flags | EXPAND_FLAG_LASTCOLOR_ARG); + ret = theme_format_expand_data_rec(theme, &p, default_fg, default_bg, last_fg, last_bg, + flags | EXPAND_FLAG_LASTCOLOR_ARG, block_list); g_free(abstract); + g_tree_unref(block_list); return ret; } -/* expand the data part in {abstract data} */ -char *theme_format_expand_data(THEME_REC *theme, const char **format, - theme_rm_col default_fg, theme_rm_col default_bg, - theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, - int flags) +static char *theme_format_expand_data_rec(THEME_REC *theme, const char **format, + theme_rm_col default_fg, theme_rm_col default_bg, + theme_rm_col *save_last_fg, theme_rm_col *save_last_bg, + int flags, GTree *block_list) { GString *str; char *ret, *abstract; @@ -545,9 +555,8 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format, break; /* error */ /* get a single {...} */ - abstract = theme_format_expand_abstract(theme, format, - &last_fg, &last_bg, - recurse_flags); + abstract = theme_format_expand_abstract(theme, format, &last_fg, &last_bg, + recurse_flags, block_list); if (abstract != NULL) { g_string_append(str, abstract); g_free(abstract); @@ -565,6 +574,15 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format, return ret; } +/* expand the data part in {abstract data} */ +char *theme_format_expand_data(THEME_REC *theme, const char **format, theme_rm_col default_fg, + theme_rm_col default_bg, theme_rm_col *save_last_fg, + theme_rm_col *save_last_bg, int flags) +{ + return theme_format_expand_data_rec(theme, format, default_fg, default_bg, save_last_bg, + save_last_bg, flags, NULL); +} + #define IS_OLD_FORMAT(code, last_fg, last_bg) \ (((code) == 'n' && (last_fg) == 'n' && (last_bg) == 'n') || \ ((code) != 'n' && ((code) == (last_fg) || (code) == (last_bg)))) From 4c662acf957502af186aa631d185d6edca709e15 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 1 Feb 2018 13:52:12 +0100 Subject: [PATCH 0319/1198] another replaces fix Credit to OSS-Fuzz --- src/fe-common/core/themes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 99dc90bc..acb5d1c7 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -382,7 +382,8 @@ char *theme_format_expand_get(THEME_REC *theme, const char **format) } else { theme_format_append_next(theme, str, format, reset, reset, - &dummy, &dummy, 0); + &dummy, &dummy, + EXPAND_FLAG_IGNORE_REPLACES); continue; } From f0bd434eb0b0fbeaecc10c3cc355100fbf90947a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 2 Feb 2018 09:50:08 +0100 Subject: [PATCH 0320/1198] stop the madness --- src/fe-text/mainwindows.c | 83 ++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 5f24674f..fd4603da 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -915,6 +915,8 @@ static int try_shrink_lower(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_lower(window); if (shrink_win != NULL) { int ok; @@ -959,6 +961,8 @@ static int try_shrink_upper(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_upper(window); if (shrink_win != NULL) { int ok; @@ -1063,6 +1067,8 @@ static int try_grow_upper(MAIN_WINDOW_REC *window, int count) static int mainwindow_shrink(MAIN_WINDOW_REC *window, int count, int resize_lower) { + g_return_val_if_fail(count >= 0, FALSE); + if (MAIN_WINDOW_TEXT_HEIGHT(window)-count < WINDOW_MIN_SIZE) return FALSE; @@ -1091,6 +1097,8 @@ static int try_rshrink_right(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_right(window, FALSE); if (shrink_win != NULL) { if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { @@ -1111,6 +1119,8 @@ static int try_rshrink_left(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; + g_return_val_if_fail(count >= 0, FALSE); + shrink_win = mainwindows_find_left(window, FALSE); if (shrink_win != NULL) { if (MAIN_WINDOW_TEXT_WIDTH(shrink_win)-count < NEW_WINDOW_WIDTH) { @@ -1168,6 +1178,8 @@ static int try_rgrow_left(MAIN_WINDOW_REC *window, int count) static int mainwindow_rshrink(MAIN_WINDOW_REC *window, int count) { + g_return_val_if_fail(count >= 0, FALSE); + if (MAIN_WINDOW_TEXT_WIDTH(window)-count < NEW_WINDOW_WIDTH) return FALSE; @@ -1220,19 +1232,29 @@ void mainwindows_redraw_dirty(void) } } +static void mainwindow_grow_int(int count) +{ + if (count == 0) { + return; + } else if (count < 0) { + if (!mainwindow_shrink(WINDOW_MAIN(active_win), -count, FALSE)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } else { + if (!mainwindow_grow(WINDOW_MAIN(active_win), count, FALSE)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } +} + /* SYNTAX: WINDOW GROW [] */ static void cmd_window_grow(const char *data) { - MAIN_WINDOW_REC *window; int count; count = *data == '\0' ? 1 : atoi(data); - window = WINDOW_MAIN(active_win); - if (!mainwindow_grow(window, count, FALSE)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + mainwindow_grow_int(count); } /* SYNTAX: WINDOW SHRINK [] */ @@ -1241,16 +1263,13 @@ static void cmd_window_shrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_shrink(WINDOW_MAIN(active_win), count, FALSE)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + + mainwindow_grow_int(-count); } /* SYNTAX: WINDOW SIZE */ static void cmd_window_size(const char *data) { - char sizestr[MAX_INT_STRLEN]; int size; if (!is_numeric(data, 0)) return; @@ -1258,13 +1277,8 @@ static void cmd_window_size(const char *data) size -= WINDOW_MAIN(active_win)->height - WINDOW_MAIN(active_win)->statusbar_lines; - if (size == 0) return; - ltoa(sizestr, size < 0 ? -size : size); - if (size < 0) - cmd_window_shrink(sizestr); - else - cmd_window_grow(sizestr); + mainwindow_grow_int(size); } /* SYNTAX: WINDOW BALANCE */ @@ -1415,16 +1429,29 @@ static void cmd_window_rshow(const char *data) _cmd_window_show_opt(data, TRUE); } +static void window_rgrow_int(int count) +{ + if (count == 0) { + return; + } else if (count < 0) { + if (!mainwindow_rshrink(WINDOW_MAIN(active_win), -count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } else { + if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); + } + } +} + /* SYNTAX: WINDOW RGROW [] */ static void cmd_window_rgrow(const char *data) { int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + + window_rgrow_int(count); } /* SYNTAX: WINDOW RSHRINK [] */ @@ -1433,29 +1460,21 @@ static void cmd_window_rshrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); - if (!mainwindow_rshrink(WINDOW_MAIN(active_win), count)) { - printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_TOO_SMALL); - } + + window_rgrow_int(-count); } /* SYNTAX: WINDOW RSIZE */ static void cmd_window_rsize(const char *data) { - char rsizestr[MAX_INT_STRLEN]; int rsize; if (!is_numeric(data, 0)) return; rsize = atoi(data); rsize -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win)); - if (rsize == 0) return; - ltoa(rsizestr, rsize < 0 ? -rsize : rsize); - if (rsize < 0) - cmd_window_rshrink(rsizestr); - else - cmd_window_rgrow(rsizestr); + window_rgrow_int(rsize); } /* SYNTAX: WINDOW RBALANCE */ From 5b5bfef03596d95079c728f65f523570dd7b03aa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 2 Feb 2018 10:05:37 +0100 Subject: [PATCH 0321/1198] check the error condition of mainwindow_create --- src/fe-text/mainwindows.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 5f24674f..0c77bcf1 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -1393,6 +1393,11 @@ static void _cmd_window_show_opt(const char *data, int right) } parent = mainwindow_create(right); + if (parent == NULL) { + printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_WINDOW_TOO_SMALL); + return; + } + parent->active = window; gui_window_reparent(window, parent); From 84f03e01467b90a4251987b32b2813ee976b357c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 2 Feb 2018 10:27:51 +0100 Subject: [PATCH 0322/1198] do not reuse sasl timeout --- src/irc/core/sasl.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 2b589579..c5aa2caa 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -55,10 +55,21 @@ static gboolean sasl_timeout(IRC_SERVER_REC *server) return FALSE; } +static void sasl_timeout_stop(IRC_SERVER_REC *server) +{ + /* Stop any pending timeout, if any */ + if (server->sasl_timeout != 0) { + g_source_remove(server->sasl_timeout); + server->sasl_timeout = 0; + } +} + static void sasl_start(IRC_SERVER_REC *server, const char *data, const char *from) { IRC_SERVER_CONNECT_REC *conn; + sasl_timeout_stop(server); + conn = server->connrec; switch (conn->sasl_mechanism) { @@ -77,11 +88,6 @@ static void sasl_fail(IRC_SERVER_REC *server, const char *data, const char *from { char *params, *error; - /* Stop any pending timeout, if any */ - if (server->sasl_timeout != 0) { - g_source_remove(server->sasl_timeout); - server->sasl_timeout = 0; - } params = event_get_params(data, 2, NULL, &error); @@ -97,10 +103,7 @@ static void sasl_fail(IRC_SERVER_REC *server, const char *data, const char *from static void sasl_already(IRC_SERVER_REC *server, const char *data, const char *from) { - if (server->sasl_timeout != 0) { - g_source_remove(server->sasl_timeout); - server->sasl_timeout = 0; - } + sasl_timeout_stop(server); server->sasl_success = TRUE; @@ -112,10 +115,7 @@ static void sasl_already(IRC_SERVER_REC *server, const char *data, const char *f static void sasl_success(IRC_SERVER_REC *server, const char *data, const char *from) { - if (server->sasl_timeout != 0) { - g_source_remove(server->sasl_timeout); - server->sasl_timeout = 0; - } + sasl_timeout_stop(server); server->sasl_success = TRUE; @@ -265,7 +265,7 @@ static void sasl_step_fail(IRC_SERVER_REC *server) irc_send_cmd_now(server, "AUTHENTICATE *"); cap_finish_negotiation(server); - server->sasl_timeout = 0; + sasl_timeout_stop(server); signal_emit("server sasl failure", 2, server, "The server sent an invalid payload"); } @@ -274,11 +274,7 @@ static void sasl_step(IRC_SERVER_REC *server, const char *data, const char *from { GString *req = NULL; - /* Stop the timer */ - if (server->sasl_timeout != 0) { - g_source_remove(server->sasl_timeout); - server->sasl_timeout = 0; - } + sasl_timeout_stop(server); if (!sasl_reassemble_incoming(server, data, &req)) { sasl_step_fail(server); @@ -302,10 +298,7 @@ static void sasl_disconnected(IRC_SERVER_REC *server) return; } - if (server->sasl_timeout != 0) { - g_source_remove(server->sasl_timeout); - server->sasl_timeout = 0; - } + sasl_timeout_stop(server); } void sasl_init(void) From 9072e988194a36186bd98db844b8285e3f37069a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 10 Jan 2018 17:49:32 +0100 Subject: [PATCH 0323/1198] change color -> extents (malloc based) --- src/fe-text/gui-entry.c | 566 +++++++++++++++++++++++++++++++------- src/fe-text/gui-entry.h | 13 +- src/fe-text/irssi.c | 2 + src/perl/textui/TextUI.xs | 66 ++++- 4 files changed, 543 insertions(+), 104 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index bef76a96..52a39969 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -65,8 +65,10 @@ static void entry_text_grow(GUI_ENTRY_REC *entry, int grow_size) entry->text_alloc = nearest_power(entry->text_alloc+grow_size); entry->text = g_realloc(entry->text, sizeof(unichar) * entry->text_alloc); - entry->colors = g_realloc(entry->colors, - sizeof(int) * entry->text_alloc); + + if (entry->uses_extents) + entry->extents = g_realloc(entry->extents, + sizeof(char *) * entry->text_alloc); } GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) @@ -79,12 +81,27 @@ GUI_ENTRY_REC *gui_entry_create(int xpos, int ypos, int width, int utf8) rec->width = width; rec->text_alloc = 1024; rec->text = g_new(unichar, rec->text_alloc); - rec->colors = g_new(int, rec->text_alloc); + rec->extents = NULL; rec->text[0] = '\0'; rec->utf8 = utf8; return rec; } +static void destroy_extents(GUI_ENTRY_REC *entry) +{ + if (entry->uses_extents) { + int i; + for (i = 0; i < entry->text_alloc; i++) { + if (entry->extents[i] != NULL) { + g_free(entry->extents[i]); + } + } + } + g_free(entry->extents); + entry->extents = NULL; + entry->uses_extents = FALSE; +} + void gui_entry_destroy(GUI_ENTRY_REC *entry) { GSList *tmp; @@ -103,8 +120,8 @@ void gui_entry_destroy(GUI_ENTRY_REC *entry) } g_slist_free(entry->kill_ring); + destroy_extents(entry); g_free(entry->text); - g_free(entry->colors); g_free(entry->prompt); g_free(entry); } @@ -168,15 +185,36 @@ void big5_to_unichars(const char *str, unichar *out) *out = '\0'; } +/* Return screen length of plain string */ +static int scrlen_str(const char *str, int utf8) +{ + int len = 0; + char *stripped; + g_return_val_if_fail(str != NULL, 0); + + stripped = strip_codes(str); + len = string_width(stripped, utf8 ? TREAT_STRING_AS_UTF8 : TREAT_STRING_AS_BYTES); + g_free(stripped); + return len; +} + /* ----------------------------- */ -static int pos2scrpos(GUI_ENTRY_REC *entry, int pos) +static int pos2scrpos(GUI_ENTRY_REC *entry, int pos, int cursor) { int i; int xpos = 0; + if (!cursor && pos <= 0) + return 0; + + if (entry->uses_extents && entry->extents[0] != NULL) { + xpos += scrlen_str(entry->extents[0], entry->utf8); + } + for (i = 0; i < pos; i++) { unichar c = entry->text[i]; + const char *extent = entry->uses_extents ? entry->extents[i+1] : NULL; if (term_type == TERM_TYPE_BIG5) xpos += big5_width(c); @@ -184,16 +222,26 @@ static int pos2scrpos(GUI_ENTRY_REC *entry, int pos) xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; else xpos++; + + if (extent != NULL) { + xpos += scrlen_str(extent, entry->utf8); + } + } return xpos; } static int scrpos2pos(GUI_ENTRY_REC *entry, int pos) { - int i, width, xpos; + int i, width, xpos = 0; - for (i = 0, xpos = 0; i < entry->text_len; i++) { + if (entry->uses_extents && entry->extents[0] != NULL) { + xpos += scrlen_str(entry->extents[0], entry->utf8); + } + + for (i = 0; i < entry->text_len && xpos < pos; i++) { unichar c = entry->text[i]; + const char *extent = entry->uses_extents ? entry->extents[i+1] : NULL; if (term_type == TERM_TYPE_BIG5) width = big5_width(c); @@ -202,15 +250,13 @@ static int scrpos2pos(GUI_ENTRY_REC *entry, int pos) else width = 1; - if (xpos + width > pos) - break; xpos += width; - } - if (xpos == pos) - return i; - else - return i-1; + if (extent != NULL) { + xpos += scrlen_str(extent, entry->utf8); + } + } + return i; } /* Fixes the cursor position in screen */ @@ -219,19 +265,19 @@ static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry) int old_scrstart; /* assume prompt len == prompt scrlen */ - int start = pos2scrpos(entry, entry->scrstart); - int now = pos2scrpos(entry, entry->pos); + int start = pos2scrpos(entry, entry->scrstart, FALSE); + int now = pos2scrpos(entry, entry->pos, TRUE); old_scrstart = entry->scrstart; - if (now-start < entry->width - 2 - entry->promptlen && now-start > 0) + if (now-start < entry->width - 2 - entry->promptlen && now-start > 0) { entry->scrpos = now-start; - else if (now < entry->width - 1 - entry->promptlen) { + } else if (now < entry->width - 1 - entry->promptlen) { entry->scrstart = 0; entry->scrpos = now; } else { entry->scrstart = scrpos2pos(entry, now-(entry->width - entry->promptlen)*2/3); - start = pos2scrpos(entry, entry->scrstart); + start = pos2scrpos(entry, entry->scrstart, FALSE); entry->scrpos = now - start; } @@ -239,66 +285,140 @@ static void gui_entry_fix_cursor(GUI_ENTRY_REC *entry) entry->redraw_needed_from = 0; } +static char *text_effects_only(const char *p) +{ + GString *str; + + str = g_string_sized_new(strlen(p)); + for (; *p != '\0'; p++) { + if (*p == 4 && p[1] != '\0') { + if (p[1] >= FORMAT_STYLE_SPECIAL) { + g_string_append_len(str, p, 2); + p++; + continue; + } + + /* irssi color */ + if (p[2] != '\0') { +#ifdef TERM_TRUECOLOR + if (p[1] == FORMAT_COLOR_24) { + if (p[3] == '\0') p += 2; + else if (p[4] == '\0') p += 3; + else if (p[5] == '\0') p += 4; + else { + g_string_append_len(str, p, 6); + p += 5; + } + } else { +#endif /* TERM_TRUECOLOR */ + g_string_append_len(str, p, 3); + p += 2; +#ifdef TERM_TRUECOLOR + } +#endif /* TERM_TRUECOLOR */ + continue; + } + } + } + + return g_string_free(str, FALSE); +} + static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) { - int i; - int xpos, end_xpos, color; + int i, start; + int start_xpos, xpos, new_xpos, end_xpos; + char *tmp; + GString *str; - xpos = entry->xpos + entry->promptlen + - pos2scrpos(entry, pos + entry->scrstart) - - pos2scrpos(entry, entry->scrstart); + start = entry->scrstart + pos; + + start_xpos = xpos = entry->xpos + entry->promptlen + + pos2scrpos(entry, start, FALSE) - + pos2scrpos(entry, entry->scrstart, FALSE); end_xpos = entry->xpos + entry->width; if (xpos > end_xpos) return; - color = ATTR_RESET; - term_set_color(root_window, ATTR_RESET); - term_move(root_window, xpos, entry->ypos); + str = g_string_sized_new(entry->text_alloc); - for (i = entry->scrstart + pos; i < entry->text_len; i++) { + term_set_color(root_window, ATTR_RESET); + /* term_move(root_window, xpos, entry->ypos); */ + + if (entry->uses_extents && entry->extents[0] != NULL) { + g_string_append(str, entry->extents[0]); + } + for (i = 0; i < start && i < entry->text_len; i++) { + const char *extent = entry->uses_extents ? entry->extents[i+1] : NULL; + if (extent != NULL) { + g_string_append(str, extent); + } + } + if (i == 0) { + xpos += scrlen_str(str->str, entry->utf8); + } else { + tmp = text_effects_only(str->str); + g_string_assign(str, tmp); + g_free(tmp); + } + + for (; i < entry->text_len; i++) { unichar c = entry->text[i]; - int col = entry->colors[i]; + const char *extent = entry->uses_extents ? entry->extents[i+1] : NULL; + new_xpos = xpos; if (entry->hidden) - xpos++; + new_xpos++; else if (term_type == TERM_TYPE_BIG5) - xpos += big5_width(c); + new_xpos += big5_width(c); else if (entry->utf8) - xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; + new_xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; else - xpos++; + new_xpos++; - if (xpos > end_xpos) + if (new_xpos > end_xpos) break; - if (col != color) { - term_set_color(root_window, col); - color = col; - } - if (entry->hidden) - term_addch(root_window, ' '); + g_string_append_c(str, ' '); else if (unichar_isprint(c)) - term_add_unichar(root_window, c); + g_string_append_unichar(str, c); else { - term_set_color(root_window, ATTR_RESET|ATTR_REVERSE); - term_addch(root_window, (c & 127)+'A'-1); - term_set_color(root_window, color); + g_string_append_c(str, 4); + g_string_append_c(str, FORMAT_STYLE_REVERSE); + g_string_append_c(str, (c & 127)+'A'-1); + g_string_append_c(str, 4); + g_string_append_c(str, FORMAT_STYLE_REVERSE); + } + xpos = new_xpos; + + if (extent != NULL) { + new_xpos += scrlen_str(extent, entry->utf8); + + if (new_xpos > end_xpos) + break; + + g_string_append(str, extent); + xpos = new_xpos; } } /* clear the rest of the input line */ if (xpos < end_xpos) { - if (end_xpos == term_width) - term_clrtoeol(root_window); - else { + if (end_xpos == term_width) { + g_string_append_c(str, 4); + g_string_append_c(str, FORMAT_STYLE_CLRTOEOL); + } else { while (xpos < end_xpos) { - term_addch(root_window, ' '); + g_string_append_c(str, ' '); xpos++; } } } + + gui_printtext_internal(start_xpos, entry->ypos, str->str); + g_string_free(str, TRUE); } static void gui_entry_draw(GUI_ENTRY_REC *entry) @@ -370,19 +490,6 @@ 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); - - stripped = strip_codes(str); - len = string_width(stripped, -1); - g_free(stripped); - return len; -} - void gui_entry_set_prompt(GUI_ENTRY_REC *entry, const char *str) { int oldlen; @@ -393,7 +500,7 @@ 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 = scrlen_str(str); + entry->promptlen = scrlen_str(str, entry->utf8); } if (entry->prompt != NULL) @@ -427,6 +534,7 @@ void gui_entry_set_text(GUI_ENTRY_REC *entry, const char *str) entry->text_len = 0; entry->pos = 0; entry->text[0] = '\0'; + destroy_extents(entry); gui_entry_insert_text(entry, str); } @@ -500,8 +608,13 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) (entry->text_len-entry->pos + 1) * sizeof(unichar)); /* make space for the color */ - g_memmove(entry->colors + entry->pos + len, entry->colors + entry->pos, - (entry->text_len-entry->pos) * sizeof(int)); + if (entry->uses_extents) { + g_memmove(entry->extents + entry->pos + len + 1, entry->extents + entry->pos + 1, + (entry->text_len-entry->pos) * sizeof(char *)); + for (i = 0; i < len; i++) { + entry->extents[entry->pos + i + 1] = NULL; + } + } if (!entry->utf8) { if (term_type == TERM_TYPE_BIG5) { @@ -520,10 +633,6 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) } } - for (i = 0; i < len; i++) { - entry->colors[entry->pos + i] = ATTR_RESET; - } - entry->text_len += len; entry->pos += len; @@ -549,12 +658,13 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) g_memmove(entry->text + entry->pos + 1, entry->text + entry->pos, (entry->text_len-entry->pos + 1) * sizeof(unichar)); - g_memmove(entry->colors + entry->pos + 1, entry->colors + entry->pos, - (entry->text_len-entry->pos) * sizeof(int)); - + if (entry->uses_extents) { + g_memmove(entry->extents + entry->pos + 1 + 1, entry->extents + entry->pos + 1, + (entry->text_len-entry->pos) * sizeof(char *)); + entry->extents[entry->pos + 1] = NULL; + } entry->text[entry->pos] = chr; - entry->colors[entry->pos] = ATTR_RESET; entry->text_len++; entry->pos++; @@ -655,7 +765,7 @@ static GUI_ENTRY_CUTBUFFER_REC *get_cutbuffer_rec(GUI_ENTRY_REC *entry, CUTBUFFE void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_cutbuffer) { - size_t w = 0; + size_t i, w = 0; g_return_if_fail(entry != NULL); @@ -724,8 +834,22 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ g_memmove(entry->text + entry->pos - size, entry->text + entry->pos, (entry->text_len-entry->pos+1) * sizeof(unichar)); - g_memmove(entry->colors + entry->pos - size, entry->colors + entry->pos, - (entry->text_len - entry->pos) * sizeof(int)); + if (entry->uses_extents) { + for (i = entry->pos - size; i < entry->pos; i++) { + if (entry->extents[i+1] != NULL) { + g_free(entry->extents[i+1]); + } + } + g_memmove(entry->extents + entry->pos - size + 1, entry->extents + entry->pos + 1, + (entry->text_len - entry->pos) * sizeof(void *)); /* no null terminator here */ + for (i = 0; i < size; i++) { + entry->extents[entry->text_len - i] = NULL; + } + if (entry->text_len == size && entry->extents[0] != NULL) { + g_free(entry->extents[0]); + entry->extents[0] = NULL; + } + } entry->pos -= size; entry->text_len -= size; @@ -748,12 +872,26 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) g_memmove(entry->text + entry->pos, entry->text + entry->pos + size, (entry->text_len-entry->pos-size+1) * sizeof(unichar)); - g_memmove(entry->colors + entry->pos, entry->colors + entry->pos + size, - (entry->text_len-entry->pos-size) * sizeof(int)); + if (entry->uses_extents) { + int i; + for (i = 0; i < size; i++) { + g_free(entry->extents[entry->pos + i + 1]); + } + g_memmove(entry->extents + entry->pos + 1, entry->extents + entry->pos + size + 1, + (entry->text_len-entry->pos-size) * sizeof(char *)); + for (i = 0; i < size; i++) { + entry->extents[entry->text_len - i] = NULL; + } + if (entry->text_len == size && entry->extents[0] != NULL) { + g_free(entry->extents[0]); + entry->extents[0] = NULL; + } + } entry->text_len -= size; gui_entry_redraw_from(entry, entry->pos); + gui_entry_fix_cursor(entry); gui_entry_draw(entry); } @@ -812,7 +950,7 @@ void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space, CUTBUFFER_UPD void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) { unichar chr; - int color; + char *extent; if (entry->pos == 0 || entry->text_len < 2) return; @@ -825,9 +963,11 @@ void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) entry->text[entry->pos] = entry->text[entry->pos-1]; entry->text[entry->pos-1] = chr; - color = entry->colors[entry->pos]; - entry->colors[entry->pos] = entry->colors[entry->pos-1]; - entry->colors[entry->pos-1] = color; + if (entry->uses_extents) { + extent = entry->extents[entry->pos+1]; + entry->extents[entry->pos+1] = entry->extents[entry->pos]; + entry->extents[entry->pos] = extent; + } entry->pos++; @@ -865,44 +1005,50 @@ void gui_entry_transpose_words(GUI_ENTRY_REC *entry) /* do wordswap if any found */ if (spos1 < epos1 && epos1 < spos2 && spos2 < epos2) { unichar *first, *sep, *second; - int *first_color, *sep_color, *second_color; + char **first_extent, **sep_extent, **second_extent; int i; first = (unichar *) g_malloc( (epos1 - spos1) * sizeof(unichar) ); sep = (unichar *) g_malloc( (spos2 - epos1) * sizeof(unichar) ); second = (unichar *) g_malloc( (epos2 - spos2) * sizeof(unichar) ); - first_color = (int *) g_malloc( (epos1 - spos1) * sizeof(int) ); - sep_color = (int *) g_malloc( (spos2 - epos1) * sizeof(int) ); - second_color = (int *) g_malloc( (epos2 - spos2) * sizeof(int) ); + first_extent = (char **) g_malloc( (epos1 - spos1) * sizeof(char *) ); + sep_extent = (char **) g_malloc( (spos2 - epos1) * sizeof(char *) ); + second_extent = (char **) g_malloc( (epos2 - spos2) * sizeof(char *) ); for (i = spos1; i < epos1; i++) { first[i-spos1] = entry->text[i]; - first_color[i-spos1] = entry->colors[i]; + if (entry->uses_extents) + first_extent[i-spos1] = entry->extents[i+1]; } for (i = epos1; i < spos2; i++) { sep[i-epos1] = entry->text[i]; - sep_color[i-epos1] = entry->colors[i]; + if (entry->uses_extents) + sep_extent[i-epos1] = entry->extents[i+1]; } for (i = spos2; i < epos2; i++) { second[i-spos2] = entry->text[i]; - second_color[i-spos2] = entry->colors[i]; + if (entry->uses_extents) + second_extent[i-spos2] = entry->extents[i+1]; } entry->pos = spos1; for (i = 0; i < epos2-spos2; i++) { entry->text[entry->pos] = second[i]; - entry->colors[entry->pos] = second_color[i]; + if (entry->uses_extents) + entry->extents[entry->pos+1] = second_extent[i]; entry->pos++; } for (i = 0; i < spos2-epos1; i++) { entry->text[entry->pos] = sep[i]; - entry->colors[entry->pos] = sep_color[i]; + if (entry->uses_extents) + entry->extents[entry->pos+1] = sep_extent[i]; entry->pos++; } for (i = 0; i < epos1-spos1; i++) { entry->text[entry->pos] = first[i]; - entry->colors[entry->pos] = first_color[i]; + if (entry->uses_extents) + entry->extents[entry->pos+1] = first_extent[i]; entry->pos++; } @@ -910,9 +1056,9 @@ void gui_entry_transpose_words(GUI_ENTRY_REC *entry) g_free(sep); g_free(second); - g_free(first_color); - g_free(sep_color); - g_free(second_color); + g_free(first_extent); + g_free(sep_extent); + g_free(second_extent); } gui_entry_redraw_from(entry, spos1); @@ -996,11 +1142,17 @@ void gui_entry_set_pos(GUI_ENTRY_REC *entry, int pos) void gui_entry_set_text_and_pos_bytes(GUI_ENTRY_REC *entry, const char *str, int pos_bytes) { - int pos; + int pos, extents_alloc; + char **extents; const char *ptr; g_return_if_fail(entry != NULL); + extents = entry->extents; + extents_alloc = entry->text_alloc; + entry->extents = NULL; + entry->uses_extents = FALSE; + gui_entry_set_text(entry, str); if (entry->utf8) { @@ -1011,6 +1163,19 @@ void gui_entry_set_text_and_pos_bytes(GUI_ENTRY_REC *entry, const char *str, int else pos = pos_bytes; + if (extents != NULL) { + entry->uses_extents = TRUE; + entry->extents = extents; + if (extents_alloc < entry->text_alloc) { + int i; + entry->extents = g_realloc(entry->extents, + sizeof(char *) * entry->text_alloc); + for (i = extents_alloc; i < entry->text_alloc; i++) { + entry->extents[i] = NULL; + } + } + } + gui_entry_redraw_from(entry, 0); gui_entry_set_pos(entry, pos); } @@ -1101,7 +1266,91 @@ void gui_entry_redraw(GUI_ENTRY_REC *entry) gui_entry_draw(entry); } -void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) +static void gui_entry_alloc_extents(GUI_ENTRY_REC *entry) +{ + entry->uses_extents = TRUE; + entry->extents = g_new0(char *, entry->text_alloc); +} + +void gui_entry_set_extent(GUI_ENTRY_REC *entry, int pos, const char *text) +{ + int update = FALSE; + + g_return_if_fail(entry != NULL); + + if (pos < 0 || pos > entry->text_len) + return; + + if (text == NULL) + return; + + if (!entry->uses_extents) { + gui_entry_alloc_extents(entry); + } + + if (g_strcmp0(entry->extents[pos], text) != 0) { + g_free(entry->extents[pos]); + if (*text == '\0') { + entry->extents[pos] = NULL; + } else { + entry->extents[pos] = g_strdup(text); + } + update = TRUE; + } + + if (update) { + gui_entry_redraw_from(entry, pos - 1); + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); + } +} + +void gui_entry_set_extents(GUI_ENTRY_REC *entry, int pos, int len, const char *left, const char *right) +{ + int end, update = FALSE; + + g_return_if_fail(entry != NULL); + + if (pos < 0 || len < 0 || pos > entry->text_len) + return; + + end = pos + len; + + if (end > entry->text_len) + end = entry->text_len; + + if (!entry->uses_extents) { + gui_entry_alloc_extents(entry); + } + + if (g_strcmp0(entry->extents[pos], left) != 0) { + g_free(entry->extents[pos]); + if (*left == '\0') { + entry->extents[pos] = NULL; + } else { + entry->extents[pos] = g_strdup(left); + } + update = TRUE; + } + + if (pos != end && g_strcmp0(entry->extents[end], right) != 0) { + g_free(entry->extents[end]); + if (*right == '\0') { + entry->extents[end] = NULL; + } else { + entry->extents[end] = g_strdup(right); + } + update = TRUE; + } + + if (update) { + gui_entry_redraw_from(entry, pos - 1); + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); + } +} + +void gui_entry_clear_extents(GUI_ENTRY_REC *entry, int pos, int len) { int i, end, update = FALSE; @@ -1115,9 +1364,14 @@ void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) if (end > entry->text_len) end = entry->text_len; - for (i = pos; i < end; i++) { - if (entry->colors[i] != color) { - entry->colors[i] = color; + if (!entry->uses_extents) { + return; + } + + for (i = pos; i <= end; i++) { + if (entry->extents[i] != NULL) { + g_free(entry->extents[i]); + entry->extents[i] = NULL; update = TRUE; } } @@ -1128,3 +1382,117 @@ void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color) gui_entry_draw(entry); } } + +char *gui_entry_get_extent(GUI_ENTRY_REC *entry, int pos) +{ + g_return_val_if_fail(entry != NULL, NULL); + + if (!entry->uses_extents) + return NULL; + + if (pos < 0 || pos >= entry->text_len) + return NULL; + + return entry->extents[pos]; +} + +#define POS_FLAG "%|" +GSList *gui_entry_get_text_and_extents(GUI_ENTRY_REC *entry) +{ + GSList *list = NULL; + GString *str; + int i; + + g_return_val_if_fail(entry != NULL, NULL); + + if (entry->uses_extents && entry->extents[0] != NULL) { + if (entry->pos == 0) { + list = g_slist_prepend(list, g_strconcat(entry->extents[0], POS_FLAG, NULL)); + } else { + list = g_slist_prepend(list, g_strdup(entry->extents[0])); + } + } else { + if (entry->pos == 0) { + list = g_slist_prepend(list, g_strdup(POS_FLAG)); + } else { + list = g_slist_prepend(list, NULL); + } + } + + str = g_string_sized_new(entry->text_alloc); + for (i = 0; i < entry->text_len; i++) { + if (entry->utf8) { + g_string_append_unichar(str, entry->text[i]); + } else if (term_type == TERM_TYPE_BIG5) { + if(entry->text[i] > 0xff) + g_string_append_c(str, (entry->text[i] >> 8) & 0xff); + g_string_append_c(str, entry->text[i] & 0xff); + } else { + g_string_append_c(str, entry->text[i]); + } + if (entry->pos == i+1 || (entry->uses_extents && entry->extents[i+1] != NULL)) { + list = g_slist_prepend(list, g_strdup(str->str)); + g_string_truncate(str, 0); + if (entry->uses_extents && entry->extents[i+1] != NULL) { + if (entry->pos == i+1) { + list = g_slist_prepend(list, g_strconcat(entry->extents[i+1], POS_FLAG, NULL)); + } else { + list = g_slist_prepend(list, g_strdup(entry->extents[i+1])); + } + } else if (entry->pos == i+1) { + list = g_slist_prepend(list, g_strdup(POS_FLAG)); + } + } + } + if (str->len > 0) { + list = g_slist_prepend(list, g_strdup(str->str)); + } + list = g_slist_reverse(list); + g_string_free(str, TRUE); + + return list; +} + +void gui_entry_set_text_and_extents(GUI_ENTRY_REC *entry, GSList *list) +{ + GSList *tmp; + int pos = -1; + int is_extent = 1; + + gui_entry_set_text(entry, ""); + for (tmp = list, is_extent = TRUE; tmp != NULL; tmp = tmp->next, is_extent ^= 1) { + if (is_extent) { + char *extent; + int len; + + if (tmp->data == NULL) + continue; + + extent = g_strdup(tmp->data); + len = strlen(extent); + if (len >= strlen(POS_FLAG) && g_strcmp0(&extent[len-strlen(POS_FLAG)], POS_FLAG) == 0) { + char *tmp; + tmp = extent; + extent = g_strndup(tmp, len - strlen(POS_FLAG)); + g_free(tmp); + pos = entry->pos; + } + + if (strlen(extent) > 0) { + gui_entry_set_extent(entry, entry->pos, extent); + } + g_free(extent); + } else { + gui_entry_insert_text(entry, tmp->data); + } + } + gui_entry_set_pos(entry, pos); +} + +void gui_entry_init(void) +{ +} + +void gui_entry_deinit(void) +{ +} diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 18cc5a4d..dff860d3 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -9,7 +9,7 @@ typedef struct { typedef struct { int text_len, text_alloc; /* as shorts, not chars */ unichar *text; - int *colors; + char **extents; GSList *kill_ring; @@ -27,6 +27,7 @@ typedef struct { unsigned int previous_append_next_kill:1; unsigned int append_next_kill:1; unsigned int yank_preceded:1; + unsigned int uses_extents:1; } GUI_ENTRY_REC; typedef enum { @@ -78,6 +79,14 @@ void gui_entry_move_words(GUI_ENTRY_REC *entry, int count, int to_space); void gui_entry_redraw(GUI_ENTRY_REC *entry); -void gui_entry_set_color(GUI_ENTRY_REC *entry, int pos, int len, int color); +void gui_entry_set_extent(GUI_ENTRY_REC *entry, int pos, const char *text); +void gui_entry_set_extents(GUI_ENTRY_REC *entry, int pos, int len, const char *left, const char *right); +void gui_entry_clear_extents(GUI_ENTRY_REC *entry, int pos, int len); +char *gui_entry_get_extent(GUI_ENTRY_REC *entry, int pos); +GSList *gui_entry_get_text_and_extents(GUI_ENTRY_REC *entry); +void gui_entry_set_text_and_extents(GUI_ENTRY_REC *entry, GSList *list); + +void gui_entry_init(void); +void gui_entry_deinit(void); #endif diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 0288e4f1..f30ce4b8 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -165,6 +165,7 @@ static void textui_finish_init(void) gui_expandos_init(); gui_printtext_init(); gui_readline_init(); + gui_entry_init(); lastlog_init(); mainwindows_init(); mainwindow_activity_init(); @@ -230,6 +231,7 @@ static void textui_deinit(void) lastlog_deinit(); statusbar_deinit(); + gui_entry_deinit(); gui_printtext_deinit(); gui_readline_deinit(); gui_windows_deinit(); diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 02ef6c73..e2f162a0 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -125,12 +125,72 @@ CODE: gui_entry_set_text(active_entry, str); void -gui_input_color(pos, len, color) +gui_input_set_extent(pos, text) + int pos + char *text +PREINIT: + char *tt; +CODE: + tt = text != NULL ? format_string_expand(text, NULL) : NULL; + gui_entry_set_extent(active_entry, pos, tt); + g_free(tt); + +void +gui_input_set_extents(pos, len, left, right) int pos int len - int color + char *left + char *right +PREINIT: + char *tl; + char *tr; CODE: - gui_entry_set_color(active_entry, pos, len, color); + tl = left != NULL ? format_string_expand(left, NULL) : NULL; + tr = right != NULL ? format_string_expand(right, NULL) : NULL; + gui_entry_set_extents(active_entry, pos, len, tl, tr); + g_free(tl); + g_free(tr); + +void +gui_input_clear_extents(pos, len = 0) + int pos + int len +CODE: + gui_entry_clear_extents(active_entry, pos, len); + +void +gui_input_get_extent(pos) + int pos +PREINIT: + char *ret; +PPCODE: + ret = gui_entry_get_extent(active_entry, pos); + XPUSHs(sv_2mortal(new_pv(ret))); + g_free(ret); + +void +gui_input_get_text_and_extents() +PREINIT: + GSList *ret, *tmp; +PPCODE: + ret = gui_entry_get_text_and_extents(active_entry); + for (tmp = ret; tmp != NULL; tmp = tmp->next) { + XPUSHs(sv_2mortal(new_pv(tmp->data))); + } + g_slist_free_full(ret, g_free); + +void +gui_input_set_text_and_extents(...) +PREINIT: + GSList *list; + int i; +PPCODE: + list = NULL; + for (i = items; i > 0; i--) { + list = g_slist_prepend(list, SvPV_nolen(ST(i-1))); + } + gui_entry_set_text_and_extents(active_entry, list); + g_slist_free(list); int gui_input_get_pos() From 2185c4ddb36e1b53548674c2e6ebf95448f2c587 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 3 Feb 2018 23:19:27 +0100 Subject: [PATCH 0324/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index ba5557e6..46d0c45a 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 13 +#define IRSSI_ABI_VERSION 14 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From b33ce255a9df6e951d90f3d3c519b005dacb7010 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 4 Feb 2018 11:18:22 +0100 Subject: [PATCH 0325/1198] check for negative bound --- src/fe-text/mainwindows.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index fd4603da..9cc540fb 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -1263,6 +1263,7 @@ static void cmd_window_shrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); + if (count < -INT_MAX) count = -INT_MAX; mainwindow_grow_int(-count); } @@ -1277,6 +1278,7 @@ static void cmd_window_size(const char *data) size -= WINDOW_MAIN(active_win)->height - WINDOW_MAIN(active_win)->statusbar_lines; + if (size < -INT_MAX) size = -INT_MAX; mainwindow_grow_int(size); } @@ -1460,6 +1462,7 @@ static void cmd_window_rshrink(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); + if (count < -INT_MAX) count = -INT_MAX; window_rgrow_int(-count); } From 1e6d787401b548cf3d5cc57d9a0d0f25f1254bf7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 7 Feb 2018 11:07:22 +0100 Subject: [PATCH 0326/1198] ensure cap_supported is existent yet --- src/common.h | 2 +- src/perl/irc/Irc.xs | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/common.h b/src/common.h index 46d0c45a..746aad4e 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 14 +#define IRSSI_ABI_VERSION 15 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index bb2d27bb..3bf81f9a 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -37,14 +37,16 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server) (void) hv_store(hv, "cap_complete", 12, newSViv(server->cap_complete), 0); (void) hv_store(hv, "sasl_success", 12, newSViv(server->sasl_success), 0); - hv_ = newHV(); - g_hash_table_iter_init(&iter, server->cap_supported); - while (g_hash_table_iter_next(&iter, &key_, &val_)) { - char *key = (char *)key_; - char *val = (char *)val_; - hv_store(hv_, key, strlen(key), new_pv(val), 0); + if (server->cap_supported != NULL) { + hv_ = newHV(); + g_hash_table_iter_init(&iter, server->cap_supported); + while (g_hash_table_iter_next(&iter, &key_, &val_)) { + char *key = (char *)key_; + char *val = (char *)val_; + hv_store(hv_, key, strlen(key), new_pv(val), 0); + } + (void) hv_store(hv, "cap_supported", 13, newRV_noinc((SV*)hv_), 0); } - (void) hv_store(hv, "cap_supported", 13, newRV_noinc((SV*)hv_), 0); av = newAV(); for (tmp = server->cap_active; tmp != NULL; tmp = tmp->next) From e32e9d63c67ab95ef0576154680a6c52334b97af Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 8 Feb 2018 14:11:23 +0100 Subject: [PATCH 0327/1198] Do not read beyond end of escaped string Credit to OSS-Fuzz --- src/fe-common/core/themes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index acb5d1c7..5a817daa 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -485,7 +485,7 @@ static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp str = g_string_new(NULL); p = ret; while (*p != '\0') { - if (*p == '\\') { + if (*p == '\\' && p[1] != '\0') { int chr; p++; chr = expand_escape(&p); From 16912e1a911a503d1ee83ea42dd20c0d5b543e9a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 8 Feb 2018 14:41:02 +0100 Subject: [PATCH 0328/1198] restore compat with glib <2.40 --- 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 dd720841..1a60d99b 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -158,11 +158,12 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add continue; } - if (!g_hash_table_insert(server->cap_supported, key, val)) { + if (g_hash_table_lookup_extended(server->cap_supported, key, NULL, NULL)) { /* The specification doesn't say anything about * duplicated values, let's just warn the user */ g_warning("The server sent the %s capability twice", key); } + g_hash_table_insert(server->cap_supported, key, val); } /* A multiline response is always terminated by a normal one, From 5c5ed64180a6b76315ee7b8c6000ee64ad5877a7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 25 Jan 2018 15:33:24 +0100 Subject: [PATCH 0329/1198] try to make sure the server is still good enough to call ischannel when printing netsplit/join --- src/fe-common/irc/fe-netjoin.c | 19 +++++++++++++------ src/fe-common/irc/fe-netsplit.c | 17 ++++++++++++----- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index a7a2e4fe..9ea633b4 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -245,17 +245,24 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - GSList *tmp, *next; + NETJOIN_SERVER_REC *rec; if (printing_joins) return; - for (tmp = joinservers; tmp != NULL; tmp = next) { - NETJOIN_SERVER_REC *server = tmp->data; + if (!IS_IRC_SERVER(dest->server)) + return; - next = tmp->next; - if (server->netjoins != NULL) - print_netjoins(server, NULL); + rec = netjoin_find_server(IRC_SERVER(dest->server)); + if (rec != NULL && rec->netjoins != NULL) { + /* if netjoins exists, the server rec should be + still valid. otherwise, calling server->ischannel + may not be safe. */ + if (dest->target != NULL && + !server_ischannel((SERVER_REC *) rec->server, dest->target)) + return; + + print_netjoins(rec, NULL); } } diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index edd3fc34..258d0d57 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -247,16 +247,23 @@ static int check_server_splits(IRC_SERVER_REC *server) message before it. */ static void sig_print_starting(TEXT_DEST_REC *dest) { - GSList *tmp; + IRC_SERVER_REC *rec; if (printing_splits) return; - for (tmp = servers; tmp != NULL; tmp = tmp->next) { - IRC_SERVER_REC *rec = tmp->data; + if (!IS_IRC_SERVER(dest->server)) + return; - if (IS_IRC_SERVER(rec) && rec->split_servers != NULL) - print_splits(rec, NULL); + rec = IRC_SERVER(dest->server); + if (rec->split_servers != NULL) { + /* if split_servers exists, the server rec should be + still valid. otherwise, calling server->ischannel + may not be safe. */ + if (dest->target != NULL && !server_ischannel((SERVER_REC *) rec, dest->target)) + return; + + print_splits(rec, NULL); } } From adc812b6b6ed2df2c670586e5308cb767955dddd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Feb 2018 00:03:17 +0100 Subject: [PATCH 0330/1198] add a peculiar bug check to autogen --- autogen.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/autogen.sh b/autogen.sh index 9feb0872..17f60f89 100755 --- a/autogen.sh +++ b/autogen.sh @@ -57,3 +57,11 @@ if test x$NOCONFIGURE = x; then else echo Skipping configure process. fi + +if grep -q '==\|\[\[' "$srcdir"/build-aux/test-driver; then + echo + echo "************************************************************************" + echo "**Warning**: your build is not portable, please do not make dist" + echo " see https://bugzilla.opensuse.org/show_bug.cgi?id=1076146" + echo "************************************************************************" +fi From 3cbcb4fe85ec3233aa36b56a047470df5d4221f3 Mon Sep 17 00:00:00 2001 From: "Staron, Martin" Date: Mon, 12 Feb 2018 12:04:46 +0100 Subject: [PATCH 0331/1198] dcc get shouldn't fail when file attrs can't be changed --- src/irc/dcc/dcc-get.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index cecbb076..ee8b9a49 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -237,8 +237,12 @@ void sig_dccget_connected(GET_DCC_REC *dcc) if (temphandle == -1) ret = -1; - else - ret = fchmod(temphandle, dcc_file_create_mode); + else { + if (fchmod(temphandle, dcc_file_create_mode) != 0) + g_warning("fchmod(3) failed: %s", strerror(errno)); + /* proceed even if chmod fails */ + ret = 0; + } close(temphandle); @@ -249,7 +253,7 @@ void sig_dccget_connected(GET_DCC_REC *dcc) /* Linux */ (errno == EPERM || /* FUSE */ - errno == ENOSYS || + errno == ENOSYS || errno == EACCES || /* BSD */ errno == EOPNOTSUPP)) { /* hard links aren't supported - some people From a6fcd5432e495aea416ebae28d44111eadf19b82 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Feb 2018 12:31:22 +0100 Subject: [PATCH 0332/1198] improve padding performance Credit to Oss-Fuzz --- src/core/special-vars.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/special-vars.c b/src/core/special-vars.c index f254c200..e131b0ed 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -337,11 +337,14 @@ char *get_alignment(const char *text, int align, int flags, char pad) /* add pad characters */ if (flags & ALIGN_PAD) { - while (string_width(str->str, policy) < align) { + int pad_len = align - string_width(str->str, policy); + if (pad_len > 0) { + char *pad_full = g_strnfill(pad_len, pad); if (flags & ALIGN_RIGHT) - g_string_prepend_c(str, pad); + g_string_prepend(str, pad_full); else - g_string_append_c(str, pad); + g_string_append(str, pad_full); + g_free(pad_full); } } From e289d34b9a50b46f57698980e899b71f0069abda Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Feb 2018 15:04:16 +0100 Subject: [PATCH 0333/1198] limit alignment padding to a screenful Credit to Oss-Fuzz --- src/core/special-vars.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/special-vars.c b/src/core/special-vars.c index e131b0ed..33d9cd55 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -33,6 +33,8 @@ #define isarg(c) \ (i_isdigit(c) || (c) == '*' || (c) == '~' || (c) == '-') +#define ALIGN_MAX 222488 + static SPECIAL_HISTORY_FUNC history_func = NULL; static char *get_argument(char **cmd, char **arglist) @@ -300,6 +302,10 @@ static int get_alignment_args(char **data, int *align, int *flags, char *pad) if (!parse_uint(str, &endptr, 10, &align_)) { return FALSE; } + /* alignment larger than supported */ + if (align_ > ALIGN_MAX) { + return FALSE; + } str = endptr; *align = align_; From 5c60e72b118b9efb09639ea26e2a70d06899431f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Feb 2018 00:44:19 +0100 Subject: [PATCH 0334/1198] add additional notes to NEWS (synced back from github releases) --- NEWS | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 4b171852..3a473162 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ v1.2-head 2018-xx-xx The Irssi team v1.1.0 2018-01-15 The Irssi team + ! Warning. Irssi is broken and will crash with OpenSSL < 1.0.2 + due to openssl/openssl commit + 5b4b9ce976fce09a7a92e2f25b91a1635cb840fe * Colour is now re-set when reaching a comma, matching mIRC behaviour (#742, #740, #790) * Irssi now shows the initial nick and name on first start @@ -80,6 +83,9 @@ v1.1.0 2018-01-15 The Irssi team - Fix space issue in glib-2.0.m4 (#621) v1.0.6 2018-01-07 The Irssi team + ! Note: Code and aliases using `$($'-like constructs are no + longer supported due to issue GL#18. Sorry about the + inconvenience. - Fix invalid memory access when reading hilight configuration (#787, #788). - Fix null pointer dereference when the channel topic is set @@ -123,6 +129,7 @@ v1.0.4 2017-07-07 The Irssi team - Minor help update (#729). v1.0.3 2017-06-06 The Irssi team + ! Regression info in 1.0.3: #716 Warnings on start up: invalid time '-1' - Fix out of bounds read when scanning expandos (GL!11). - Fix invalid memory access with quoted filenames in DCC (GL#8, GL!12). @@ -141,6 +148,7 @@ v1.0.3 2017-06-06 The Irssi team - Minor typo correction in help. By Michael Hansen (#707). v1.0.2 2017-03-10 The Irssi team + ! Warning. Irssi is broken on GLib 2.46 (bgo#755496) - Prevent some null-pointer crashes (GL!9). - Fix compilation with OpenSSL 1.1.0 (#628, #597). - Correct dereferencing of already freed server objects during @@ -279,6 +287,8 @@ v0.8.20 2016-09-16 The Irssi team Quarkslab. v0.8.19 2016-03-23 The Irssi team + ! If your cursor keys stopped working, try this first: `/bind + meta-O key meta2' - Fixed regression when joining and parting channels on IRCnet (#435) - Fixed SASL EXTERNAL. By Mantas Mikulėnas (grawity, #432) - Fixed regression when not using SASL (#438) @@ -294,11 +304,15 @@ v0.8.19 2016-03-23 The Irssi team v0.8.18 2016-02-13 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 @@ -311,12 +325,14 @@ v0.8.18 2016-02-13 The Irssi team effect for anyone given that it has been unsupported for several years. + 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). + 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. From 666ddc2ecdd9ad7bc966c78565a5fd9985e099c8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Feb 2018 00:55:30 +0100 Subject: [PATCH 0335/1198] Merge tag '1.0.7' into integrate/1.0.7 --- NEWS | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/NEWS b/NEWS index 4b171852..9ac6883f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,24 @@ v1.2-head 2018-xx-xx The Irssi team +v1.0.7 2018-02-15 The Irssi team + - Prevent use after free error during the execution of some + commands. Found by Joseph Bisch (GL#17, GL!24). + - Revert netsplit print optimisation due to crashes (#465, #809, + #812, #819, #824). + - Fix use after free when SASL messages are received in + unexpected order (GL#26, GL!33). + - Fix null pointer dereference in the tab completion when an + empty nick is joined (GL#24, GL!31). + - Fix use after free when entering oper password (GL#22, + GL!32). + - Fix null pointer dereference when too many windows are + opened (GL#27, #837). + - Fix out of bounds access in theme strings when the last + escape is incomplete. Credit to Oss-Fuzz (#842). + - Fix out of bounds write when using negative counts on window + resize (GL#25, GL#29, #836). + - Minor help correction. By William Jackson (#834). + v1.1.0 2018-01-15 The Irssi team * Colour is now re-set when reaching a comma, matching mIRC behaviour (#742, #740, #790) From 0b9beeb01d4ff3890120ace913884fcd915e4b26 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Feb 2018 01:17:11 +0100 Subject: [PATCH 0336/1198] Merge tag '1.1.1' into integrate/1.1.1 --- NEWS | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 9ac6883f..9d2648f5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ v1.2-head 2018-xx-xx The Irssi team +v1.1.1 2018-02-15 The Irssi team + ! Contains all changes from 1.0.7 + - Restore compatibility with OpenSSL < 1.0.2 (#820, #831) + - Fix test compilation on some platforms (#815, #816) + - Fix portability and backwards compatibility of test runner + (#818, #845) + v1.0.7 2018-02-15 The Irssi team - Prevent use after free error during the execution of some commands. Found by Joseph Bisch (GL#17, GL!24). diff --git a/configure.ac b/configure.ac index e8df7d9e..0231e109 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.1-head) +AC_INIT(irssi, 1.2-head) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 203f6c532947e8b7c7e30fad91220aad083c7f08 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Feb 2018 13:46:29 +0100 Subject: [PATCH 0337/1198] also unblock theme elements when processing finished --- src/fe-common/core/themes.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 5a817daa..e9818be9 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -413,7 +413,7 @@ static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp { GString *str; const char *p, *format; - char *abstract, *data, *ret; + char *abstract, *data, *ret, *blocking; theme_rm_col default_fg, default_bg; int len; @@ -455,8 +455,10 @@ static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp /* unknown abstract, just display the data */ data = "$0-"; g_free(abstract); + blocking = NULL; } else { - g_tree_insert(block_list, abstract, abstract); + blocking = abstract; + g_tree_insert(block_list, blocking, blocking); } abstract = g_strdup(data); @@ -503,6 +505,9 @@ static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp ret = theme_format_expand_data_rec(theme, &p, default_fg, default_bg, last_fg, last_bg, flags | EXPAND_FLAG_LASTCOLOR_ARG, block_list); g_free(abstract); + if (blocking != NULL) { + g_tree_remove(block_list, blocking); + } g_tree_unref(block_list); return ret; } From 097a9f4988333b1d445ba70df006da6ef26bfaa9 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 16 Feb 2018 10:09:48 -0300 Subject: [PATCH 0338/1198] Document second parameter (seek position) of /cat command --- docs/help/in/cat.in | 6 +++++- src/fe-common/core/fe-core-commands.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) 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/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 */ +/* SYNTAX: CAT [] */ static void cmd_cat(const char *data) { char *fname, *fposstr; From 016b42baea9d7dcd2a284f873246c06259c560dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Sun, 4 Jan 2015 01:57:21 +0100 Subject: [PATCH 0339/1198] Add OTR support. This patch adds support for the OTR protocol to irssi. This is an import of the external irssi-otr project that we are now taking over maintership for. Major thanks to the original authors of Irssi-OTR: Uli Meis and David Goulet. Thanks to the OTR community in #OTR on OFTC, thanks to everyone who have helped testing the patches and submitted UI suggestions. --- .travis.yml | 10 +- AUTHORS | 2 + configure.ac | 69 +++ docs/help/in/otr.in | 111 +++++ docs/signals.txt | 6 + m4/libotr.m4 | 134 ++++++ src/Makefile.am | 6 +- src/core/net-nonblock.c | 35 -- src/core/network.c | 33 ++ src/core/network.h | 2 + src/fe-text/Makefile.am | 5 +- src/fe-text/irssi.c | 17 +- src/otr/Makefile.am | 42 ++ src/otr/irssi-otr.h | 39 ++ src/otr/key.c | 402 +++++++++++++++++ src/otr/key.h | 35 ++ src/otr/module.c | 261 +++++++++++ src/otr/module.h | 29 ++ src/otr/otr-fe.c | 344 +++++++++++++++ src/otr/otr-fe.h | 28 ++ src/otr/otr-formats.c | 108 +++++ src/otr/otr-formats.h | 112 +++++ src/otr/otr-ops.c | 362 ++++++++++++++++ src/otr/otr.c | 941 ++++++++++++++++++++++++++++++++++++++++ src/otr/otr.h | 170 ++++++++ 25 files changed, 3262 insertions(+), 41 deletions(-) create mode 100644 docs/help/in/otr.in create mode 100644 m4/libotr.m4 create mode 100644 src/otr/Makefile.am create mode 100644 src/otr/irssi-otr.h create mode 100644 src/otr/key.c create mode 100644 src/otr/key.h create mode 100644 src/otr/module.c create mode 100644 src/otr/module.h create mode 100644 src/otr/otr-fe.c create mode 100644 src/otr/otr-fe.h create mode 100644 src/otr/otr-formats.c create mode 100644 src/otr/otr-formats.h create mode 100644 src/otr/otr-ops.c create mode 100644 src/otr/otr.c create mode 100644 src/otr/otr.h diff --git a/.travis.yml b/.travis.yml index e2b3f57c..a17cb3ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,17 +27,23 @@ addons: packages: - libperl-dev - elinks + - libgcrypt11-dev before_install: - perl -V - - ./autogen.sh --with-proxy --with-bot --with-perl=module + - wget https://otr.cypherpunks.ca/libotr-4.1.1.tar.gz + - tar zxf libotr-*.tar.gz + - cd libotr-* + - ./configure --prefix $HOME/otr-prefix && make && make install + - cd .. + - ./autogen.sh --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-prefix/lib --with-libotr-inc-prefix=$HOME/otr-prefix/include - make dist - cd .. - tar xaf */irssi-*.tar.* - cd irssi-* install: - - ./configure --with-proxy --with-bot --with-perl=module --prefix=$HOME/irssi-build + - ./configure --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-prefix/lib --with-libotr-inc-prefix=$HOME/otr-prefix/include --prefix=$HOME/irssi-build $( $UNITTESTS && echo --enable-always-build-tests ) - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - make install diff --git a/AUTHORS b/AUTHORS index c1280552..db5ad2de 100644 --- a/AUTHORS +++ b/AUTHORS @@ -27,6 +27,8 @@ Large feature patches by: Heikki Orsila : DCC SEND queueing Mark Trumbull : DCC SERVER Francesco Fracassi : Passive DCC + Uli Meis : OTR support + David Goulet : OTR support Other patches (grep for "patch" in ChangeLog) by: diff --git a/configure.ac b/configure.ac index 0231e109..6cba4fb3 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,21 @@ AC_ARG_WITH(perl, fi, want_perl=static) +AC_ARG_WITH(otr, +[ --with-otr[=yes|no|module] Build with OTR support - also specifies + if it should be built into the main irssi + binary or as a module (default)], + if test x$withval = xyes; then + want_otr=module + elif test x$withval = xstatic; then + want_otr=static + elif test x$withval = xmodule; then + want_otr=module + else + want_otr=no + fi, + want_otr=no) + AC_ARG_ENABLE(true-color, [ --enable-true-color Build with true color support in terminal], if test x$enableval = xno ; then @@ -527,6 +542,48 @@ if test "x$want_capsicum" = "xyes"; then ]) fi +dnl ** +dnl ** OTR checks +dnl ** + +have_otr=no +if test "x$want_otr" != "xno"; then + AM_PATH_LIBGCRYPT(1:1.2.0, [], [AC_ERROR(libgcrypt 1.2.0 or newer is required.)]) + AM_PATH_LIBOTR(4.1.0, [], [AC_ERROR([libotr 4.1.0 or newer is required.])]) + + OTR_CFLAGS="$LIBOTR_CFLAGS $LIBGCRYPT_CFLAGS" + OTR_LDFLAGS="$LIBOTR_LIBS $LIBGCRYPT_LIBS" + + AC_SUBST(otr_module_lib) + AC_SUBST(otr_static_lib) + + if test "x$want_otr" != "xno"; then + if test "x$want_otr" = "xstatic"; then + otr_module_lib= + otr_static_lib=libotr_core_static.la + + OTR_LINK_LIBS="../otr/libotr_core_static.la" + OTR_LINK_FLAGS="$OTR_LDFLAGS" + + AC_DEFINE(HAVE_STATIC_OTR) + else + otr_module_lib=libotr_core.la + otr_static_lib= + fi + fi + + AC_SUBST(otr_module_lib) + AC_SUBST(otr_static_lib) + + AC_SUBST(OTR_CFLAGS) + AC_SUBST(OTR_LDFLAGS) + + AC_SUBST(OTR_LINK_LIBS) + AC_SUBST(OTR_LINK_FLAGS) + + have_otr=yes +fi + dnl ** check what we want to build AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes") AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes") @@ -535,6 +592,7 @@ AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes") AM_CONDITIONAL(HAVE_PERL, test "$want_perl" != "no") AM_CONDITIONAL(HAVE_CAPSICUM, test "x$want_capsicum" = "xyes") AM_CONDITIONAL(USE_GREGEX, test "x$want_gregex" = "xyes") +AM_CONDITIONAL(HAVE_OTR, test "x$have_otr" != "xno") # move LIBS to PROG_LIBS so they're not tried to be used when linking eg. perl libraries PROG_LIBS=$LIBS @@ -629,6 +687,7 @@ fi AH_TEMPLATE(HAVE_GMODULE) AH_TEMPLATE(HAVE_SOCKS_H, [misc..]) AH_TEMPLATE(HAVE_STATIC_PERL) +AH_TEMPLATE(HAVE_STATIC_OTR) AH_TEMPLATE(PRIuUOFF_T, [printf()-format for uoff_t, eg. "u" or "lu" or "llu"]) AH_TEMPLATE(UOFF_T_INT, [What type should be used for uoff_t]) AH_TEMPLATE(UOFF_T_LONG) @@ -662,6 +721,7 @@ src/perl/common/Makefile.PL src/perl/irc/Makefile.PL src/perl/ui/Makefile.PL src/perl/textui/Makefile.PL +src/otr/Makefile scripts/Makefile scripts/examples/Makefile tests/Makefile @@ -755,5 +815,14 @@ echo "Building with true color support.. : $want_truecolor" echo "Building with GRegex ............. : $want_gregex" echo "Building with Capsicum ........... : $want_capsicum" +if test "x$want_otr" = "xstatic"; then + echo "Building with OTR support ........ : static (in irssi binary)" +elif test "x$want_otr" = "xmodule"; then + echo "Building with OTR support ........ : module" +else + echo "Building with OTR support ........ : no" +fi + + echo echo "If there are any problems, read the INSTALL file." diff --git a/docs/help/in/otr.in b/docs/help/in/otr.in new file mode 100644 index 00000000..c31bd8e8 --- /dev/null +++ b/docs/help/in/otr.in @@ -0,0 +1,111 @@ + +OTR %|[OPTION] + +Command to control the OTR module. Without an option, this help is printed. + +This help contains three sections which are %9options, quickstart and files.%n + +To add the OTR status bar (highly recommended): + +%9/statusbar window add otr%n + +%9Options:%n + +AUTH + Start or respond to an authentication process. + +AUTHQ + Start a SMP authentication process. + + Example: %9/otr authq "My question is" "this is the secret"%n + +AUTHABORT + Abort an ongoing authentication process. + +CONTEXTS + List known contexts which basically list the known fingerprints and their + state. + +DEBUG + Turn on debugging. + +DISTRUST + Distrust a specific fingerprint. This command can be done inside a private + window for which the current fingerprint of the other person will be used + or else set fp to a human readable OTR fingerprint available with the above + contexts command. + + Examples: %9/otr distrust 487FFADA 5073FEDD C5AB5C14 5BB6C1FF 6D40D48A%n + +FINISH + End the OTR session. This MUST be done inside a private conversation + window. + +FORGET + Forget a specific fingerprint (deleted from the known fingerprints). The + behavior is the same as the distrust command explained above. + +GENKEY + Generate OTR keys for a given account name. This is done automatically + if someone tries to establish a secure session. + + This process is done in a background worker and can take an arbitrary + amount of time. The completion is checked when another irssi event is + catched. + +HELP + Print this help. + +INFO + Display the OTR fingerprint(s) of all your account(s). + +INIT + Initialize an OTR conversation within a private conversation window. + +TRUST + Trust a specific fingerprint. The behavior is the same as the forget and + distrust commands explained above. + +VERSION + Print the version of the OTR module. + +%9Quickstart:%n + +Start a private conversation with the person you want to initiate a secure +session. Once in the private message window: + +%9/otr init%n + +Key generation should start if no key is found for your account name. Once the +process is done, either type a message which should automatically start the +session or redo the init command. + +Time to authenticate the person. Either use a shared secret exchange through +phone or GPG-signed email or use the socialist millionaire problem mechanism +(SMP) which is basically to ask a question for which the answer can only be +known by the other person. + +%9/otr auth %n OR %9/otr authq "A question" %n + +Or to respond to an authentication: + +%9/otr auth %n + +%9Files:%n + +This otr modules creates a directory in %9$HOME/.irssi/otr%n and creates three +files: + +* %9otr.key%n + Contains your OTR private key(s). NEVER shared this directory with someone + else unless you know what you are doing. + +* %9otr.fp%n + The known fingerprints with their _trust_ status. + +* %9otr.instag + Instance tag of the libotr. This should NEVER be copied to an other + computer. If unsure, just ignore this file. + +For more information on OTR, see https://otr.cypherpunks.ca/ + diff --git a/docs/signals.txt b/docs/signals.txt index 7776dad7..84d4518f 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -350,3 +350,9 @@ Perl ---- "script error", PERL_SCRIPT_REC, char *errormsg + +OTR Core +-------- + +otr.c: + "otr event", SERVER_REC, char *nick, char *status diff --git a/m4/libotr.m4 b/m4/libotr.m4 new file mode 100644 index 00000000..80b25f86 --- /dev/null +++ b/m4/libotr.m4 @@ -0,0 +1,134 @@ +dnl +dnl Off-the-Record Messaging library +dnl Copyright (C) 2004-2007 Ian Goldberg, Chris Alexander, Nikita Borisov +dnl +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of version 2.1 of the GNU Lesser General +dnl Public License as published by the Free Software Foundation. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +dnl + +dnl AM_PATH_LIBOTR([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for libotr, and define LIBOTR_CFLAGS and LIBOTR_LIBS as appropriate. +dnl enables arguments --with-libotr-prefix= +dnl --with-libotr-inc-prefix= +dnl +dnl You must already have found libgcrypt with AM_PATH_LIBGCRYPT +dnl +dnl Adapted from alsa.m4, originally by +dnl Richard Boulton +dnl Christopher Lansdown +dnl Jaroslav Kysela + +AC_DEFUN([AM_PATH_LIBOTR], +[dnl Save the original CFLAGS, LDFLAGS, and LIBS +libotr_save_CFLAGS="$CFLAGS" +libotr_save_LDFLAGS="$LDFLAGS" +libotr_save_LIBS="$LIBS" +libotr_found=yes + +dnl +dnl Get the cflags and libraries for libotr +dnl +AC_ARG_WITH(libotr-prefix, +[ --with-libotr-prefix=PFX Prefix where libotr is installed(optional)], +[libotr_prefix="$withval"], [libotr_prefix=""]) + +AC_ARG_WITH(libotr-inc-prefix, +[ --with-libotr-inc-prefix=PFX Prefix where libotr includes are (optional)], +[libotr_inc_prefix="$withval"], [libotr_inc_prefix=""]) + +dnl Add any special include directories +AC_MSG_CHECKING(for libotr CFLAGS) +if test "$libotr_inc_prefix" != "" ; then + LIBOTR_CFLAGS="$LIBOTR_CFLAGS -I$libotr_inc_prefix" + CFLAGS="$CFLAGS $LIBOTR_CFLAGS" +fi +AC_MSG_RESULT($LIBOTR_CFLAGS) + +dnl add any special lib dirs +AC_MSG_CHECKING(for libotr LIBS) +if test "$libotr_prefix" != "" ; then + LIBOTR_LIBS="$LIBOTR_LIBS -L$libotr_prefix" + LDFLAGS="$LDFLAGS $LIBOTR_LIBS" +fi + +dnl add the libotr library +LIBOTR_LIBS="$LIBOTR_LIBS -lotr" +LIBS="$LIBOTR_LIBS $LIBS" +AC_MSG_RESULT($LIBOTR_LIBS) + +dnl Check for a working version of libotr that is of the right version. +min_libotr_version=ifelse([$1], ,3.0.0,$1) +no_libotr="" + libotr_min_major_version=`echo $min_libotr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + libotr_min_minor_version=`echo $min_libotr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + libotr_min_sub_version=`echo $min_libotr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` +AC_MSG_CHECKING(for libotr headers version $libotr_min_major_version.x >= $min_libotr_version) + +AC_LANG_SAVE +AC_LANG_C +AC_TRY_COMPILE([ +#include +#include +], [ +# if(OTRL_VERSION_MAJOR != $libotr_min_major_version) +# error not present +# else + +# if(OTRL_VERSION_MINOR > $libotr_min_minor_version) + exit(0); +# else +# if(OTRL_VERSION_MINOR < $libotr_min_minor_version) +# error not present +# endif + +# if(OTRL_VERSION_SUB < $libotr_min_sub_version) +# error not present +# endif +# endif +# endif +exit(0); +], + [AC_MSG_RESULT(found.)], + [AC_MSG_RESULT(not present.) + ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libotr not found.)]) + libotr_found=no] +) +AC_LANG_RESTORE + +dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. +AC_CHECK_LIB([otr], [otrl_message_receiving],, + [ifelse([$3], , [AC_MSG_ERROR(No linkable libotr was found.)]) + libotr_found=no], + $LIBGCRYPT_LIBS +) + +LDFLAGS="$libotr_save_LDFLAGS" +LIBS="$libotr_save_LIBS" + +if test "x$libotr_found" = "xyes" ; then + ifelse([$2], , :, [$2]) +else + LIBOTR_CFLAGS="" + LIBOTR_LIBS="" + ifelse([$3], , :, [$3]) +fi + +dnl That should be it. Now just export our symbols: +AC_SUBST(LIBOTR_CFLAGS) +AC_SUBST(LIBOTR_LIBS) +]) + diff --git a/src/Makefile.am b/src/Makefile.am index a7fb2ee2..48cdc3eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,8 +14,12 @@ if HAVE_PERL PERLDIR=perl endif +if HAVE_OTR +OTRDIR=otr +endif + pkginc_srcdir=$(pkgincludedir)/src pkginc_src_HEADERS = \ common.h -SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(TEXTUI) $(BOTUI) $(FUZZERUI) +SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(OTRDIR) $(TEXTUI) $(BOTUI) $(FUZZERUI) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index d6e767b6..94c53e74 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -35,41 +35,6 @@ typedef struct { int tag; } SIMPLE_THREAD_REC; -static int g_io_channel_write_block(GIOChannel *channel, void *data, int len) -{ - gsize ret; - int sent; - GIOStatus status; - - sent = 0; - do { - status = g_io_channel_write_chars(channel, (char *) data + sent, - len-sent, &ret, NULL); - sent += ret; - } while (sent < len && status != G_IO_STATUS_ERROR); - - return sent < len ? -1 : 0; -} - -static int g_io_channel_read_block(GIOChannel *channel, void *data, int len) -{ - time_t maxwait; - gsize ret; - int received; - GIOStatus status; - - maxwait = time(NULL)+2; - received = 0; - do { - status = g_io_channel_read_chars(channel, (char *) data + received, - len-received, &ret, NULL); - received += ret; - } while (received < len && time(NULL) < maxwait && - status != G_IO_STATUS_ERROR && status != G_IO_STATUS_EOF); - - return received < len ? -1 : 0; -} - /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, diff --git a/src/core/network.c b/src/core/network.c index d280b463..0e326e22 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -48,6 +48,39 @@ GIOChannel *g_io_channel_new(int handle) return chan; } +int g_io_channel_write_block(GIOChannel *channel, void *data, int len) +{ + gsize ret; + int sent; + GIOStatus status; + + sent = 0; + do { + status = g_io_channel_write_chars(channel, (char *) data + sent, len - sent, &ret, NULL); + sent += ret; + } while (sent < len && status != G_IO_STATUS_ERROR); + + return sent < len ? -1 : 0; +} + +int g_io_channel_read_block(GIOChannel *channel, void *data, int len) +{ + time_t maxwait; + gsize ret; + int received; + GIOStatus status; + + maxwait = time(NULL)+2; + received = 0; + do { + status = g_io_channel_read_chars(channel, (char *) data + received, len - received, &ret, NULL); + received += ret; + } while (received < len && time(NULL) < maxwait && + status != G_IO_STATUS_ERROR && status != G_IO_STATUS_EOF); + + return received < len ? -1 : 0; +} + IPADDR ip4_any = { AF_INET, #if defined(IN6ADDR_ANY_INIT) diff --git a/src/core/network.h b/src/core/network.h index e60f607f..30fd6aab 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -36,6 +36,8 @@ GIOChannel *g_io_channel_new(int handle); /* Returns 1 if IPADDRs are the same. */ /* Deprecated since it is unused. It will be deleted in a later release. */ int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED; +int g_io_channel_write_block(GIOChannel *channel, void *data, int len); +int g_io_channel_read_block(GIOChannel *channel, void *data, int len); int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index bdd3df22..6ce8427c 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -9,7 +9,8 @@ AM_CPPFLAGS = \ irssi_DEPENDENCIES = \ @COMMON_LIBS@ \ @PERL_LINK_LIBS@ \ - @PERL_FE_LINK_LIBS@ + @PERL_FE_LINK_LIBS@ \ + @OTR_LINK_LIBS@ irssi_LDFLAGS = -export-dynamic @@ -17,6 +18,8 @@ irssi_LDADD = \ @COMMON_LIBS@ \ @PERL_LINK_LIBS@ \ @PERL_FE_LINK_LIBS@ \ + @OTR_LINK_LIBS@ \ + @OTR_LINK_FLAGS@ \ @PERL_LINK_FLAGS@ \ @PROG_LIBS@ \ @TEXTUI_LIBS@ diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index f30ce4b8..728f456e 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -54,6 +54,11 @@ void fe_perl_init(void); void fe_perl_deinit(void); #endif +#ifdef HAVE_STATIC_OTR +void otr_core_init(void); +void otr_core_deinit(void); +#endif + void irc_init(void); void irc_deinit(void); @@ -183,6 +188,10 @@ static void textui_finish_init(void) fe_perl_init(); #endif +#ifdef HAVE_STATIC_OTR + otr_core_init(); +#endif + dirty_check(); fe_common_core_finish_init(); @@ -221,8 +230,12 @@ static void textui_deinit(void) module_unload(modules->data); #ifdef HAVE_STATIC_PERL - perl_core_deinit(); - fe_perl_deinit(); + perl_core_deinit(); + fe_perl_deinit(); +#endif + +#ifdef HAVE_STATIC_OTR + otr_core_deinit(); #endif dirty_check(); /* one last time to print any quit messages */ diff --git a/src/otr/Makefile.am b/src/otr/Makefile.am new file mode 100644 index 00000000..3b991839 --- /dev/null +++ b/src/otr/Makefile.am @@ -0,0 +1,42 @@ +moduledir = $(libdir)/irssi/modules + +module_LTLIBRARIES = $(otr_module_lib) +noinst_LTLIBRARIES = $(otr_static_lib) + +EXTRA_LTLIBRARIES = \ + libotr_core.la \ + libotr_core_static.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core/ \ + -I$(top_srcdir)/src/irc/core/ \ + -I$(top_srcdir)/src/fe-common/core/ \ + -I$(top_srcdir)/src/fe-text/ \ + $(GLIB_CFLAGS) \ + $(OTR_CFLAGS) + +libotr_core_la_LDFLAGS = -module -avoid-version -rpath $(moduledir) +libotr_core_la_LIBADD = $(OTR_LDFLAGS) + +otr_sources = \ + key.c \ + module.c \ + otr-formats.c \ + otr-ops.c \ + otr-fe.c \ + otr.c + +libotr_core_la_SOURCES = \ + $(otr_sources) + +libotr_core_static_la_SOURCES = \ + $(otr_sources) + +noinst_HEADERS = \ + irssi-otr.h \ + key.h \ + module.h \ + otr-formats.h \ + otr-fe.h \ + otr.h diff --git a/src/otr/irssi-otr.h b/src/otr/irssi-otr.h new file mode 100644 index 00000000..718e1e66 --- /dev/null +++ b/src/otr/irssi-otr.h @@ -0,0 +1,39 @@ +/* + * Off-the-Record Messaging (OTR) module for the irssi IRC client + * + * Copyright (C) 2008 - Uli Meis + * 2012 - David Goulet + * + * 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 + */ + +#ifndef IRSSI_IRSSI_OTR_H +#define IRSSI_IRSSI_OTR_H + +/* Ease our life a bit. */ +#define OTR_IRSSI_MSG_PREFIX "%9OTR%9: " + +/* + * Irssi macros for printing text to console. + */ +#define IRSSI_OTR_DEBUG(fmt, ...) \ + do { \ + if (otr_debug_get()) { \ + printtext(NULL, NULL, MSGLEVEL_MSGS, OTR_IRSSI_MSG_PREFIX fmt, \ + ## __VA_ARGS__); \ + } \ + } while (0) + +#endif /* IRSSI_IRSSI_OTR_H */ diff --git a/src/otr/key.c b/src/otr/key.c new file mode 100644 index 00000000..4032b0b2 --- /dev/null +++ b/src/otr/key.c @@ -0,0 +1,402 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) 2008 - Uli Meis + * 2012 - David Goulet + * + * 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 + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "key.h" + +#include "levels.h" +#include "network.h" +#include "pidwait.h" +#include "printtext.h" + +#include "irssi-otr.h" +#include "otr-formats.h" + +/* + * Status of key generation. + */ +enum key_gen_status { + KEY_GEN_IDLE = 0, + KEY_GEN_RUNNING = 1, + KEY_GEN_FINISHED = 2, + KEY_GEN_ERROR = 3, +}; + +/* + * Data of the state of key generation. + */ +struct key_gen_data { + struct otr_user_state *ustate; + char *account_name; + char *key_file_path; + enum key_gen_status status; + gcry_error_t gcry_error; +}; + +/* + * Event from the key generation process. + */ +struct key_gen_event { + enum key_gen_status status; + gcry_error_t error; +}; + +/* + * Key generation process. + */ +struct key_gen_worker { + int tag; + GIOChannel *pipes[2]; +}; + +/* + * Key generation data for the thread in charge of creating the key. + */ +static struct key_gen_data key_gen_state = { + .status = KEY_GEN_IDLE, + .gcry_error = GPG_ERR_NO_ERROR, +}; + +/* + * Build file path concatenate to the irssi config dir. + */ +static char *file_path_build(const char *path) +{ + g_return_val_if_fail(path != NULL, NULL); + + /* Either NULL or the filename is returned here which is valid. */ + return g_strdup_printf("%s/%s", get_irssi_dir(), path); +} + +/* + * Emit a key generation status event. + */ +static void emit_event(GIOChannel *pipe, enum key_gen_status status, gcry_error_t error) +{ + struct key_gen_event event; + + g_return_if_fail(pipe != NULL); + + event.status = status; + event.error = error; + + g_io_channel_write_block(pipe, &event, sizeof(event)); +} + +/* + * Reset key generation state and status is IDLE. + */ +static void reset_key_gen_state(void) +{ + /* Safety. */ + g_free(key_gen_state.key_file_path); + g_free(key_gen_state.account_name); + + /* Nullify everything. */ + memset(&key_gen_state, 0, sizeof(key_gen_state)); + key_gen_state.status = KEY_GEN_IDLE; + key_gen_state.gcry_error = GPG_ERR_NO_ERROR; +} + +/* + * Read status event from key generation worker. + */ +static void read_key_gen_status(struct key_gen_worker *worker, GIOChannel *pipe) +{ + struct key_gen_event event; + gcry_error_t err; + + g_return_if_fail(worker != NULL); + + fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); + + if (g_io_channel_read_block(pipe, &event, sizeof(event)) == -1) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + g_strerror(errno)); + return; + } + + key_gen_state.status = event.status; + key_gen_state.gcry_error = event.error; + + if (event.status == KEY_GEN_FINISHED || event.status == KEY_GEN_ERROR) { + /* Worker is done. */ + g_source_remove(worker->tag); + + g_io_channel_shutdown(worker->pipes[0], TRUE, NULL); + g_io_channel_unref(worker->pipes[0]); + + g_io_channel_shutdown(worker->pipes[1], TRUE, NULL); + g_io_channel_unref(worker->pipes[1]); + + g_free(worker); + + if (event.status == KEY_GEN_ERROR) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + gcry_strerror(key_gen_state.gcry_error)); + reset_key_gen_state(); + return; + } + + err = otrl_privkey_read(key_gen_state.ustate->otr_state, key_gen_state.key_file_path); + + if (err != GPG_ERR_NO_ERROR) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + gcry_strerror(key_gen_state.gcry_error)); + } else { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, + TXT_OTR_KEYGEN_COMPLETED, + key_gen_state.account_name); + } + + reset_key_gen_state(); + } +} + +/* + * Run key generation in a seperate process (takes ages). The other process + * will rewrite the key file, we shouldn't change anything till it's done and + * we've reloaded the keys. + */ +void key_gen_run(struct otr_user_state *ustate, const char *account_name) +{ + struct key_gen_worker *worker; + int fd[2]; + gcry_error_t err; + pid_t pid; + + g_return_if_fail(ustate != NULL); + g_return_if_fail(account_name != NULL); + + if (key_gen_state.status != KEY_GEN_IDLE) { + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_OTR_KEYGEN_RUNNING, key_gen_state.account_name); + return; + } + + /* Make sure the pointer does not go away during the proess. */ + key_gen_state.account_name = strdup(account_name); + key_gen_state.ustate = ustate; + + /* Creating key file path. */ + key_gen_state.key_file_path = file_path_build(OTR_KEYFILE); + if (key_gen_state.key_file_path == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + g_strerror(errno)); + reset_key_gen_state(); + return; + } + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_OTR_KEYGEN_STARTED, key_gen_state.account_name); + + if (pipe(fd) != 0) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + g_strerror(errno)); + reset_key_gen_state(); + return; + } + + worker = g_new0(struct key_gen_worker, 1); + + if (worker == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_OTR_KEYGEN_FAILED, + key_gen_state.account_name, + g_strerror(errno)); + reset_key_gen_state(); + return; + } + + worker->pipes[0] = g_io_channel_new(fd[0]); + worker->pipes[1] = g_io_channel_new(fd[1]); + + pid = fork(); + + if (pid > 0) { + /* Parent process */ + pidwait_add(pid); + worker->tag = g_input_add(worker->pipes[0], G_INPUT_READ, (GInputFunction)read_key_gen_status, worker); + return; + } + + if (pid != 0) { + /* error */ + g_warning("Key generation failed: %s", g_strerror(errno)); + + g_source_remove(worker->tag); + + g_io_channel_shutdown(worker->pipes[0], TRUE, NULL); + g_io_channel_unref(worker->pipes[0]); + + g_io_channel_shutdown(worker->pipes[1], TRUE, NULL); + g_io_channel_unref(worker->pipes[1]); + + g_free(worker); + + return; + } + + /* Child process */ + key_gen_state.status = KEY_GEN_RUNNING; + emit_event(worker->pipes[1], KEY_GEN_RUNNING, GPG_ERR_NO_ERROR); + + err = otrl_privkey_generate(key_gen_state.ustate->otr_state, key_gen_state.key_file_path, key_gen_state.account_name, OTR_PROTOCOL_ID); + + if (err != GPG_ERR_NO_ERROR) { + emit_event(worker->pipes[1], KEY_GEN_ERROR, err); + _exit(99); + return; + } + + emit_event(worker->pipes[1], KEY_GEN_FINISHED, GPG_ERR_NO_ERROR); + + _exit(99); +} + +/* + * Write fingerprints to file. + */ +void key_write_fingerprints(struct otr_user_state *ustate) +{ + gcry_error_t err; + char *filename; + + g_return_if_fail(ustate != NULL); + + filename = file_path_build(OTR_FINGERPRINTS_FILE); + g_return_if_fail(filename != NULL); + + err = otrl_privkey_write_fingerprints(ustate->otr_state, filename); + if (err == GPG_ERR_NO_ERROR) { + IRSSI_OTR_DEBUG("Fingerprints saved to %9%s%9", filename); + } else { + IRSSI_OTR_DEBUG("Error writing fingerprints: %d (%d)", + gcry_strerror(err), gcry_strsource(err)); + } + + g_free(filename); +} + +/* + * Write instance tags to file. + */ +void key_write_instags(struct otr_user_state *ustate) +{ + gcry_error_t err; + char *filename; + + g_return_if_fail(ustate != NULL); + + filename = file_path_build(OTR_INSTAG_FILE); + g_return_if_fail(filename != NULL); + + err = otrl_instag_write(ustate->otr_state, filename); + if (err == GPG_ERR_NO_ERROR) { + IRSSI_OTR_DEBUG("Instance tags saved in %9%s%9", filename); + } else { + IRSSI_OTR_DEBUG("Error saving instance tags: %d (%d)", + gcry_strerror(err), gcry_strsource(err)); + } + + g_free(filename); +} + +/* + * Load private keys. + */ +void key_load(struct otr_user_state *ustate) +{ + int ret; + gcry_error_t err; + char *filename; + + g_return_if_fail(ustate != NULL); + + filename = file_path_build(OTR_KEYFILE); + g_return_if_fail(filename != NULL); + + ret = access(filename, F_OK); + if (ret < 0) { + IRSSI_OTR_DEBUG("No private keys found in %9%s%9", filename); + g_free(filename); + return; + } + + err = otrl_privkey_read(ustate->otr_state, filename); + if (err == GPG_ERR_NO_ERROR) { + IRSSI_OTR_DEBUG("Private keys loaded from %9%s%9", filename); + } else { + IRSSI_OTR_DEBUG("Error loading private keys: %d (%d)", + gcry_strerror(err), gcry_strsource(err)); + } + + g_free(filename); +} + +/* + * Load fingerprints. + */ +void key_load_fingerprints(struct otr_user_state *ustate) +{ + int ret; + gcry_error_t err; + char *filename; + + g_return_if_fail(ustate != NULL); + + filename = file_path_build(OTR_FINGERPRINTS_FILE); + g_return_if_fail(filename != NULL); + + ret = access(filename, F_OK); + if (ret < 0) { + IRSSI_OTR_DEBUG("No fingerprints found in %9%s%9", filename); + g_free(filename); + return; + } + + err = otrl_privkey_read_fingerprints(ustate->otr_state, filename, NULL, + NULL); + if (err == GPG_ERR_NO_ERROR) { + IRSSI_OTR_DEBUG("Fingerprints loaded from %9%s%9", filename); + } else { + IRSSI_OTR_DEBUG("Error loading fingerprints: %d (%d)", + gcry_strerror(err), gcry_strsource(err)); + } + + g_free(filename); +} diff --git a/src/otr/key.h b/src/otr/key.h new file mode 100644 index 00000000..259a8e67 --- /dev/null +++ b/src/otr/key.h @@ -0,0 +1,35 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) 2012 - David Goulet + * + * 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 + */ + +#ifndef IRSSI_OTR_KEY_H +#define IRSSI_OTR_KEY_H + +#include "common.h" +#include "servers.h" + +#include "otr.h" + +void key_gen_run(struct otr_user_state *ustate, const char *account_name); +void key_load(struct otr_user_state *ustate); +void key_load_fingerprints(struct otr_user_state *ustate); +void key_write_fingerprints(struct otr_user_state *ustate); +void key_write_instags(struct otr_user_state *ustate); + +#endif /* IRSSI_OTR_KEY_H */ diff --git a/src/otr/module.c b/src/otr/module.c new file mode 100644 index 00000000..ca3107b1 --- /dev/null +++ b/src/otr/module.c @@ -0,0 +1,261 @@ +/* + * Off-the-Record Messaging (OTR) module for the irssi IRC client + * + * Copyright (C) 2008 Uli Meis + * 2012 David Goulet + * + * 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 + */ + +#define _GNU_SOURCE +#include + +#include "module.h" + +#include "signals.h" +#include "queries.h" +#include "commands.h" + +#include "irc.h" +#include "irc-servers.h" +#include "irc-queries.h" +#include "irc-commands.h" + +#include "key.h" +#include "otr.h" +#include "otr-formats.h" +#include "otr-fe.h" +#include "misc.h" + +/* + * Global state for the user. Init when the module loads. + */ +struct otr_user_state *user_state_global; + +/* + * Pipes all outgoing private messages through OTR + */ +static void sig_server_sendmsg(SERVER_REC *server, const char *target, + const char *msg, void *target_type_p) +{ + char *otrmsg = NULL; + + if (GPOINTER_TO_INT(target_type_p) != SEND_TARGET_NICK) { + otrl_message_free(otrmsg); + return; + } + + /* Critical section. On error, message MUST NOT be sent */ + if (otr_send(server, msg, target, &otrmsg)) { + signal_stop(); + otrl_message_free(otrmsg); + return; + } + + if (otrmsg == NULL) { + /* Send original message */ + signal_continue(4, server, target, msg, target_type_p); + } else { + /* Send encrypted message */ + signal_continue(4, server, target, otrmsg, target_type_p); + } + + otrl_message_free(otrmsg); +} + +/* + * Pipes all incoming private messages through OTR + */ +void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address) +{ + char *new_msg = NULL; + + if (otr_receive(server, msg, nick, &new_msg)) { + signal_stop(); + otrl_message_free(new_msg); + return; + } + + if (new_msg == NULL) { + /* This message was not OTR */ + signal_continue(4, server, msg, nick, address); + } else { + /* + * Check for /me IRC marker and if so, handle it so the user does not + * receive a message beginning with /me but rather let irssi handle it + * as a IRC action. + */ + if (strncmp(new_msg, OTR_IRC_MARKER_ME, OTR_IRC_MARKER_ME_LEN) == 0) { + signal_stop(); + signal_emit("message irc action", 5, server, new_msg + OTR_IRC_MARKER_ME_LEN, nick, address, nick); + } else { + /* OTR received message */ + signal_continue(4, server, new_msg, nick, address); + } + } + + otrl_message_free(new_msg); +} + +/* + * Finish an OTR conversation when its query is closed. + */ +static void sig_query_destroyed(QUERY_REC *query) +{ + if (query && query->server && query->server->connrec) { + otr_finish(query->server, query->name); + } +} + +/* + * Handle /me IRC command. + */ +static void cmd_me(const char *data, IRC_SERVER_REC *server, + WI_ITEM_REC *item) +{ + const char *target; + char *msg, *otrmsg = NULL; + QUERY_REC *query; + + query = QUERY(item); + + if (query == NULL || query->server == NULL) { + return; + } + + CMD_IRC_SERVER(server); + if (!IS_IRC_QUERY(query)) { + return; + } + + if (server == NULL || !server->connected) { + cmd_return_error(CMDERR_NOT_CONNECTED); + } + + target = window_item_get_target(item); + + msg = g_strdup_printf(OTR_IRC_MARKER_ME "%s", data); + g_return_if_fail(msg != NULL); + + /* Critical section. On error, message MUST NOT be sent */ + otr_send(query->server, msg, target, &otrmsg); + g_free(msg); + + if (otrmsg == NULL) { + return; + } + + signal_stop(); + + if (otrmsg) { + /* Send encrypted message */ + otr_send_message(SERVER(server), target, otrmsg); + otrl_message_free(otrmsg); + } + + signal_emit("message irc own_action", 3, server, data, item->visible_name); +} + +/* + * Optionally finish conversations on /quit. We're already doing this on unload + * but the quit handler terminates irc connections before unloading. + */ +static void cmd_quit(const char *data, void *server, WI_ITEM_REC *item) +{ + otr_finishall(user_state_global); +} + +/* + * Create otr module directory if none exists. + */ +static void create_module_dir(void) +{ + char *dir_path = NULL; + struct stat statbuf; + + /* Create ~/.irssi/otr directory. */ + dir_path = g_strdup_printf("%s/%s", get_irssi_dir(), OTR_DIR); + g_return_if_fail(dir_path != NULL); + + if (stat(dir_path, &statbuf) != 0) { + if (g_mkdir_with_parents(dir_path, 0700) != 0) + g_warning("Unable to create OTR directory path."); + } else if (!S_ISDIR(statbuf.st_mode)) { + g_warning("%s is not a directory.", dir_path); + g_warning("You should remove it with command: rm %s", dir_path); + } + + g_free(dir_path); +} + +void otr_send_message(SERVER_REC *server, const char *recipient, const char *msg) +{ + /* + * Apparently, there are cases where the server record is NULL which has + * been reported with the irssi xmpp plugin. In that case, just return an + * do nothing. + */ + g_return_if_fail(server != NULL); + + server->send_message(server, recipient, msg, GPOINTER_TO_INT(SEND_TARGET_NICK)); +} + +/* + * irssi init() + */ +void otr_core_init(void) +{ + module_register("otr", "core"); + + create_module_dir(); + + otr_lib_init(); + + user_state_global = otr_init_user_state(); + g_return_if_fail(user_state_global != NULL); + + signal_add_first("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); + signal_add_first("message private", (SIGNAL_FUNC) sig_message_private); + signal_add("query destroyed", (SIGNAL_FUNC) sig_query_destroyed); + + command_bind_first("quit", NULL, (SIGNAL_FUNC) cmd_quit); + command_bind_irc_first("me", NULL, (SIGNAL_FUNC) cmd_me); + + otr_fe_init(); +} + +/* + * irssi deinit() + */ +void otr_core_deinit(void) +{ + signal_remove("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); + signal_remove("message private", (SIGNAL_FUNC) sig_message_private); + signal_remove("query destroyed", (SIGNAL_FUNC) sig_query_destroyed); + + otr_fe_deinit(); + + command_unbind("quit", (SIGNAL_FUNC) cmd_quit); + command_unbind("me", (SIGNAL_FUNC) cmd_me); + + otr_finishall(user_state_global); + + /* Remove glib timer if any. */ + otr_control_timer(0, NULL); + + otr_free_user_state(user_state_global); + + otr_lib_uninit(); +} diff --git a/src/otr/module.h b/src/otr/module.h new file mode 100644 index 00000000..fdfc77bd --- /dev/null +++ b/src/otr/module.h @@ -0,0 +1,29 @@ +/* + * Off-the-Record Messaging (OTR) module for the irssi IRC client + * + * Copyright (C) 2012 - David Goulet + * + * 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 + */ + +#ifndef IRSSI_OTR_MODULE +#define IRSSI_OTR_MODULE + +#include "common.h" +#include "servers.h" + +void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address); + +#endif /* IRSSI_OTR_MODULE */ diff --git a/src/otr/otr-fe.c b/src/otr/otr-fe.c new file mode 100644 index 00000000..13e37576 --- /dev/null +++ b/src/otr/otr-fe.c @@ -0,0 +1,344 @@ +/* + * Off-the-Record Messaging (OTR) module for the irssi IRC client + * + * Copyright (C) 2008 Uli Meis + * 2012 David Goulet + * 2014 Alexander Færøy + * + * 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 "levels.h" +#include "printtext.h" +#include "commands.h" +#include "irc.h" +#include "irc-servers.h" +#include "irc-queries.h" +#include "statusbar-item.h" + +#include "otr.h" +#include "otr-formats.h" +#include "key.h" + +static void cmd_otr(const char *data, SERVER_REC *server, void *item) +{ + if (*data == '\0') + data = "info"; // FIXME(ahf): Is this really what we want as default? + + command_runsub("otr", data, server, item); + + // We always redraw the OTR statusbar, just in case. + statusbar_items_redraw("otr"); +} + +static void cmd_otr_debug(const char *data) +{ + otr_debug_toggle(); + + if (otr_debug_get()) + printtext(NULL, NULL, MSGLEVEL_CRAP, "OTR debugging enabled"); + else + printtext(NULL, NULL, MSGLEVEL_CRAP, "OTR debugging disabled"); +} + +static void cmd_otr_init(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + ConnContext *ctx; + + g_return_if_fail(server != NULL); + + if (!server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (!IS_QUERY(item)) + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + query = QUERY(item); + target = query->name; + + ctx = otr_find_context(server, target, FALSE); + if (ctx && ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) { + printformat(server, target, MSGLEVEL_CRAP, TXT_OTR_SESSION_ALREADY_SECURED, ctx->accountname); + return; + } + + printformat(server, target, MSGLEVEL_CRAP, TXT_OTR_SESSION_INITIATING); + + /* + * Irssi does not handle well the HTML tag in the default OTR query message + * so just send the OTR tag instead. Contact me for a better fix! :) + */ + otr_send_message(server, target, "?OTRv23?"); +} + +static void cmd_otr_finish(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + g_return_if_fail(server != NULL); + + if (!server->connected) + cmd_return_error(CMDERR_NOT_CONNECTED); + + if (!IS_QUERY(item)) + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + query = QUERY(item); + target = query->name; + + otr_finish(server, target); +} + +static void cmd_otr_trust(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + char *fingerprint, *human_fingerprint; + void *free_arg; + + g_return_if_fail(server != NULL); + + query = QUERY(item); + target = query ? query->name : NULL; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint)) + return; + + // We fallback to target if fingerprint isn't specified. + if (*fingerprint == '\0' && target == NULL) + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + human_fingerprint = g_ascii_strup(fingerprint, -1); + otr_trust(server, target, human_fingerprint, user_state_global); + g_free(human_fingerprint); + + cmd_params_free(free_arg); +} + +static void cmd_otr_distrust(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + char *fingerprint, *human_fingerprint; + void *free_arg; + + g_return_if_fail(server != NULL); + + query = QUERY(item); + target = query ? query->name : NULL; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint)) + return; + + // We fallback to target if fingerprint isn't specified. + if (*fingerprint == '\0' && target == NULL) + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + human_fingerprint = g_ascii_strup(fingerprint, -1); + otr_distrust(server, target, human_fingerprint, user_state_global); + g_free(human_fingerprint); + + cmd_params_free(free_arg); +} + +static void cmd_otr_forget(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + char *fingerprint, *human_fingerprint; + void *free_arg; + + g_return_if_fail(server != NULL); + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint)) + return; + + query = QUERY(item); + target = query ? query->name : NULL; + + // We fallback to target if fingerprint isn't specified. + if (*fingerprint == '\0' && target == NULL) + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + human_fingerprint = g_ascii_strup(fingerprint, -1); + otr_forget(server, target, human_fingerprint, user_state_global); + g_free(human_fingerprint); + + cmd_params_free(free_arg); +} + +static void cmd_otr_authabort(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + query = QUERY(item); + target = query ? query->name : NULL; + + if (server == NULL || target == NULL) + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + + otr_auth_abort(server, target); +} + +static void cmd_otr_auth(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + char *secret; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 1, &secret)) + return; + + query = QUERY(item); + target = query ? query->name : NULL; + + if (server == NULL || target == NULL || *secret == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + if (*secret == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + otr_auth(server, target, NULL, secret); + + cmd_params_free(free_arg); +} + +static void cmd_otr_authq(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + QUERY_REC *query; + char *target; + + char *question, *secret; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 2, &question, &secret)) + return; + + query = QUERY(item); + target = query ? query->name : NULL; + + if (server == NULL || target == NULL || *question == '\0' || *secret == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + otr_auth(server, target, question, secret); + + cmd_params_free(free_arg); +} + +static void cmd_otr_genkey(const char *data) +{ + char *account_name; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 1, &account_name)) + return; + + if (*account_name == '\0') + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + + key_gen_run(user_state_global, account_name); + + cmd_params_free(free_arg); +} + +static void cmd_otr_contexts(const char *data) +{ + otr_contexts(user_state_global); +} + +static void cmd_otr_info(const char *data) +{ + gboolean empty = TRUE; + char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + OtrlPrivKey *key; + + for (key = user_state_global->otr_state->privkey_root; key != NULL; key = key->next) { + otrl_privkey_fingerprint(user_state_global->otr_state, ownfp, key->accountname, OTR_PROTOCOL_ID); + + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_OTR_FP_NICK, key->accountname, ownfp); + + empty = FALSE; + } + + if (empty) + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_OTR_KEYS_UNAVAILABLE); +} + +static void statusbar_otr(struct SBAR_ITEM_REC *item, int get_size_only) +{ + WI_ITEM_REC *wi_item = active_win->active; + QUERY_REC *query = QUERY(wi_item); + enum otr_status_format format = TXT_OTR_MODULE_NAME; + + if (query && query->server && query->server->connrec) { + format = otr_get_status_format(query->server, query->name); + } + + statusbar_item_default_handler(item, get_size_only, + format ? fe_otr_formats[format].def : "", " ", FALSE); +} + +void otr_fe_init(void) +{ + theme_register(fe_otr_formats); + + command_bind("otr", NULL, (SIGNAL_FUNC) cmd_otr); + command_bind("otr debug", NULL, (SIGNAL_FUNC) cmd_otr_debug); + command_bind("otr init", NULL, (SIGNAL_FUNC) cmd_otr_init); + command_bind("otr finish", NULL, (SIGNAL_FUNC) cmd_otr_finish); + command_bind("otr trust", NULL, (SIGNAL_FUNC) cmd_otr_trust); + command_bind("otr distrust", NULL, (SIGNAL_FUNC) cmd_otr_distrust); + command_bind("otr forget", NULL, (SIGNAL_FUNC) cmd_otr_forget); + command_bind("otr authabort", NULL, (SIGNAL_FUNC) cmd_otr_authabort); + command_bind("otr auth", NULL, (SIGNAL_FUNC) cmd_otr_auth); + command_bind("otr authq", NULL, (SIGNAL_FUNC) cmd_otr_authq); + command_bind("otr genkey", NULL, (SIGNAL_FUNC) cmd_otr_genkey); + command_bind("otr contexts", NULL, (SIGNAL_FUNC) cmd_otr_contexts); + command_bind("otr info", NULL, (SIGNAL_FUNC) cmd_otr_info); + + statusbar_item_register("otr", NULL, statusbar_otr); + statusbar_items_redraw("window"); +} + +void otr_fe_deinit(void) +{ + theme_unregister(); + + command_unbind("otr", (SIGNAL_FUNC) cmd_otr); + command_unbind("otr debug", (SIGNAL_FUNC) cmd_otr_debug); + command_unbind("otr init", (SIGNAL_FUNC) cmd_otr_init); + command_unbind("otr finish", (SIGNAL_FUNC) cmd_otr_finish); + command_unbind("otr trust", (SIGNAL_FUNC) cmd_otr_trust); + command_unbind("otr distrust", (SIGNAL_FUNC) cmd_otr_distrust); + command_unbind("otr forget", (SIGNAL_FUNC) cmd_otr_forget); + command_unbind("otr authabort", (SIGNAL_FUNC) cmd_otr_authabort); + command_unbind("otr auth", (SIGNAL_FUNC) cmd_otr_auth); + command_unbind("otr authq", (SIGNAL_FUNC) cmd_otr_authq); + command_unbind("otr genkey", (SIGNAL_FUNC) cmd_otr_genkey); + command_unbind("otr contexts", (SIGNAL_FUNC) cmd_otr_contexts); + command_unbind("otr info", (SIGNAL_FUNC) cmd_otr_info); + + statusbar_item_unregister("otr"); +} diff --git a/src/otr/otr-fe.h b/src/otr/otr-fe.h new file mode 100644 index 00000000..c9aaebb3 --- /dev/null +++ b/src/otr/otr-fe.h @@ -0,0 +1,28 @@ +/* + * Off-the-Record Messaging (OTR) module for the irssi IRC client + * + * Copyright (C) 2008 Uli Meis + * 2012 David Goulet + * + * 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 + */ + +#ifndef IRSSI_OTR_FE_H +#define IRSSI_OTR_FE_H + +void otr_fe_init(void); +void otr_fe_deinit(void); + +#endif diff --git a/src/otr/otr-formats.c b/src/otr/otr-formats.c new file mode 100644 index 00000000..e430b6b5 --- /dev/null +++ b/src/otr/otr-formats.c @@ -0,0 +1,108 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) - 2012 David Goulet + * 2014 Alexander Færøy + * + * 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 "otr.h" +#include "otr-formats.h" + +FORMAT_REC fe_otr_formats[] = { + { MODULE_NAME, "Core", 0 }, + + /* Status bar format. */ + { NULL, "OTR Statusbar", 0 }, + + { "otr_stb_plaintext", "{sb plaintext}", 0}, + { "otr_stb_finished", "{sb %yfinished%n}", 0}, + { "otr_stb_unknown", "{sb {hilight state unknown (BUG!)}}", 0}, + { "otr_stb_untrusted", "{sb %GOTR%n (%runverified%n)}", 0}, + { "otr_stb_trust", "{sb %GOTR%n}", 0}, + + /* OTR format. */ + { NULL, "OTR", 0 }, + + { "otr_auth_aborted", "Authentication aborted", 0}, + { "otr_auth_initiated", "Initiated authentication", 0}, + { "otr_auth_ongoing_aborted", "Ongoing authentication aborted", 0}, + { "otr_auth_response", "Responding to authentication", 0}, + + { "otr_ctx_list_header", "{hilight Contexts}", 0}, + { "otr_ctx_list_encrypted_line", "{hilight $0} - {hilight $1} (Encrypted)", 2, { 0, 0 }}, + { "otr_ctx_list_finished_line", "{hilight $0} - {hilight $1} (Finished)", 2, { 0, 0 }}, + { "otr_ctx_list_manual_line", " {hilight $0} (Manual)", 1, { 0, 0 }}, + { "otr_ctx_list_plaintext_line", "{hilight $0} - {hilight $1} (Plaintext)", 2, { 0, 0 }}, + { "otr_ctx_list_smp_line", " {hilight $0} (SMP)", 1, { 0, 0 }}, + { "otr_ctx_list_unknown_line", "{hilight $0} - {hilight $1} (Unknown)", 2, { 0, 0 }}, + { "otr_ctx_list_unused_line", "{hilight $0} - {hilight $1} (Unused)", 2, { 0, 0 }}, + { "otr_ctx_list_unverified_line", " {hilight $0} (Unverified)", 1, { 0, 0 }}, + { "otr_ctx_list_footer", "", 0}, + { "otr_ctx_missing", "{error No active OTR contexts found}", 0}, + { "otr_ctx_nick_missing", "{error Context for {hilight $0} not found}", 1, { 1 }}, + + { "otr_fp_already_distrusted", "{error Already distrusting: {hilight $0}", 1, { 0 }}, + { "otr_fp_already_trusted", "{error Already trusting: {hilight $0}", 1, { 0 }}, + { "otr_fp_ctx_encrypted", "Fingerprint context is still encrypted. Finish the OTR session before forgetting a fingerprint", 0}, + { "otr_fp_distrusted", "Distrusting {hilight $0}", 1, { 0 }}, + { "otr_fp_forgotten", "Fingerprint {hilight $0} forgotten", 1, { 0 }}, + { "otr_fp_info", "OTR key fingerprint: {hilight $1} for {hilight $0}", 2, { 0, 0 }}, + { "otr_fp_missing", "{error Fingerprint {hilight $0} not found", 1, { 0 }}, + { "otr_fp_nick", "Fingerprint for {hilight $0}: {hilight $1}", 2, { 0, 0 }}, + { "otr_fp_trusted", "Trusting {hilight $0}", 1, { 0 }}, + + { "otr_keygen_completed", "OTR key generation for {hilight $0} completed", 1, { 0 }}, + { "otr_keygen_failed", "OTR key generation for {hilight $0} failed: {error $1}", 2, { 0, 0 }}, + { "otr_keygen_running", "OTR key generation for {hilight $0} is still in progress", 1, { 0 }}, + { "otr_keygen_started", "OTR key generation for {hilight $0} started", 1, { 0 }}, + + { "otr_keys_unavailable", "{error No OTR keys available}", 0}, + + { "otr_msg_encryption_ended", "{hilight $0} has closed the connection to you", 1, { 0 }}, + { "otr_msg_encryption_error", "{error An error occured when encrypting your message}", 0}, + { "otr_msg_encryption_required", "Encryptioned is required", 0}, + { "otr_msg_error", "Error in private conversation: {error $0}", 1, { 0 }}, + { "otr_msg_general_error", "General Error: {error $0}", 1, { 0 }}, + { "otr_msg_malformed", "Malformed message from {hilight $0}", 1, { 0 }}, + { "otr_msg_not_in_private", "The encrypted message from {hilight $0} was is unreadable because you're not communicating privately", 1, { 0 }}, + { "otr_msg_reflected", "Received reflected message from {hilight $0}", 0, { 0 }}, + { "otr_msg_resent", "The last message to {hilight $0} was resent: $1", 2, { 0, 0 }}, + { "otr_msg_unencrypted", "The following message from {hilight $0} was {error not} encrypted", 1, { 0 }}, + { "otr_msg_unreadable", "Unreadable encrypted message from {hilight $0}", 1, { 0 }}, + { "otr_msg_unrecognized", "Unrecognized OTR message from {hilight $0}", 1, { 0 }}, + + { "otr_session_already_finished", "Nothing to do", 0}, + { "otr_session_already_secured", "Secure session with {hilight $0} already established", 1, { 0 }}, + { "otr_session_finished", "{hilight $0} has finished the OTR session. Use /otr init to restart or /otr finish to finish.", 1, { 0 }}, + { "otr_session_finishing", "Finished conversation with {hilight $0}", 1, { 0 }}, + { "otr_session_initiating", "Initiating OTR session ...", 0}, + { "otr_session_insecure", "Session insecured", 0}, + { "otr_session_missing", "{error No OTR session available}", 0}, + { "otr_session_secure", "Session secured", 0}, + { "otr_session_unauthenticated_warning", "Your peer is not authenticated", 0}, + + { "otr_smp_answer_footer", "Use /otr auth to complete", 0}, + { "otr_smp_answer_header", "{hilight $0} wants to authenticate and asked:", 1, { 0 }}, + { "otr_smp_answer_question", "Question: {hilight $0}", 1, { 0 }}, + { "otr_smp_failure", "Authentication with {hilight $0} failed", 1, { 0 }}, + { "otr_smp_in_progress", "{hilight $0} replied to your auth request", 1, { 0 }}, + { "otr_smp_secret_question", "{hilight $0} wants to authenticate. Use /otr auth to complete", 1, { 0 }}, + { "otr_smp_success", "Authentication with {hilight $0} succesful", 1, { 0 }}, + + /* Last element. */ + { NULL, NULL, 0 } +}; diff --git a/src/otr/otr-formats.h b/src/otr/otr-formats.h new file mode 100644 index 00000000..454b2f6c --- /dev/null +++ b/src/otr/otr-formats.h @@ -0,0 +1,112 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) - 2012 David Goulet + * 2014 Alexander Færøy + * + * 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 + */ + +#ifndef IRSSI_OTR_FORMATS_H +#define IRSSI_OTR_FORMATS_H + +#include "formats.h" + +/* + * Must be in sync with the fe_otr_formats array. + */ +enum otr_status_format { + TXT_OTR_MODULE_NAME, + + /* Status bar format. */ + TXT_OTR_FILL_1, + TXT_OTR_STB_PLAINTEXT, + TXT_OTR_STB_FINISHED, + TXT_OTR_STB_UNKNOWN, + TXT_OTR_STB_UNTRUSTED, + TXT_OTR_STB_TRUST, + + /* OTR format. */ + TXT_OTR_FILL_2, + TXT_OTR_AUTH_ABORTED, + TXT_OTR_AUTH_INITIATED, + TXT_OTR_AUTH_ONGOING_ABORTED, + TXT_OTR_AUTH_RESPONSE, + + TXT_OTR_CTX_LIST_HEADER, + TXT_OTR_CTX_LIST_ENCRYPTED_LINE, + TXT_OTR_CTX_LIST_FINISHED_LINE, + TXT_OTR_CTX_LIST_MANUAL_LINE, + TXT_OTR_CTX_LIST_PLAINTEXT_LINE, + TXT_OTR_CTX_LIST_SMP_LINE, + TXT_OTR_CTX_LIST_UNKNOWN_LINE, + TXT_OTR_CTX_LIST_UNUSED_LINE, + TXT_OTR_CTX_LIST_UNVERIFIED_LINE, + TXT_OTR_CTX_LIST_FOOTER, + TXT_OTR_CTX_MISSING, + TXT_OTR_CTX_NICK_MISSING, + + TXT_OTR_FP_ALREADY_DISTRUSED, + TXT_OTR_FP_ALREADY_TRUSTED, + TXT_OTR_FP_CTX_ENCRYPTED, + TXT_OTR_FP_DISTRUSTED, + TXT_OTR_FP_FORGOTTEN, + TXT_OTR_FP_INFO, + TXT_OTR_FP_MISSING, + TXT_OTR_FP_NICK, + TXT_OTR_FP_TRUSTED, + + TXT_OTR_KEYGEN_COMPLETED, + TXT_OTR_KEYGEN_FAILED, + TXT_OTR_KEYGEN_RUNNING, + TXT_OTR_KEYGEN_STARTED, + + TXT_OTR_KEYS_UNAVAILABLE, + + TXT_OTR_MSG_ENCRYPTION_ENDED, + TXT_OTR_MSG_ENCRYPTION_ERROR, + TXT_OTR_MSG_ENCRYPTION_REQUIRED, + TXT_OTR_MSG_ERROR, + TXT_OTR_MSG_GENERAL_ERROR, + TXT_OTR_MSG_MALFORMED, + TXT_OTR_MSG_NOT_IN_PRIVATE, + TXT_OTR_MSG_REFLECTED, + TXT_OTR_MSG_RESENT, + TXT_OTR_MSG_UNENCRYPTED, + TXT_OTR_MSG_UNREADABLE, + TXT_OTR_MSG_UNRECOGNIZED, + + TXT_OTR_SESSION_ALREADY_FINISHED, + TXT_OTR_SESSION_ALREADY_SECURED, + TXT_OTR_SESSION_FINISHED, + TXT_OTR_SESSION_FINISHING, + TXT_OTR_SESSION_INITIATING, + TXT_OTR_SESSION_INSECURE, + TXT_OTR_SESSION_MISSING, + TXT_OTR_SESSION_SECURE, + TXT_OTR_SESSION_UNAUTHENTICATED_WARNING, + + TXT_OTR_SMP_ANSWER_FOOTER, + TXT_OTR_SMP_ANSWER_HEADER, + TXT_OTR_SMP_ANSWER_QUESTION, + TXT_OTR_SMP_FAILURE, + TXT_OTR_SMP_IN_PROGRESS, + TXT_OTR_SMP_SECRET_QUESTION, + TXT_OTR_SMP_SUCCESS +}; + +extern FORMAT_REC fe_otr_formats[]; + +#endif /* IRSSI_OTR_FORMATS_H */ diff --git a/src/otr/otr-ops.c b/src/otr/otr-ops.c new file mode 100644 index 00000000..9359e63e --- /dev/null +++ b/src/otr/otr-ops.c @@ -0,0 +1,362 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * Copyright (C) 2008 Uli Meis + * + * 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 "signals.h" +#include "levels.h" +#include "printtext.h" +#include "fe-windows.h" + +#include "key.h" +#include "module.h" +#include "otr-formats.h" +#include "irssi-otr.h" + +static OtrlPolicy OTR_DEFAULT_POLICY = OTRL_POLICY_MANUAL | OTRL_POLICY_WHITESPACE_START_AKE; + +/* + * Return default policy for now. + */ +static OtrlPolicy ops_policy(void *opdata, ConnContext *context) +{ + return OTR_DEFAULT_POLICY; +} + +/* + * Request for key generation. + * + * The lib actually expects us to be finished before the call returns. Since + * this can take more than an hour on some systems there isn't even a point in + * trying... + */ +static void ops_create_privkey(void *opdata, const char *accountname, + const char *protocol) +{ + key_gen_run(user_state_global, accountname); +} + +/* + * Inject OTR message. + */ +static void ops_inject_msg(void *opdata, const char *accountname, + const char *protocol, const char *recipient, const char *message) +{ + SERVER_REC *server = opdata; + + IRSSI_OTR_DEBUG("Inject msg:\n[%s]", message); + otr_send_message(server, recipient, message); +} + +/* + * Gone secure. + */ +static void ops_secure(void *opdata, ConnContext *context) +{ + char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + SERVER_REC *server = opdata; + struct otr_peer_context *opc; + + g_return_if_fail(context != NULL); + /* This should *really* not happened */ + g_return_if_fail(context->msgstate == OTRL_MSGSTATE_ENCRYPTED); + + printformat(server, context->username, MSGLEVEL_CLIENTCRAP, TXT_OTR_SESSION_SECURE); + otr_status_change(server, context->username, OTR_STATUS_GONE_SECURE); + + opc = context->app_data; + opc->active_fingerprint = context->active_fingerprint; + + if (otrl_context_is_fingerprint_trusted(context->active_fingerprint)) { + /* Secure and trusted */ + return; + } + + /* Not authenticated. Let's print out the fingerprints for comparison. */ + otrl_privkey_hash_to_human(peerfp, context->active_fingerprint->fingerprint); + otrl_privkey_fingerprint(user_state_global->otr_state, ownfp, context->accountname, OTR_PROTOCOL_ID); + + printformat(server, context->username, MSGLEVEL_CLIENTCRAP, TXT_OTR_SESSION_UNAUTHENTICATED_WARNING); + printformat(server, context->username, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_INFO, server->nick, ownfp); + printformat(server, context->username, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_INFO, context->username, peerfp); +} + +/* + * Gone insecure. + */ +static void ops_insecure(void *opdata, ConnContext *context) +{ + SERVER_REC *server = opdata; + + printformat(server, context->username, MSGLEVEL_CLIENTCRAP, TXT_OTR_SESSION_INSECURE); + otr_status_change(server, context->username, OTR_STATUS_GONE_INSECURE); +} + +/* + * Really critical with IRC. Unfortunately, we can't tell our peer which size + * to use. + */ +static int ops_max_msg(void *opdata, ConnContext *context) +{ + return OTR_MAX_MSG_SIZE; +} + +static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event, ConnContext *context, const char *message, gcry_error_t err) +{ + SERVER_REC *server = opdata; + char *username = context->username; + + switch (msg_event) { + case OTRL_MSGEVENT_NONE: + break; + case OTRL_MSGEVENT_ENCRYPTION_REQUIRED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_ENCRYPTION_REQUIRED); + break; + case OTRL_MSGEVENT_ENCRYPTION_ERROR: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_ENCRYPTION_ERROR); + break; + case OTRL_MSGEVENT_CONNECTION_ENDED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_ENCRYPTION_ENDED, username); + break; + case OTRL_MSGEVENT_SETUP_ERROR: + if (!err) { + err = GPG_ERR_INV_VALUE; + } + switch (err) { + case GPG_ERR_INV_VALUE: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_MALFORMED, username); + break; + default: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_ERROR, gcry_strerror(err)); + break; + } + break; + case OTRL_MSGEVENT_MSG_REFLECTED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_REFLECTED, username); + break; + case OTRL_MSGEVENT_MSG_RESENT: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_RESENT, username, message); + break; + case OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_NOT_IN_PRIVATE, username); + break; + case OTRL_MSGEVENT_RCVDMSG_UNREADABLE: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_UNREADABLE, username); + break; + case OTRL_MSGEVENT_RCVDMSG_MALFORMED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_MALFORMED, username); + break; + case OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD: + IRSSI_OTR_DEBUG("Heartbeat received from %s.", username); + break; + case OTRL_MSGEVENT_LOG_HEARTBEAT_SENT: + IRSSI_OTR_DEBUG("Heartbeat sent to %s.", username); + break; + case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_ERROR, message); + break; + case OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_UNENCRYPTED, username); + + /* + * This is a hack I found to send the message in a private window of + * the username without creating an infinite loop since the 'message + * private' signal is hijacked in this module. If someone is able to + * clean this up with a more elegant solution, by all means PLEASE + * submit a patch or email me a better way. + */ + signal_remove("message private", (SIGNAL_FUNC) sig_message_private); + signal_emit("message private", 4, server, message, username, server->connrec->address); + signal_add_first("message private", (SIGNAL_FUNC) sig_message_private); + break; + case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED: + printformat(server, username, MSGLEVEL_CLIENTERROR, TXT_OTR_MSG_UNRECOGNIZED, username); + break; + case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE: + IRSSI_OTR_DEBUG("%s has sent a message for a different instance.", username); + break; + } +} + +/* + * A context changed. + */ +static void ops_up_ctx_list(void *opdata) +{ + otr_status_change(opdata, NULL, OTR_STATUS_CTX_UPDATE); +} + +/* + * Save fingerprint changes. + */ +static void ops_write_fingerprints(void *data) +{ + key_write_fingerprints(user_state_global); +} + +static int ops_is_logged_in(void *opdata, const char *accountname, const char *protocol, const char *recipient) +{ + int ret; + SERVER_REC *server = opdata; + + /* Logged in? */ + ret = server != NULL; + + IRSSI_OTR_DEBUG("User %s %s logged in", accountname, ret ? "" : "not"); + + return ret; +} + +static void ops_create_instag(void *opdata, const char *accountname, + const char *protocol) +{ + otrl_instag_generate(user_state_global->otr_state, "/dev/null", accountname, protocol); + key_write_instags(user_state_global); +} + +static void ops_smp_event(void *opdata, OtrlSMPEvent smp_event, + ConnContext *context, unsigned short progress_percent, char *question) +{ + SERVER_REC *server = opdata; + const char *from = context->username; + struct otr_peer_context *opc = context->app_data; + + /* + * Without a peer context, we can't update the status bar. Code flow error + * if none is found. This context is created automatically by an otrl_* + * call or if non existent when returned from + * otrl_message_sending/receiving. + */ + g_return_if_fail(opc != NULL); + + opc->smp_event = smp_event; + + switch (smp_event) { + case OTRL_SMPEVENT_ASK_FOR_SECRET: + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_SECRET_QUESTION, from); + opc->ask_secret = 1; + otr_status_change(server, from, OTR_STATUS_SMP_INCOMING); + break; + case OTRL_SMPEVENT_ASK_FOR_ANSWER: + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_ANSWER_HEADER, from); + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_ANSWER_QUESTION, question); + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_ANSWER_FOOTER); + opc->ask_secret = 1; + otr_status_change(server, from, OTR_STATUS_SMP_INCOMING); + break; + case OTRL_SMPEVENT_IN_PROGRESS: + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_IN_PROGRESS, from); + otr_status_change(server, from, OTR_STATUS_SMP_FINALIZE); + break; + case OTRL_SMPEVENT_SUCCESS: + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SMP_SUCCESS, from); + otr_status_change(server, from, OTR_STATUS_SMP_SUCCESS); + break; + case OTRL_SMPEVENT_ABORT: + otr_auth_abort(server, context->username); + otr_status_change(server, from, OTR_STATUS_SMP_ABORTED); + break; + case OTRL_SMPEVENT_FAILURE: + case OTRL_SMPEVENT_CHEATED: + case OTRL_SMPEVENT_ERROR: + printformat(server, from, MSGLEVEL_CLIENTERROR, TXT_OTR_SMP_FAILURE, from); + otr_status_change(server, from, OTR_STATUS_SMP_FAILED); + break; + default: + g_warning("Received unknown SMP event: %d", smp_event); + break; + } +} + +/* + * timer_control callback. + */ +static void ops_timer_control(void *opdata, unsigned int interval) +{ + otr_control_timer(interval, opdata); +} + +/* + * Handle otr error message. + */ +static const char *ops_otr_error_message(void *opdata, ConnContext *context, + OtrlErrorCode code) +{ + char *msg = NULL; + + switch (code) { + case OTRL_ERRCODE_NONE: + break; + case OTRL_ERRCODE_ENCRYPTION_ERROR: + msg = strdup("Error occurred encrypting message."); + break; + case OTRL_ERRCODE_MSG_NOT_IN_PRIVATE: + if (context) { + msg = strdup("You sent encrypted data which was unexpected"); + } + break; + case OTRL_ERRCODE_MSG_UNREADABLE: + msg = strdup("You transmitted an unreadable encrypted message"); + break; + case OTRL_ERRCODE_MSG_MALFORMED: + msg = strdup("You transmitted a malformed data message."); + break; + } + + return msg; +} + +/* + * Free otr error message callback. + */ +static void ops_otr_error_message_free(void *opdata, const char *err_msg) +{ + g_free_not_null((char *)err_msg); +} + +/* + * Assign OTR message operations. + */ +OtrlMessageAppOps otr_ops = { + ops_policy, + ops_create_privkey, + ops_is_logged_in, + ops_inject_msg, + ops_up_ctx_list, + NULL, /* new_fingerprint */ + ops_write_fingerprints, + ops_secure, + ops_insecure, + NULL, /* still_secure */ + ops_max_msg, + NULL, /* account_name */ + NULL, /* account_name_free */ + NULL, /* received_symkey */ + ops_otr_error_message, + ops_otr_error_message_free, + NULL, /* resent_msg_prefix */ + NULL, /* resent_msg_prefix_free */ + ops_smp_event, + ops_handle_msg_event, + ops_create_instag, + NULL, /* convert_msg */ + NULL, /* convert_free */ + ops_timer_control, +}; diff --git a/src/otr/otr.c b/src/otr/otr.c new file mode 100644 index 00000000..765bc048 --- /dev/null +++ b/src/otr/otr.c @@ -0,0 +1,941 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) 2008 - Uli Meis + * 2012 - David Goulet + * + * 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 + */ + +#define _GNU_SOURCE +#include +#include +#include + +#include "common.h" +#include "levels.h" +#include "signals.h" +#include "printtext.h" +#include "statusbar-item.h" + +#include "irssi-otr.h" +#include "otr-formats.h" +#include "key.h" + +static int otr_debug = 0; + +static const char *statusbar_txt[] = { + "FINISHED", + "TRUST_MANUAL", + "TRUST_SMP", + "SMP_ABORT", + "SMP_STARTED", + "SMP_RESPONDED", + "SMP_INCOMING", + "SMP_FINALIZE", + "SMP_ABORTED", + "PEER_FINISHED", + "SMP_FAILED", + "SMP_SUCCESS", + "GONE_SECURE", + "GONE_INSECURE", + "CTX_UPDATE" +}; + +/* Glib timer for otr. */ +static guint otr_timerid; + +/* + * Load instance tags. + */ +static void instag_load(struct otr_user_state *ustate) +{ + int ret; + char *filename; + gcry_error_t err; + + g_return_if_fail(ustate != NULL); + + /* Getting the otr instance filename path */ + filename = g_strdup_printf("%s%s", get_irssi_dir(), OTR_INSTAG_FILE); + g_return_if_fail(filename != NULL); + + ret = access(filename, F_OK); + if (ret < 0) { + IRSSI_OTR_DEBUG("no instance tags found at %9%s%9", filename); + g_free(filename); + return; + } + + err = otrl_instag_read(ustate->otr_state, filename); + if (err == GPG_ERR_NO_ERROR) + IRSSI_OTR_DEBUG("Instance tags loaded from %9%s%9", filename); + else + IRSSI_OTR_DEBUG("Error loading instance tags: %d (%d)", gcry_strerror(err), gcry_strsource(err)); + + g_free(filename); +} + +/* + * Free otr peer context. Callback passed to libotr. + */ +static void free_peer_context_cb(void *data) +{ + g_free_not_null(data); +} + +/* + * Allocate otr peer context. Callback passed to libotr. + */ +static void add_peer_context_cb(void *data, ConnContext *context) +{ + struct otr_peer_context *opc; + + opc = otr_create_peer_context(); + if (opc == NULL) { + return; + } + + opc->active_fingerprint = context->active_fingerprint; + + context->app_data = opc; + context->app_data_free = free_peer_context_cb; + + IRSSI_OTR_DEBUG("Peer context created for %s", context->username); +} + +/* + * Find Irssi server record by network name. + */ +static SERVER_REC *find_server_by_network(const char *network) +{ + GSList *tmp; + SERVER_REC *server; + + g_return_val_if_fail(network != NULL, NULL); + + for (tmp = servers; tmp; tmp = tmp->next) { + server = tmp->data; + + if (g_ascii_strncasecmp(server->tag, network, strlen(server->tag))) + return server; + } + + return NULL; +} + +/* + * Check if fingerprint is in an encrypted context. + * + * Return 1 if it does, else 0. + */ +static int check_fp_encrypted_msgstate(Fingerprint *fp) +{ + ConnContext *context; + + g_return_val_if_fail(fp != NULL, 0); + + /* Loop on all fingerprint's context(es). */ + for (context = fp->context; + context != NULL && context->m_context == fp->context; + context = context->next) { + if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED && + context->active_fingerprint == fp) { + return 1; + } + } + + /* No state is encrypted. */ + return 0; +} + +/* + * Timer called from the glib main loop and set up by the timer_control + * callback of libotr. + */ +static gboolean timer_fired_cb(gpointer data) +{ + otrl_message_poll(user_state_global->otr_state, &otr_ops, NULL); + return TRUE; +} + +void otr_control_timer(unsigned int interval, void *opdata) +{ + if (otr_timerid) { + g_source_remove(otr_timerid); + otr_timerid = 0; + } + + if (interval > 0) { + otr_timerid = g_timeout_add_seconds(interval, timer_fired_cb, opdata); + } +} + +/* + * Is OTR debugging enabled or disabled? + */ +int otr_debug_get(void) +{ + return otr_debug; +} + +/* + * Toggle OTR debugging. + */ +void otr_debug_toggle(void) +{ + otr_debug = !otr_debug; +} + +/* + * Find context from nickname and irssi server record. + */ +ConnContext *otr_find_context(SERVER_REC *server, const char *nick, int create) +{ + ConnContext *ctx = NULL; + + g_return_val_if_fail(server != NULL, NULL); + g_return_val_if_fail(server->tag != NULL, NULL); + g_return_val_if_fail(nick != NULL, NULL); + + ctx = otrl_context_find(user_state_global->otr_state, nick, server->tag, + OTR_PROTOCOL_ID, OTRL_INSTAG_BEST, create, NULL, + add_peer_context_cb, server); + + return ctx; +} + +/* + * Create otr peer context. + */ +struct otr_peer_context *otr_create_peer_context(void) +{ + return g_new0(struct otr_peer_context, 1); +} + +/* + * Return a newly allocated OTR user state. + */ +struct otr_user_state *otr_init_user_state(void) +{ + struct otr_user_state *ous = NULL; + + ous = g_new0(struct otr_user_state, 1); + if (ous == NULL) { + return ous; + } + + ous->otr_state = otrl_userstate_create(); + + instag_load(ous); + + /* Load keys and fingerprints. */ + key_load(ous); + key_load_fingerprints(ous); + + return ous; +} + +/* + * Destroy otr user state. + */ +void otr_free_user_state(struct otr_user_state *ustate) +{ + if (ustate->otr_state) { + otrl_userstate_free(ustate->otr_state); + ustate->otr_state = NULL; + } + + g_free(ustate); +} + +/* + * init otr lib. + */ +void otr_lib_init() +{ + OTRL_INIT; +} + +/* + * deinit otr lib. + */ +void otr_lib_uninit() +{ +} + +/* + * Hand the given message to OTR. + * + * Return 0 if the message was successfully handled or else a negative value. + */ +int otr_send(SERVER_REC *server, const char *msg, const char *to, char **otr_msg) +{ + gcry_error_t err; + ConnContext *ctx = NULL; + + g_return_val_if_fail(server != NULL, -1); + g_return_val_if_fail(server->tag != NULL, -1); + + IRSSI_OTR_DEBUG("OTR: Sending message: %s", msg); + + err = otrl_message_sending(user_state_global->otr_state, &otr_ops, + server, server->tag, OTR_PROTOCOL_ID, to, OTRL_INSTAG_BEST, msg, NULL, otr_msg, + OTRL_FRAGMENT_SEND_ALL_BUT_LAST, &ctx, add_peer_context_cb, server); + if (err) { + g_warning("OTR: Send failed: %s", gcry_strerror(err)); + return -1; + } + + /* Add peer context to OTR context if none exists. */ + if (ctx && !ctx->app_data) { + add_peer_context_cb(server, ctx); + } + + return 0; +} + +/* + * List otr contexts to the main Irssi windows. + */ +void otr_contexts(struct otr_user_state *ustate) +{ + char human_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN], *trust; + ConnContext *ctx, *c_iter; + Fingerprint *fp; + + g_return_if_fail(ustate != NULL); + + if (ustate->otr_state->context_root == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_OTR_CTX_MISSING); + return; + } + + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_HEADER); + + /* Iterate over all contextes of the user state. */ + for (ctx = ustate->otr_state->context_root; ctx != NULL; ctx = ctx->next) { + OtrlMessageState best_mstate = OTRL_MSGSTATE_PLAINTEXT; + + /* Skip master context. */ + if (ctx != ctx->m_context) + continue; + + for (fp = ctx->fingerprint_root.next; fp != NULL; fp = fp->next) { + int used = 0; + char *username, *accountname; + + username = ctx->username; + accountname = ctx->accountname; + + for (c_iter = ctx->m_context; c_iter && c_iter->m_context == ctx->m_context; c_iter = c_iter->next) { + /* Print account name, username and msgstate. */ + if (c_iter->active_fingerprint == fp) { + used = 1; + + if (c_iter->msgstate == OTRL_MSGSTATE_ENCRYPTED) + best_mstate = OTRL_MSGSTATE_ENCRYPTED; + else if (c_iter->msgstate == OTRL_MSGSTATE_FINISHED && best_mstate == OTRL_MSGSTATE_PLAINTEXT) + best_mstate = OTRL_MSGSTATE_FINISHED; + } + } + + if (used) { + switch (best_mstate) { + case OTRL_MSGSTATE_ENCRYPTED: + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_ENCRYPTED_LINE, accountname, username); + break; + case OTRL_MSGSTATE_PLAINTEXT: + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_PLAINTEXT_LINE, accountname, username); + break; + case OTRL_MSGSTATE_FINISHED: + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_FINISHED_LINE, accountname, username); + break; + default: + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_UNKNOWN_LINE, accountname, username); + break; + }; + } else + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_UNUSED_LINE, accountname, username); + + /* Hash fingerprint to human. */ + otrl_privkey_hash_to_human(human_fp, fp->fingerprint); + + trust = fp->trust; + if (trust && trust[0] != '\0') { + if (strncmp(trust, "smp", 3) == 0) + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_SMP_LINE, human_fp); + else + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_MANUAL_LINE, human_fp); + } else + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_UNVERIFIED_LINE, human_fp); + } + } + + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_OTR_CTX_LIST_FOOTER); +} + +/* + * Finish the conversation. + */ +void otr_finish(SERVER_REC *server, const char *nick) +{ + ConnContext *ctx; + + g_return_if_fail(server != NULL); + g_return_if_fail(nick != NULL); + + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + printformat(server, nick, MSGLEVEL_CRAP, TXT_OTR_SESSION_ALREADY_FINISHED); + return; + } + + otrl_message_disconnect(user_state_global->otr_state, &otr_ops, server, + ctx->accountname, OTR_PROTOCOL_ID, nick, ctx->their_instance); + + otr_status_change(server, nick, OTR_STATUS_FINISHED); + + printformat(server, nick, MSGLEVEL_CRAP, TXT_OTR_SESSION_FINISHING, nick); +} + +/* + * Finish all otr contexts. + */ +void otr_finishall(struct otr_user_state *ustate) +{ + ConnContext *context; + SERVER_REC *server; + + g_return_if_fail(ustate != NULL); + + for (context = ustate->otr_state->context_root; context; + context = context->next) { + /* Only finish encrypted session. */ + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + continue; + } + + server = find_server_by_network(context->accountname); + if (server == NULL) { + IRSSI_OTR_DEBUG("Unable to find server window for account %s", context->accountname); + continue; + } + + otr_finish(server, context->username); + } +} + +/* + * Trust our peer. + */ +void otr_trust(SERVER_REC *server, const char *nick, char *str_fp, + struct otr_user_state *ustate) +{ + char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + struct otr_peer_context *opc; + ConnContext *ctx; + Fingerprint *fp_trust; + + g_return_if_fail(ustate != NULL); + + /* No human string fingerprint given. */ + if (*str_fp == '\0') { + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + return; + } + + opc = ctx->app_data; + /* Always NEED a peer context or else code error. */ + g_return_if_fail(opc != NULL); + + fp_trust = ctx->active_fingerprint; + } else { + fp_trust = otr_find_hash_fingerprint_from_human(str_fp, ustate); + } + + if (fp_trust != NULL) { + otrl_privkey_hash_to_human(peerfp, fp_trust->fingerprint); + + if (otrl_context_is_fingerprint_trusted(fp_trust)) { + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_FP_ALREADY_TRUSTED, peerfp); + return; + } + + /* Trust level is manual at this point. */ + otrl_context_set_trust(fp_trust, "manual"); + key_write_fingerprints(ustate); + + otr_status_change(server, nick, OTR_STATUS_TRUST_MANUAL); + + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_TRUSTED, peerfp); + } else + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_FP_MISSING, str_fp); +} + +/* + * implements /otr authabort + */ +void otr_auth_abort(SERVER_REC *server, const char *nick) +{ + ConnContext *ctx; + + g_return_if_fail(server != NULL); + g_return_if_fail(nick != NULL); + + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_CTX_NICK_MISSING, nick); + return; + } + + otrl_message_abort_smp(user_state_global->otr_state, &otr_ops, server, ctx); + otr_status_change(server, nick, OTR_STATUS_SMP_ABORT); + + if (ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_AUTH_ONGOING_ABORTED); + else + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_AUTH_ABORTED); +} + +/* + * Initiate or respond to SMP authentication. + */ +void otr_auth(SERVER_REC *server, const char *nick, const char *question, + const char *secret) +{ + int ret; + size_t secret_len = 0; + ConnContext *ctx; + struct otr_peer_context *opc; + + g_return_if_fail(server != NULL); + g_return_if_fail(nick != NULL); + + ctx = otr_find_context(server, nick, 0); + if (ctx == NULL) { + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_CTX_NICK_MISSING, nick); + return; + } + + opc = ctx->app_data; + /* Again, code flow error. */ + g_return_if_fail(opc != NULL); + + if (ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_SESSION_MISSING); + return; + } + + /* Aborting an ongoing auth */ + if (ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) { + otr_auth_abort(server, nick); + } + + /* reset trust level */ + if (ctx->active_fingerprint) { + ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint); + if (!ret) { + otrl_context_set_trust(ctx->active_fingerprint, ""); + key_write_fingerprints(user_state_global); + } + } + + /* Libotr allows empty secret. */ + if (secret) { + secret_len = strlen(secret); + } + + if (opc->ask_secret) { + otrl_message_respond_smp(user_state_global->otr_state, &otr_ops, + server, ctx, (unsigned char *) secret, secret_len); + otr_status_change(server, nick, OTR_STATUS_SMP_RESPONDED); + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_AUTH_RESPONSE); + } else { + if (question != NULL) + otrl_message_initiate_smp_q(user_state_global->otr_state, &otr_ops, server, ctx, question, (unsigned char *) secret, secret_len); + else + otrl_message_initiate_smp(user_state_global->otr_state, &otr_ops, server, ctx, (unsigned char *) secret, secret_len); + + otr_status_change(server, nick, OTR_STATUS_SMP_STARTED); + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_AUTH_INITIATED); + } + + opc->ask_secret = 0; +} + +/* + * For the given message we received through irssi, check if we need to queue + * it for the case where that message is part of a bigger OTR full message. + * This can happen with bitlbee for instance where OTR message are split in + * different PRIVMSG. + * + * This uses a "queue" in the peer context so it's it very important to have + * the peer context associated with the message (nickname + irssi object). + * + * Return an otr_msg_status code indicating the caller what to do with the msg. + * OTR_MSG_ERROR indicates an error probably memory related. OTR_MSG_WAIT_MORE + * tells the caller to NOT send out the message since we are waiting for more + * to complete the OTR original message. OTR_MSG_ORIGINAL tell the caller to + * simply use the original message. OTR_MSG_USE_QUEUE indicates that full_msg + * can be used containing the reconstructed message. The caller SHOULD free(3) + * this pointer after use. + */ +static enum otr_msg_status enqueue_otr_fragment(const char *msg, struct otr_peer_context *opc, char **full_msg) +{ + enum otr_msg_status ret; + size_t msg_len; + + g_return_val_if_fail(msg != NULL, OTR_MSG_ERROR); + g_return_val_if_fail(opc != NULL, OTR_MSG_ERROR); + + /* We are going to use it quite a bit so ease our life a bit. */ + msg_len = strlen(msg); + + if (opc->full_msg) { + if (msg_len > (opc->msg_size - opc->msg_len)) { + char *tmp_ptr; + + /* Realloc memory if there is not enough space. */ + tmp_ptr = realloc(opc->full_msg, opc->msg_size + msg_len + 1); + if (tmp_ptr == NULL) { + free(opc->full_msg); + opc->full_msg = NULL; + ret = OTR_MSG_ERROR; + return ret; + } + opc->full_msg = tmp_ptr; + opc->msg_size += msg_len + 1; + } + + /* Copy msg to full message since we already have a part pending. */ + strncpy(opc->full_msg + opc->msg_len, msg, msg_len); + opc->msg_len += msg_len; + opc->full_msg[opc->msg_len] = '\0'; + + IRSSI_OTR_DEBUG("Partial OTR message added to queue: %s", msg); + + /* + * Are we waiting for more? If the message ends with a ".", the + * transmission has ended else we have to wait for more. + */ + if (msg[msg_len - 1] != OTR_MSG_END_TAG) { + ret = OTR_MSG_WAIT_MORE; + return ret; + } + + /* + * Dup the string with enough space for the NULL byte since we are + * about to free it before passing it to the caller. + */ + *full_msg = strndup(opc->full_msg, opc->msg_len + 1); + /* Reset everything. */ + free(opc->full_msg); + opc->full_msg = NULL; + opc->msg_size = opc->msg_len = 0; + ret = OTR_MSG_USE_QUEUE; + return ret; + } else { + char *pos; + + /* + * Try to find the OTR message tag at the _beginning_of the packet and + * check if this packet is not the end with the end tag of OTR "." + */ + pos = strstr(msg, OTR_MSG_BEGIN_TAG); + if (pos && (pos == msg) && msg[msg_len - 1] != OTR_MSG_END_TAG) { + /* Allocate full message buffer with an extra for NULL byte. */ + opc->full_msg = g_new0(char, (msg_len * 2) + 1); + if (!opc->full_msg) { + ret = OTR_MSG_ERROR; + return ret; + } + /* Copy full message with NULL terminated byte. */ + strncpy(opc->full_msg, msg, msg_len); + opc->msg_len += msg_len; + opc->msg_size += ((msg_len * 2) + 1); + opc->full_msg[opc->msg_len] = '\0'; + ret = OTR_MSG_WAIT_MORE; + IRSSI_OTR_DEBUG("Partial OTR message begins the queue: %s", msg); + return ret; + } + + /* Use original message. */ + ret = OTR_MSG_ORIGINAL; + } + + return ret; +} + +/* + * Hand the given message to OTR. + * + * Returns 0 if its an OTR protocol message or else negative value. + */ +int otr_receive(SERVER_REC *server, const char *msg, const char *from, char **new_msg) +{ + int ret = -1; + char *full_msg = NULL; + const char *recv_msg = NULL; + OtrlTLV *tlvs; + ConnContext *ctx; + struct otr_peer_context *opc; + OtrlTLV *tlv = NULL; + + g_return_val_if_fail(server != NULL, -1); + g_return_val_if_fail(server->tag != NULL, -1); + + IRSSI_OTR_DEBUG("Receiving message: %s", msg); + + ctx = otr_find_context(server, from, 1); + if (ctx == NULL) { + return ret; + } + + /* Add peer context to OTR context if none exists */ + if (ctx->app_data == NULL) + add_peer_context_cb(server, ctx); + + opc = ctx->app_data; + g_return_val_if_fail(opc != NULL, -1); + + ret = enqueue_otr_fragment(msg, opc, &full_msg); + switch (ret) { + case OTR_MSG_ORIGINAL: + recv_msg = msg; + break; + case OTR_MSG_USE_QUEUE: + recv_msg = full_msg; + break; + case OTR_MSG_WAIT_MORE: + ret = 1; + g_free_not_null(full_msg); + return ret; + case OTR_MSG_ERROR: + ret = -1; + g_free_not_null(full_msg); + return ret; + } + + ret = otrl_message_receiving(user_state_global->otr_state, + &otr_ops, server, server->tag, OTR_PROTOCOL_ID, from, recv_msg, new_msg, + &tlvs, &ctx, add_peer_context_cb, server); + if (ret) { + IRSSI_OTR_DEBUG("Ignoring message of length %d from %s to %s.\n%s", strlen(msg), from, server->tag, msg); + } else { + if (*new_msg) { + IRSSI_OTR_DEBUG("Converted received message."); + } + } + + /* Check for disconnected message */ + tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); + if (tlv != NULL) { + otr_status_change(server, from, OTR_STATUS_PEER_FINISHED); + printformat(server, from, MSGLEVEL_CLIENTCRAP, TXT_OTR_SESSION_FINISHED, from); + } + + otrl_tlv_free(tlvs); + + IRSSI_OTR_DEBUG("Message received."); + + g_free_not_null(full_msg); + + return ret; +} + +/* + * Get the OTR status of this conversation. + */ +enum otr_status_format otr_get_status_format(SERVER_REC *server, const char *nick) +{ + int ret; + enum otr_status_format code; + ConnContext *ctx = NULL; + + g_return_val_if_fail(server != NULL, TXT_OTR_STB_UNKNOWN); + + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + code = TXT_OTR_STB_PLAINTEXT; + return code; + } + + switch (ctx->msgstate) { + case OTRL_MSGSTATE_PLAINTEXT: + code = TXT_OTR_STB_PLAINTEXT; + break; + case OTRL_MSGSTATE_ENCRYPTED: + /* Begin by checking trust. */ + ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint); + if (ret) { + code = TXT_OTR_STB_TRUST; + } else { + code = TXT_OTR_STB_UNTRUSTED; + } + break; + case OTRL_MSGSTATE_FINISHED: + code = TXT_OTR_STB_FINISHED; + break; + default: + g_warning("BUG! Invalid msgstate: %d", ctx->msgstate); + code = TXT_OTR_STB_UNKNOWN; + break; + } + + if (ctx) { + IRSSI_OTR_DEBUG("Code: %d, state: %d, sm_prog_state: %d, auth state: %d", + code, ctx->msgstate, ctx->smstate->sm_prog_state, + ctx->auth.authstate); + } + return code; +} + +/* + * Change status bar text for a given nickname. + */ +void otr_status_change(SERVER_REC *server, const char *nick, + enum otr_status_event event) +{ + statusbar_items_redraw("otr"); + signal_emit("otr event", 3, server, nick, statusbar_txt[event]); +} + +/* + * Search for a OTR Fingerprint object from the given human readable string and + * return a pointer to the object if found else NULL. + */ +Fingerprint *otr_find_hash_fingerprint_from_human(const char *human_fp, struct otr_user_state *ustate) +{ + char str_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + Fingerprint *fp = NULL, *fp_iter = NULL; + ConnContext *context; + + /* Loop on all context of the user state */ + for (context = ustate->otr_state->context_root; context != NULL; + context = context->next) { + /* Loop on all fingerprint of the context */ + for (fp_iter = context->fingerprint_root.next; fp_iter; + fp_iter = fp_iter->next) { + otrl_privkey_hash_to_human(str_fp, fp_iter->fingerprint); + /* Compare human fingerprint given in argument to the current. */ + if (strncmp(str_fp, human_fp, sizeof(str_fp)) == 0) { + fp = otrl_context_find_fingerprint(context, + fp_iter->fingerprint, 0, NULL); + return fp; + } + } + } + + return fp; +} + +/* + * Forget a fingerprint. + * + * If str_fp is not NULL, it must be on the OTR human format like this: + * "487FFADA 5073FEDD C5AB5C14 5BB6C1FF 6D40D48A". If str_fp is NULL, get the + * context of the target nickname, check for the OTR peer context active + * fingerprint and forget this one if possible. + */ +void otr_forget(SERVER_REC *server, const char *nick, char *str_fp, struct otr_user_state *ustate) +{ + char fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + Fingerprint *fp_forget; + ConnContext *ctx = NULL; + struct otr_peer_context *opc; + + /* No human string fingerprint given. */ + if (*str_fp == '\0') { + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + return; + } + + opc = ctx->app_data; + /* Always NEED a peer context or else code error. */ + g_return_if_fail(opc != NULL); + + fp_forget = opc->active_fingerprint; + } else { + fp_forget = otr_find_hash_fingerprint_from_human(str_fp, ustate); + } + + if (fp_forget) { + /* Don't do anything if context is in encrypted state. */ + if (check_fp_encrypted_msgstate(fp_forget)) { + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_CTX_ENCRYPTED); + return; + } + + otrl_privkey_hash_to_human(fp, fp_forget->fingerprint); + /* Forget fp and context if it's the only one remaining. */ + otrl_context_forget_fingerprint(fp_forget, 1); + /* Update fingerprints file. */ + key_write_fingerprints(ustate); + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_FORGOTTEN, fp); + } else + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_FP_MISSING, str_fp); +} + +/* + * Distrust a fingerprint. + * + * If str_fp is not NULL, it must be on the OTR human format like this: + * "487FFADA 5073FEDD C5AB5C14 5BB6C1FF 6D40D48A". If str_fp is NULL, get the + * context of the target nickname, check for the OTR peer context active + * fingerprint and distrust it. + */ +void otr_distrust(SERVER_REC *server, const char *nick, char *str_fp, + struct otr_user_state *ustate) +{ + char fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN]; + Fingerprint *fp_distrust; + ConnContext *ctx; + struct otr_peer_context *opc; + + /* No human string fingerprint given. */ + if (*str_fp == '\0') { + ctx = otr_find_context(server, nick, FALSE); + if (ctx == NULL) { + return; + } + + opc = ctx->app_data; + /* Always NEED a peer context or else code error. */ + g_return_if_fail(opc != NULL); + + fp_distrust = opc->active_fingerprint; + } else + fp_distrust = otr_find_hash_fingerprint_from_human(str_fp, ustate); + + if (fp_distrust != NULL) { + otrl_privkey_hash_to_human(fp, fp_distrust->fingerprint); + + if (!otrl_context_is_fingerprint_trusted(fp_distrust)) { + /* Fingerprint already not trusted. Do nothing. */ + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_FP_ALREADY_DISTRUSED, fp); + return; + } + + otrl_context_set_trust(fp_distrust, ""); + + /* Update fingerprints file. */ + key_write_fingerprints(ustate); + printformat(server, nick, MSGLEVEL_CLIENTCRAP, TXT_OTR_FP_DISTRUSTED, fp); + } else + printformat(server, nick, MSGLEVEL_CLIENTERROR, TXT_OTR_FP_MISSING, str_fp); +} diff --git a/src/otr/otr.h b/src/otr/otr.h new file mode 100644 index 00000000..60a08184 --- /dev/null +++ b/src/otr/otr.h @@ -0,0 +1,170 @@ +/* + * Off-the-Record Messaging (OTR) modules for IRC + * + * Copyright (C) 2008 - Uli Meis + * 2012 - David Goulet + * + * 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 + */ + +#ifndef IRSSI_OTR_OTR_H +#define IRSSI_OTR_OTR_H + +/* Libotr */ +#include +#include +#include +#include + +#include "common.h" +#include "servers.h" + +/* irssi module name */ +#define MODULE_NAME "otr/core" + +/* + * XXX: Maybe this should be configurable? + */ +#define OTR_MAX_MSG_SIZE 400 + +/* OTR protocol id */ +#define OTR_PROTOCOL_ID "IRC" + +#define OTR_DIR "otr" +#define OTR_KEYFILE OTR_DIR "/otr.key" +#define OTR_FINGERPRINTS_FILE OTR_DIR "/otr.fp" +#define OTR_INSTAG_FILE OTR_DIR "/otr.instag" + +/* + * Specified in OTR protocol version 3. See: + * http://www.cypherpunks.ca/otr/Protocol-v3-4.0.0.html + */ +#define OTR_MSG_BEGIN_TAG "?OTR:" +#define OTR_MSG_END_TAG '.' + +/* IRC /me command marker and len. */ +#define OTR_IRC_MARKER_ME "/me " +#define OTR_IRC_MARKER_ME_LEN sizeof(OTR_IRC_MARKER_ME) - 1 + +/* Irssi otr user state */ +struct otr_user_state { + OtrlUserState otr_state; +}; + +/* + * Peer OTR internal context. + */ +struct otr_peer_context { + /* The SMP event status. Used for the Irssi status bar. */ + OtrlSMPEvent smp_event; + /* Did the SMP secret was asked so are we in a responder state? */ + unsigned int ask_secret; + /* + * The fingerprint of the private message OTR session. This is useful for + * the forget command for which we can recover the fingerprint + * automatically. + */ + Fingerprint *active_fingerprint; + /* + * If needed, used to reconstruct the full message from fragmentation. + * Bitlbee for instance does that where we receive a *long* OTR message + * split in multiple PRIVMSG so we need to reconstruct it. + */ + char *full_msg; + /* Size of full_msg. Note this is the allocated memory size. */ + size_t msg_size; + /* Len of the actual string in full_msg NOT counting the NULL byte. */ + size_t msg_len; +}; + +/* given to otr_status_change */ +enum otr_status_event { + OTR_STATUS_FINISHED, + OTR_STATUS_TRUST_MANUAL, + OTR_STATUS_TRUST_SMP, + OTR_STATUS_SMP_ABORT, + OTR_STATUS_SMP_STARTED, + OTR_STATUS_SMP_RESPONDED, + OTR_STATUS_SMP_INCOMING, + OTR_STATUS_SMP_FINALIZE, + OTR_STATUS_SMP_ABORTED, + OTR_STATUS_PEER_FINISHED, + OTR_STATUS_SMP_FAILED, + OTR_STATUS_SMP_SUCCESS, + OTR_STATUS_GONE_SECURE, + OTR_STATUS_GONE_INSECURE, + OTR_STATUS_CTX_UPDATE +}; + +enum otr_msg_status { + OTR_MSG_ORIGINAL = 1, + OTR_MSG_WAIT_MORE = 2, + OTR_MSG_USE_QUEUE = 3, + OTR_MSG_ERROR = 4, +}; + +/* there can be only one */ +extern struct otr_user_state *user_state_global; + +/* Libotr ops functions */ +extern OtrlMessageAppOps otr_ops; + +int otr_debug_get(void); +void otr_debug_toggle(void); + +void otr_send_message(SERVER_REC *irssi, const char *recipient, + const char *message); +void otr_status_change(SERVER_REC *irssi, const char *nick, + enum otr_status_event event); + +/* init stuff */ + +struct otr_user_state *otr_init_user_state(void); +void otr_free_user_state(struct otr_user_state *ustate); + +void otr_lib_init(); +void otr_lib_uninit(); + +void otr_control_timer(unsigned int interval, void *opdata); + +/* Message transport. */ +int otr_send(SERVER_REC *irssi, const char *msg, const char *to, + char **otr_msg); +int otr_receive(SERVER_REC *irssi, const char *msg, + const char *from, char **new_msg); + +/* User interaction */ +void otr_finish(SERVER_REC *irssi, const char *nick); +void otr_auth(SERVER_REC *irssi, const char *nick, const char *question, + const char *secret); +void otr_auth_abort(SERVER_REC *irssi, const char *nick); +void otr_contexts(struct otr_user_state *ustate); +void otr_finishall(struct otr_user_state *ustate); +void otr_forget(SERVER_REC *irssi, const char *nick, char *str_fp, + struct otr_user_state *ustate); +void otr_distrust(SERVER_REC *irssi, const char *nick, char *str_fp, + struct otr_user_state *ustate); +void otr_trust(SERVER_REC *irssi, const char *nick, char *str_fp, + struct otr_user_state *ustate); + +enum otr_status_format otr_get_status_format(SERVER_REC *irssi, + const char *nick); + +struct otr_peer_context *otr_create_peer_context(void); +ConnContext *otr_find_context(SERVER_REC *irssi, const char *nick, int create); +Fingerprint *otr_find_hash_fingerprint_from_human(const char *human_fp, + struct otr_user_state *ustate); + +#endif /* IRSSI_OTR_OTR_H */ From 7a4bfc16021e7762bd8e6c5d11d0f913101dc5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Tue, 27 Feb 2018 00:04:56 +0100 Subject: [PATCH 0340/1198] Better wording. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6cba4fb3..2852480c 100644 --- a/configure.ac +++ b/configure.ac @@ -149,9 +149,9 @@ AC_ARG_WITH(perl, want_perl=static) AC_ARG_WITH(otr, -[ --with-otr[=yes|no|module] Build with OTR support - also specifies +[ --with-otr[=yes|no|static] Build with OTR support - also specifies if it should be built into the main irssi - binary or as a module (default)], + binary (static) or as a module (default)], if test x$withval = xyes; then want_otr=module elif test x$withval = xstatic; then From 0b057b4ff43cfc560f67fe8312830289534de7d5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 7 Mar 2018 02:22:58 +0100 Subject: [PATCH 0341/1198] run syncdocs.sh and syncscripts.sh Sync startup howto to fd1ed2227d529a7ee00d6206caa871ee40c08b69 Sync scriptassist to (2003020806) 211cd515ec87cf9a5d893e97894c2e4b58952f19 --- docs/startup-HOWTO.html | 6 +++--- docs/startup-HOWTO.txt | 15 ++++++++------- scripts/scriptassist.pl | 13 +++++++++---- utils/syncdocs.sh | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) 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

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 /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:

+

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:

/SET use_proxy ON
 /SET proxy_address irc.bouncer.org
@@ -434,7 +434,7 @@ Ctrl-X                - set the next server in list active
 
 

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>
@@ -488,7 +488,7 @@ Ctrl-X                - set the next server in list active
 
 

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? :)

+

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 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/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 @@ -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/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{.*(?=\s*)?(
\s*)?)?\s*(
\s*){0,3})}{\1\2}g;' srcdir=`dirname "$0"` From fb9f5174c2f85c113dac8dbc1d146fe530e53e44 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 8 Mar 2018 20:35:00 +0100 Subject: [PATCH 0342/1198] Compare channels/networks fields case-insensitively Fixes #856 --- src/core/channels-setup.c | 9 +++++++-- src/core/servers-setup.c | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) 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/servers-setup.c b/src/core/servers-setup.c index 9492c58c..878dd0ea 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 (address == NULL || chatnet == NULL) { + return 0; + } + if (g_strcmp0(address, server->address) != 0 || g_strcmp0(chatnet, server->chatnet) != 0 || - port != server->port) + port != server->port) { return 1; + } return 0; } From 76d958a87fea1d744f45a9e022cf980752c7ea73 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 9 Mar 2018 17:36:28 +0100 Subject: [PATCH 0343/1198] More g_strcmp0 -> g_ascii_strcasecmp --- src/core/servers-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 878dd0ea..2a92a367 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -478,8 +478,8 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) return 0; } - if (g_strcmp0(address, server->address) != 0 || - g_strcmp0(chatnet, server->chatnet) != 0 || + if (g_ascii_strcasecmp(address, server->address) != 0 || + g_ascii_strcasecmp(chatnet, server->chatnet) != 0 || port != server->port) { return 1; } From 7ec6c500b4abed6f3a93a7afaba26ba08ca09be9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Mar 2018 17:46:26 +0100 Subject: [PATCH 0344/1198] make default keybinds deletable --- src/fe-common/core/keyboard.c | 54 +++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) 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] [ [ []]] */ +/* SYNTAX: BIND [-list] [-delete | -reset] [ [ []]] */ 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) From b7906b87065829029f3b7ea21eb29699f7dc21fc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Mar 2018 10:06:29 +0100 Subject: [PATCH 0345/1198] in fact hidden levels should not be re-set when you run /set --- src/fe-text/gui-windows.c | 2 -- 1 file changed, 2 deletions(-) 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, From 8d07f52bae6fa7e85988125293f08a72e39de8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Thu, 15 Mar 2018 14:01:50 +0100 Subject: [PATCH 0346/1198] Add ABI check for otr_core module. --- src/otr/module.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/otr/module.c b/src/otr/module.c index ca3107b1..0d83629f 100644 --- a/src/otr/module.c +++ b/src/otr/module.c @@ -24,6 +24,7 @@ #include "module.h" +#include "common.h" #include "signals.h" #include "queries.h" #include "commands.h" @@ -259,3 +260,8 @@ void otr_core_deinit(void) otr_lib_uninit(); } + +void otr_core_abicheck(int *version) +{ + *version = IRSSI_ABI_VERSION; +} From 65a139aa9e8a7cb7a7a123ab57ee05836c9e89ea Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Mar 2018 12:44:04 +0100 Subject: [PATCH 0347/1198] move no window printing code --- src/fe-text/gui-printtext.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index c52f9ced..13d8c233 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -249,9 +249,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 +282,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; } From c7ca8102c002287f492ca71f2193ee9b269f5bf5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 17 Mar 2018 13:36:38 +0100 Subject: [PATCH 0348/1198] fix a crash when trying to append to a NULL line reported by @vague666 --- src/fe-text/gui-printtext.c | 7 +++++++ src/fe-text/textbuffer-view.c | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 13d8c233..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; 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); From 77a671c03726969525367f36429c448a3a0aaae8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Mar 2018 09:11:02 +0100 Subject: [PATCH 0349/1198] update bind help --- docs/help/in/bind.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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. From d845ee7361886599f6ffa4f403b44a3f45fd88db Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Mar 2018 09:18:42 +0100 Subject: [PATCH 0350/1198] change the statusbar commands so that no accidenal status bars are created --- docs/help/in/statusbar.in | 51 ++-- src/fe-text/statusbar-config.c | 449 +++++++++++++++++++++------------ 2 files changed, 316 insertions(+), 184 deletions(-) diff --git a/docs/help/in/statusbar.in b/docs/help/in/statusbar.in index 7d64b816..9d68d1c9 100644 --- a/docs/help/in/statusbar.in +++ b/docs/help/in/statusbar.in @@ -5,27 +5,35 @@ %9Parameters:%9 - ENABLE: Adds a statusbar to the list of statusbars. - DISABLE: Removes a statusbar from the list. Note that for - built-in statusbars they can be enabled again should the - user wish to add back the default statusbars. + ADD: Adds a statusbar to the list of statusbars. + MODIFY: Modifies the configuration of a statusbar. RESET: Restores the default statusbar configuration. - TYPE: Sets the type of statusbar, for each split window or only + ADDITEM: Adds an item to the specified statusbar. It can be set to + appear before/after another item and left/right aligned + to a specified position on the screen. + MODIFYITEM: Changes an item position inside a bar. + REMOVEITEM: Removes an item from the specified statusbar. + INFO: List the current details and items of the specified + statusbar. + + -disable: Removes a statusbar from the list. + -type: Sets the type of statusbar, for each split window or only for the current root screen. - PLACEMENT: Sets the placement of the statusbar, either at the top or + -placement: Sets the placement of the statusbar, either at the top or the bottom of the screen. - POSITION: Sets the position of the statusbar. Represented as a + -position: Sets the position of the statusbar. Represented as a number, with 0 implying the first position. - VISIBLE: Sets the visibility of the statusbar or item. If set to + -visible: Sets the visibility of the statusbar or item. If set to always it is visible on all screens, otherwise if set to inactive or active then it is only visible on inactive or active screens, respectively. - ADD: Adds an item to the specified statusbar. It can be set to - appear before/after another item and left/right aligned - to a specified position on the screen. - REMOVE: Removes an item from the specified statusbar. + -before: This item is added before the other item. + -after: This item is added after the other item. + -priority: When the statusbar items overflow, the item with the + lowest priority is removed first + -alignment: Display the item on the right side. - Where name refers to the name of the statusbar; if no argument is + Where statusbar refers to the name of the statusbar; if no argument is given, the entire list of statusbars will be displayed. %9Description:%9 @@ -36,12 +44,17 @@ %9Examples:%9 /STATUSBAR - /STATUSBAR window - /STATUSBAR window REMOVE time - /STATUSBAR window ADD time - /STATUSBAR window RESET - /STATUSBAR topic DISABLE - /STATUSBAR topic ENABLE + /STATUSBAR INFO window + /STATUSBAR REMOVEITEM time window + /STATUSBAR ADDITEM time window + /STATUSBAR RESET window + /STATUSBAR MODIFY -disable topic + /STATUSBAR MODIFY -nodisable topic + +%9Remarks:%9 + + Statusbar syntax was changed in Irssi 1.2. The old syntax is still + accepted for backward compatibility, but no longer documented. %9See also:%9 WINDOW diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 48f4aa61..391a5768 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -95,8 +95,10 @@ statusbar_config_find(STATUSBAR_GROUP_REC *group, const char *name) for (tmp = group->config_bars; tmp != NULL; tmp = tmp->next) { STATUSBAR_CONFIG_REC *config = tmp->data; - if (g_strcmp0(config->name, name) == 0) - return config; + if ((config->name == NULL || name == NULL) ? + config->name == name : + g_ascii_strcasecmp(config->name, name) == 0) + return config; } return NULL; @@ -273,6 +275,24 @@ static const char *sbar_get_visibility(STATUSBAR_CONFIG_REC *rec) rec->visible == STATUSBAR_VISIBLE_INACTIVE ? "inactive" : "??"; } +static CONFIG_NODE *sbar_node(const char *name, gboolean create) +{ + CONFIG_NODE *node; + STATUSBAR_CONFIG_REC *rec = statusbar_config_find(active_statusbar_group, name); + if (rec != NULL) { + name = rec->name; + } else if (!create) { + return NULL; + } + + /* lookup/create the statusbar node */ + node = iconfig_node_traverse("statusbar", TRUE); + node = iconfig_node_section(node, active_statusbar_group->name, NODE_TYPE_BLOCK); + node = iconfig_node_section(node, name, NODE_TYPE_BLOCK); + + return node; +} + static void statusbar_list_items(STATUSBAR_CONFIG_REC *bar) { GSList *tmp; @@ -334,98 +354,133 @@ static void cmd_statusbar_list(void) static void cmd_statusbar_print_info(const char *name) { - GSList *tmp; + STATUSBAR_CONFIG_REC *rec = statusbar_config_find(active_statusbar_group, name); - tmp = active_statusbar_group->config_bars; - for (; tmp != NULL; tmp = tmp->next) { - STATUSBAR_CONFIG_REC *rec = tmp->data; - - if (g_ascii_strcasecmp(rec->name, name) == 0) { - statusbar_print(rec); - return; - } + if (rec != NULL) { + statusbar_print(rec); + return; } printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name); } -/* SYNTAX: STATUSBAR ENABLE */ -static void cmd_statusbar_enable(const char *data, void *server, - void *item, CONFIG_NODE *node) +/* SYNTAX: STATUSBAR ADD|MODIFY [-disable | -nodisable] [-type window|root] + [-placement top|bottom] [-position #] [-visible always|active|inactive] */ +static void cmd_statusbar_add_modify(const char *data, void *server, void *witem) { - iconfig_node_set_str(node, "disabled", NULL); + GHashTable *optlist; + CONFIG_NODE *node; + char *name, *type, *placement, *visible; + void *free_arg; + int error; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, + "statusbar add", &optlist, &name)) + return; + + if (*name == '\0') { + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + } + + error = 0; + + type = NULL; + data = g_hash_table_lookup(optlist, "type"); + if (data != NULL) { + if (g_ascii_strcasecmp(data, "window") == 0) + type = "window"; + else if (g_ascii_strcasecmp(data, "root") == 0) + type = "root"; + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_UNKNOWN_TYPE, + data); + error++; + } + } + + placement = NULL; + data = g_hash_table_lookup(optlist, "placement"); + if (data != NULL) { + if (g_ascii_strcasecmp(data, "top") == 0) + placement = "top"; + else if (g_ascii_strcasecmp(data, "bottom") == 0) + placement = "bottom"; + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_STATUSBAR_UNKNOWN_PLACEMENT, data); + error++; + } + } + + visible = NULL; + data = g_hash_table_lookup(optlist, "visible"); + if (data != NULL) { + if (g_ascii_strcasecmp(data, "always") == 0) + visible = "always"; + else if (g_ascii_strcasecmp(data, "active") == 0) + visible = "active"; + else if (g_ascii_strcasecmp(data, "inactive") == 0) + visible = "inactive"; + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_STATUSBAR_UNKNOWN_VISIBILITY, data); + error++; + } + } + + if (error) { + cmd_params_free(free_arg); + return; + } + + node = sbar_node(name, TRUE); + if (g_hash_table_lookup(optlist, "nodisable")) + iconfig_node_set_str(node, "disabled", NULL); + if (g_hash_table_lookup(optlist, "disable")) + iconfig_node_set_bool(node, "disabled", TRUE); + if (type != NULL) + iconfig_node_set_str(node, "type", type); + if (placement != NULL) + iconfig_node_set_str(node, "placement", placement); + data = g_hash_table_lookup(optlist, "position"); + if (data != NULL) + iconfig_node_set_int(node, "position", atoi(data)); + if (visible != NULL) + iconfig_node_set_str(node, "visible", visible); + + read_statusbar_config(); + cmd_params_free(free_arg); } -/* SYNTAX: STATUSBAR DISABLE */ -static void cmd_statusbar_disable(const char *data, void *server, - void *item, CONFIG_NODE *node) +/* SYNTAX: STATUSBAR RESET */ +static void cmd_statusbar_reset(const char *data, void *server, void *witem) { - iconfig_node_set_bool(node, "disabled", TRUE); -} + CONFIG_NODE *node, *parent; + char *name; + void *free_arg; -/* SYNTAX: STATUSBAR RESET */ -static void cmd_statusbar_reset(const char *data, void *server, - void *item, CONFIG_NODE *node) -{ - CONFIG_NODE *parent; + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_STRIP_TRAILING_WS, &name)) + return; + + if (*name == '\0') { + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + } + + node = sbar_node(name, FALSE); + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name); + cmd_params_free(free_arg); + return; + } parent = iconfig_node_traverse("statusbar", TRUE); - parent = iconfig_node_section(parent, active_statusbar_group->name, - NODE_TYPE_BLOCK); + parent = iconfig_node_section(parent, active_statusbar_group->name, NODE_TYPE_BLOCK); - iconfig_node_set_str(parent, node->key, NULL); -} + iconfig_node_set_str(parent, node->key, NULL); -/* SYNTAX: STATUSBAR TYPE window|root */ -static void cmd_statusbar_type(const char *data, void *server, - void *item, CONFIG_NODE *node) -{ - if (g_ascii_strcasecmp(data, "window") == 0) - iconfig_node_set_str(node, "type", "window"); - else if (g_ascii_strcasecmp(data, "root") == 0) - iconfig_node_set_str(node, "type", "root"); - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_UNKNOWN_TYPE, data); - } -} - -/* SYNTAX: STATUSBAR PLACEMENT top|bottom */ -static void cmd_statusbar_placement(const char *data, void *server, - void *item, CONFIG_NODE *node) -{ - if (g_ascii_strcasecmp(data, "top") == 0) - iconfig_node_set_str(node, "placement", "top"); - else if (g_ascii_strcasecmp(data, "bottom") == 0) - iconfig_node_set_str(node, "placement", "bottom"); - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_UNKNOWN_PLACEMENT, data); - } -} - -/* SYNTAX: STATUSBAR POSITION */ -static void cmd_statusbar_position(const char *data, void *server, - void *item, CONFIG_NODE *node) -{ - iconfig_node_set_int(node, "position", atoi(data)); -} - -/* SYNTAX: STATUSBAR VISIBLE always|active|inactive */ -static void cmd_statusbar_visible(const char *data, void *server, - void *item, CONFIG_NODE *node) -{ - if (g_ascii_strcasecmp(data, "always") == 0) - iconfig_node_set_str(node, "visible", "always"); - else if (g_ascii_strcasecmp(data, "active") == 0) - iconfig_node_set_str(node, "visible", "active"); - else if (g_ascii_strcasecmp(data, "inactive") == 0) - iconfig_node_set_str(node, "visible", "inactive"); - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_UNKNOWN_VISIBILITY, data); - } + read_statusbar_config(); + cmd_params_free(free_arg); } static CONFIG_NODE *statusbar_items_section(CONFIG_NODE *parent) @@ -455,45 +510,58 @@ static CONFIG_NODE *statusbar_items_section(CONFIG_NODE *parent) node = iconfig_node_section(parent, rec->name, NODE_TYPE_BLOCK); if (rec->priority != 0) - iconfig_node_set_int(node, "priority", rec->priority); + iconfig_node_set_int(node, "priority", rec->priority); if (rec->right_alignment) - iconfig_node_set_str(node, "alignment", "right"); + iconfig_node_set_str(node, "alignment", "right"); } - return parent; + return parent; } -/* SYNTAX: STATUSBAR ADD [-before | -after ] - [-priority #] [-alignment left|right] */ -static void cmd_statusbar_add(const char *data, void *server, - void *item, CONFIG_NODE *node) +/* SYNTAX: STATUSBAR ADDITEM|MODIFYITEM [-before | -after ] + [-priority #] [-alignment left|right] */ +static void cmd_statusbar_additem_modifyitem(const char *data, void *server, void *witem) { - GHashTable *optlist; - char *name, *value; + CONFIG_NODE *node; + GHashTable *optlist; + char *item, *statusbar, *value; void *free_arg; - int index; + int index; - node = statusbar_items_section(node); - if (node == NULL) - return; - - if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, - "statusbar add", &optlist, &name)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, + "statusbar additem", &optlist, &item, &statusbar)) return; - /* get the index */ + if (*statusbar == '\0') { + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + } + + node = sbar_node(statusbar, FALSE); + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); + cmd_params_free(free_arg); + return; + } + + node = statusbar_items_section(node); + if (node == NULL) { + cmd_params_free(free_arg); + return; + } + + /* get the index */ index = -1; value = g_hash_table_lookup(optlist, "before"); if (value != NULL) index = config_node_index(node, value); value = g_hash_table_lookup(optlist, "after"); if (value != NULL) index = config_node_index(node, value)+1; - /* create/move item */ - node = iconfig_node_section_index(node, name, index, NODE_TYPE_BLOCK); + /* create/move item */ + node = iconfig_node_section_index(node, item, index, NODE_TYPE_BLOCK); - /* set the options */ - value = g_hash_table_lookup(optlist, "priority"); - if (value != NULL) iconfig_node_set_int(node, "priority", atoi(value)); + /* set the options */ + value = g_hash_table_lookup(optlist, "priority"); + if (value != NULL) iconfig_node_set_int(node, "priority", atoi(value)); value = g_hash_table_lookup(optlist, "alignment"); if (value != NULL) { @@ -502,67 +570,115 @@ static void cmd_statusbar_add(const char *data, void *server, "right" : NULL); } + read_statusbar_config(); cmd_params_free(free_arg); } -/* SYNTAX: STATUSBAR REMOVE */ -static void cmd_statusbar_remove(const char *data, void *server, - void *item, CONFIG_NODE *node) +/* SYNTAX: STATUSBAR REMOVEITEM */ +static void cmd_statusbar_removeitem(const char *data, void *server, void *witem) { - node = statusbar_items_section(node); - if (node == NULL) - return; + CONFIG_NODE *node; + char *item, *statusbar; + void *free_arg; + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_STRIP_TRAILING_WS, &item, &statusbar)) + return; - if (iconfig_node_section(node, data, -1) != NULL) - iconfig_node_set_str(node, data, NULL); - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_ITEM_NOT_FOUND, data); + if (*statusbar == '\0') { + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); } + + node = sbar_node(statusbar, FALSE); + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); + cmd_params_free(free_arg); + return; + } + + node = statusbar_items_section(node); + if (node == NULL) { + cmd_params_free(free_arg); + return; + } + + if (iconfig_node_section(node, item, -1) != NULL) + iconfig_node_set_str(node, item, NULL); + else { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + } + + read_statusbar_config(); + cmd_params_free(free_arg); +} + +/* SYNTAX: STATUSBAR INFO */ +static void cmd_statusbar_info(const char *data) +{ + void *free_arg; + char *name; + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_STRIP_TRAILING_WS, &name)) + return; + + if (*name == '\0') { + cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + } + + /* print statusbar info */ + cmd_statusbar_print_info(name); + cmd_params_free(free_arg); + return; } static void cmd_statusbar(const char *data) { - CONFIG_NODE *node; - char *name, *cmd, *params, *signal; + char *arg1, *arg2, *params, *oldcmd; void *free_arg; - if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &name, &cmd, ¶ms)) + if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + &arg1, &arg2, ¶ms)) return; - if (*name == '\0') { - /* list all statusbars */ - cmd_statusbar_list(); - cmd_params_free(free_arg); - return; + /* backward compatibility layer */ + oldcmd = NULL; + if (*arg1 == '\0') { + oldcmd = g_strdup("list"); + } else if (g_ascii_strcasecmp(arg2, "enable") == 0) { + oldcmd = g_strdup_printf("add -nodisable %s %s", arg1, params); + } else if (g_ascii_strcasecmp(arg2, "disable") == 0) { + oldcmd = g_strdup_printf("add -disable %s %s", arg1, params); + } else if (g_ascii_strcasecmp(arg2, "reset") == 0) { + oldcmd = g_strdup_printf("reset %s", arg1); + } else if (g_ascii_strcasecmp(arg2, "type") == 0) { + oldcmd = g_strdup_printf("add -type %s %s", params, arg1); + } else if (g_ascii_strcasecmp(arg2, "placement") == 0) { + oldcmd = g_strdup_printf("add -placement %s %s", params, arg1); + } else if (g_ascii_strcasecmp(arg2, "position") == 0) { + oldcmd = g_strdup_printf("add -position %s %s", params, arg1); + } else if (g_ascii_strcasecmp(arg2, "visible") == 0) { + oldcmd = g_strdup_printf("add -visible %s %s", params, arg1); + } else if (g_ascii_strcasecmp(arg2, "add") == 0) { + oldcmd = g_strdup_printf("additem %s %s", params, arg1); + } else if (g_ascii_strcasecmp(arg2, "remove") == 0) { + oldcmd = g_strdup_printf("removeitem %s %s", params, arg1); + } else if (*arg2 == '\0') { + oldcmd = g_strdup_printf("statusbar %s", arg1); + if (command_find(oldcmd) == NULL) { + g_free(oldcmd); + oldcmd = g_strdup_printf("info %s", arg1); + } else { + g_free(oldcmd); + oldcmd = NULL; + } } - if (*cmd == '\0') { - /* print statusbar info */ - cmd_statusbar_print_info(name); - cmd_params_free(free_arg); - return; - } - - /* lookup/create the statusbar node */ - node = iconfig_node_traverse("statusbar", TRUE); - node = iconfig_node_section(node, active_statusbar_group->name, - NODE_TYPE_BLOCK); - node = iconfig_node_section(node, name, NODE_TYPE_BLOCK); - - /* call the subcommand */ - signal = g_strconcat("command statusbar ", cmd, NULL); - ascii_strdown(signal); - if (!signal_emit(signal, 4, params, NULL, NULL, node)) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_UNKNOWN_COMMAND, cmd); - } else { - read_statusbar_config(); - } - g_free(signal); - cmd_params_free(free_arg); + if (oldcmd) { + command_runsub("statusbar", oldcmd, NULL, NULL); + g_free(oldcmd); + } else { + command_runsub("statusbar", data, NULL, NULL); + } + + return; } void statusbar_config_init(void) @@ -571,18 +687,22 @@ void statusbar_config_init(void) signal_add_last("setup reread", (SIGNAL_FUNC) read_statusbar_config); signal_add("theme changed", (SIGNAL_FUNC) read_statusbar_config); - command_bind("statusbar", NULL, (SIGNAL_FUNC) cmd_statusbar); - command_bind("statusbar enable", NULL, (SIGNAL_FUNC) cmd_statusbar_enable); - command_bind("statusbar disable", NULL, (SIGNAL_FUNC) cmd_statusbar_disable); - command_bind("statusbar reset", NULL, (SIGNAL_FUNC) cmd_statusbar_reset); - command_bind("statusbar add", NULL, (SIGNAL_FUNC) cmd_statusbar_add); - command_bind("statusbar remove", NULL, (SIGNAL_FUNC) cmd_statusbar_remove); - command_bind("statusbar type", NULL, (SIGNAL_FUNC) cmd_statusbar_type); - command_bind("statusbar placement", NULL, (SIGNAL_FUNC) cmd_statusbar_placement); - command_bind("statusbar position", NULL, (SIGNAL_FUNC) cmd_statusbar_position); - command_bind("statusbar visible", NULL, (SIGNAL_FUNC) cmd_statusbar_visible); + command_bind("statusbar", NULL, (SIGNAL_FUNC) cmd_statusbar); + command_bind("statusbar list", NULL, (SIGNAL_FUNC) cmd_statusbar_list); + command_bind("statusbar add", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_bind("statusbar modify", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_bind("statusbar reset", NULL, (SIGNAL_FUNC) cmd_statusbar_reset); + command_bind("statusbar info", NULL, (SIGNAL_FUNC) cmd_statusbar_info); + command_bind("statusbar additem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_bind("statusbar modifyitem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_bind("statusbar removeitem", NULL, (SIGNAL_FUNC) cmd_statusbar_removeitem); - command_set_options("statusbar add", "+before +after +priority +alignment"); + command_set_options("statusbar additem", "+before +after +priority +alignment"); + command_set_options("statusbar modifyitem", "+before +after +priority +alignment"); + command_set_options("statusbar add", + "disable nodisable +type +placement +position +visible"); + command_set_options("statusbar modify", + "disable nodisable +type +placement +position +visible"); } void statusbar_config_deinit(void) @@ -590,14 +710,13 @@ void statusbar_config_deinit(void) signal_remove("setup reread", (SIGNAL_FUNC) read_statusbar_config); signal_remove("theme changed", (SIGNAL_FUNC) read_statusbar_config); - command_unbind("statusbar", (SIGNAL_FUNC) cmd_statusbar); - command_unbind("statusbar enable", (SIGNAL_FUNC) cmd_statusbar_enable); - command_unbind("statusbar disable", (SIGNAL_FUNC) cmd_statusbar_disable); - command_unbind("statusbar reset", (SIGNAL_FUNC) cmd_statusbar_reset); - command_unbind("statusbar add", (SIGNAL_FUNC) cmd_statusbar_add); - command_unbind("statusbar remove", (SIGNAL_FUNC) cmd_statusbar_remove); - command_unbind("statusbar type", (SIGNAL_FUNC) cmd_statusbar_type); - command_unbind("statusbar placement", (SIGNAL_FUNC) cmd_statusbar_placement); - command_unbind("statusbar position", (SIGNAL_FUNC) cmd_statusbar_position); - command_unbind("statusbar visible", (SIGNAL_FUNC) cmd_statusbar_visible); + command_unbind("statusbar", (SIGNAL_FUNC) cmd_statusbar); + command_unbind("statusbar list", (SIGNAL_FUNC) cmd_statusbar_list); + command_unbind("statusbar add", (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_unbind("statusbar modify", (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_unbind("statusbar reset", (SIGNAL_FUNC) cmd_statusbar_reset); + command_unbind("statusbar info", (SIGNAL_FUNC) cmd_statusbar_info); + command_unbind("statusbar additem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_unbind("statusbar modifyitem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_unbind("statusbar removeitem", (SIGNAL_FUNC) cmd_statusbar_removeitem); } From 61c58b7690e9eec159ba32e5ea40809ed17ef424 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Mar 2018 10:35:39 +0100 Subject: [PATCH 0351/1198] actually check which of add or modify was called --- src/fe-text/statusbar-config.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 391a5768..75d10612 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -374,6 +374,7 @@ static void cmd_statusbar_add_modify(const char *data, void *server, void *witem char *name, *type, *placement, *visible; void *free_arg; int error; + int add = GPOINTER_TO_INT(signal_get_user_data()); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "statusbar add", &optlist, &name)) @@ -429,12 +430,20 @@ static void cmd_statusbar_add_modify(const char *data, void *server, void *witem } } + if (!error) { + node = sbar_node(name, add); + + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name); + error++; + } + } + if (error) { cmd_params_free(free_arg); return; } - node = sbar_node(name, TRUE); if (g_hash_table_lookup(optlist, "nodisable")) iconfig_node_set_str(node, "disabled", NULL); if (g_hash_table_lookup(optlist, "disable")) @@ -527,6 +536,7 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi char *item, *statusbar, *value; void *free_arg; int index; + int additem = GINT_TO_POINTER(signal_get_user_data()); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "statusbar additem", &optlist, &item, &statusbar)) @@ -556,6 +566,12 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi value = g_hash_table_lookup(optlist, "after"); if (value != NULL) index = config_node_index(node, value)+1; + if (!additem && iconfig_node_section(node, item, -1) == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + cmd_params_free(free_arg); + return; + } + /* create/move item */ node = iconfig_node_section_index(node, item, index, NODE_TYPE_BLOCK); @@ -689,12 +705,12 @@ void statusbar_config_init(void) command_bind("statusbar", NULL, (SIGNAL_FUNC) cmd_statusbar); command_bind("statusbar list", NULL, (SIGNAL_FUNC) cmd_statusbar_list); - command_bind("statusbar add", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify); - command_bind("statusbar modify", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_bind_data("statusbar add", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify, GINT_TO_POINTER(TRUE)); + command_bind_data("statusbar modify", NULL, (SIGNAL_FUNC) cmd_statusbar_add_modify, GINT_TO_POINTER(FALSE)); command_bind("statusbar reset", NULL, (SIGNAL_FUNC) cmd_statusbar_reset); command_bind("statusbar info", NULL, (SIGNAL_FUNC) cmd_statusbar_info); - command_bind("statusbar additem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); - command_bind("statusbar modifyitem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_bind_data("statusbar additem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem, GINT_TO_POINTER(TRUE)); + command_bind_data("statusbar modifyitem", NULL, (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem, GINT_TO_POINTER(FALSE)); command_bind("statusbar removeitem", NULL, (SIGNAL_FUNC) cmd_statusbar_removeitem); command_set_options("statusbar additem", "+before +after +priority +alignment"); @@ -712,11 +728,11 @@ void statusbar_config_deinit(void) command_unbind("statusbar", (SIGNAL_FUNC) cmd_statusbar); command_unbind("statusbar list", (SIGNAL_FUNC) cmd_statusbar_list); - command_unbind("statusbar add", (SIGNAL_FUNC) cmd_statusbar_add_modify); - command_unbind("statusbar modify", (SIGNAL_FUNC) cmd_statusbar_add_modify); + command_unbind_full("statusbar add", (SIGNAL_FUNC) cmd_statusbar_add_modify, GINT_TO_POINTER(TRUE)); + command_unbind_full("statusbar modify", (SIGNAL_FUNC) cmd_statusbar_add_modify, GINT_TO_POINTER(FALSE)); command_unbind("statusbar reset", (SIGNAL_FUNC) cmd_statusbar_reset); command_unbind("statusbar info", (SIGNAL_FUNC) cmd_statusbar_info); - command_unbind("statusbar additem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); - command_unbind("statusbar modifyitem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem); + command_unbind_full("statusbar additem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem, GINT_TO_POINTER(TRUE)); + command_unbind_full("statusbar modifyitem", (SIGNAL_FUNC) cmd_statusbar_additem_modifyitem, GINT_TO_POINTER(FALSE)); command_unbind("statusbar removeitem", (SIGNAL_FUNC) cmd_statusbar_removeitem); } From c8191b33155ae7ee1ebb07d87b8e001f75188eeb Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Mar 2018 09:41:53 +0100 Subject: [PATCH 0352/1198] abi bump --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 746aad4e..de29abd5 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 15 +#define IRSSI_ABI_VERSION 16 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 501c150ec21b1dceeecc0c201d22fc1bad161cf4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Mar 2018 17:39:08 +0100 Subject: [PATCH 0353/1198] make new status bar actually work --- src/fe-text/statusbar-config.c | 196 ++++++++++++++++++++++++++------- 1 file changed, 154 insertions(+), 42 deletions(-) diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 75d10612..a6ec81fe 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -275,22 +275,49 @@ static const char *sbar_get_visibility(STATUSBAR_CONFIG_REC *rec) rec->visible == STATUSBAR_VISIBLE_INACTIVE ? "inactive" : "??"; } -static CONFIG_NODE *sbar_node(const char *name, gboolean create) +#define iconfig_sbar_node(a, b) config_sbar_node(mainconfig, a, b) +static CONFIG_NODE *config_sbar_node(CONFIG_REC *config, const char *name, gboolean create) { CONFIG_NODE *node; + + node = config_node_traverse(config, "statusbar", create); + if (node != NULL) { + node = config_node_section(config, node, active_statusbar_group->name, + create ? NODE_TYPE_BLOCK : -1); + } + + if (node != NULL) { + node = config_node_section(config, node, name, create ? NODE_TYPE_BLOCK : -1); + } + + return node; +} + +static CONFIG_NODE *sbar_node(const char *name, gboolean create) +{ STATUSBAR_CONFIG_REC *rec = statusbar_config_find(active_statusbar_group, name); if (rec != NULL) { name = rec->name; - } else if (!create) { - return NULL; } /* lookup/create the statusbar node */ - node = iconfig_node_traverse("statusbar", TRUE); - node = iconfig_node_section(node, active_statusbar_group->name, NODE_TYPE_BLOCK); - node = iconfig_node_section(node, name, NODE_TYPE_BLOCK); + return iconfig_sbar_node(name, create); +} - return node; +static gboolean sbar_node_isdefault(const char *name) +{ + CONFIG_REC *config; + CONFIG_NODE *node; + + /* read the default statusbar settings from internal config */ + config = config_open(NULL, -1); + config_parse_data(config, default_config, "internal"); + + node = config_sbar_node(config, name, FALSE); + + config_close(config); + + return node != NULL ? TRUE : FALSE; } static void statusbar_list_items(STATUSBAR_CONFIG_REC *bar) @@ -432,6 +459,11 @@ static void cmd_statusbar_add_modify(const char *data, void *server, void *witem if (!error) { node = sbar_node(name, add); + if (node == NULL && !add && sbar_node_isdefault(name)) { + /* If this node is a default status bar, we need to create it in the config + * to configure it */ + node = sbar_node(name, TRUE); + } if (node == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name); @@ -477,50 +509,59 @@ static void cmd_statusbar_reset(const char *data, void *server, void *witem) } node = sbar_node(name, FALSE); - if (node == NULL) { + if (node == NULL && !sbar_node_isdefault(name)) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, name); cmd_params_free(free_arg); return; } - parent = iconfig_node_traverse("statusbar", TRUE); - parent = iconfig_node_section(parent, active_statusbar_group->name, NODE_TYPE_BLOCK); + parent = iconfig_node_traverse("statusbar", FALSE); + if (parent != NULL) { + parent = iconfig_node_section(parent, active_statusbar_group->name, -1); + } - iconfig_node_set_str(parent, node->key, NULL); + if (parent != NULL && node != NULL) { + iconfig_node_set_str(parent, node->key, NULL); + } read_statusbar_config(); cmd_params_free(free_arg); } -static CONFIG_NODE *statusbar_items_section(CONFIG_NODE *parent) +#define iconfig_sbar_items_section(a, b) config_sbar_items_section(mainconfig, a, b) +static CONFIG_NODE *config_sbar_items_section(CONFIG_REC *config, CONFIG_NODE *parent, + gboolean create) +{ + return config_node_section(config, parent, "items", create ? NODE_TYPE_BLOCK : -1); +} + +static CONFIG_NODE *statusbar_copy_config(CONFIG_REC *config, CONFIG_NODE *source, + CONFIG_NODE *parent) { - STATUSBAR_CONFIG_REC *bar; - CONFIG_NODE *node; GSList *tmp; - node = iconfig_node_section(parent, "items", -1); - if (node != NULL) - return node; + g_return_val_if_fail(parent != NULL, NULL); - /* find the statusbar configuration from memory */ - bar = statusbar_config_find(active_statusbar_group, parent->key); - if (bar == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_NOT_FOUND, parent->key); - return NULL; - } + parent = iconfig_sbar_items_section(parent, TRUE); /* since items list in config file overrides defaults, we'll need to copy the whole list. */ - parent = iconfig_node_section(parent, "items", NODE_TYPE_BLOCK); - for (tmp = bar->items; tmp != NULL; tmp = tmp->next) { - SBAR_ITEM_CONFIG_REC *rec = tmp->data; + for (tmp = config_node_first(source->value); tmp != NULL; tmp = config_node_next(tmp)) { + int priority, right_alignment; + CONFIG_NODE *node, *snode; - node = iconfig_node_section(parent, rec->name, - NODE_TYPE_BLOCK); - if (rec->priority != 0) - iconfig_node_set_int(node, "priority", rec->priority); - if (rec->right_alignment) + snode = tmp->data; + + priority = config_node_get_int(snode, "priority", 0); + right_alignment = + g_strcmp0(config_node_get_str(snode, "alignment", ""), "right") == 0; + + /* create new item */ + node = iconfig_node_section(parent, snode->key, NODE_TYPE_BLOCK); + + if (priority != 0) + iconfig_node_set_int(node, "priority", priority); + if (right_alignment) iconfig_node_set_str(node, "alignment", "right"); } @@ -531,12 +572,13 @@ static CONFIG_NODE *statusbar_items_section(CONFIG_NODE *parent) [-priority #] [-alignment left|right] */ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, void *witem) { + CONFIG_REC *config, *close_config; CONFIG_NODE *node; GHashTable *optlist; char *item, *statusbar, *value; void *free_arg; int index; - int additem = GINT_TO_POINTER(signal_get_user_data()); + int additem = GPOINTER_TO_INT(signal_get_user_data()); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "statusbar additem", &optlist, &item, &statusbar)) @@ -546,15 +588,33 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); } + close_config = NULL; + config = mainconfig; + node = sbar_node(statusbar, FALSE); + if (node == NULL) { + /* we are looking up defaults from the internal config */ + close_config = config = config_open(NULL, -1); + config_parse_data(config, default_config, "internal"); + node = config_sbar_node(config, statusbar, FALSE); + } + if (node == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); + if (close_config != NULL) { + config_close(close_config); + } cmd_params_free(free_arg); return; } - node = statusbar_items_section(node); + node = config_sbar_items_section(config, node, additem); + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + if (close_config != NULL) { + config_close(close_config); + } cmd_params_free(free_arg); return; } @@ -566,8 +626,28 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi value = g_hash_table_lookup(optlist, "after"); if (value != NULL) index = config_node_index(node, value)+1; - if (!additem && iconfig_node_section(node, item, -1) == NULL) { + if (!additem && config_node_section(config, node, item, -1) == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + if (close_config != NULL) { + config_close(close_config); + } + cmd_params_free(free_arg); + return; + } + + if (config != mainconfig) { + /* we need to copy default to user config */ + node = statusbar_copy_config(config, node, sbar_node(statusbar, TRUE)); + config = mainconfig; + } + + if (close_config != NULL) { + config_close(close_config); + close_config = NULL; + } + + if (node == NULL) { + g_warning("node not found"); cmd_params_free(free_arg); return; } @@ -593,6 +673,7 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi /* SYNTAX: STATUSBAR REMOVEITEM */ static void cmd_statusbar_removeitem(const char *data, void *server, void *witem) { + CONFIG_REC *config, *close_config; CONFIG_NODE *node; char *item, *statusbar; void *free_arg; @@ -603,25 +684,56 @@ static void cmd_statusbar_removeitem(const char *data, void *server, void *witem cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); } + close_config = NULL; + config = mainconfig; + node = sbar_node(statusbar, FALSE); if (node == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); - cmd_params_free(free_arg); - return; + /* we are looking up defaults from the internal config */ + close_config = config = config_open(NULL, -1); + config_parse_data(config, default_config, "internal"); + node = config_sbar_node(config, statusbar, FALSE); } - node = statusbar_items_section(node); if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); + if (close_config != NULL) { + config_close(close_config); + } cmd_params_free(free_arg); return; } - if (iconfig_node_section(node, item, -1) != NULL) - iconfig_node_set_str(node, item, NULL); - else { + node = config_sbar_items_section(config, node, FALSE); + + if (node == NULL || config_node_section(config, node, item, -1) == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + if (close_config != NULL) { + config_close(close_config); + } + cmd_params_free(free_arg); + return; } + if (config != mainconfig) { + /* we need to copy default to user config */ + node = statusbar_copy_config(config, node, sbar_node(statusbar, TRUE)); + config = mainconfig; + } + + if (close_config != NULL) { + config_close(close_config); + close_config = NULL; + } + + if (node == NULL) { + g_warning("node not found"); + cmd_params_free(free_arg); + return; + } + + iconfig_node_set_str(node, item, NULL); + read_statusbar_config(); cmd_params_free(free_arg); } From 977c2c0a0d911e3b7b43387ed19c5bfee565c617 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Mar 2018 17:53:03 +0100 Subject: [PATCH 0354/1198] refactor common parts --- src/fe-text/statusbar-config.c | 155 +++++++++++---------------------- 1 file changed, 52 insertions(+), 103 deletions(-) diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index a6ec81fe..0c6070fa 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -568,11 +568,54 @@ static CONFIG_NODE *statusbar_copy_config(CONFIG_REC *config, CONFIG_NODE *sourc return parent; } +static CONFIG_NODE *sbar_find_item_with_defaults(const char *statusbar, const char *item, + gboolean create) +{ + CONFIG_REC *config, *close_config; + CONFIG_NODE *node; + + close_config = NULL; + config = mainconfig; + node = sbar_node(statusbar, FALSE); + + if (node == NULL) { + /* we are looking up defaults from the internal config */ + close_config = config = config_open(NULL, -1); + config_parse_data(config, default_config, "internal"); + node = config_sbar_node(config, statusbar, FALSE); + } + + if (node == NULL) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); + if (close_config != NULL) + config_close(close_config); + return NULL; + } + + node = config_sbar_items_section(config, node, create); + + if (node == NULL || (!create && config_node_section(config, node, item, -1) == NULL)) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); + if (close_config != NULL) + config_close(close_config); + return NULL; + } + + if (config != mainconfig) { + /* we need to copy default to user config */ + node = statusbar_copy_config(config, node, sbar_node(statusbar, TRUE)); + } + + if (close_config != NULL) + config_close(close_config); + + return node; +} + /* SYNTAX: STATUSBAR ADDITEM|MODIFYITEM [-before | -after ] [-priority #] [-alignment left|right] */ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, void *witem) { - CONFIG_REC *config, *close_config; CONFIG_NODE *node; GHashTable *optlist; char *item, *statusbar, *value; @@ -588,33 +631,8 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); } - close_config = NULL; - config = mainconfig; - - node = sbar_node(statusbar, FALSE); + node = sbar_find_item_with_defaults(statusbar, item, additem); if (node == NULL) { - /* we are looking up defaults from the internal config */ - close_config = config = config_open(NULL, -1); - config_parse_data(config, default_config, "internal"); - node = config_sbar_node(config, statusbar, FALSE); - } - - if (node == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); - if (close_config != NULL) { - config_close(close_config); - } - cmd_params_free(free_arg); - return; - } - - node = config_sbar_items_section(config, node, additem); - - if (node == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); - if (close_config != NULL) { - config_close(close_config); - } cmd_params_free(free_arg); return; } @@ -622,35 +640,11 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi /* get the index */ index = -1; value = g_hash_table_lookup(optlist, "before"); - if (value != NULL) index = config_node_index(node, value); + if (value != NULL) + index = config_node_index(node, value); value = g_hash_table_lookup(optlist, "after"); - if (value != NULL) index = config_node_index(node, value)+1; - - if (!additem && config_node_section(config, node, item, -1) == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); - if (close_config != NULL) { - config_close(close_config); - } - cmd_params_free(free_arg); - return; - } - - if (config != mainconfig) { - /* we need to copy default to user config */ - node = statusbar_copy_config(config, node, sbar_node(statusbar, TRUE)); - config = mainconfig; - } - - if (close_config != NULL) { - config_close(close_config); - close_config = NULL; - } - - if (node == NULL) { - g_warning("node not found"); - cmd_params_free(free_arg); - return; - } + if (value != NULL) + index = config_node_index(node, value) + 1; /* create/move item */ node = iconfig_node_section_index(node, item, index, NODE_TYPE_BLOCK); @@ -684,55 +678,10 @@ static void cmd_statusbar_removeitem(const char *data, void *server, void *witem cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); } - close_config = NULL; - config = mainconfig; + node = sbar_find_item_with_defaults(statusbar, item, FALSE); - node = sbar_node(statusbar, FALSE); - if (node == NULL) { - /* we are looking up defaults from the internal config */ - close_config = config = config_open(NULL, -1); - config_parse_data(config, default_config, "internal"); - node = config_sbar_node(config, statusbar, FALSE); - } - - if (node == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_NOT_FOUND, statusbar); - if (close_config != NULL) { - config_close(close_config); - } - cmd_params_free(free_arg); - return; - } - - node = config_sbar_items_section(config, node, FALSE); - - if (node == NULL || config_node_section(config, node, item, -1) == NULL) { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_STATUSBAR_ITEM_NOT_FOUND, item); - if (close_config != NULL) { - config_close(close_config); - } - cmd_params_free(free_arg); - return; - } - - if (config != mainconfig) { - /* we need to copy default to user config */ - node = statusbar_copy_config(config, node, sbar_node(statusbar, TRUE)); - config = mainconfig; - } - - if (close_config != NULL) { - config_close(close_config); - close_config = NULL; - } - - if (node == NULL) { - g_warning("node not found"); - cmd_params_free(free_arg); - return; - } - - iconfig_node_set_str(node, item, NULL); + if (node != NULL) + iconfig_node_set_str(node, item, NULL); read_statusbar_config(); cmd_params_free(free_arg); From ee04cd503ff70a1aed79cdb2c9f787c98b075182 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Mar 2018 17:59:11 +0100 Subject: [PATCH 0355/1198] add disabled txt --- src/fe-text/module-formats.c | 1 + src/fe-text/module-formats.h | 1 + src/fe-text/statusbar-config.c | 8 ++++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index b234f46c..277872c6 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -67,6 +67,7 @@ FORMAT_REC gui_text_formats[] = { "statusbar_info_item_footer", "", 0 }, { "statusbar_info_item_name", "%# : $[35]0 $[9]1 $2", 3, { 0, 1, 0 } }, { "statusbar_not_found", "Statusbar doesn't exist: $0", 1, { 0 } }, + { "statusbar_not_found", "Statusbar is disabled: $0", 1, { 0 } }, { "statusbar_item_not_found", "Statusbar item doesn't exist: $0", 1, { 0 } }, { "statusbar_unknown_command", "Unknown statusbar command: $0", 1, { 0 } }, { "statusbar_unknown_type", "Statusbar type must be 'window' or 'root'", 1, { 0 } }, diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h index b753238b..a9f4c6ae 100644 --- a/src/fe-text/module-formats.h +++ b/src/fe-text/module-formats.h @@ -42,6 +42,7 @@ enum { TXT_STATUSBAR_INFO_ITEM_FOOTER, TXT_STATUSBAR_INFO_ITEM_NAME, TXT_STATUSBAR_NOT_FOUND, + TXT_STATUSBAR_NOT_ENABLED, TXT_STATUSBAR_ITEM_NOT_FOUND, TXT_STATUSBAR_UNKNOWN_COMMAND, TXT_STATUSBAR_UNKNOWN_TYPE, diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 0c6070fa..7b5b6884 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -388,8 +388,12 @@ static void cmd_statusbar_print_info(const char *name) return; } - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_STATUSBAR_NOT_FOUND, name); + if (sbar_node(name, FALSE) != NULL || sbar_node_isdefault(name)) + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_STATUSBAR_NOT_ENABLED, name); + else + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_STATUSBAR_NOT_FOUND, name); } /* SYNTAX: STATUSBAR ADD|MODIFY [-disable | -nodisable] [-type window|root] From 138eca0749dd05a4a16df9e43d87af2143b224f2 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Mar 2018 18:11:12 +0100 Subject: [PATCH 0356/1198] fix build --- src/fe-text/module-formats.h | 18 +++++++++--------- src/fe-text/statusbar-config.c | 5 ++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h index a9f4c6ae..ac60fdb7 100644 --- a/src/fe-text/module-formats.h +++ b/src/fe-text/module-formats.h @@ -30,24 +30,24 @@ enum { TXT_FILL_3, - TXT_STATUSBAR_LIST_HEADER, + TXT_STATUSBAR_LIST_HEADER, TXT_STATUSBAR_LIST_FOOTER, TXT_STATUSBAR_LIST, TXT_STATUSBAR_INFO_NAME, TXT_STATUSBAR_INFO_TYPE, - TXT_STATUSBAR_INFO_PLACEMENT, + TXT_STATUSBAR_INFO_PLACEMENT, TXT_STATUSBAR_INFO_POSITION, TXT_STATUSBAR_INFO_VISIBLE, - TXT_STATUSBAR_INFO_ITEM_HEADER, + TXT_STATUSBAR_INFO_ITEM_HEADER, TXT_STATUSBAR_INFO_ITEM_FOOTER, - TXT_STATUSBAR_INFO_ITEM_NAME, - TXT_STATUSBAR_NOT_FOUND, - TXT_STATUSBAR_NOT_ENABLED, - TXT_STATUSBAR_ITEM_NOT_FOUND, + TXT_STATUSBAR_INFO_ITEM_NAME, + TXT_STATUSBAR_NOT_FOUND, + TXT_STATUSBAR_NOT_ENABLED, + TXT_STATUSBAR_ITEM_NOT_FOUND, TXT_STATUSBAR_UNKNOWN_COMMAND, - TXT_STATUSBAR_UNKNOWN_TYPE, + TXT_STATUSBAR_UNKNOWN_TYPE, TXT_STATUSBAR_UNKNOWN_PLACEMENT, - TXT_STATUSBAR_UNKNOWN_VISIBILITY, + TXT_STATUSBAR_UNKNOWN_VISIBILITY, TXT_FILL_4, diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 7b5b6884..314befaa 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -101,7 +101,7 @@ statusbar_config_find(STATUSBAR_GROUP_REC *group, const char *name) return config; } - return NULL; + return NULL; } static void statusbar_reset_defaults(void) @@ -542,7 +542,7 @@ static CONFIG_NODE *config_sbar_items_section(CONFIG_REC *config, CONFIG_NODE *p static CONFIG_NODE *statusbar_copy_config(CONFIG_REC *config, CONFIG_NODE *source, CONFIG_NODE *parent) { - GSList *tmp; + GSList *tmp; g_return_val_if_fail(parent != NULL, NULL); @@ -671,7 +671,6 @@ static void cmd_statusbar_additem_modifyitem(const char *data, void *server, voi /* SYNTAX: STATUSBAR REMOVEITEM */ static void cmd_statusbar_removeitem(const char *data, void *server, void *witem) { - CONFIG_REC *config, *close_config; CONFIG_NODE *node; char *item, *statusbar; void *free_arg; From 25a44dacf4114f33f3a887f358c02f4fd9938427 Mon Sep 17 00:00:00 2001 From: Dorian Harmans Date: Fri, 23 Mar 2018 21:35:35 +0100 Subject: [PATCH 0357/1198] fix build with LibreSSL 2.7.0 --- src/core/network-openssl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 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; From b52cf1015eaa4d759c9377df35a56988655dce89 Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 28 Mar 2018 22:40:17 -0300 Subject: [PATCH 0358/1198] otr: add KEY_GEN_STARTED state to avoid starting it twice Fun race condition there, got this when testing with the jabber xmlconsole open in bitlbee --- src/otr/key.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/otr/key.c b/src/otr/key.c index 4032b0b2..7fee4084 100644 --- a/src/otr/key.c +++ b/src/otr/key.c @@ -43,9 +43,10 @@ */ enum key_gen_status { KEY_GEN_IDLE = 0, - KEY_GEN_RUNNING = 1, - KEY_GEN_FINISHED = 2, - KEY_GEN_ERROR = 3, + KEY_GEN_STARTED = 1, + KEY_GEN_RUNNING = 2, + KEY_GEN_FINISHED = 3, + KEY_GEN_ERROR = 4, }; /* @@ -208,6 +209,7 @@ void key_gen_run(struct otr_user_state *ustate, const char *account_name) /* Make sure the pointer does not go away during the proess. */ key_gen_state.account_name = strdup(account_name); key_gen_state.ustate = ustate; + key_gen_state.status = KEY_GEN_STARTED; /* Creating key file path. */ key_gen_state.key_file_path = file_path_build(OTR_KEYFILE); From dd7dc7ca7d0b04ae2d522a209845c453bfd9aab5 Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 28 Mar 2018 23:06:47 -0300 Subject: [PATCH 0359/1198] otr: fix missing 'target' param in 'message private' signal Fixes warnings like these on '/msg yourself' -!- Irssi: critical privmsg_get_query: assertion 'nick != NULL' failed -!- Irssi: critical query_find: assertion 'nick != NULL' failed --- src/otr/module.c | 6 +++--- src/otr/module.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/otr/module.c b/src/otr/module.c index 0d83629f..f561b91c 100644 --- a/src/otr/module.c +++ b/src/otr/module.c @@ -79,7 +79,7 @@ static void sig_server_sendmsg(SERVER_REC *server, const char *target, /* * Pipes all incoming private messages through OTR */ -void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address) +void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { char *new_msg = NULL; @@ -91,7 +91,7 @@ void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, if (new_msg == NULL) { /* This message was not OTR */ - signal_continue(4, server, msg, nick, address); + signal_continue(5, server, msg, nick, address, target); } else { /* * Check for /me IRC marker and if so, handle it so the user does not @@ -103,7 +103,7 @@ void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, signal_emit("message irc action", 5, server, new_msg + OTR_IRC_MARKER_ME_LEN, nick, address, nick); } else { /* OTR received message */ - signal_continue(4, server, new_msg, nick, address); + signal_continue(5, server, new_msg, nick, address, target); } } diff --git a/src/otr/module.h b/src/otr/module.h index fdfc77bd..513ee03b 100644 --- a/src/otr/module.h +++ b/src/otr/module.h @@ -24,6 +24,6 @@ #include "common.h" #include "servers.h" -void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address); +void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target); #endif /* IRSSI_OTR_MODULE */ From 7d7c6975edc13d6f285c00dfc8a4f1a98ffa6702 Mon Sep 17 00:00:00 2001 From: dequis Date: Wed, 28 Mar 2018 23:36:03 -0300 Subject: [PATCH 0360/1198] otr: add target param to the unencrypted 'message private' signal Same case as the previous commit. --- src/otr/otr-ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/otr/otr-ops.c b/src/otr/otr-ops.c index 9359e63e..4e8c4e81 100644 --- a/src/otr/otr-ops.c +++ b/src/otr/otr-ops.c @@ -183,7 +183,7 @@ static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event, ConnC * submit a patch or email me a better way. */ signal_remove("message private", (SIGNAL_FUNC) sig_message_private); - signal_emit("message private", 4, server, message, username, server->connrec->address); + signal_emit("message private", 5, server, message, username, server->connrec->address, server->nick); signal_add_first("message private", (SIGNAL_FUNC) sig_message_private); break; case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED: From a3b9e2370fd02eb6a400744e31d7db27c8fe92b8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 29 Mar 2018 22:00:40 +0200 Subject: [PATCH 0361/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 746aad4e..de29abd5 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 15 +#define IRSSI_ABI_VERSION 16 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 2830d91a89277052ee8e6978a41a7773c9fe5025 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 29 Mar 2018 22:41:12 +0200 Subject: [PATCH 0362/1198] use precompiled libotr --- .travis.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index a17cb3ec..30f9cc35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,19 +31,16 @@ addons: before_install: - perl -V - - wget https://otr.cypherpunks.ca/libotr-4.1.1.tar.gz - - tar zxf libotr-*.tar.gz - - cd libotr-* - - ./configure --prefix $HOME/otr-prefix && make && make install - - cd .. - - ./autogen.sh --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-prefix/lib --with-libotr-inc-prefix=$HOME/otr-prefix/include + - wget https://github.com/irssi-import/libotr/releases/download/4.1.1/travis-trusty-libotr-4.1.1.tar.gz + - tar zxf travis-trusty-libotr*.tar.gz -C $HOME + - ./autogen.sh --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-build/lib --with-libotr-inc-prefix=$HOME/otr-build/include - make dist - cd .. - tar xaf */irssi-*.tar.* - cd irssi-* install: - - ./configure --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-prefix/lib --with-libotr-inc-prefix=$HOME/otr-prefix/include --prefix=$HOME/irssi-build + - ./configure --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-build/lib --with-libotr-inc-prefix=$HOME/otr-build/include --prefix=$HOME/irssi-build $( $UNITTESTS && echo --enable-always-build-tests ) - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - make install From c08685a1a3e4a719fcfe8f30a338a91db8c3b8d1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 19 Mar 2018 16:06:46 +0100 Subject: [PATCH 0363/1198] also reconnect lookup_servers --- src/core/servers-reconnect.c | 15 +++++++++++++++ src/core/servers.c | 1 + 2 files changed, 16 insertions(+) diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 1727704c..5f609cf5 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -111,6 +111,21 @@ static int server_reconnect_timeout(void) } } + for (tmp = lookup_servers; tmp != NULL; tmp = next) { + SERVER_REC *server = tmp->data; + + next = tmp->next; + if (server->connect_time + connect_timeout < now && + connect_timeout > 0) { + if (server->connect_tag != -1) { + g_source_remove(server->connect_tag); + server->connect_tag = -1; + } + server->connection_lost = TRUE; + server_connect_failed(server, "Timeout"); + } + } + /* If server_connect() removes the next reconnection in queue, we're screwed. I don't think this should happen anymore, but just to be sure we don't crash, do this safely. */ diff --git a/src/core/servers.c b/src/core/servers.c index 11eccc53..81bdb89e 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -426,6 +426,7 @@ int server_start_connect(SERVER_REC *server) server_connect_callback_readpipe, server); + server->connect_time = time(NULL); lookup_servers = g_slist_append(lookup_servers, server); signal_emit("server looking", 1, server); From 4501917cae4523d11fb049a5d20e5582bb0893ea Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 31 Mar 2018 01:46:10 -0300 Subject: [PATCH 0364/1198] otr: rename module.c to otr-module.c --- src/otr/Makefile.am | 2 +- src/otr/{module.c => otr-module.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/otr/{module.c => otr-module.c} (100%) diff --git a/src/otr/Makefile.am b/src/otr/Makefile.am index 3b991839..7cc02d6d 100644 --- a/src/otr/Makefile.am +++ b/src/otr/Makefile.am @@ -21,7 +21,7 @@ libotr_core_la_LIBADD = $(OTR_LDFLAGS) otr_sources = \ key.c \ - module.c \ + otr-module.c \ otr-formats.c \ otr-ops.c \ otr-fe.c \ diff --git a/src/otr/module.c b/src/otr/otr-module.c similarity index 100% rename from src/otr/module.c rename to src/otr/otr-module.c From 0b2f5b0a1e30932b07245c508a673eb0e9b6ab37 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 31 Mar 2018 01:51:47 -0300 Subject: [PATCH 0365/1198] otr: fix blatant lies in help text --- docs/help/in/otr.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/otr.in b/docs/help/in/otr.in index c31bd8e8..f76a2d53 100644 --- a/docs/help/in/otr.in +++ b/docs/help/in/otr.in @@ -1,7 +1,7 @@ OTR %|[OPTION] -Command to control the OTR module. Without an option, this help is printed. +Command to control the OTR module. Without an option, /OTR INFO is printed. This help contains three sections which are %9options, quickstart and files.%n From 407680efdc662787ecbd1297d1f4781acdb5168c Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 2 Apr 2018 12:30:59 -0300 Subject: [PATCH 0366/1198] Add libgcrypt.m4 so autogen doesn't require libgcrypt-dev --- m4/libgcrypt.m4 | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 m4/libgcrypt.m4 diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 new file mode 100644 index 00000000..c67cfece --- /dev/null +++ b/m4/libgcrypt.m4 @@ -0,0 +1,143 @@ +# libgcrypt.m4 - Autoconf macros to detect libgcrypt +# Copyright (C) 2002, 2003, 2004, 2011, 2014 g10 Code GmbH +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Last-changed: 2014-10-02 + + +dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. +dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl with the API version to also check the API compatibility. Example: +dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed +dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using +dnl this features allows to prevent build against newer versions of libgcrypt +dnl with a changed API. +dnl +dnl If a prefix option is not used, the config script is first +dnl searched in $SYSROOT/bin and then along $PATH. If the used +dnl config script does not match the host specification the script +dnl is added to the gpg_config_script_warn variable. +dnl +AC_DEFUN([AM_PATH_LIBGCRYPT], +[ AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(libgcrypt-prefix, + AC_HELP_STRING([--with-libgcrypt-prefix=PFX], + [prefix where LIBGCRYPT is installed (optional)]), + libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") + if test x"${LIBGCRYPT_CONFIG}" = x ; then + if test x"${libgcrypt_config_prefix}" != x ; then + LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config" + else + case "${SYSROOT}" in + /*) + if test -x "${SYSROOT}/bin/libgcrypt-config" ; then + LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config" + fi + ;; + '') + ;; + *) + AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.]) + ;; + esac + fi + fi + + AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) + tmp=ifelse([$1], ,1:1.2.0,$1) + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libgcrypt_api=0 + min_libgcrypt_version="$tmp" + fi + + AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) + ok=no + if test "$LIBGCRYPT_CONFIG" != "no" ; then + req_major=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` + major=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + micro=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + fi + if test $ok = yes; then + AC_MSG_RESULT([yes ($libgcrypt_config_version)]) + else + AC_MSG_RESULT(no) + fi + if test $ok = yes; then + # If we have a recent libgcrypt, we should also check that the + # API is compatible + if test "$req_libgcrypt_api" -gt 0 ; then + tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + AC_MSG_CHECKING([LIBGCRYPT API version]) + if test "$req_libgcrypt_api" -eq "$tmp" ; then + AC_MSG_RESULT([okay]) + else + ok=no + AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) + fi + fi + fi + fi + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` + ifelse([$2], , :, [$2]) + libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` + if test x"$libgcrypt_config_host" != xnone ; then + if test x"$libgcrypt_config_host" != x"$host" ; then + AC_MSG_WARN([[ +*** +*** The config script $LIBGCRYPT_CONFIG was +*** built for $libgcrypt_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libgcrypt-prefix +*** to specify a matching config script or use \$SYSROOT. +***]]) + gpg_config_script_warn="$gpg_config_script_warn libgcrypt" + fi + fi + else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(LIBGCRYPT_CFLAGS) + AC_SUBST(LIBGCRYPT_LIBS) +]) From 8607a5fa78ba44db51cc75a020e1a53c4e04a057 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 7 Apr 2018 21:47:38 -0300 Subject: [PATCH 0367/1198] signals.txt: add missing 'server cap new|delete' signals Emitted by cap_emit_signal in irc/core/irc-cap.c, added as part of the CAP 3.2 PR merged recentlyish. --- docs/signals.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/signals.txt b/docs/signals.txt index 84d4518f..4dbfb2e2 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -132,6 +132,8 @@ irc-servers.c: irc-cap.c "server cap ack ", SERVER_REC "server cap nak ", SERVER_REC + "server cap new ", SERVER_REC + "server cap delete ", SERVER_REC "server cap end", SERVER_REC sasl.c From af5ee997e7544eb59ed509ef8fb79ec449756e90 Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 8 Apr 2018 01:24:48 -0300 Subject: [PATCH 0368/1198] Add "server cap req" signal, emitted before requesting caps --- docs/signals.txt | 1 + src/irc/core/irc-cap.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index 84d4518f..97ce6c69 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -133,6 +133,7 @@ irc-cap.c "server cap ack ", SERVER_REC "server cap nak ", SERVER_REC "server cap end", SERVER_REC + "server cap req", SERVER_REC, char *caps sasl.c "server sasl failure", SERVER_REC, char *reason diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 1a60d99b..bcaeb10d 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -48,11 +48,17 @@ int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) if (!g_hash_table_lookup_extended(server->cap_supported, cap, NULL, NULL)) return FALSE; + signal_emit("server cap req", 2, server, cap); irc_send_cmdv(server, "CAP REQ %s", cap); return TRUE; } else if (!enable && gslist_find_string(server->cap_active, cap)) { - irc_send_cmdv(server, "CAP REQ -%s", cap); + char *negcap = g_strdup_printf("-%s", cap); + + signal_emit("server cap req", 2, server, negcap); + irc_send_cmdv(server, "CAP REQ %s", negcap); + + g_free(negcap); return TRUE; } @@ -194,10 +200,12 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add server->cap_queue = NULL; /* If the server doesn't support any cap we requested close the negotiation here */ - if (avail_caps > 0) + if (avail_caps > 0) { + signal_emit("server cap req", 2, server, cmd->str + sizeof("CAP REQ :") - 1); irc_send_cmd_now(server, cmd->str); - else + } else { cap_finish_negotiation(server); + } g_string_free(cmd, TRUE); } From d0151fd5a21cf026afa67239ad79f23bc26f0a10 Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 8 Apr 2018 01:26:11 -0300 Subject: [PATCH 0369/1198] Add fe-cap to show messages for CAP-related events in the UI Replaces cap.pl --- src/fe-common/irc/Makefile.am | 1 + src/fe-common/irc/fe-cap.c | 84 ++++++++++++++++++++++++++++++ src/fe-common/irc/fe-common-irc.c | 5 ++ src/fe-common/irc/module-formats.c | 7 +++ src/fe-common/irc/module-formats.h | 7 +++ 5 files changed, 104 insertions(+) create mode 100644 src/fe-common/irc/fe-cap.c diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index bf88f5cd..a5e95885 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -27,6 +27,7 @@ real_sources = \ fe-common-irc.c \ fe-whois.c \ fe-sasl.c \ + fe-cap.c \ irc-completion.c \ module-formats.c diff --git a/src/fe-common/irc/fe-cap.c b/src/fe-common/irc/fe-cap.c new file mode 100644 index 00000000..4f9d8ea9 --- /dev/null +++ b/src/fe-common/irc/fe-cap.c @@ -0,0 +1,84 @@ +/* + fe-cap.c : irssi + + Copyright (C) 2018 dequis + + 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 "module.h" +#include "module-formats.h" +#include "signals.h" +#include "levels.h" +#include "misc.h" + +#include "irc-servers.h" + +#include "printtext.h" + +static const struct { + const char *command; + const int template; +} fe_cap_messages[] = { + {"LS", IRCTXT_CAP_LS}, + {"ACK", IRCTXT_CAP_ACK}, + {"NAK", IRCTXT_CAP_NAK}, + {"LIST", IRCTXT_CAP_LIST}, + {"NEW", IRCTXT_CAP_NEW}, + {"DEL", IRCTXT_CAP_DEL}, +}; + +static void event_cap(IRC_SERVER_REC *server, char *args, char *nick, char *address) +{ + int i; + char *params, *evt, *list, *star; + + params = event_get_params(args, 4, NULL, &evt, &star, &list); + + if (params == NULL) { + return; + } + + /* With multiline CAP LS, if the '*' parameter isn't present, + * adjust the parameter pointer to compensate for this */ + if (strcmp(star, "*") != 0 && list[0] == '\0') { + list = star; + } + + for (i = 0; i < G_N_ELEMENTS(fe_cap_messages); i++) { + if (!g_ascii_strcasecmp(evt, fe_cap_messages[i].command)) { + printformat(server, NULL, MSGLEVEL_CRAP, fe_cap_messages[i].template, list); + } + } + + g_free(params); +} + +static void sig_server_cap_req(IRC_SERVER_REC *server, char *caps) +{ + printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_CAP_REQ, caps); +} + +void fe_cap_init(void) +{ + signal_add("event cap", (SIGNAL_FUNC) event_cap); + signal_add("server cap req", (SIGNAL_FUNC) sig_server_cap_req); +} + +void fe_cap_deinit(void) +{ + signal_remove("event cap", (SIGNAL_FUNC) event_cap); + signal_remove("server cap req", (SIGNAL_FUNC) sig_server_cap_req); +} diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c index 4a3ef1d3..b1bfb525 100644 --- a/src/fe-common/irc/fe-common-irc.c +++ b/src/fe-common/irc/fe-common-irc.c @@ -72,6 +72,9 @@ void fe_whois_deinit(void); void fe_sasl_init(void); void fe_sasl_deinit(void); +void fe_cap_init(void); +void fe_cap_deinit(void); + void irc_completion_init(void); void irc_completion_deinit(void); @@ -95,6 +98,7 @@ void fe_common_irc_init(void) fe_netjoin_init(); fe_whois_init(); fe_sasl_init(); + fe_cap_init(); irc_completion_init(); settings_check(); @@ -121,6 +125,7 @@ void fe_common_irc_deinit(void) fe_netjoin_deinit(); fe_whois_deinit(); fe_sasl_deinit(); + fe_cap_deinit(); irc_completion_deinit(); theme_unregister(); diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index f7b074ec..722aed73 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -46,6 +46,13 @@ FORMAT_REC fecommon_irc_formats[] = { { "setupserver_footer", "", 0 }, { "sasl_success", "SASL authentication succeeded", 0 }, { "sasl_error", "Cannot authenticate via SASL ($0)", 1, { 0 } }, + { "cap_req", "Capabilities requested: $0", 1, { 0 } }, + { "cap_ls", "Capabilities supported: $0", 1, { 0 } }, + { "cap_ack", "Capabilities acknowledged: $0", 1, { 0 } }, + { "cap_nak", "Capabilities refused: $0", 1, { 0 } }, + { "cap_list", "Capabilities currently enabled: $0", 1, { 0 } }, + { "cap_new", "Capabilities now available: $0", 1, { 0 } }, + { "cap_del", "Capabilities removed: $0", 1, { 0 } }, /* ---- */ { NULL, "Channels", 0 }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index c45f4562..7969b5ac 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -24,6 +24,13 @@ enum { IRCTXT_SETUPSERVER_FOOTER, IRCTXT_SASL_SUCCESS, IRCTXT_SASL_ERROR, + IRCTXT_CAP_REQ, + IRCTXT_CAP_LS, + IRCTXT_CAP_ACK, + IRCTXT_CAP_NAK, + IRCTXT_CAP_LIST, + IRCTXT_CAP_NEW, + IRCTXT_CAP_DEL, IRCTXT_FILL_2, From 8deb6182c692904733544568479035b31fe1007e Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 8 Apr 2018 15:52:09 -0300 Subject: [PATCH 0370/1198] Make config_write more atomic to prevent truncation when out of space This is modeled after glib's g_file_set_contents. It doesn't use that function directly because the writing is done with GIOChannel streaming-like writes and g_file_set_contents expects the whole thing to be in-memory. Main differences with g_file_set_contents: - complete lack of win32 special casing (cygwin/WSL should work though) - no fallocate() (linux only, but we don't know the size upfront, anyway) - always calls fsync (glib skips it on btrfs or when not overwriting) Other than that, it's the same old mkstemp + fsync + rename. --- src/lib-config/write.c | 45 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index 37e51f09..ab2c6975 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -301,30 +301,67 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) { int ret; int fd; + int save_errno; + char *tmp_name; + const char *dest_name; g_return_val_if_fail(rec != NULL, -1); g_return_val_if_fail(fname != NULL || rec->fname != NULL, -1); g_return_val_if_fail(create_mode != -1 || rec->create_mode != -1, -1); - fd = open(fname != NULL ? fname : rec->fname, + dest_name = fname != NULL ? fname : rec->fname; + tmp_name = g_strdup_printf("%s.XXXXXX", dest_name); + + fd = g_mkstemp_full(tmp_name, O_WRONLY | O_TRUNC | O_CREAT, create_mode != -1 ? create_mode : rec->create_mode); - if (fd == -1) - return config_error(rec, g_strerror(errno)); + if (fd == -1) { + config_error(rec, g_strerror(errno)); + ret = -1; + goto out; + } rec->handle = g_io_channel_unix_new(fd); g_io_channel_set_encoding(rec->handle, NULL, NULL); g_io_channel_set_close_on_unref(rec->handle, TRUE); + rec->tmp_indent_level = 0; rec->tmp_last_lf = TRUE; ret = config_write_block(rec, rec->mainnode, FALSE, TRUE); + save_errno = errno; + if (ret == -1) { /* write error */ - config_error(rec, errno == 0 ? "bug" : g_strerror(errno)); + unlink(tmp_name); + config_error(rec, save_errno == 0 ? "bug" : g_strerror(save_errno)); + goto out; + } + + ret = fsync(fd); + save_errno = errno; + + if (ret == -1) { + unlink(tmp_name); + config_error(rec, g_strerror(errno)); + goto out; } g_io_channel_unref(rec->handle); rec->handle = NULL; + if (rename(tmp_name, dest_name) == -1) { + unlink(tmp_name); + config_error(rec, g_strerror(errno)); + goto out; + } + +out: + if (rec->handle) { + g_io_channel_unref(rec->handle); + rec->handle = NULL; + } + + g_free(tmp_name); + return ret; } From 34b31e8451829e7b515a60cf12183203a059d1c4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 16 Apr 2018 16:19:54 +0200 Subject: [PATCH 0371/1198] record line info on empty lines --- src/fe-common/core/formats.c | 9 +++++++++ src/fe-text/textbuffer.c | 3 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 4c819c2d..8ad4b3af 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1233,6 +1233,15 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) dup = str = g_strdup(text); flags = 0; fgcolor = theme->default_color; bgcolor = -1; + + if (*str == '\0') { + /* empty line, write line info only */ + signal_emit_id(signal_gui_print_text, 6, dest->window, + GINT_TO_POINTER(fgcolor), + GINT_TO_POINTER(bgcolor), + GINT_TO_POINTER(flags), str, + dest); + } while (*str != '\0') { type = '\0'; for (ptr = str; *ptr != '\0'; ptr++) { diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 01cdd118..9e1ace96 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -355,9 +355,6 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); - if (len == 0) - return insert_after; - line = !buffer->last_eol ? insert_after : textbuffer_line_insert(buffer, insert_after); From 3075cbc6fb383024b87563611021f9fb712182fd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 24 Apr 2018 14:00:30 +0200 Subject: [PATCH 0372/1198] Fix test compilation on old glib e.g. Debian 7 --- tests/irc/flood/test-796.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 2e4affa0..0c98509b 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -165,7 +165,9 @@ int main(int argc, char **argv) server_destroy_flood_set_up, test_server_destroy_flood, server_destroy_flood_tear_down); +#if GLIB_CHECK_VERSION(2,38,0) g_test_set_nonfatal_assertions(); +#endif core_preinit(*argv); irssi_gui = IRSSI_GUI_NONE; From 631650bd8ab467af8347b5d9b51b2b0193adfe63 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 7 May 2018 21:22:43 +0200 Subject: [PATCH 0373/1198] Revert "record line info on empty lines" --- src/fe-common/core/formats.c | 9 --------- src/fe-text/textbuffer.c | 3 +++ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 8ad4b3af..4c819c2d 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1233,15 +1233,6 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) dup = str = g_strdup(text); flags = 0; fgcolor = theme->default_color; bgcolor = -1; - - if (*str == '\0') { - /* empty line, write line info only */ - signal_emit_id(signal_gui_print_text, 6, dest->window, - GINT_TO_POINTER(fgcolor), - GINT_TO_POINTER(bgcolor), - GINT_TO_POINTER(flags), str, - dest); - } while (*str != '\0') { type = '\0'; for (ptr = str; *ptr != '\0'; ptr++) { diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 9e1ace96..01cdd118 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -355,6 +355,9 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); + if (len == 0) + return insert_after; + line = !buffer->last_eol ? insert_after : textbuffer_line_insert(buffer, insert_after); From db3b671328d0e6890b17c23baf9d4280d086e89b Mon Sep 17 00:00:00 2001 From: vague666 Date: Tue, 5 Jun 2018 14:43:37 +0200 Subject: [PATCH 0374/1198] Added HIDDEN level to ignores --- src/core/ignore.c | 17 +++++++++--- src/core/ignore.h | 2 ++ src/fe-common/core/fe-ignore.c | 9 ++++++- src/fe-common/core/fe-messages.c | 27 ++++++++++++++++++++ src/fe-common/core/window-activity.c | 2 +- src/fe-common/irc/dcc/fe-dcc-chat-messages.c | 12 +++++++++ src/fe-common/irc/fe-irc-messages.c | 9 +++++++ 7 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index cec91e6b..8aece6fc 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -82,9 +82,9 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * However we also want to allow NO_ACT combined with levels, so mask it out and * match levels if set. */ #define ignore_match_level(rec, level) \ - (((level & MSGLEVEL_NO_ACT) != 0) ? \ - ((~MSGLEVEL_NO_ACT & level) & (rec)->level) != 0 : \ - ((rec)->level & MSGLEVEL_NO_ACT ? 0 : \ + (((level & (MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN)) != 0) ? \ + ((~(MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN) & level) & (rec)->level) != 0 : \ + ((rec)->level & (MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN) ? 0 : \ (level & (rec)->level) != 0)) #define ignore_match_nickmask(rec, nick, nickmask) \ @@ -212,6 +212,12 @@ IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) continue; + if ((flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) == 0) + continue; + + if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0) + continue; + if ((rec->mask == NULL && mask != NULL) || (rec->mask != NULL && mask == NULL)) continue; @@ -264,6 +270,11 @@ IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **ch return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_NOACT); } +IGNORE_REC *ignore_find_hidden(const char *servertag, const char *mask, char **channels, int hidden) +{ + return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_HIDDEN); +} + static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; diff --git a/src/core/ignore.h b/src/core/ignore.h index 31171b58..439927ed 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -29,6 +29,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, enum { IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ + IGNORE_FIND_HIDDEN = 0x03, /* Exclude the targets with HIDDEN level */ }; IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, @@ -38,6 +39,7 @@ IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const cha 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); +IGNORE_REC *ignore_find_hidden(const char *servertag, const char *mask, char **channels, int hidden); 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 03fd4dd2..88dc48f7 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -157,7 +157,8 @@ static void cmd_ignore(const char *data) g_strsplit(chanarg, ",", -1); rec = ignore_find_full(servertag, mask, patternarg, channels, - IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); + IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0) | + ((level & MSGLEVEL_HIDDEN) ? IGNORE_FIND_HIDDEN : 0)); new_ignore = rec == NULL; if (rec == NULL) { @@ -179,6 +180,12 @@ static void cmd_ignore(const char *data) rec->level |= MSGLEVEL_ALL; } + if (rec->level == MSGLEVEL_HIDDEN) { + /* If only HIDDEN was specified add all levels; it makes no + * sense on its own. */ + rec->level |= MSGLEVEL_ALL; + } + if (new_ignore && rec->level == 0) { /* tried to unignore levels from nonexisting ignore */ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 487a5754..05c64d70 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -204,6 +204,9 @@ static void sig_message_public(SERVER_REC *server, const char *msg, if (ignore_check(server, nick, address, target, msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, target, msg, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); @@ -263,6 +266,9 @@ static void sig_message_private(SERVER_REC *server, const char *msg, if (ignore_check(server, nick, address, NULL, msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, NULL, msg, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (own) { printformat(server, target, level, query == NULL ? TXT_OWN_MSG_PRIVATE : @@ -358,6 +364,9 @@ static void sig_message_join(SERVER_REC *server, const char *channel, if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + printformat(server, channel, level, TXT_JOIN, nick, address, channel); } @@ -371,6 +380,9 @@ static void sig_message_part(SERVER_REC *server, const char *channel, if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + printformat(server, channel, level, TXT_PART, nick, address, channel, reason); } @@ -390,6 +402,9 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, if (ignore_check(server, nick, address, NULL, reason, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, NULL, reason, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + print_channel = NULL; once = settings_get_bool("show_quit_once"); @@ -412,6 +427,9 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, if (ignore_check(server, nick, address, rec->visible_name, reason, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, rec->visible_name, reason, MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (print_channel == NULL || active_win->active == (WI_ITEM_REC *) rec) print_channel = rec->visible_name; @@ -461,6 +479,9 @@ static void sig_message_kick(SERVER_REC *server, const char *channel, if (ignore_check(server, kicker, address, channel, reason, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, kicker, address, channel, reason, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + printformat(server, channel, level, TXT_KICK, nick, channel, kicker, reason, address); } @@ -482,6 +503,9 @@ static void print_nick_change_channel(SERVER_REC *server, const char *channel, if (!(level & MSGLEVEL_NO_ACT) && ignore_check(server, oldnick, address, channel, newnick, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (!(level & MSGLEVEL_HIDDEN) && ignore_check(server, oldnick, address, channel, newnick, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + printformat(server, channel, level, ownnick ? TXT_YOUR_NICK_CHANGED : TXT_NICK_CHANGED, oldnick, newnick, channel, address); @@ -561,6 +585,9 @@ static void sig_message_topic(SERVER_REC *server, const char *channel, if (ignore_check(server, nick, address, channel, topic, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, channel, topic, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + printformat(server, channel, level, *topic != '\0' ? TXT_NEW_TOPIC : TXT_TOPIC_UNSET, nick, channel, topic, address); diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 3be30ae7..89493aea 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -125,7 +125,7 @@ static void read_settings(void) hide_targets = *targets == '\0' ? NULL : g_strsplit(targets, " ", -1); - hide_level = MSGLEVEL_NEVER | MSGLEVEL_NO_ACT | + hide_level = MSGLEVEL_NEVER | MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN | settings_get_level("activity_hide_level"); msg_level = settings_get_level("activity_msg_level"); hilight_level = MSGLEVEL_HILIGHT | diff --git a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c index 45791f56..3a45a36b 100644 --- a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c +++ b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c @@ -96,6 +96,10 @@ static void sig_message_dcc(CHAT_DCC_REC *dcc, const char *msg) level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); @@ -118,6 +122,10 @@ static void sig_message_dcc_action(CHAT_DCC_REC *dcc, const char *msg) level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); @@ -139,6 +147,10 @@ static void sig_message_dcc_ctcp(CHAT_DCC_REC *dcc, const char *cmd, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, + level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 40ca306d..e8558a17 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -162,6 +162,10 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(SERVER(server), nick, address, target, msg, + level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (server_ischannel(SERVER(server), target)) { item = irc_channel_find(server, target); } else { @@ -241,6 +245,11 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg, msg, level | MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; + if (ignore_check(server, nick, address, + server_ischannel(SERVER(server), target) ? target : NULL, + msg, level | MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (server_ischannel(SERVER(server), target)) { /* notice in some channel */ printformat(server, target, level, From ac3af3fb56d98b884d03646e3c15435c8a435bf3 Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 6 Jun 2018 10:00:38 +0200 Subject: [PATCH 0375/1198] these were bitflags --- src/core/ignore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ignore.h b/src/core/ignore.h index 439927ed..958aa801 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -29,7 +29,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, enum { IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ - IGNORE_FIND_HIDDEN = 0x03, /* Exclude the targets with HIDDEN level */ + IGNORE_FIND_HIDDEN = 0x04, /* Exclude the targets with HIDDEN level */ }; IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, From 1547248e9448c22476a56c630ee18d95a57dc05f Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 6 Jun 2018 11:03:44 +0200 Subject: [PATCH 0376/1198] simplify code --- src/fe-common/core/fe-ignore.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 88dc48f7..39c4dd9f 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -118,7 +118,7 @@ static void cmd_ignore(const char *data) char *patternarg, *chanarg, *mask, *levels, *timestr, *servertag; char **channels; void *free_arg; - int new_ignore, msecs, level; + int new_ignore, msecs, level, flags; if (*data == '\0') { cmd_ignore_show(); @@ -156,9 +156,13 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = ignore_find_full(servertag, mask, patternarg, channels, - IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0) | - ((level & MSGLEVEL_HIDDEN) ? IGNORE_FIND_HIDDEN : 0)); + flags = IGNORE_FIND_PATTERN; + if (level & MSGLEVEL_NO_ACT) + flags |= IGNORE_FIND_NOACT; + if (level & MSGLEVEL_HIDDEN) + flags |= IGNORE_FIND_HIDDEN; + + rec = ignore_find_full(servertag, mask, patternarg, channels, flags); new_ignore = rec == NULL; if (rec == NULL) { From d2e1caf7205220c9fd73861604de8248eb07f0d6 Mon Sep 17 00:00:00 2001 From: vague666 Date: Thu, 7 Jun 2018 15:17:46 +0200 Subject: [PATCH 0377/1198] simplifying code --- src/core/ignore.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 8aece6fc..574ecb5d 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -81,10 +81,11 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * used as a flag to indicate it should only look at ignore items with NO_ACT. * However we also want to allow NO_ACT combined with levels, so mask it out and * match levels if set. */ +#define FLAG_MSGLEVELS ( MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN ) #define ignore_match_level(rec, level) \ - (((level & (MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN)) != 0) ? \ - ((~(MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN) & level) & (rec)->level) != 0 : \ - ((rec)->level & (MSGLEVEL_NO_ACT|MSGLEVEL_HIDDEN) ? 0 : \ + (((level & FLAG_MSGLEVELS)!= 0) ? \ + ((~FLAG_MSGLEVELS & level) & (rec)->level) != 0 : \ + ((rec)->level & FLAG_MSGLEVELS ? 0 : \ (level & (rec)->level) != 0)) #define ignore_match_nickmask(rec, nick, nickmask) \ From ba2554dd1485259b95b4b37f281c989086b24739 Mon Sep 17 00:00:00 2001 From: vague666 Date: Sat, 9 Jun 2018 05:55:25 +0200 Subject: [PATCH 0378/1198] missing space --- src/core/ignore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 574ecb5d..8745c434 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -83,7 +83,7 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * match levels if set. */ #define FLAG_MSGLEVELS ( MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN ) #define ignore_match_level(rec, level) \ - (((level & FLAG_MSGLEVELS)!= 0) ? \ + (((level & FLAG_MSGLEVELS) != 0) ? \ ((~FLAG_MSGLEVELS & level) & (rec)->level) != 0 : \ ((rec)->level & FLAG_MSGLEVELS ? 0 : \ (level & (rec)->level) != 0)) From 1ab679bf32028b175c14f977659af540550bba47 Mon Sep 17 00:00:00 2001 From: vague666 Date: Thu, 14 Jun 2018 20:02:30 +0200 Subject: [PATCH 0379/1198] remove = from format because people get confused by it --- src/fe-common/core/module-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index eb0ddb61..d3c7251b 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -282,7 +282,7 @@ FORMAT_REC fecommon_core_formats[] = { { "glib_error", "{error $0} $1", 2, { 0, 0 } }, { "overwrite_config", "Overwrite config (y/N)?", 0 }, { "set_title", "[{hilight $0}]", 1, { 0 } }, - { "set_item", "$0 = $1", 2, { 0, 0 } }, + { "set_item", "$[-!32]0 %_$1", 2, { 0, 0 } }, { "set_unknown", "Unknown setting $0", 1, { 0 } }, { "set_not_boolean", "Setting {hilight $0} isn't boolean, use /SET", 1, { 0 } }, { "no_completions", "There are no completions", 0 }, From d84a24444fbef8af6ae72888cfc3a539e0a1f005 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Fri, 29 Jun 2018 09:00:38 -0400 Subject: [PATCH 0380/1198] core/ignore: fix ignore_match_level handling of flag levels --- src/core/ignore.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 8745c434..3f08cb10 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -82,11 +82,17 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * However we also want to allow NO_ACT combined with levels, so mask it out and * match levels if set. */ #define FLAG_MSGLEVELS ( MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN ) -#define ignore_match_level(rec, level) \ - (((level & FLAG_MSGLEVELS) != 0) ? \ - ((~FLAG_MSGLEVELS & level) & (rec)->level) != 0 : \ - ((rec)->level & FLAG_MSGLEVELS ? 0 : \ - (level & (rec)->level) != 0)) +static int ignore_match_level(IGNORE_REC *rec, int level) +{ + if (level & FLAG_MSGLEVELS) { + int flaglevel = level & FLAG_MSGLEVELS; + return (level & rec->level) && (flaglevel & rec->level); + } else if (!(rec->level & FLAG_MSGLEVELS)) { + return (level & rec->level); + } else { + return FALSE; + } +} #define ignore_match_nickmask(rec, nick, nickmask) \ ((rec)->mask == NULL || \ From 4f45828ff3de2952fa2d6be8515e67986213e7a8 Mon Sep 17 00:00:00 2001 From: Janik Rabe Date: Wed, 18 Jul 2018 21:12:38 +0300 Subject: [PATCH 0381/1198] Keep errstr set to NULL if errno is not set Don't use errno if it is not set and show the default error message instead. This prevents messages like "SSL handshake failed: Success" from being shown. --- src/core/network-openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 692c7e71..95697135 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -842,7 +842,7 @@ int irssi_ssl_handshake(GIOChannel *handle) return -1; case SSL_ERROR_SYSCALL: errstr = ERR_reason_error_string(ERR_get_error()); - if (errstr == NULL && ret == -1) + if (errstr == NULL && ret == -1 && errno) errstr = strerror(errno); g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "server closed connection unexpectedly"); return -1; From 0e187cf9cfb99c19f3dc9cf532fb5bac92dd1145 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Tue, 24 Jul 2018 18:29:31 -0700 Subject: [PATCH 0382/1198] Fix typo in comment --- src/irc/core/channel-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 46bbd5fa..6cdfe147 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -126,7 +126,7 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; - /* the topic may be send out encoded, so we need to + /* the topic may be sent out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); if (topic != NULL) { From b9e301362db545a4108b5d08c7eda45441a475f5 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Tue, 24 Jul 2018 18:30:51 -0700 Subject: [PATCH 0383/1198] Ignore vim editor files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 916457f8..1ab7df5f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ tests/irc/core/test-irc.trs *.la *.lo *.o +*.swp *~ *.tar.bz2 From 15840ac27bd05e710ae13afe1a3c29853d2d6a0b Mon Sep 17 00:00:00 2001 From: Will Storey Date: Tue, 24 Jul 2018 18:31:57 -0700 Subject: [PATCH 0384/1198] If we receive a 0 length topic, record it as unset Fixes #888. Previously we showed that there was a topic set when using /topic, just an empty one. This was different than how we show such topics when initially joining a channel. Now we say that the topic is unset in both cases. --- src/irc/core/channel-events.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 6cdfe147..38cc0bdd 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -126,23 +126,25 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; + + g_free_and_null(chanrec->topic); + g_free_and_null(chanrec->topic_by); + chanrec->topic_time = 0; + /* the topic may be sent out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); - if (topic != NULL) { - g_free_not_null(chanrec->topic); - chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); + if (recoded == NULL || strlen(recoded) == 0) { + signal_emit("channel topic changed", 1, chanrec); + g_free(recoded); + return; } - g_free(recoded); - g_free_not_null(chanrec->topic_by); + chanrec->topic = recoded; chanrec->topic_by = g_strdup(setby); - - if (chanrec->topic_by == NULL) { + if (chanrec->topic_by != NULL) { /* ensure invariant topic_time > 0 <=> topic_by != NULL. this could be triggered by a topic command without sender */ - chanrec->topic_time = 0; - } else { chanrec->topic_time = settime; } From b114b11e36598157b7b014cc8d4325fbf04c9b1e Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 30 Jul 2018 23:45:56 -0300 Subject: [PATCH 0385/1198] channel_change_topic: change one strlen == 0 to *str == '\0' --- src/irc/core/channel-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 38cc0bdd..4b74b322 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -134,7 +134,7 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, /* the topic may be sent out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); - if (recoded == NULL || strlen(recoded) == 0) { + if (recoded == NULL || *recoded == '\0') { signal_emit("channel topic changed", 1, chanrec); g_free(recoded); return; From f3909b8bcb509bbb57d685ec5a2b9f93097b5755 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Fri, 3 Aug 2018 17:07:06 -0400 Subject: [PATCH 0386/1198] core/ignore: fix #900 --- src/core/ignore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 3f08cb10..57c84623 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -86,7 +86,8 @@ static int ignore_match_level(IGNORE_REC *rec, int level) { if (level & FLAG_MSGLEVELS) { int flaglevel = level & FLAG_MSGLEVELS; - return (level & rec->level) && (flaglevel & rec->level); + int msglevel = level & ~FLAG_MSGLEVELS; + return (msglevel & rec->level) && (flaglevel & rec->level); } else if (!(rec->level & FLAG_MSGLEVELS)) { return (level & rec->level); } else { From 10f632664989117afe6d4496a419f712fbb4c3b6 Mon Sep 17 00:00:00 2001 From: David Phillips Date: Tue, 24 Jul 2018 19:31:45 +1200 Subject: [PATCH 0387/1198] Redraw on SIGWINCH when screen size hasn't changed Some programs and users send SIGWINCH as a request for the client to redraw in the event of session detachment/reattachment (e.g. abduco). A well-formed terminal will only send SIGWINCH when the window size has changed, so there is no need to optimise this case out. --- src/fe-text/term.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fe-text/term.c b/src/fe-text/term.c index 4600f02e..408dc7ef 100644 --- a/src/fe-text/term.c +++ b/src/fe-text/term.c @@ -81,11 +81,9 @@ void term_resize_dirty(void) if (!term_get_size(&width, &height)) width = height = -1; - if (height != term_height || width != term_width) { - term_resize(width, height); - mainwindows_resize(term_width, term_height); - term_resize_final(width, height); - } + term_resize(width, height); + mainwindows_resize(term_width, term_height); + term_resize_final(width, height); } #ifdef SIGWINCH From 764f8215a9dad09b93832fdbb0c87eb1b0e6e773 Mon Sep 17 00:00:00 2001 From: Lukas Waymann Date: Sun, 12 Aug 2018 07:22:14 +0000 Subject: [PATCH 0388/1198] Fix `/save` replacing symlinks with regular files A side-effect of 8deb618 is that `/save` may replace configuration files that are symlinks with regular files. Fix this by resolving all symlinks before renaming the temporary file. --- src/lib-config/write.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index ab2c6975..d325fc52 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -304,6 +304,7 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) int save_errno; char *tmp_name; const char *dest_name; + char *real_dest = NULL; g_return_val_if_fail(rec != NULL, -1); g_return_val_if_fail(fname != NULL || rec->fname != NULL, -1); @@ -349,7 +350,15 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) g_io_channel_unref(rec->handle); rec->handle = NULL; - if (rename(tmp_name, dest_name) == -1) { + /* expand all symlinks; else we may replace a symlink with a regular file */ + real_dest = realpath(dest_name, NULL); + if (real_dest == NULL) { + unlink(tmp_name); + config_error(rec, g_strerror(errno)); + goto out; + } + + if (rename(tmp_name, real_dest) == -1) { unlink(tmp_name); config_error(rec, g_strerror(errno)); goto out; @@ -362,6 +371,7 @@ out: } g_free(tmp_name); + g_free(real_dest); return ret; } From 7d3eb47ab51a93defb267912704e84b3241b4db6 Mon Sep 17 00:00:00 2001 From: Lukas Waymann Date: Sun, 12 Aug 2018 10:55:47 +0000 Subject: [PATCH 0389/1198] Fix potential `rename(3)` across file systems Make sure the temporary file in the `config_write` function is created on the same file system as the file we `rename` it to later. --- src/lib-config/write.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index d325fc52..255d79c0 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -302,15 +302,21 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) int ret; int fd; int save_errno; - char *tmp_name; - const char *dest_name; - char *real_dest = NULL; + char *tmp_name = NULL; + char *dest_name = NULL; g_return_val_if_fail(rec != NULL, -1); g_return_val_if_fail(fname != NULL || rec->fname != NULL, -1); g_return_val_if_fail(create_mode != -1 || rec->create_mode != -1, -1); - dest_name = fname != NULL ? fname : rec->fname; + /* expand all symlinks; else we may replace a symlink with a regular file */ + dest_name = realpath(fname != NULL ? fname : rec->fname, NULL); + if (dest_name == NULL) { + config_error(rec, g_strerror(errno)); + ret = -1; + goto out; + } + tmp_name = g_strdup_printf("%s.XXXXXX", dest_name); fd = g_mkstemp_full(tmp_name, @@ -350,15 +356,7 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) g_io_channel_unref(rec->handle); rec->handle = NULL; - /* expand all symlinks; else we may replace a symlink with a regular file */ - real_dest = realpath(dest_name, NULL); - if (real_dest == NULL) { - unlink(tmp_name); - config_error(rec, g_strerror(errno)); - goto out; - } - - if (rename(tmp_name, real_dest) == -1) { + if (rename(tmp_name, dest_name) == -1) { unlink(tmp_name); config_error(rec, g_strerror(errno)); goto out; @@ -371,7 +369,7 @@ out: } g_free(tmp_name); - g_free(real_dest); + g_free(dest_name); return ret; } From 817179a7606b616795cf67e24505526dded34381 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 13 Aug 2018 14:43:25 +0200 Subject: [PATCH 0390/1198] Revert "Flag topic as unset if it is zero length" --- .gitignore | 1 - src/irc/core/channel-events.c | 22 ++++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1ab7df5f..916457f8 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ tests/irc/core/test-irc.trs *.la *.lo *.o -*.swp *~ *.tar.bz2 diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 4b74b322..46bbd5fa 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -126,25 +126,23 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; - - g_free_and_null(chanrec->topic); - g_free_and_null(chanrec->topic_by); - chanrec->topic_time = 0; - - /* the topic may be sent out encoded, so we need to + /* the topic may be send out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); - if (recoded == NULL || *recoded == '\0') { - signal_emit("channel topic changed", 1, chanrec); - g_free(recoded); - return; + if (topic != NULL) { + g_free_not_null(chanrec->topic); + chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); } + g_free(recoded); - chanrec->topic = recoded; + g_free_not_null(chanrec->topic_by); chanrec->topic_by = g_strdup(setby); - if (chanrec->topic_by != NULL) { + + if (chanrec->topic_by == NULL) { /* ensure invariant topic_time > 0 <=> topic_by != NULL. this could be triggered by a topic command without sender */ + chanrec->topic_time = 0; + } else { chanrec->topic_time = settime; } From 4f5f62ac63697d23e8a4d432f181a85c45a49d5e Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Wed, 15 Aug 2018 11:11:09 -0400 Subject: [PATCH 0391/1198] Add server-fuzz to fe-fuzz Based on test-796.c in the tests directory. --- src/fe-fuzz/Makefile.am | 17 +++- src/fe-fuzz/server.c | 176 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 src/fe-fuzz/server.c diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index 40abd5ba..f52d9c47 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = irc fe-common -bin_PROGRAMS = irssi-fuzz +bin_PROGRAMS = irssi-fuzz server-fuzz # Force link with CXX for libfuzzer support CCLD=$(CXX) $(CXXFLAGS) @@ -21,7 +21,18 @@ irssi_fuzz_LDADD = \ irssi_fuzz_SOURCES = \ irssi.c \ - $(top_srcdir)/src/fe-text/module-formats.c + ../fe-text/module-formats.c + +server_fuzz_DEPENDENCIES = @COMMON_LIBS@ + +server_fuzz_LDADD = \ + @COMMON_LIBS@ \ + @PROG_LIBS@ \ + $(FUZZER_LIBS) + +server_fuzz_SOURCES = \ + server.c \ + ../fe-text/module-formats.c noinst_HEADERS = \ - $(top_srcdir)/src/fe-text/module-formats.h + ../fe-text/module-formats.h diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c new file mode 100644 index 00000000..76eeb17e --- /dev/null +++ b/src/fe-fuzz/server.c @@ -0,0 +1,176 @@ +/* + server.c : irssi + + Copyright (C) 2018 Joseph Bisch + + 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 "module.h" +#include "modules-load.h" +#include "module-formats.h" +#include "levels.h" +#include "themes.h" +#include "core.h" +#include "fe-common-core.h" +#include "args.h" +#include "printtext.h" +#include "misc.h" +#include "servers-setup.h" + +#include +#include +#include +#include +#include + +#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); + +SERVER_REC *server; + +void event_connected(IRC_SERVER_REC *server, const char *data, const char *from) +{ + char *params, *nick; + + g_return_if_fail(server != NULL); + + params = event_get_params(data, 1, &nick); + + if (g_strcmp0(server->nick, nick) != 0) { + /* nick changed unexpectedly .. connected via proxy, etc. */ + g_free(server->nick); + server->nick = g_strdup(nick); + } + + /* set the server address */ + g_free(server->real_address); + server->real_address = from == NULL ? + g_strdup(server->connrec->address) : /* shouldn't happen.. */ + g_strdup(from); + + /* last welcome message found - commands can be sent to server now. */ + server->connected = 1; + server->real_connect_time = time(NULL); + + /* let the queue send now that we are identified */ + g_get_current_time(&server->wait_cmd); + + if (server->connrec->usermode != NULL) { + /* Send the user mode, before the autosendcmd. + * Do not pass this through cmd_mode because it + * is not known whether the resulting MODE message + * (if any) is the initial umode or a reply to this. + */ + irc_send_cmdv(server, "MODE %s %s", server->nick, + server->connrec->usermode); + g_free_not_null(server->wanted_usermode); + server->wanted_usermode = g_strdup(server->connrec->usermode); + } + + signal_emit("event connected", 1, server); + g_free(params); +} + +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)@%+")); +} + +void test_server() { + //SERVER_REC *server; /* = g_new0(IRC_SERVER_REC, 1); */ + CHAT_PROTOCOL_REC *proto; + SERVER_CONNECT_REC *conn; + + 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"); + + /* 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(); */ + + server_connect_unref(conn); +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + core_register_options(); + fe_common_core_register_options(); + /* no args */ + args_execute(0, NULL); + core_preinit((*argv)[0]); + core_init(); + irc_init(); + fe_common_core_init(); + fe_common_irc_init(); + signal_add("event 001", (SIGNAL_FUNC) event_connected); + module_register("core", "fe-fuzz"); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + if (size < 1) return 0; + + test_server(); + gboolean prefixedChoice = (gboolean)*data; + gchar *copy = g_strndup((const gchar *)data+1, size-1); + gchar **lines = g_strsplit(copy, "\r\n", -1); + gchar **head = lines; + + for (; *lines != NULL; lines++) { + gchar *prefixedLine; + if (prefixedChoice) { + prefixedLine = g_strdup_printf(":user %s\n", *lines); + } else { + prefixedLine = g_strdup_printf("%s\n", *lines); + } + signal_emit("server incoming", 2, server, prefixedLine); + g_free(prefixedLine); + } + + g_strfreev(head); + g_free(copy); + server_unref(server); + return 0; +} From a19b503a31fa4fb31c2e6ee79ffdc18bf4a87db0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 21 Aug 2018 00:31:12 +0200 Subject: [PATCH 0392/1198] properly record line info on empty lines --- src/fe-common/core/formats.c | 7 +++++++ src/fe-text/gui-printtext.c | 12 +++++++++--- src/fe-text/textbuffer.c | 6 ++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 4c819c2d..f7466337 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1233,6 +1233,13 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) dup = str = g_strdup(text); flags = 0; fgcolor = theme->default_color; bgcolor = -1; + + if (*str == '\0') { + /* empty line, write line info only */ + signal_emit_id(signal_gui_print_text, 6, dest->window, GINT_TO_POINTER(fgcolor), + GINT_TO_POINTER(bgcolor), GINT_TO_POINTER(flags), str, dest); + } + while (*str != '\0') { type = '\0'; for (ptr = str; *ptr != '\0'; ptr++) { diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 83a36f14..f860dc1c 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -307,9 +307,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, } textbuffer_line_add_colors(view->buffer, &insert_after, fg, bg, flags); - insert_after = textbuffer_insert(view->buffer, insert_after, - (unsigned char *) str, - strlen(str), &lineinfo); + /* for historical reasons, the \n will set + GUI_PRINT_FLAG_NEWLINE and print an empty string. in this + special case, ignore the empty string which would otherwise + start another new line */ + if (~flags & GUI_PRINT_FLAG_NEWLINE || *str != '\0') { + insert_after = textbuffer_insert(view->buffer, insert_after, (unsigned char *) str, + strlen(str), &lineinfo); + } + if (gui->use_insert_after) gui->insert_after = insert_after; } diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 01cdd118..cf530212 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -333,8 +333,9 @@ void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, data[pos++] = LINE_CMD_INDENT; } - if (pos > 0) + if (pos > 0) { *line = textbuffer_insert(buffer, *line, data, pos, NULL); + } buffer->last_flags = flags; } @@ -355,9 +356,6 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); - if (len == 0) - return insert_after; - line = !buffer->last_eol ? insert_after : textbuffer_line_insert(buffer, insert_after); From af1e4d6e34317452ac32380bed795aecb00f5d88 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 21 Aug 2018 09:21:23 +0200 Subject: [PATCH 0393/1198] initialise the line to zeros --- src/fe-text/textbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index cf530212..5f9e68ad 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -192,7 +192,7 @@ static LINE_REC *textbuffer_line_create(TEXT_BUFFER_REC *buffer) if (buffer->cur_text == NULL) text_chunk_create(buffer); - rec = g_slice_new(LINE_REC); + rec = g_slice_new0(LINE_REC); rec->text = buffer->cur_text->buffer + buffer->cur_text->pos; buffer->cur_text->refcount++; From 0d8632943d8fb526fbd4d853c86294d0037c43f6 Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 23 Aug 2018 02:02:33 -0300 Subject: [PATCH 0394/1198] Add a wrapper of wcwidth() that picks the best implementation This adds a i_wcwidth() function that replaces mk_wcwidth(), and a 'wcwidth_implementation' setting to pick which one it wraps. Values: - old: uses our local mk_wcwidth() which implements unicode 5.0 - system: uses the libc-provided wcwidth(), which may be better or worse than ours depending on how up to date the system is. - auto: tests the system one against two characters that became fullwidth in unicode 5.2 and 9.0 respectively. If either of them pass, pick the system implementation, otherwise pick ours. It defaults to auto. mk_wcwidth() is still preferable in some cases, since the way it uses ranges for fullwidth characters means most CJK blocks are covered even if their characters didn't exist back then. The "system" implementation is also wrapped to never return -1, but to assume those unknown characters use one cell. Quoting the code: /* Treat all unknown characters as taking one cell. This is * the reason mk_wcwidth and other outdated implementations * mostly worked with newer unicode, while glibc's wcwidth * needs updating to recognize new characters. * * Instead of relying on that, we keep the behavior of assuming * one cell even for glibc's implementation, which is still * highly accurate and less of a headache overall. */ --- src/core/Makefile.am | 1 + src/core/core.c | 5 ++ src/core/utf8.c | 2 +- src/core/utf8.h | 6 ++ src/core/wcwidth-wrapper.c | 117 ++++++++++++++++++++++++++++++++++ src/fe-text/gui-entry.c | 16 ++--- src/fe-text/term-terminfo.c | 4 +- src/fe-text/textbuffer-view.c | 2 +- 8 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 src/core/wcwidth-wrapper.c diff --git a/src/core/Makefile.am b/src/core/Makefile.am index f64d9e2e..4cc2226c 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -53,6 +53,7 @@ libcore_a_SOURCES = \ utf8.c \ $(regex_impl) \ wcwidth.c \ + wcwidth-wrapper.c \ tls.c \ write-buffer.c diff --git a/src/core/core.c b/src/core/core.c index 506d6a13..3c335fd2 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -60,6 +60,9 @@ void chat_commands_deinit(void); void log_away_init(void); void log_away_deinit(void); +void wcwidth_wrapper_init(void); +void wcwidth_wrapper_deinit(void); + int irssi_gui; int irssi_init_finished; int reload_config; @@ -258,6 +261,7 @@ void core_init(void) nicklist_init(); chat_commands_init(); + wcwidth_wrapper_init(); settings_add_str("misc", "ignore_signals", ""); settings_add_bool("misc", "override_coredump_limit", FALSE); @@ -281,6 +285,7 @@ void core_deinit(void) signal_remove("setup changed", (SIGNAL_FUNC) read_settings); signal_remove("irssi init finished", (SIGNAL_FUNC) sig_irssi_init_finished); + wcwidth_wrapper_deinit(); chat_commands_deinit(); nicklist_deinit(); diff --git a/src/core/utf8.c b/src/core/utf8.c index c53d8816..c44fdbd6 100644 --- a/src/core/utf8.c +++ b/src/core/utf8.c @@ -36,7 +36,7 @@ int string_advance(char const **str, int policy) c = g_utf8_get_char(*str); *str = g_utf8_next_char(*str); - return unichar_isprint(c) ? mk_wcwidth(c) : 1; + return unichar_isprint(c) ? i_wcwidth(c) : 1; } else { /* Assume TREAT_STRING_AS_BYTES: */ *str += 1; diff --git a/src/core/utf8.h b/src/core/utf8.h index 5bb53193..9f7d1aaa 100644 --- a/src/core/utf8.h +++ b/src/core/utf8.h @@ -12,8 +12,14 @@ typedef guint32 unichar; /* Returns width for character (0-2). */ +int i_wcwidth(unichar c); + +/* Older variant of the above */ int mk_wcwidth(unichar c); +/* Signature for wcwidth implementations */ +typedef int (*WCWIDTH_FUNC) (unichar ucs); + /* Advance the str pointer one character further; return the number of columns * occupied by the skipped character. */ diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c new file mode 100644 index 00000000..e08707e9 --- /dev/null +++ b/src/core/wcwidth-wrapper.c @@ -0,0 +1,117 @@ +/* + wcwidth-wrapper.c : irssi + + Copyright (C) 2018 dequis + + 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. +*/ + +#define _XOPEN_SOURCE +#include + +#include "module.h" +#include "signals.h" +#include "settings.h" +#include "utf8.h" + +/* wcwidth=2 since unicode 5.2.0 */ +#define UNICODE_SQUARE_HIRAGANA_HOKA 0x1F200 + +/* wcwidth=2 since unicode 9.0.0 */ +#define UNICODE_IRSSI_LOGO 0x1F525 + +enum { + WCWIDTH_IMPL_AUTO = 0, + WCWIDTH_IMPL_OLD, + WCWIDTH_IMPL_SYSTEM, +}; + +WCWIDTH_FUNC wcwidth_impl_func = mk_wcwidth; + +int i_wcwidth(unichar ucs) +{ + return (*wcwidth_impl_func)(ucs); +} + +static int system_wcwidth(unichar ucs) +{ + int retval = wcwidth((wchar_t) ucs); + + if (retval < 0) { + /* Treat all unknown characters as taking one cell. This is + * the reason mk_wcwidth and other outdated implementations + * mostly worked with newer unicode, while glibc's wcwidth + * needs updating to recognize new characters. + * + * Instead of relying on that, we keep the behavior of assuming + * one cell even for glibc's implementation, which is still + * highly accurate and less of a headache overall. + */ + return 1; + } + + return retval; +} + +static void read_settings(void) +{ + static int choice = -1; + int newchoice; + + newchoice = settings_get_choice("wcwidth_implementation"); + + if (choice == newchoice) { + return; + } + + choice = newchoice; + + switch (choice) { + case WCWIDTH_IMPL_AUTO: + /* Test against characters that have wcwidth=2 + * since unicode 5.2 and 9.0 respectively */ + + if (system_wcwidth(UNICODE_SQUARE_HIRAGANA_HOKA) == 2 || + system_wcwidth(UNICODE_IRSSI_LOGO) == 2) { + wcwidth_impl_func = &system_wcwidth; + } else { + /* Fall back to our own (which implements 5.0) */ + wcwidth_impl_func = &mk_wcwidth; + } + break; + + case WCWIDTH_IMPL_OLD: + wcwidth_impl_func = &mk_wcwidth; + break; + + case WCWIDTH_IMPL_SYSTEM: + wcwidth_impl_func = &system_wcwidth; + break; + } + +} + +void wcwidth_wrapper_init(void) +{ + settings_add_choice("misc", "wcwidth_implementation", WCWIDTH_IMPL_AUTO, "auto;old;system"); + + read_settings(); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); +} + +void wcwidth_wrapper_deinit(void) +{ + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); +} diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 52a39969..b3c73c15 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -51,7 +51,7 @@ static unichar i_tolower(unichar c) static int i_isalnum(unichar c) { if (term_type == TERM_TYPE_UTF8) - return (g_unichar_isalnum(c) || mk_wcwidth(c) == 0); + return (g_unichar_isalnum(c) || i_wcwidth(c) == 0); return c <= 255 ? isalnum(c) : 0; } @@ -219,7 +219,7 @@ static int pos2scrpos(GUI_ENTRY_REC *entry, int pos, int cursor) if (term_type == TERM_TYPE_BIG5) xpos += big5_width(c); else if (entry->utf8) - xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; + xpos += unichar_isprint(c) ? i_wcwidth(c) : 1; else xpos++; @@ -246,7 +246,7 @@ static int scrpos2pos(GUI_ENTRY_REC *entry, int pos) if (term_type == TERM_TYPE_BIG5) width = big5_width(c); else if (entry->utf8) - width = unichar_isprint(c) ? mk_wcwidth(c) : 1; + width = unichar_isprint(c) ? i_wcwidth(c) : 1; else width = 1; @@ -373,7 +373,7 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) else if (term_type == TERM_TYPE_BIG5) new_xpos += big5_width(c); else if (entry->utf8) - new_xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1; + new_xpos += unichar_isprint(c) ? i_wcwidth(c) : 1; else new_xpos++; @@ -647,7 +647,7 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) if (chr == 0 || chr == 13 || chr == 10) return; /* never insert NUL, CR or LF characters */ - if (entry->utf8 && entry->pos == 0 && mk_wcwidth(chr) == 0) + if (entry->utf8 && entry->pos == 0 && i_wcwidth(chr) == 0) return; gui_entry_redraw_from(entry, entry->pos); @@ -829,7 +829,7 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ if (entry->utf8) while (entry->pos-size-w > 0 && - mk_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; + i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; g_memmove(entry->text + entry->pos - size, entry->text + entry->pos, (entry->text_len-entry->pos+1) * sizeof(unichar)); @@ -867,7 +867,7 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) if (entry->utf8) while (entry->pos+size < entry->text_len && - mk_wcwidth(entry->text[entry->pos+size]) == 0) size++; + i_wcwidth(entry->text[entry->pos+size]) == 0) size++; g_memmove(entry->text + entry->pos, entry->text + entry->pos + size, (entry->text_len-entry->pos-size+1) * sizeof(unichar)); @@ -1188,7 +1188,7 @@ void gui_entry_move_pos(GUI_ENTRY_REC *entry, int pos) if (entry->utf8) { int step = pos < 0 ? -1 : 1; - while(mk_wcwidth(entry->text[entry->pos]) == 0 && + while(i_wcwidth(entry->text[entry->pos]) == 0 && entry->pos + step >= 0 && entry->pos + step <= entry->text_len) entry->pos += step; } diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 68947f0c..6e031ebf 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -515,7 +515,7 @@ void term_add_unichar(TERM_WINDOW *window, unichar chr) switch (term_type) { case TERM_TYPE_UTF8: - term_printed_text(unichar_isprint(chr) ? mk_wcwidth(chr) : 1); + term_printed_text(unichar_isprint(chr) ? i_wcwidth(chr) : 1); term_addch_utf8(window, chr); break; case TERM_TYPE_BIG5: @@ -558,7 +558,7 @@ int term_addstr(TERM_WINDOW *window, const char *str) len++; ptr++; } else { - len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1; + len += unichar_isprint(tmp) ? i_wcwidth(tmp) : 1; ptr = g_utf8_next_char(ptr); } } diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 3ccd95f5..dda2ed97 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -197,7 +197,7 @@ static inline unichar read_unichar(const unsigned char *data, const unsigned cha *width = 1; } else { *next = (unsigned char *)g_utf8_next_char(data); - *width = unichar_isprint(chr) ? mk_wcwidth(chr) : 1; + *width = unichar_isprint(chr) ? i_wcwidth(chr) : 1; } return chr; } From 24f1ed7edb7d8498fdc6ec34e7727bca93fde74d Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 23 Aug 2018 03:22:30 -0300 Subject: [PATCH 0395/1198] irc-cap: Don't show warning on CAP LIST response --- src/irc/core/irc-cap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index bcaeb10d..5ab8d94f 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -276,6 +276,9 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add g_free(val); } } + else if (!g_ascii_strcasecmp(evt, "LIST")) { + /* do nothing, fe-cap will handle it */ + } else { g_warning("Unhandled CAP subcommand %s", evt); } From b95ce3e812b1d7218b6e5cea47084160cce84da7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Aug 2018 13:16:50 +0200 Subject: [PATCH 0396/1198] add julia's utf8proc wcwidth implementation --- configure.ac | 7 ++++++- src/core/wcwidth-wrapper.c | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d29c132b..a7d3feb7 100644 --- a/configure.ac +++ b/configure.ac @@ -326,6 +326,11 @@ PKG_CHECK_MODULES([OPENSSL], [openssl], [ ]) ]) +dnl ** +dnl ** utf8proc +dnl ** +AC_CHECK_LIB([utf8proc], [utf8proc_version]) + dnl ** dnl ** curses checks dnl ** @@ -815,7 +820,7 @@ echo "Building with 64bit DCC support .. : $offt_64bit" echo "Building with true color support.. : $want_truecolor" echo "Building with GRegex ............. : $want_gregex" echo "Building with Capsicum ........... : $want_capsicum" - +echo "Building with utf8proc ........... : $ac_cv_lib_utf8proc_utf8proc_version" if test "x$want_otr" = "xstatic"; then echo "Building with OTR support ........ : static (in irssi binary)" elif test "x$want_otr" = "xmodule"; then diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index e08707e9..7b0a4def 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -26,6 +26,10 @@ #include "settings.h" #include "utf8.h" +#ifdef HAVE_LIBUTF8PROC +#include +#endif + /* wcwidth=2 since unicode 5.2.0 */ #define UNICODE_SQUARE_HIRAGANA_HOKA 0x1F200 @@ -35,7 +39,10 @@ enum { WCWIDTH_IMPL_AUTO = 0, WCWIDTH_IMPL_OLD, - WCWIDTH_IMPL_SYSTEM, + WCWIDTH_IMPL_SYSTEM +#ifdef HAVE_LIBUTF8PROC + ,WCWIDTH_IMPL_JULIA +#endif }; WCWIDTH_FUNC wcwidth_impl_func = mk_wcwidth; @@ -99,13 +106,23 @@ static void read_settings(void) case WCWIDTH_IMPL_SYSTEM: wcwidth_impl_func = &system_wcwidth; break; + +#ifdef HAVE_LIBUTF8PROC + case WCWIDTH_IMPL_JULIA: + wcwidth_impl_func = (WCWIDTH_FUNC) &utf8proc_charwidth; + break; +#endif } } void wcwidth_wrapper_init(void) { +#ifdef HAVE_LIBUTF8PROC + settings_add_choice("misc", "wcwidth_implementation", WCWIDTH_IMPL_AUTO, "auto;old;system;julia"); +#else settings_add_choice("misc", "wcwidth_implementation", WCWIDTH_IMPL_AUTO, "auto;old;system"); +#endif read_settings(); signal_add("setup changed", (SIGNAL_FUNC) read_settings); From 3ef0b9b3d06ae1c004fa1e140042eefe00acb9c0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Aug 2018 14:03:16 +0200 Subject: [PATCH 0397/1198] move "auto" to default instead --- src/core/wcwidth-wrapper.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index 7b0a4def..b010069b 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -37,7 +37,6 @@ #define UNICODE_IRSSI_LOGO 0x1F525 enum { - WCWIDTH_IMPL_AUTO = 0, WCWIDTH_IMPL_OLD, WCWIDTH_IMPL_SYSTEM #ifdef HAVE_LIBUTF8PROC @@ -86,19 +85,6 @@ static void read_settings(void) choice = newchoice; switch (choice) { - case WCWIDTH_IMPL_AUTO: - /* Test against characters that have wcwidth=2 - * since unicode 5.2 and 9.0 respectively */ - - if (system_wcwidth(UNICODE_SQUARE_HIRAGANA_HOKA) == 2 || - system_wcwidth(UNICODE_IRSSI_LOGO) == 2) { - wcwidth_impl_func = &system_wcwidth; - } else { - /* Fall back to our own (which implements 5.0) */ - wcwidth_impl_func = &mk_wcwidth; - } - break; - case WCWIDTH_IMPL_OLD: wcwidth_impl_func = &mk_wcwidth; break; @@ -118,10 +104,22 @@ static void read_settings(void) void wcwidth_wrapper_init(void) { + int wcwidth_impl_default = 0; + /* Test against characters that have wcwidth=2 + * since unicode 5.2 and 9.0 respectively */ + + if (system_wcwidth(UNICODE_SQUARE_HIRAGANA_HOKA) == 2 || + system_wcwidth(UNICODE_IRSSI_LOGO) == 2) { + wcwidth_impl_default = WCWIDTH_IMPL_SYSTEM; + } else { + /* Fall back to our own (which implements 5.0) */ + wcwidth_impl_default = WCWIDTH_IMPL_OLD; + } + #ifdef HAVE_LIBUTF8PROC - settings_add_choice("misc", "wcwidth_implementation", WCWIDTH_IMPL_AUTO, "auto;old;system;julia"); + settings_add_choice("misc", "wcwidth_implementation", wcwidth_impl_default, "old;system;julia"); #else - settings_add_choice("misc", "wcwidth_implementation", WCWIDTH_IMPL_AUTO, "auto;old;system"); + settings_add_choice("misc", "wcwidth_implementation", wcwidth_impl_default, "old;system"); #endif read_settings(); From b2a429bfb45c63d6518ff8af5d8861618434bdae Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Aug 2018 14:03:53 +0200 Subject: [PATCH 0398/1198] update line cache on switching wcwidth implementation --- src/core/wcwidth-wrapper.c | 2 +- src/fe-text/gui-windows.c | 12 ++++++++++++ src/fe-text/textbuffer-view.c | 8 ++++---- src/fe-text/textbuffer-view.h | 2 ++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index b010069b..b670396d 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -123,7 +123,7 @@ void wcwidth_wrapper_init(void) #endif read_settings(); - signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add_first("setup changed", (SIGNAL_FUNC) read_settings); } void wcwidth_wrapper_deinit(void) diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index f761e390..0ad4c921 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -31,6 +31,7 @@ #include "gui-printtext.h" static int window_create_override; +int wcwidth_impl; static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *parent) @@ -51,6 +52,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, !settings_get_bool("indent_always"), get_default_indent_func()); textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); + wcwidth_impl = settings_get_choice("wcwidth_implementation"); textbuffer_view_set_hidden_level(gui->view, MSGLEVEL_HIDDEN); if (parent->active == window) textbuffer_view_set_window(gui->view, parent->screen_win); @@ -202,11 +204,17 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent) void gui_windows_reset_settings(void) { GSList *tmp; + int old_wcwidth_impl = wcwidth_impl; + wcwidth_impl = settings_get_choice("wcwidth_implementation"); for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; GUI_WINDOW_REC *gui = WINDOW_GUI(rec); + if (old_wcwidth_impl != wcwidth_impl) { + textbuffer_view_reset_cache(gui->view); + } + textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); textbuffer_view_set_default_indent(gui->view, @@ -217,6 +225,10 @@ void gui_windows_reset_settings(void) textbuffer_view_set_scroll(gui->view, gui->use_scroll ? gui->scroll : settings_get_bool("scroll")); + + if (old_wcwidth_impl != wcwidth_impl) { + textbuffer_view_redraw(gui->view); + } } } diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index dda2ed97..e85381e0 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -374,7 +374,7 @@ static void view_update_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, view->cache->last_linecount = view_get_linecount(view, line); } -static void view_reset_cache(TEXT_BUFFER_VIEW_REC *view) +void textbuffer_view_reset_cache(TEXT_BUFFER_VIEW_REC *view) { GSList *tmp; @@ -691,7 +691,7 @@ void textbuffer_view_set_break_wide(TEXT_BUFFER_VIEW_REC *view, { if (view->break_wide != break_wide) { view->break_wide = break_wide; - view_reset_cache(view); + textbuffer_view_reset_cache(view); } } @@ -703,7 +703,7 @@ static void view_unregister_indent_func(TEXT_BUFFER_VIEW_REC *view, /* recreate cache so it won't contain references to the indent function */ - view_reset_cache(view); + textbuffer_view_reset_cache(view); view->cache = textbuffer_cache_get(view->siblings, view->width); } @@ -1314,7 +1314,7 @@ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view) g_hash_table_foreach_remove(view->bookmarks, (GHRFunc) g_free_true, NULL); - view_reset_cache(view); + textbuffer_view_reset_cache(view); textbuffer_view_clear(view); g_slist_foreach(view->siblings, (GFunc) textbuffer_view_clear, NULL); } diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index a670df2b..1ae7c163 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -129,6 +129,8 @@ void textbuffer_view_scroll_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line); /* Return line cache */ LINE_CACHE_REC *textbuffer_view_get_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line); +/* Reset the whole line cache */ +void textbuffer_view_reset_cache(TEXT_BUFFER_VIEW_REC *view); /* Functions for manipulating the text buffer, using these commands update From 610ab2dafac4668732733009b079ebcf585dee9f Mon Sep 17 00:00:00 2001 From: "coypu@sdf.org" Date: Sat, 11 Aug 2018 22:28:14 +0000 Subject: [PATCH 0399/1198] Use-after-frees Hi folks! I tried clang-static-analyzer on irssi 1.1.1, it seems like it finds some things. Here's a diff, but there might be more that you would want to check, or choose to work differently. (in special-vars.c, ret is commands->data sometime) I hope it's not too much trouble if reported as a confidential bug. Thanks. --- src/core/modules.c | 3 ++- src/core/rawlog.c | 3 ++- src/core/special-vars.c | 2 +- src/fe-common/core/themes.c | 3 ++- src/irc/dcc/dcc.c | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/modules.c b/src/core/modules.c index a2542c84..4b7a91ca 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -289,8 +289,9 @@ void modules_deinit(void) while (list != NULL) { module_uniq_destroy(list->data); - g_free(list->data); + gconstpointer tmp = list->data; list = g_slist_remove(list, list->data); + g_free(tmp); } g_hash_table_destroy(idlookup); diff --git a/src/core/rawlog.c b/src/core/rawlog.c index fdd51241..da63fa50 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -64,9 +64,10 @@ static void rawlog_add(RAWLOG_REC *rawlog, char *str) if (rawlog->nlines < rawlog_lines || rawlog_lines <= 2) rawlog->nlines++; else { - g_free(rawlog->lines->data); + gconstpointer tmp = rawlog->lines->data; rawlog->lines = g_slist_remove(rawlog->lines, rawlog->lines->data); + g_free(tmp); } if (rawlog->logging) { diff --git a/src/core/special-vars.c b/src/core/special-vars.c index 33d9cd55..7081b602 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -620,8 +620,8 @@ void eval_special_string(const char *cmd, const char *data, /* FIXME: window item would need reference counting as well, eg. "/EVAL win close;say hello" wouldn't work now.. */ - g_free(ret); commands = g_slist_remove(commands, commands->data); + g_free(ret); } g_free(orig); } diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index e9818be9..cb3a7717 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -1424,8 +1424,9 @@ void themes_reload(void) change_theme(settings_get_str("theme"), FALSE); while (refs != NULL) { - theme_unref(refs->data); + gconstpointer tmp = refs->data; refs = g_slist_remove(refs, refs->data); + theme_unref(tmp); } } diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index c51f7c7a..eca4fe64 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -57,8 +57,8 @@ void dcc_unregister_type(const char *type) pos = gslist_find_string(dcc_types, type); if (pos != NULL) { - g_free(pos->data); dcc_types = g_slist_remove(dcc_types, pos->data); + g_free(pos->data); } } From 071ada830bd77055107220a420c96b41702f8cc2 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Aug 2018 14:21:37 +0200 Subject: [PATCH 0400/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index de29abd5..8d4da02f 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 16 +#define IRSSI_ABI_VERSION 17 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 9dd836b87663929ae540b6b3c724c53b24e512ba Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 24 Aug 2018 02:11:22 -0300 Subject: [PATCH 0401/1198] =?UTF-8?q?Fix=20"discards=20=E2=80=98const?= =?UTF-8?q?=E2=80=99=20qualifier"=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/modules.c | 2 +- src/core/rawlog.c | 2 +- src/fe-common/core/themes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/modules.c b/src/core/modules.c index 4b7a91ca..8439b73d 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -289,7 +289,7 @@ void modules_deinit(void) while (list != NULL) { module_uniq_destroy(list->data); - gconstpointer tmp = list->data; + void *tmp = list->data; list = g_slist_remove(list, list->data); g_free(tmp); } diff --git a/src/core/rawlog.c b/src/core/rawlog.c index da63fa50..e6bb7017 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -64,7 +64,7 @@ static void rawlog_add(RAWLOG_REC *rawlog, char *str) if (rawlog->nlines < rawlog_lines || rawlog_lines <= 2) rawlog->nlines++; else { - gconstpointer tmp = rawlog->lines->data; + void *tmp = rawlog->lines->data; rawlog->lines = g_slist_remove(rawlog->lines, rawlog->lines->data); g_free(tmp); diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index cb3a7717..a95f6180 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -1424,7 +1424,7 @@ void themes_reload(void) change_theme(settings_get_str("theme"), FALSE); while (refs != NULL) { - gconstpointer tmp = refs->data; + void *tmp = refs->data; refs = g_slist_remove(refs, refs->data); theme_unref(tmp); } From ade2f87fe599773886a044b7c29a482622dfaea4 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 24 Aug 2018 02:19:42 -0300 Subject: [PATCH 0402/1198] Fix use after free introduced by the use after free patch --- src/irc/dcc/dcc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index eca4fe64..01ab0e59 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -57,8 +57,9 @@ void dcc_unregister_type(const char *type) pos = gslist_find_string(dcc_types, type); if (pos != NULL) { - dcc_types = g_slist_remove(dcc_types, pos->data); - g_free(pos->data); + void *tmp = pos->data; + dcc_types = g_slist_remove(dcc_types, pos->data); + g_free(tmp); } } From e450a7f8c1c74132625d0a884f0ca851abd69197 Mon Sep 17 00:00:00 2001 From: dequis Date: Fri, 24 Aug 2018 02:27:45 -0300 Subject: [PATCH 0403/1198] modules_deinit: Fix -Werror=declaration-after-statement --- src/core/modules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/modules.c b/src/core/modules.c index 8439b73d..9b531899 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -288,8 +288,8 @@ void modules_deinit(void) g_hash_table_foreach(stridlookup, (GHFunc) uniq_get_modules, &list); while (list != NULL) { - module_uniq_destroy(list->data); void *tmp = list->data; + module_uniq_destroy(list->data); list = g_slist_remove(list, list->data); g_free(tmp); } From 92804cb1aa753fa1f5e9b588a4bd7125bc98ce49 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 27 Aug 2018 00:01:47 -0300 Subject: [PATCH 0404/1198] gui-windows: make the wcwidth_impl global var into static --- src/fe-text/gui-windows.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 0ad4c921..e7f799c8 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -31,7 +31,7 @@ #include "gui-printtext.h" static int window_create_override; -int wcwidth_impl; +static int wcwidth_impl; static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, MAIN_WINDOW_REC *parent) @@ -205,7 +205,8 @@ void gui_windows_reset_settings(void) { GSList *tmp; int old_wcwidth_impl = wcwidth_impl; - wcwidth_impl = settings_get_choice("wcwidth_implementation"); + + wcwidth_impl = settings_get_choice("wcwidth_implementation"); for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; From 7b70d051da10e6ea54cc118e8f7f254ddd07f6c1 Mon Sep 17 00:00:00 2001 From: dequis Date: Mon, 27 Aug 2018 00:14:01 -0300 Subject: [PATCH 0405/1198] wcwidth-wrapper: avoid cast with a tiny wrapper, julia_wcwidth() --- src/core/wcwidth-wrapper.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index b670396d..8dd9dac7 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -71,6 +71,15 @@ static int system_wcwidth(unichar ucs) return retval; } +#ifdef HAVE_LIBUTF8PROC +/* wrapper because the function signatures are different + * (the parameter is unsigned for us, signed for them) */ +static int julia_wcwidth(unichar ucs) +{ + return utf8proc_charwidth(ucs); +} +#endif + static void read_settings(void) { static int choice = -1; @@ -95,7 +104,7 @@ static void read_settings(void) #ifdef HAVE_LIBUTF8PROC case WCWIDTH_IMPL_JULIA: - wcwidth_impl_func = (WCWIDTH_FUNC) &utf8proc_charwidth; + wcwidth_impl_func = &julia_wcwidth; break; #endif } From bbca1a5a0fa59567fc3082263dc5e9b087e02da6 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 27 Aug 2018 20:50:17 -0700 Subject: [PATCH 0406/1198] Revert "Revert "Flag topic as unset if it is zero length"" This reverts commit 817179a7606b616795cf67e24505526dded34381. --- .gitignore | 1 + src/irc/core/channel-events.c | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 916457f8..1ab7df5f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ tests/irc/core/test-irc.trs *.la *.lo *.o +*.swp *~ *.tar.bz2 diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 46bbd5fa..4b74b322 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -126,23 +126,25 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; - /* the topic may be send out encoded, so we need to + + g_free_and_null(chanrec->topic); + g_free_and_null(chanrec->topic_by); + chanrec->topic_time = 0; + + /* the topic may be sent out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); - if (topic != NULL) { - g_free_not_null(chanrec->topic); - chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); + if (recoded == NULL || *recoded == '\0') { + signal_emit("channel topic changed", 1, chanrec); + g_free(recoded); + return; } - g_free(recoded); - g_free_not_null(chanrec->topic_by); + chanrec->topic = recoded; chanrec->topic_by = g_strdup(setby); - - if (chanrec->topic_by == NULL) { + if (chanrec->topic_by != NULL) { /* ensure invariant topic_time > 0 <=> topic_by != NULL. this could be triggered by a topic command without sender */ - chanrec->topic_time = 0; - } else { chanrec->topic_time = settime; } From 04db359a6d0f6d8630c2439fb26b7420ecc48582 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Thu, 9 Aug 2018 13:49:46 -0700 Subject: [PATCH 0407/1198] Handle topic info numeric separately from topic & topic numeric As we called the same function for the topic info numeric, we ended up losing the topic as that numeric does not include it. We now call a different function to handle this case more carefully. Fixes #903. --- src/irc/core/channel-events.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 4b74b322..e533a6f0 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -28,6 +28,9 @@ #include "irc-servers.h" #include "irc-channels.h" +static void set_topic_info(CHANNEL_REC *const, char const *const, + time_t const); + static void check_join_failure(IRC_SERVER_REC *server, const char *channel) { CHANNEL_REC *chanrec; @@ -141,14 +144,36 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, } chanrec->topic = recoded; + set_topic_info(chanrec, setby, settime); + + signal_emit("channel topic changed", 1, chanrec); +} + +static void channel_change_topic_info(IRC_SERVER_REC *server, + const char *channel, const char *setby, time_t settime) +{ + CHANNEL_REC *chanrec; + + chanrec = channel_find(SERVER(server), channel); + if (chanrec == NULL) return; + + g_free_and_null(chanrec->topic_by); + chanrec->topic_time = 0; + + set_topic_info(chanrec, setby, settime); + + signal_emit("channel topic changed", 1, chanrec); +} + +static void set_topic_info(CHANNEL_REC *const chanrec, char const *const setby, + time_t const settime) +{ chanrec->topic_by = g_strdup(setby); if (chanrec->topic_by != NULL) { /* ensure invariant topic_time > 0 <=> topic_by != NULL. this could be triggered by a topic command without sender */ chanrec->topic_time = settime; } - - signal_emit("channel topic changed", 1, chanrec); } static void event_topic_get(IRC_SERVER_REC *server, const char *data) @@ -188,7 +213,7 @@ static void event_topic_info(IRC_SERVER_REC *server, const char *data) &topicby, &topictime); t = (time_t) atol(topictime); - channel_change_topic(server, channel, NULL, topicby, t); + channel_change_topic_info(server, channel, topicby, t); g_free(params); } From 2d6033542e0e47072d61ef442430c3014e3b430f Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 11 Aug 2018 10:48:00 -0700 Subject: [PATCH 0408/1198] Add functions to override irssi dir and config Setting up to test is easier this way. --- src/core/core.c | 10 ++++++++++ src/core/core.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/core/core.c b/src/core/core.c index 506d6a13..d87e86e2 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -73,12 +73,22 @@ const char *get_irssi_dir(void) return irssi_dir; } +void set_irssi_dir(char *const s) +{ + irssi_dir = s; +} + /* return full path for ~/.irssi/config */ const char *get_irssi_config(void) { return irssi_config_file; } +void set_irssi_config(char *const s) +{ + irssi_config_file = s; +} + static void sig_reload_config(int signo) { reload_config = TRUE; diff --git a/src/core/core.h b/src/core/core.h index 982dbaad..395e5c83 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -16,6 +16,9 @@ extern int irssi_init_finished; /* TRUE after "irssi init finished" signal is se extern int reload_config; /* TRUE after received SIGHUP. */ extern time_t client_start_time; +void set_irssi_dir(char *const); +void set_irssi_config(char *const); + void core_preinit(const char *path); void core_register_options(void); From 2ccb312b8b56db9585a4801184c064bfd3e3ff90 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 11 Aug 2018 10:49:26 -0700 Subject: [PATCH 0409/1198] Expose functions for testing --- src/irc/core/Makefile.am | 1 + src/irc/core/channel-events.c | 7 ++++--- src/irc/core/channel-events.h | 12 ++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/irc/core/channel-events.h diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am index 20caaeb1..c668faea 100644 --- a/src/irc/core/Makefile.am +++ b/src/irc/core/Makefile.am @@ -40,6 +40,7 @@ pkginc_irc_coredir=$(pkgincludedir)/src/irc/core pkginc_irc_core_HEADERS = \ bans.h \ ctcp.h \ + channel-events.h \ channel-rejoin.h \ irc.h \ irc-channels.h \ diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index e533a6f0..0cdb47fd 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -21,6 +21,7 @@ #include "module.h" #include "signals.h" #include "misc.h" +#include "channel-events.h" #include "channels-setup.h" #include "settings.h" #include "recode.h" @@ -176,7 +177,7 @@ static void set_topic_info(CHANNEL_REC *const chanrec, char const *const setby, } } -static void event_topic_get(IRC_SERVER_REC *server, const char *data) +void event_topic_get(IRC_SERVER_REC *server, const char *data) { char *params, *channel, *topic; @@ -187,7 +188,7 @@ static void event_topic_get(IRC_SERVER_REC *server, const char *data) g_free(params); } -static void event_topic(IRC_SERVER_REC *server, const char *data, +void event_topic(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *channel, *topic, *mask; @@ -202,7 +203,7 @@ static void event_topic(IRC_SERVER_REC *server, const char *data, g_free(params); } -static void event_topic_info(IRC_SERVER_REC *server, const char *data) +void event_topic_info(IRC_SERVER_REC *server, const char *data) { char *params, *channel, *topicby, *topictime; time_t t; diff --git a/src/irc/core/channel-events.h b/src/irc/core/channel-events.h new file mode 100644 index 00000000..f0dea8b4 --- /dev/null +++ b/src/irc/core/channel-events.h @@ -0,0 +1,12 @@ +#ifndef __CHANNEL_EVENTS_H +#define __CHANNEL_EVENTS_H + +#include "irc.h" + +/* Not private for tests. */ +void event_topic_get(IRC_SERVER_REC *, const char *); +void event_topic(IRC_SERVER_REC *, const char *, + const char *, const char *); +void event_topic_info(IRC_SERVER_REC *, const char *); + +#endif From 6f38d67d87f2ef443172cca4d9ee82300d9f5ca4 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 11 Aug 2018 10:49:47 -0700 Subject: [PATCH 0410/1198] Add tests for channel change events --- tests/irc/core/Makefile.am | 11 +- tests/irc/core/test-channel-events.c | 202 +++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 tests/irc/core/test-channel-events.c diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index 86f1d547..f60da03f 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -8,21 +8,24 @@ AM_CPPFLAGS = \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) -test_programs = test-irc +test_programs = test-channel-events test-irc -test_irc_CPPFLAGS = \ +CPPFLAGS = \ -I$(top_srcdir)/src/irc/core \ $(AM_CPPFLAGS) -test_irc_DEPENDENCIES = \ +DEPENDENCIES = \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a -test_irc_LDADD = \ +LDADD = \ ../../../src/irc/core/libirc_core.a \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a \ @PROG_LIBS@ +test_channel_events_SOURCES = \ + test-channel-events.c + test_irc_SOURCES = \ test-irc.c diff --git a/tests/irc/core/test-channel-events.c b/tests/irc/core/test-channel-events.c new file mode 100644 index 00000000..477e235c --- /dev/null +++ b/tests/irc/core/test-channel-events.c @@ -0,0 +1,202 @@ +/* + test-irc.c : irssi + + Copyright (C) 2018 Will Storey + + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "test-channel-events" + +typedef struct { + char const *const description; + char const *const input; + char const *const topic; + char const *const topic_by; + time_t const topic_time; +} topic_test_case; + +static void test_event_topic_get(topic_test_case const *const); +static void test_event_topic(topic_test_case const *const); +static void test_event_topic_info(topic_test_case const *const); +static void setup(void); +static void teardown(void); + +static IRC_SERVER_REC *server; +static CHANNEL_REC *channel; + +topic_test_case const event_topic_get_test_cases[] = { + { + .description = "Normal 332 message with a topic with multiple words", + .input = "testnick #test :new topic", + .topic = "new topic", + .topic_by = NULL, + .topic_time = 0, + }, +}; + +topic_test_case const event_topic_info_test_cases[] = { + { + .description = "Normal 333 message", + .input = "testnick #test newnick!user@example.com 1533866229", + .topic = "initial topic", + .topic_by = "newnick!user@example.com", + .topic_time = 1533866229, + }, +}; + +topic_test_case const event_topic_test_cases[] = { + { + .description = "Normal TOPIC message", + .input = "#test :new topic", + .topic = "new topic", + .topic_by = "newnick!user@example.com", + .topic_time = 0, /* Dynamic */ + }, +}; + +int main(int argc, char **argv) +{ + int i, res; + + g_test_init(&argc, &argv, NULL); + + modules_init(); + signals_init(); + set_irssi_dir("/tmp/irssi"); + set_irssi_config("/tmp/irssi/config"); + settings_init(); + recode_init(); + + settings_add_str("lookandfeel", "term_charset", "UTF-8"); + recode_update_charset(); + + for (i = 0; i < G_N_ELEMENTS(event_topic_get_test_cases); i++) { + char *const name = g_strdup_printf("/test/event_topic_get/%d", i); + g_test_add_data_func(name, &event_topic_get_test_cases[i], + (GTestDataFunc)test_event_topic_get); + g_free(name); + } + + for (i = 0; i < G_N_ELEMENTS(event_topic_test_cases); i++) { + char *const name = g_strdup_printf("/test/event_topic/%d", i); + g_test_add_data_func(name, &event_topic_test_cases[i], + (GTestDataFunc)test_event_topic); + g_free(name); + } + + for (i = 0; i < G_N_ELEMENTS(event_topic_info_test_cases); i++) { + char *const name = g_strdup_printf("/test/event_topic_info/%d", i); + g_test_add_data_func(name, &event_topic_info_test_cases[i], + (GTestDataFunc)test_event_topic_info); + g_free(name); + } + +#if GLIB_CHECK_VERSION(2,38,0) + g_test_set_nonfatal_assertions(); +#endif + res = g_test_run(); + + recode_deinit(); + settings_deinit(); + signals_deinit(); + modules_deinit(); + + return res; +} + +static void test_event_topic_get(topic_test_case const *const test) +{ + setup(); + + event_topic_get(server, test->input); + + g_assert_cmpstr(channel->topic, ==, test->topic); + g_assert_cmpstr(channel->topic_by, ==, test->topic_by); + g_assert_cmpint(channel->topic_time, ==, test->topic_time); + + teardown(); +} + +static void test_event_topic(topic_test_case const *const test) +{ + time_t now; + + setup(); + + now = time(NULL); + event_topic(server, test->input, "newnick", "user@example.com"); + + g_assert_cmpstr(channel->topic, ==, test->topic); + g_assert_cmpstr(channel->topic_by, ==, test->topic_by); + g_assert_cmpint(channel->topic_time, >=, now); + + teardown(); +} + +static void test_event_topic_info(topic_test_case const *const test) +{ + setup(); + + event_topic_info(server, test->input); + + g_assert_cmpstr(channel->topic, ==, test->topic); + g_assert_cmpstr(channel->topic_by, ==, test->topic_by); + g_assert_cmpint(channel->topic_time, ==, test->topic_time); + + teardown(); +} + +static void setup(void) +{ + server = g_new0(IRC_SERVER_REC, 1); + MODULE_DATA_INIT(server); + server->type = module_get_uniq_id("SERVER", 0); + + channel = g_new0(CHANNEL_REC, 1); + channel->name = "#test"; + server->channels = g_slist_append(server->channels, channel); + + g_assert_nonnull(channel_find(SERVER(server), "#test")); + + channel->topic = g_strdup("initial topic"); + channel->topic_by = g_strdup("initialnick!user@example.com"); + channel->topic_time = 123; +} + +static void teardown(void) +{ + g_slist_free(server->channels); + MODULE_DATA_DEINIT(server); + g_free(server); + + g_free(channel->topic); + g_free(channel->topic_by); + g_free(channel); +} From 0edb64c4dc731065705f3303307f20b3ccb5674a Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 11 Aug 2018 10:52:39 -0700 Subject: [PATCH 0411/1198] Add test files to .gitignore --- .gitignore | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1ab7df5f..ee1480cb 100644 --- a/.gitignore +++ b/.gitignore @@ -51,8 +51,23 @@ src/perl/*/Makefile.old src/fe-fuzz/crash-* src/fe-fuzz/oom-* -tests/irc/core/test-irc -tests/irc/core/test-irc.trs +/core +/tests/fe-common/core/test-formats +/tests/fe-common/core/test-formats.log +/tests/fe-common/core/test-formats.trs +/tests/fe-common/core/test-suite.log +/tests/irc/core/core +/tests/irc/core/test-channel-events +/tests/irc/core/test-channel-events.log +/tests/irc/core/test-channel-events.trs +/tests/irc/core/test-irc +/tests/irc/core/test-irc.log +/tests/irc/core/test-irc.trs +/tests/irc/core/test-suite.log +/tests/irc/flood/test-796 +/tests/irc/flood/test-796.log +/tests/irc/flood/test-796.trs +/tests/irc/flood/test-suite.log *.a *.bs From b11932d24f01703d07eb0f7a0de6c226ebcde195 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 27 Aug 2018 21:04:23 -0700 Subject: [PATCH 0412/1198] Make channel event functions static again --- src/irc/core/channel-events.c | 6 +++--- src/irc/core/channel-events.h | 7 ++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 0cdb47fd..85d985ea 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -177,7 +177,7 @@ static void set_topic_info(CHANNEL_REC *const chanrec, char const *const setby, } } -void event_topic_get(IRC_SERVER_REC *server, const char *data) +static void event_topic_get(IRC_SERVER_REC *server, const char *data) { char *params, *channel, *topic; @@ -188,7 +188,7 @@ void event_topic_get(IRC_SERVER_REC *server, const char *data) g_free(params); } -void event_topic(IRC_SERVER_REC *server, const char *data, +static void event_topic(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { char *params, *channel, *topic, *mask; @@ -203,7 +203,7 @@ void event_topic(IRC_SERVER_REC *server, const char *data, g_free(params); } -void event_topic_info(IRC_SERVER_REC *server, const char *data) +static void event_topic_info(IRC_SERVER_REC *server, const char *data) { char *params, *channel, *topicby, *topictime; time_t t; diff --git a/src/irc/core/channel-events.h b/src/irc/core/channel-events.h index f0dea8b4..6d01c48e 100644 --- a/src/irc/core/channel-events.h +++ b/src/irc/core/channel-events.h @@ -3,10 +3,7 @@ #include "irc.h" -/* Not private for tests. */ -void event_topic_get(IRC_SERVER_REC *, const char *); -void event_topic(IRC_SERVER_REC *, const char *, - const char *, const char *); -void event_topic_info(IRC_SERVER_REC *, const char *); +void channel_events_init(void); +void channel_events_deinit(void); #endif From 7b09cac9ec0ce7e549ae8fecf4db8b8d811c18b1 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 27 Aug 2018 21:04:54 -0700 Subject: [PATCH 0413/1198] Call functions via signals rather than directly This allows us to leave functions static. --- tests/irc/core/test-channel-events.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/irc/core/test-channel-events.c b/tests/irc/core/test-channel-events.c index 477e235c..98c70ce8 100644 --- a/tests/irc/core/test-channel-events.c +++ b/tests/irc/core/test-channel-events.c @@ -93,6 +93,7 @@ int main(int argc, char **argv) set_irssi_config("/tmp/irssi/config"); settings_init(); recode_init(); + channel_events_init(); settings_add_str("lookandfeel", "term_charset", "UTF-8"); recode_update_charset(); @@ -123,6 +124,7 @@ int main(int argc, char **argv) #endif res = g_test_run(); + channel_events_deinit(); recode_deinit(); settings_deinit(); signals_deinit(); @@ -135,7 +137,7 @@ static void test_event_topic_get(topic_test_case const *const test) { setup(); - event_topic_get(server, test->input); + signal_emit("event 332", 2, server, test->input); g_assert_cmpstr(channel->topic, ==, test->topic); g_assert_cmpstr(channel->topic_by, ==, test->topic_by); @@ -151,7 +153,8 @@ static void test_event_topic(topic_test_case const *const test) setup(); now = time(NULL); - event_topic(server, test->input, "newnick", "user@example.com"); + signal_emit("event topic", 4, server, test->input, "newnick", + "user@example.com"); g_assert_cmpstr(channel->topic, ==, test->topic); g_assert_cmpstr(channel->topic_by, ==, test->topic_by); @@ -164,7 +167,7 @@ static void test_event_topic_info(topic_test_case const *const test) { setup(); - event_topic_info(server, test->input); + signal_emit("event 333", 2, server, test->input); g_assert_cmpstr(channel->topic, ==, test->topic); g_assert_cmpstr(channel->topic_by, ==, test->topic_by); From 82702de047237550d1299cb9b7461a952e6cc74d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 29 Aug 2018 09:09:58 +0200 Subject: [PATCH 0414/1198] Add information about crash on unload to perl.txt reported by urchlay: http://urchlay.naptime.net/repos/misc-scripts/tree/selfunload.pl --- docs/perl.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/perl.txt b/docs/perl.txt index 59f65462..4f875c97 100644 --- a/docs/perl.txt +++ b/docs/perl.txt @@ -1192,6 +1192,7 @@ Client->{} Bugs and Limitations -------------------- * Calling die in 'script error' handler causes segfault (#101) +* Calling "script unload" from your own script causes segfault * Storing and later using any Irssi object may result in use-after-free related crash - Workaround: always acquire fresh objects * Calling $dcc->close from the "dcc created" signal will cause unstable behaviour and crashes (#386) From 3351c54a2f8ac2add41ba7ce829c215a65d3c923 Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 1 Sep 2018 19:12:17 -0300 Subject: [PATCH 0415/1198] Fix /save not working if the config didn't previously exist realpath() was supposed to resolve symlinks but it also fails with ENOENT (no such file or directory) if the file just isn't there. --- src/lib-config/write.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index 255d79c0..b8ef6156 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -302,6 +302,7 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) int ret; int fd; int save_errno; + const char *base_name; char *tmp_name = NULL; char *dest_name = NULL; @@ -309,12 +310,20 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) g_return_val_if_fail(fname != NULL || rec->fname != NULL, -1); g_return_val_if_fail(create_mode != -1 || rec->create_mode != -1, -1); + base_name = fname != NULL ? fname : rec->fname; + /* expand all symlinks; else we may replace a symlink with a regular file */ - dest_name = realpath(fname != NULL ? fname : rec->fname, NULL); + dest_name = realpath(base_name, NULL); + if (dest_name == NULL) { - config_error(rec, g_strerror(errno)); - ret = -1; - goto out; + if (errno == ENOENT) { + dest_name = g_strdup(base_name); + errno = 0; + } else { + config_error(rec, g_strerror(errno)); + ret = -1; + goto out; + } } tmp_name = g_strdup_printf("%s.XXXXXX", dest_name); From e2e27d1809684a6745d7b449561aeb5f30a42a74 Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 2 Sep 2018 01:20:09 -0300 Subject: [PATCH 0416/1198] Improve error message when failing to create the config dir --- src/core/settings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/settings.c b/src/core/settings.c index 3ebb9e4a..5fc37ded 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -762,7 +762,8 @@ static void init_configfile(void) if (stat(get_irssi_dir(), &statbuf) != 0) { /* ~/.irssi not found, create it. */ if (g_mkdir_with_parents(get_irssi_dir(), 0700) != 0) { - g_error("Couldn't create %s directory", get_irssi_dir()); + g_error("Couldn't create %s directory: %s", + get_irssi_dir(), g_strerror(errno)); } } else if (!S_ISDIR(statbuf.st_mode)) { g_error("%s is not a directory.\n" From 04497ed69d35cf44b0700437bf427f48dbc42871 Mon Sep 17 00:00:00 2001 From: Dominyk Tiller Date: Mon, 3 Sep 2018 00:30:48 +0100 Subject: [PATCH 0417/1198] configure: fix Perl detection on macOS Mojave Apple has significantly changed the way `perl` is structured in macOS Mojave/10.14, which is due to ship stable this month. The `perl` restructuring has been an issue for a while but I recently obtained confirmation from Apple the changes were intentional & consequently not something that was going to be walked back before Mojave reaches its stable release. As of 10.14 the Perl headers are moving inside the SDK, instead of residing in `/System` directly. There's a flag to tell Clang to look inside the SDK without projects having to explicitly locate the SDK & fiddle with the location themselves, which is `-iwithsysroot`, and that's what `perl` outputs now when `configure` checks `perl -MExtUtils::Embed -e ccopts`: ``` -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector -iwithsysroot /System/Library/Perl/5.18/darwin-thread-multi-2level/CORE ``` The latter bit of that was previously `-I/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE`. The problem here is that `configure` filters out flags that start with a lowercase `i` and consequently the Perl elements fail to build. This tiny patch fixes that issue, restoring Perl support to `irssi` when built on macOS 10.14. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d29c132b..9b2c54d1 100644 --- a/configure.ac +++ b/configure.ac @@ -388,8 +388,8 @@ if test "$want_perl" != "no"; then dnl * fix those command line options a bit so GCC won't dnl * complain about them. Normally there's only few options dnl * that we want to keep: - dnl * -Ddefine -Uundef -I/path -fopt -mopt - PERL_CFLAGS=`echo $PERL_CFLAGS | $perlpath -pe 's/^(.* )?-@<:@^DUIfm@:>@@<:@^ @:>@+/\1/g; s/^(.* )?\+@<:@^ @:>@+/\1/g'` + dnl * -Ddefine -Uundef -I/path -fopt -mopt -iwithsysroot + PERL_CFLAGS=`echo $PERL_CFLAGS | $perlpath -pe 's/^(.* )?-@<:@^DUIifm@:>@@<:@^ @:>@+/\1/g; s/^(.* )?\+@<:@^ @:>@+/\1/g'` PERL_EXTRA_OPTS="CCCDLFLAGS=\"-fPIC\"" AC_SUBST(PERL_EXTRA_OPTS) From 329448939ba8f9cc9803d4b3045d517b0ab0f9aa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 4 Sep 2018 09:36:45 +0200 Subject: [PATCH 0418/1198] Fix gnu wcwidth --- src/core/wcwidth-wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index 8dd9dac7..03d0dc0c 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -18,7 +18,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _XOPEN_SOURCE +#define _GNU_SOURCE #include #include "module.h" From 3f0a4ef1970a164d7bce64e2fa887036fd162236 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 4 Sep 2018 10:17:20 +0200 Subject: [PATCH 0419/1198] Remove incorrectly copied automake commands from fuzzer --- src/fe-fuzz/fe-common/core/Makefile.am | 13 ------------- src/fe-fuzz/irc/core/Makefile.am | 13 ------------- 2 files changed, 26 deletions(-) diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am index 4fe5937c..9aa39a84 100644 --- a/src/fe-fuzz/fe-common/core/Makefile.am +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -10,19 +10,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) -AM_DEPENDENCIES = \ - ../../../core/libcore.a \ - ../../../lib-config/libirssi_config.a \ - ../../../irc/libirc.a \ - ../../../irc/core/libirc_core.a \ - ../../../irc/dcc/libirc_dcc.a \ - ../../../irc/flood/libirc_flood.a \ - ../../../irc/notifylist/libirc_notifylist.a \ - ../../../fe-common/core/libfe_common_core.a \ - ../../../fe-common/irc/libfe_common_irc.a \ - ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ - ../../../fe-common/irc/notifylist/libfe_irc_notifylist.a - LDADD = \ ../../../irc/libirc.a \ ../../../irc/core/libirc_core.a \ diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am index fa614abb..cb8b7e31 100644 --- a/src/fe-fuzz/irc/core/Makefile.am +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -10,19 +10,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) -AM_DEPENDENCIES = \ - ../../../core/libcore.a \ - ../../../lib-config/libirssi_config.a \ - ../../../irc/libirc.a \ - ../../../irc/core/libirc_core.a \ - ../../../irc/dcc/libirc_dcc.a \ - ../../../irc/flood/libirc_flood.a \ - ../../../irc/notifylist/libirc_notifylist.a \ - ../../../fe-common/core/libfe_common_core.a \ - ../../../fe-common/irc/libfe_common_irc.a \ - ../../../fe-common/irc/dcc/libfe_irc_dcc.a \ - ../../../fe-common/irc/notifylist/libfe_irc_notifylist a - LDADD = \ ../../../irc/libirc.a \ ../../../irc/core/libirc_core.a \ From 74e8371bde8143535da46a833835313d75ae8f4e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 4 Sep 2018 14:12:03 +0200 Subject: [PATCH 0420/1198] fix accessing unallocated text when checking entry position fixes #928 --- src/fe-text/gui-entry.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index b3c73c15..ee3de77d 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -212,7 +212,7 @@ static int pos2scrpos(GUI_ENTRY_REC *entry, int pos, int cursor) xpos += scrlen_str(entry->extents[0], entry->utf8); } - for (i = 0; i < pos; i++) { + for (i = 0; i < entry->text_len && i < pos; i++) { unichar c = entry->text[i]; const char *extent = entry->uses_extents ? entry->extents[i+1] : NULL; @@ -226,9 +226,8 @@ static int pos2scrpos(GUI_ENTRY_REC *entry, int pos, int cursor) if (extent != NULL) { xpos += scrlen_str(extent, entry->utf8); } - } - return xpos; + return xpos + pos - i; } static int scrpos2pos(GUI_ENTRY_REC *entry, int pos) From c80946bcf5f1a9c48213fd718a8c8bffc6dd1307 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 4 Sep 2018 15:50:58 +0200 Subject: [PATCH 0421/1198] Disconnect SASL properly in case the sasl module got unloaded from server stops from getting on the network when sasl is unavailable fixes #629 --- src/fe-common/irc/fe-sasl.c | 22 ------------------- src/irc/core/irc-servers-setup.c | 2 +- src/irc/core/sasl.c | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index fc8105fc..ed11f047 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -40,36 +40,14 @@ static void sig_sasl_failure(IRC_SERVER_REC *server, const char *reason) printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_SASL_ERROR, reason); } -static void sig_cap_end(IRC_SERVER_REC *server) -{ - /* The negotiation has now been terminated, if we didn't manage to - * authenticate successfully with the server just disconnect. */ - if (!server->sasl_success && - server->connrec->sasl_mechanism != SASL_MECHANISM_NONE && - settings_get_bool("sasl_disconnect_on_failure")) { - /* We can't use server_disconnect() here because we'd end up - * freeing the 'server' object and be guilty of a slew of UaF. */ - server->connection_lost = TRUE; - /* By setting connection_lost we make sure the communication is - * halted and when the control goes back to irc_parse_incoming - * the server object is safely destroyed. */ - signal_stop(); - } - -} - void fe_sasl_init(void) { - settings_add_bool("server", "sasl_disconnect_on_failure", TRUE); - signal_add("server sasl success", (SIGNAL_FUNC) sig_sasl_success); signal_add("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); - signal_add_first("server cap end", (SIGNAL_FUNC) sig_cap_end); } void fe_sasl_deinit(void) { signal_remove("server sasl success", (SIGNAL_FUNC) sig_sasl_success); signal_remove("server sasl failure", (SIGNAL_FUNC) sig_sasl_failure); - signal_remove("server cap end", (SIGNAL_FUNC) sig_cap_end); } diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index e79557ab..0af93902 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -98,9 +98,9 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, if (ircnet->sasl_mechanism != NULL) { if (!g_ascii_strcasecmp(ircnet->sasl_mechanism, "plain")) { /* The PLAIN method needs both the username and the password */ + conn->sasl_mechanism = SASL_MECHANISM_PLAIN; if (ircnet->sasl_username != NULL && *ircnet->sasl_username && ircnet->sasl_password != NULL && *ircnet->sasl_password) { - conn->sasl_mechanism = SASL_MECHANISM_PLAIN; conn->sasl_username = ircnet->sasl_username; conn->sasl_password = ircnet->sasl_password; } else diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index c5aa2caa..b7abe748 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -301,9 +301,42 @@ static void sasl_disconnected(IRC_SERVER_REC *server) sasl_timeout_stop(server); } +static void sig_sasl_over(IRC_SERVER_REC *server) +{ + if (!IS_IRC_SERVER(server)) + return; + + /* The negotiation has now been terminated, if we didn't manage to + * authenticate successfully with the server just disconnect. */ + if (!server->sasl_success && + server->connrec->sasl_mechanism != SASL_MECHANISM_NONE) { + if (server->cap_supported == NULL || + !g_hash_table_lookup_extended(server->cap_supported, "sasl", NULL, NULL)) { + signal_emit("server sasl failure", 2, server, "The server did not offer SASL"); + } + + if (settings_get_bool("sasl_disconnect_on_failure")) { + /* We can't use server_disconnect() here because we'd end up + * freeing the 'server' object and be guilty of a slew of UaF. */ + server->connection_lost = TRUE; + /* By setting connection_lost we make sure the communication is + * halted and when the control goes back to irc_parse_incoming + * the server object is safely destroyed. */ + signal_stop(); + } + } + +} + void sasl_init(void) { + settings_add_bool("server", "sasl_disconnect_on_failure", TRUE); + + signal_add_first("event 001", (SIGNAL_FUNC) sig_sasl_over); + /* this event can get us connected on broken ircds, see irc-servers.c */ + signal_add_first("event 375", (SIGNAL_FUNC) sig_sasl_over); signal_add_first("server cap ack sasl", (SIGNAL_FUNC) sasl_start); + signal_add_first("server cap end", (SIGNAL_FUNC) sig_sasl_over); signal_add_first("event authenticate", (SIGNAL_FUNC) sasl_step); signal_add_first("event 903", (SIGNAL_FUNC) sasl_success); signal_add_first("event 902", (SIGNAL_FUNC) sasl_fail); @@ -316,7 +349,10 @@ void sasl_init(void) void sasl_deinit(void) { + signal_remove("event 001", (SIGNAL_FUNC) sig_sasl_over); + signal_remove("event 375", (SIGNAL_FUNC) sig_sasl_over); signal_remove("server cap ack sasl", (SIGNAL_FUNC) sasl_start); + signal_remove("server cap end", (SIGNAL_FUNC) sig_sasl_over); signal_remove("event authenticate", (SIGNAL_FUNC) sasl_step); signal_remove("event 903", (SIGNAL_FUNC) sasl_success); signal_remove("event 902", (SIGNAL_FUNC) sasl_fail); From c174247502ebffe615f1e55ba7a5010856db41d3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 14 Sep 2018 11:59:05 +0200 Subject: [PATCH 0422/1198] fix compilation of theme-indent module --- src/fe-text/Makefile.am | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index 6ce8427c..ef2e3611 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -53,20 +53,20 @@ irssi_SOURCES = \ pkginc_fe_textdir=$(pkgincludedir)/src/fe-text pkginc_fe_text_HEADERS = \ - statusbar-item.h + gui-printtext.h \ + gui-windows.h \ + mainwindows.h \ + statusbar-item.h \ + term.h \ + textbuffer.h \ + textbuffer-view.h noinst_HEADERS = \ - gui-entry.h \ - gui-printtext.h \ - gui-readline.h \ - gui-windows.h \ - mainwindows.h \ - statusbar.h \ - statusbar-config.h \ - term.h \ + gui-entry.h \ + gui-readline.h \ + statusbar.h \ + statusbar-config.h \ terminfo-core.h \ - textbuffer.h \ - textbuffer-view.h \ module.h \ module-formats.h From 20dcf4e53e05f61ed6e901f203e6f1ab90bc2bea Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 14 Sep 2018 12:44:41 +0200 Subject: [PATCH 0423/1198] fix compilation of python module --- src/fe-text/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index ef2e3611..448a9389 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -56,6 +56,7 @@ pkginc_fe_text_HEADERS = \ gui-printtext.h \ gui-windows.h \ mainwindows.h \ + statusbar.h \ statusbar-item.h \ term.h \ textbuffer.h \ @@ -64,7 +65,6 @@ pkginc_fe_text_HEADERS = \ noinst_HEADERS = \ gui-entry.h \ gui-readline.h \ - statusbar.h \ statusbar-config.h \ terminfo-core.h \ module.h \ From b9a274a81d4020b4a1c5809b150ec869c897f17b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Sep 2018 12:26:13 +0200 Subject: [PATCH 0424/1198] correctly separate ignore flags (no_act, hidden) from level --- src/core/ignore.c | 32 ++++++++--------- src/core/ignore.h | 2 ++ src/fe-common/core/fe-messages.c | 36 ++++++++++---------- src/fe-common/irc/dcc/fe-dcc-chat-messages.c | 24 ++++++------- src/fe-common/irc/fe-irc-messages.c | 16 ++++----- src/fe-common/irc/fe-modes.c | 16 +++++++-- src/perl/common/Ignore.xs | 23 +++++++++++++ 7 files changed, 92 insertions(+), 57 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 57c84623..5b89f6f4 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -82,17 +82,12 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * However we also want to allow NO_ACT combined with levels, so mask it out and * match levels if set. */ #define FLAG_MSGLEVELS ( MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN ) -static int ignore_match_level(IGNORE_REC *rec, int level) +static int ignore_match_level(IGNORE_REC *rec, int level, int flags) { - if (level & FLAG_MSGLEVELS) { - int flaglevel = level & FLAG_MSGLEVELS; - int msglevel = level & ~FLAG_MSGLEVELS; - return (msglevel & rec->level) && (flaglevel & rec->level); - } else if (!(rec->level & FLAG_MSGLEVELS)) { - return (level & rec->level); - } else { - return FALSE; - } + level &= ~FLAG_MSGLEVELS; + flags &= FLAG_MSGLEVELS; + + return ((flags & rec->level) == flags) && ((level & rec->level) != 0); } #define ignore_match_nickmask(rec, nick, nickmask) \ @@ -109,7 +104,7 @@ static int ignore_match_level(IGNORE_REC *rec, int level) ((rec)->channels == NULL || ((channel) != NULL && \ strarray_find((rec)->channels, (channel)) != -1)) -static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text, int level) +static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text, int level, int flags) { GSList *tmp; @@ -121,7 +116,7 @@ static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text, int leve IGNORE_REC *rec = tmp->data; if (rec->mask != NULL && rec->replies && - ignore_match_level(rec, level) && + ignore_match_level(rec, level, flags) && ignore_match_channel(rec, chanrec->name) && ignore_check_replies_rec(rec, chanrec, text)) return TRUE; @@ -130,8 +125,8 @@ static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text, int leve return FALSE; } -int ignore_check(SERVER_REC *server, const char *nick, const char *host, - const char *channel, const char *text, int level) +int ignore_check_flags(SERVER_REC *server, const char *nick, const char *host, + const char *channel, const char *text, int level, int flags) { CHANNEL_REC *chanrec; NICK_REC *nickrec; @@ -167,7 +162,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, ignore_match_channel(rec, channel) && ignore_match_nickmask(rec, nick, nickmask); if (match && - ignore_match_level(rec, level) && + ignore_match_level(rec, level, flags) && ignore_match_pattern(rec, text)) { len = rec->mask == NULL ? 0 : strlen(rec->mask); if (len > best_mask) { @@ -188,7 +183,12 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, if (best_match || (level & MSGLEVEL_PUBLIC) == 0) return best_match; - return ignore_check_replies(chanrec, text, level); + return ignore_check_replies(chanrec, text, level, flags); +} + +int ignore_check(SERVER_REC *server, const char *nick, const char *host, + const char *channel, const char *text, int level) { + return ignore_check_flags(server, nick, host, channel, text, level, 0); } IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char *pattern, diff --git a/src/core/ignore.h b/src/core/ignore.h index 958aa801..607ee115 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -25,6 +25,8 @@ extern GSList *ignores; int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); +int ignore_check_flags(SERVER_REC *server, const char *nick, const char *host, + const char *channel, const char *text, int level, int flags); enum { IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 05c64d70..31a2011d 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -201,10 +201,10 @@ static void sig_message_public(SERVER_REC *server, const char *msg, if (for_me) level |= MSGLEVEL_HILIGHT; - if (ignore_check(server, nick, address, target, msg, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, target, msg, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, target, msg, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, target, msg, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; if (settings_get_bool("emphasis")) @@ -263,10 +263,10 @@ static void sig_message_private(SERVER_REC *server, const char *msg, if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg); - if (ignore_check(server, nick, address, NULL, msg, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, NULL, msg, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, NULL, msg, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, NULL, msg, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; if (own) { @@ -361,10 +361,10 @@ static void sig_message_join(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_JOINS; - if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; printformat(server, channel, level, @@ -377,10 +377,10 @@ static void sig_message_part(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_PARTS; - if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; printformat(server, channel, level, @@ -399,10 +399,10 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_QUITS)) return; - if (ignore_check(server, nick, address, NULL, reason, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, NULL, reason, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, NULL, reason, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, NULL, reason, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; print_channel = NULL; @@ -424,10 +424,10 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, continue; } - if (ignore_check(server, nick, address, rec->visible_name, reason, MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, rec->visible_name, reason, MSGLEVEL_QUITS, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, rec->visible_name, reason, MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, rec->visible_name, reason, MSGLEVEL_QUITS, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; if (print_channel == NULL || @@ -476,10 +476,10 @@ static void sig_message_kick(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_KICKS; - if (ignore_check(server, kicker, address, channel, reason, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, kicker, address, channel, reason, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, kicker, address, channel, reason, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, kicker, address, channel, reason, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; printformat(server, channel, level, @@ -500,10 +500,10 @@ static void print_nick_change_channel(SERVER_REC *server, const char *channel, level = MSGLEVEL_NICKS; if (ownnick) level |= MSGLEVEL_NO_ACT; - if (!(level & MSGLEVEL_NO_ACT) && ignore_check(server, oldnick, address, channel, newnick, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, oldnick, address, channel, newnick, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (!(level & MSGLEVEL_HIDDEN) && ignore_check(server, oldnick, address, channel, newnick, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, oldnick, address, channel, newnick, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; printformat(server, channel, level, @@ -582,10 +582,10 @@ static void sig_message_topic(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_TOPICS; - if (ignore_check(server, nick, address, channel, topic, level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(server, nick, address, channel, topic, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, channel, topic, level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(server, nick, address, channel, topic, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; printformat(server, channel, level, diff --git a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c index 3a45a36b..9ae88c8e 100644 --- a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c +++ b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c @@ -92,12 +92,12 @@ static void sig_message_dcc(CHAT_DCC_REC *dcc, const char *msg) tag = g_strconcat("=", dcc->id, NULL); query = query_find(NULL, tag); - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, @@ -118,12 +118,12 @@ static void sig_message_dcc_action(CHAT_DCC_REC *dcc, const char *msg) tag = g_strconcat("=", dcc->id, NULL); query = query_find(NULL, tag); - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, @@ -143,12 +143,12 @@ static void sig_message_dcc_ctcp(CHAT_DCC_REC *dcc, const char *cmd, tag = g_strconcat("=", dcc->id, NULL); - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, - level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, + level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, - level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, + level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index e8558a17..86e0836c 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -158,12 +158,12 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, if (ignore_check(SERVER(server), nick, address, target, msg, level)) return; - if (ignore_check(SERVER(server), nick, address, target, msg, - level | MSGLEVEL_NO_ACT)) + if (ignore_check_flags(SERVER(server), nick, address, target, msg, + level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(SERVER(server), nick, address, target, msg, - level | MSGLEVEL_HIDDEN)) + if (ignore_check_flags(SERVER(server), nick, address, target, msg, + level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; if (server_ischannel(SERVER(server), target)) { @@ -240,14 +240,14 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg, msg, level)) return; - if (ignore_check(server, nick, address, + if (ignore_check_flags(server, nick, address, server_ischannel(SERVER(server), target) ? target : NULL, - msg, level | MSGLEVEL_NO_ACT)) + msg, level, MSGLEVEL_NO_ACT)) level |= MSGLEVEL_NO_ACT; - if (ignore_check(server, nick, address, + if (ignore_check_flags(server, nick, address, server_ischannel(SERVER(server), target) ? target : NULL, - msg, level | MSGLEVEL_HIDDEN)) + msg, level, MSGLEVEL_HIDDEN)) level |= MSGLEVEL_HIDDEN; if (server_ischannel(SERVER(server), target)) { diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c index 53e56c97..ad829757 100644 --- a/src/fe-common/irc/fe-modes.c +++ b/src/fe-common/irc/fe-modes.c @@ -162,19 +162,29 @@ static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, const char *nick, const char *addr, const char *mode) { + int level = MSGLEVEL_MODES; + if (nick == NULL) nick = server->real_address; if (ignore_check(SERVER(server), nick, addr, channel, mode, MSGLEVEL_MODES)) return; + if (ignore_check_flags(SERVER(server), nick, addr, channel, + mode, MSGLEVEL_MODES, MSGLEVEL_NO_ACT)) + level |= MSGLEVEL_NO_ACT; + + if (ignore_check_flags(SERVER(server), nick, addr, channel, + mode, MSGLEVEL_MODES, MSGLEVEL_HIDDEN)) + level |= MSGLEVEL_HIDDEN; + if (!server_ischannel(SERVER(server), channel)) { /* user mode change */ - printformat(server, NULL, MSGLEVEL_MODES, + printformat(server, NULL, level, IRCTXT_USERMODE_CHANGE, mode, channel); } else if (addr == NULL) { /* channel mode changed by server */ - printformat(server, channel, MSGLEVEL_MODES, + printformat(server, channel, level, IRCTXT_SERVER_CHANMODE_CHANGE, channel, mode, nick); } else { @@ -187,7 +197,7 @@ static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, if (chanrec != NULL && g_ascii_strcasecmp(nick, server->nick) != 0) msg_multi_mode(chanrec, nick, addr, mode); else { - printformat(server, channel, MSGLEVEL_MODES, + printformat(server, channel, level, IRCTXT_CHANMODE_CHANGE, channel, mode, nick, addr); } diff --git a/src/perl/common/Ignore.xs b/src/perl/common/Ignore.xs index 8dfd0ad3..144497de 100644 --- a/src/perl/common/Ignore.xs +++ b/src/perl/common/Ignore.xs @@ -25,6 +25,19 @@ CODE: OUTPUT: RETVAL +int +ignore_check_flags(nick, host, channel, text, level, flags) + char *nick + char *host + char *channel + char *text + int level + int flags +CODE: + RETVAL = ignore_check_flags(NULL, nick, host, channel, text, level, flags); +OUTPUT: + RETVAL + #******************************* MODULE = Irssi::Ignore PACKAGE = Irssi::Server #******************************* @@ -38,6 +51,16 @@ ignore_check(server, nick, host, channel, text, level) char *text int level +int +ignore_check_flags(server, nick, host, channel, text, level, flags) + Irssi::Server server + char *nick + char *host + char *channel + char *text + int level + int flags + #******************************* MODULE = Irssi::Ignore PACKAGE = Irssi::Ignore PREFIX = ignore_ #******************************* From 7e9f8c694b38ae785771fb837fb0a4a434b614d3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Sep 2018 12:48:42 +0200 Subject: [PATCH 0425/1198] simplify ignore hidden/no_act code --- src/core/ignore.c | 16 +++++ src/core/ignore.h | 2 + src/fe-common/core/fe-messages.c | 67 ++++---------------- src/fe-common/irc/dcc/fe-dcc-chat-messages.c | 27 ++------ src/fe-common/irc/fe-irc-messages.c | 31 ++------- src/fe-common/irc/fe-modes.c | 12 +--- 6 files changed, 45 insertions(+), 110 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 5b89f6f4..58999709 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -191,6 +191,22 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_flags(server, nick, host, channel, text, level, 0); } +int ignore_check_plus(SERVER_REC *server, const char *nick, const char *address, + const char *target, const char *msg, int *level, int test_ignore) { + int olevel = *level; + + if (test_ignore && ignore_check(server, nick, address, target, msg, olevel)) + return TRUE; + + if (ignore_check_flags(server, nick, address, target, msg, olevel, MSGLEVEL_NO_ACT)) + *level |= MSGLEVEL_NO_ACT; + + if (ignore_check_flags(server, nick, address, target, msg, olevel, MSGLEVEL_HIDDEN)) + *level |= MSGLEVEL_HIDDEN; + + return FALSE; +} + IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char *pattern, char **channels, const int flags) { diff --git a/src/core/ignore.h b/src/core/ignore.h index 607ee115..20c5475e 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -27,6 +27,8 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); int ignore_check_flags(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level, int flags); +int ignore_check_plus(SERVER_REC *server, const char *nick, const char *host, + const char *channel, const char *text, int *level, int test_ignore); enum { IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 31a2011d..12cb1055 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -201,11 +201,7 @@ static void sig_message_public(SERVER_REC *server, const char *msg, if (for_me) level |= MSGLEVEL_HILIGHT; - if (ignore_check_flags(server, nick, address, target, msg, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, target, msg, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, nick, address, target, msg, &level, FALSE); if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); @@ -263,11 +259,7 @@ static void sig_message_private(SERVER_REC *server, const char *msg, if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg); - if (ignore_check_flags(server, nick, address, NULL, msg, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, NULL, msg, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, nick, address, NULL, msg, &level, FALSE); if (own) { printformat(server, target, level, @@ -361,11 +353,7 @@ static void sig_message_join(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_JOINS; - if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, nick, address, channel, NULL, &level, FALSE); printformat(server, channel, level, TXT_JOIN, nick, address, channel); @@ -377,11 +365,7 @@ static void sig_message_part(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_PARTS; - if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, channel, NULL, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, nick, address, channel, NULL, &level, FALSE); printformat(server, channel, level, TXT_PART, nick, address, channel, reason); @@ -396,15 +380,9 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, char *print_channel; int once, count, level = MSGLEVEL_QUITS; - if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_QUITS)) + if (ignore_check_plus(server, nick, address, NULL, reason, &level, TRUE)) return; - if (ignore_check_flags(server, nick, address, NULL, reason, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, NULL, reason, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; - print_channel = NULL; once = settings_get_bool("show_quit_once"); @@ -418,18 +396,12 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, if (!nicklist_find(rec, nick)) continue; - if (ignore_check(server, nick, address, rec->visible_name, - reason, MSGLEVEL_QUITS)) { + if (ignore_check_plus(server, nick, address, rec->visible_name, + reason, &level, TRUE)) { count++; continue; } - if (ignore_check_flags(server, nick, address, rec->visible_name, reason, MSGLEVEL_QUITS, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, rec->visible_name, reason, MSGLEVEL_QUITS, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; - if (print_channel == NULL || active_win->active == (WI_ITEM_REC *) rec) print_channel = rec->visible_name; @@ -476,11 +448,7 @@ static void sig_message_kick(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_KICKS; - if (ignore_check_flags(server, kicker, address, channel, reason, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, kicker, address, channel, reason, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, kicker, address, channel, reason, &level, FALSE); printformat(server, channel, level, TXT_KICK, nick, channel, kicker, reason, address); @@ -493,18 +461,11 @@ static void print_nick_change_channel(SERVER_REC *server, const char *channel, { int level; - if (ignore_check(server, oldnick, address, - channel, newnick, MSGLEVEL_NICKS)) - return; - level = MSGLEVEL_NICKS; if (ownnick) level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, oldnick, address, channel, newnick, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, oldnick, address, channel, newnick, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + if (ignore_check_plus(server, oldnick, address, + channel, newnick, &level, TRUE)) + return; printformat(server, channel, level, ownnick ? TXT_YOUR_NICK_CHANGED : TXT_NICK_CHANGED, @@ -582,11 +543,7 @@ static void sig_message_topic(SERVER_REC *server, const char *channel, { int level = MSGLEVEL_TOPICS; - if (ignore_check_flags(server, nick, address, channel, topic, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, channel, topic, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(server, nick, address, channel, topic, &level, FALSE); printformat(server, channel, level, *topic != '\0' ? TXT_NEW_TOPIC : TXT_TOPIC_UNSET, diff --git a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c index 9ae88c8e..41cea64c 100644 --- a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c +++ b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c @@ -92,13 +92,8 @@ static void sig_message_dcc(CHAT_DCC_REC *dcc, const char *msg) tag = g_strconcat("=", dcc->id, NULL); query = query_find(NULL, tag); - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + &level, FALSE); format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); @@ -118,13 +113,8 @@ static void sig_message_dcc_action(CHAT_DCC_REC *dcc, const char *msg) tag = g_strconcat("=", dcc->id, NULL); query = query_find(NULL, tag); - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, - level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg, + &level, FALSE); format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); @@ -143,13 +133,8 @@ static void sig_message_dcc_ctcp(CHAT_DCC_REC *dcc, const char *cmd, tag = g_strconcat("=", dcc->id, NULL); - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, - level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, - level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; + ignore_check_plus(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd, + &level, FALSE); format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag, level, NULL); diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 86e0836c..89c501a8 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -155,17 +155,9 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, level = MSGLEVEL_ACTIONS | (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS); - if (ignore_check(SERVER(server), nick, address, target, msg, level)) + if (ignore_check_plus(SERVER(server), nick, address, target, msg, &level, TRUE)) return; - if (ignore_check_flags(SERVER(server), nick, address, target, msg, - level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(SERVER(server), nick, address, target, msg, - level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; - if (server_ischannel(SERVER(server), target)) { item = irc_channel_find(server, target); } else { @@ -226,30 +218,21 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg, target = fe_channel_skip_prefix(IRC_SERVER(server), target); if (address == NULL || *address == '\0') { + level = MSGLEVEL_SNOTES; /* notice from server */ - if (!ignore_check(server, nick, "", - target, msg, MSGLEVEL_SNOTES)) { - printformat(server, target, MSGLEVEL_SNOTES, + if (!ignore_check_plus(server, nick, "", + target, msg, &level, TRUE)) { + printformat(server, target, level, IRCTXT_NOTICE_SERVER, nick, msg); } return; } - if (ignore_check(server, nick, address, + if (ignore_check_plus(server, nick, address, server_ischannel(SERVER(server), target) ? target : NULL, - msg, level)) + msg, &level, TRUE)) return; - if (ignore_check_flags(server, nick, address, - server_ischannel(SERVER(server), target) ? target : NULL, - msg, level, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(server, nick, address, - server_ischannel(SERVER(server), target) ? target : NULL, - msg, level, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; - if (server_ischannel(SERVER(server), target)) { /* notice in some channel */ printformat(server, target, level, diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c index ad829757..dfe65c2d 100644 --- a/src/fe-common/irc/fe-modes.c +++ b/src/fe-common/irc/fe-modes.c @@ -166,18 +166,10 @@ static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, if (nick == NULL) nick = server->real_address; - if (ignore_check(SERVER(server), nick, addr, channel, - mode, MSGLEVEL_MODES)) + if (ignore_check_plus(SERVER(server), nick, addr, channel, + mode, &level, TRUE)) return; - if (ignore_check_flags(SERVER(server), nick, addr, channel, - mode, MSGLEVEL_MODES, MSGLEVEL_NO_ACT)) - level |= MSGLEVEL_NO_ACT; - - if (ignore_check_flags(SERVER(server), nick, addr, channel, - mode, MSGLEVEL_MODES, MSGLEVEL_HIDDEN)) - level |= MSGLEVEL_HIDDEN; - if (!server_ischannel(SERVER(server), channel)) { /* user mode change */ printformat(server, NULL, level, From 011d9437d158ae815cfab55a5e2c0b0a57430353 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Sep 2018 13:08:43 +0200 Subject: [PATCH 0426/1198] oops --- src/core/ignore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 58999709..9bfcfaf5 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -87,7 +87,7 @@ static int ignore_match_level(IGNORE_REC *rec, int level, int flags) level &= ~FLAG_MSGLEVELS; flags &= FLAG_MSGLEVELS; - return ((flags & rec->level) == flags) && ((level & rec->level) != 0); + return ((FLAG_MSGLEVELS & rec->level) == flags) && ((level & rec->level) != 0); } #define ignore_match_nickmask(rec, nick, nickmask) \ From cb6279c63bbb98a419f9f72495b8a8232a3e7529 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Mon, 17 Sep 2018 13:28:46 +0000 Subject: [PATCH 0427/1198] fe-text: add window_default_hidelevel setting Allows specifying the hidelevel that new windows get by default. --- src/fe-text/gui-windows.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index e7f799c8..0890fe6f 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -53,7 +53,7 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, get_default_indent_func()); textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide")); wcwidth_impl = settings_get_choice("wcwidth_implementation"); - textbuffer_view_set_hidden_level(gui->view, MSGLEVEL_HIDDEN); + textbuffer_view_set_hidden_level(gui->view, settings_get_level("window_default_hidelevel")); if (parent->active == window) textbuffer_view_set_window(gui->view, parent->screen_win); return gui; @@ -303,6 +303,7 @@ void gui_windows_init(void) settings_add_bool("lookandfeel", "indent_always", FALSE); settings_add_bool("lookandfeel", "break_wide", FALSE); settings_add_bool("lookandfeel", "scroll", TRUE); + settings_add_level("lookandfeel", "window_default_hidelevel", "HIDDEN"); window_create_override = MAIN_WINDOW_TYPE_NONE; From 074e6cf768b9c153b64a916b4b2d332d8ba6bef4 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Mon, 17 Sep 2018 14:26:25 +0000 Subject: [PATCH 0428/1198] fe-text: only save non-default window hidelevel This will only save the window hidelevel in the layout if it differs from window_default_hidelevel. --- src/fe-text/mainwindows-layout.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index 17c6647b..b937dffe 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -42,7 +42,7 @@ static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) iconfig_node_set_int(node, "parent", active->refnum); } - if (gui->view->hidden_level != MSGLEVEL_HIDDEN) { + if (gui->view->hidden_level != settings_get_level("window_default_hidelevel")) { char *level = bits2level(gui->view->hidden_level); iconfig_node_set_str(node, "hidelevel", level); g_free(level); @@ -56,6 +56,7 @@ static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) { WINDOW_REC *parent; GUI_WINDOW_REC *gui; + char *default_hidelevel = settings_get_str("window_default_hidelevel"); gui = WINDOW_GUI(window); @@ -66,7 +67,7 @@ static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) if (config_node_get_bool(node, "sticky", FALSE)) gui_window_set_sticky(window); - textbuffer_view_set_hidden_level(gui->view, level2bits(config_node_get_str(node, "hidelevel", "HIDDEN"), NULL)); + textbuffer_view_set_hidden_level(gui->view, level2bits(config_node_get_str(node, "hidelevel", default_hidelevel), NULL)); if (config_node_get_str(node, "scroll", NULL) != NULL) { gui->use_scroll = TRUE; From cad79f1db74787c68951e166cdc68af21ec67301 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Mon, 17 Sep 2018 14:34:06 +0000 Subject: [PATCH 0429/1198] Fix compilation warning --- src/fe-text/mainwindows-layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index b937dffe..b3f8e741 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -56,7 +56,7 @@ static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) { WINDOW_REC *parent; GUI_WINDOW_REC *gui; - char *default_hidelevel = settings_get_str("window_default_hidelevel"); + const char *default_hidelevel = settings_get_str("window_default_hidelevel"); gui = WINDOW_GUI(window); From f231a59e81a7487dc46ad58fbdbde90d3b750435 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 20 Sep 2018 17:50:35 +0200 Subject: [PATCH 0430/1198] properly document the ignore_match_level so I understand it next time --- src/core/ignore.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 9bfcfaf5..371da83b 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -87,7 +87,17 @@ static int ignore_match_level(IGNORE_REC *rec, int level, int flags) level &= ~FLAG_MSGLEVELS; flags &= FLAG_MSGLEVELS; - return ((FLAG_MSGLEVELS & rec->level) == flags) && ((level & rec->level) != 0); + if (!flags) { + /* case: we are not checking special flags. then, the + record must not have any flags either, but it must + have some of the levels */ + return !(FLAG_MSGLEVELS & rec->level) && (level & rec->level); + } else { + /* case: we want to test if some special flags + apply. then, the record must have some of the + flags and some of the levels */ + return (flags & rec->level) && (level & rec->level); + } } #define ignore_match_nickmask(rec, nick, nickmask) \ From 01f961cdf1d009ea4a8adc55fd6688f81dbb76c6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Sep 2018 12:56:06 +0200 Subject: [PATCH 0431/1198] Don't trigger activity on hidden lines by default This is controlled by a new activity_hide_window_hidelevel setting. --- docs/signals.txt | 1 + src/fe-common/core/window-activity.c | 12 +++++++++-- src/fe-text/textbuffer-commands.c | 31 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index 270315b8..959387b2 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -286,6 +286,7 @@ themes.c: window-activity.c: "window hilight", WINDOW_REC + "window hilight check", TEXT_DEST_REC, char *msg, int *data_level, int *should_ignore "window dehilight", WINDOW_REC "window activity", WINDOW_REC, int old_level "window item hilight", WI_ITEM_REC diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 89493aea..77d6d4a0 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -34,7 +34,7 @@ #include "fe-common-core.h" static char **hide_targets; -static int hide_level, msg_level, hilight_level; +static int hide_level, msg_level, hilight_level, signal_window_hilight_check; void window_activity(WINDOW_REC *window, int data_level, const char *hilight_color) @@ -74,6 +74,7 @@ static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg) { WI_ITEM_REC *item; int data_level; + int cb_ignore = 0; if (dest->window == active_win || (dest->level & hide_level)) return; @@ -91,6 +92,12 @@ static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg) return; } + /* we should ask the text view if this line is hidden */ + signal_emit_id(signal_window_hilight_check, 5, dest, msg, &data_level, &cb_ignore); + if (cb_ignore) { + return; + } + if (dest->target != NULL) { item = window_item_find(dest->server, dest->target); if (item != NULL) { @@ -125,7 +132,7 @@ static void read_settings(void) hide_targets = *targets == '\0' ? NULL : g_strsplit(targets, " ", -1); - hide_level = MSGLEVEL_NEVER | MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN | + hide_level = MSGLEVEL_NEVER | MSGLEVEL_NO_ACT | settings_get_level("activity_hide_level"); msg_level = settings_get_level("activity_msg_level"); hilight_level = MSGLEVEL_HILIGHT | @@ -138,6 +145,7 @@ void window_activity_init(void) settings_add_level("lookandfeel", "activity_hide_level", ""); settings_add_level("lookandfeel", "activity_msg_level", "PUBLIC"); settings_add_level("lookandfeel", "activity_hilight_level", "MSGS DCCMSGS"); + signal_window_hilight_check = signal_get_uniq_id("window hilight check"); read_settings(); signal_add("print text", (SIGNAL_FUNC) sig_hilight_text); diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c index 97d897f3..7278772c 100644 --- a/src/fe-text/textbuffer-commands.c +++ b/src/fe-text/textbuffer-commands.c @@ -30,6 +30,8 @@ #include "printtext.h" #include "gui-windows.h" +static int activity_hide_window_hidelevel; + /* SYNTAX: CLEAR [-all] [] */ static void cmd_clear(const char *data) { @@ -373,8 +375,32 @@ static void sig_away_changed(SERVER_REC *server) } } +static void sig_window_hilight_check(TEXT_DEST_REC *dest, char *msg, int *data_level, int *ignore) +{ + GUI_WINDOW_REC *gui; + + g_return_if_fail(dest != NULL); + g_return_if_fail(ignore != NULL); + + if (*ignore != 0 || !activity_hide_window_hidelevel || dest->window == NULL) + return; + + gui = WINDOW_GUI(dest->window); + + if (dest->level & gui->view->hidden_level) { + *ignore = TRUE; + } +} + +static void read_settings(void) +{ + activity_hide_window_hidelevel = settings_get_bool("activity_hide_window_hidelevel"); +} + void textbuffer_commands_init(void) { + settings_add_bool("lookandfeel", "activity_hide_window_hidelevel", TRUE); + command_bind("clear", NULL, (SIGNAL_FUNC) cmd_clear); command_bind("window scroll", NULL, (SIGNAL_FUNC) cmd_window_scroll); command_bind("window hidelevel", NULL, (SIGNAL_FUNC) cmd_window_hidelevel); @@ -390,7 +416,10 @@ void textbuffer_commands_init(void) command_set_options("scrollback clear", "all"); command_set_options("scrollback levelclear", "all -level"); + read_settings(); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); signal_add("away mode changed", (SIGNAL_FUNC) sig_away_changed); + signal_add("window hilight check", (SIGNAL_FUNC) sig_window_hilight_check); } void textbuffer_commands_deinit(void) @@ -406,5 +435,7 @@ void textbuffer_commands_deinit(void) command_unbind("scrollback end", (SIGNAL_FUNC) cmd_scrollback_end); command_unbind("scrollback status", (SIGNAL_FUNC) cmd_scrollback_status); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); signal_remove("away mode changed", (SIGNAL_FUNC) sig_away_changed); + signal_remove("window hilight check", (SIGNAL_FUNC) sig_window_hilight_check); } From db005007cf3c951ace57b1810b30248fe371e4be Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 26 Sep 2018 14:16:09 +0200 Subject: [PATCH 0432/1198] fix irssi being stuck when resized very small --- src/fe-text/mainwindows.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 83a3e0cc..68cb9880 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -285,8 +285,13 @@ static MAIN_WINDOW_REC *mainwindows_find_lower(MAIN_WINDOW_REC *window) MAIN_WINDOW_REC *best; GSList *tmp; + /* unfortunate special case: if the window has been resized + and there is not enough room, the last_line could become + smaller than the first_line, sending us in an infinite + loop */ if (window != NULL) - last_line = window->last_line; + last_line = + window->last_line > window->first_line ? window->last_line : window->first_line; else last_line = -1; From 76b934d18e81ffbfa1e7480396d47fcced9394e8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 26 Sep 2018 15:19:44 +0200 Subject: [PATCH 0433/1198] Fix broken display after resizing many windows very small --- src/fe-text/mainwindows.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 83a3e0cc..d9b26a97 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -520,7 +520,7 @@ static void gui_windows_remove_parent(MAIN_WINDOW_REC *window) } } -void mainwindow_destroy(MAIN_WINDOW_REC *window) +static void mainwindow_destroy_full(MAIN_WINDOW_REC *window, int respace) { g_return_if_fail(window != NULL); @@ -531,7 +531,7 @@ void mainwindow_destroy(MAIN_WINDOW_REC *window) if (mainwindows != NULL) { gui_windows_remove_parent(window); - if (!quitting) { + if (respace) { mainwindows_add_space(window); mainwindows_redraw(); } @@ -542,12 +542,14 @@ void mainwindow_destroy(MAIN_WINDOW_REC *window) if (active_mainwin == window) active_mainwin = NULL; } +void mainwindow_destroy(MAIN_WINDOW_REC *window) +{ + mainwindow_destroy_full(window, !quitting); +} + void mainwindow_destroy_half(MAIN_WINDOW_REC *window) { - int really_quitting = quitting; - quitting = TRUE; - mainwindow_destroy(window); - quitting = really_quitting; + mainwindow_destroy_full(window, FALSE); } void mainwindows_redraw(void) @@ -821,6 +823,12 @@ void mainwindows_resize(int width, int height) mainwindows_resize_smaller(ydiff); } + /* if we lost our active mainwin, get a new one */ + if (active_mainwin == NULL && !quitting) { + active_mainwin = WINDOW_MAIN(active_win); + window_set_active(active_mainwin->active); + } + signal_emit("terminal resized", 0); irssi_redraw(); From 8684ccb45c267fdeaaa779fce9323047aa5a9e38 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 28 Sep 2018 11:40:50 +0200 Subject: [PATCH 0434/1198] invalidate startline and bottom_startline when hidden this was overlooked when adding hidden line support. if the lines are removed, Irssi has to update the startline. It does that by "scrolling" the lines to the proper place. The scroll function was adjusted to calculate 0 for hidden lines, thus it would miss them. --- src/fe-text/textbuffer-view.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index e85381e0..e5141430 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -1230,6 +1230,11 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, if (is_last == 1) view->startline = NULL; } + + if (view->startline == line) { + view->startline = line->next; + view->subline = 0; + } } else { if (textbuffer_line_exists_after(view->bottom_startline, line)) { @@ -1239,6 +1244,11 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, view->empty_linecount += linecount-realcount; } + if (view->bottom_startline == line) { + view->bottom_startline = view->bottom_startline->next; + view->bottom_subline = 0; + } + if (textbuffer_line_exists_after(view->startline, line)) { view_remove_line_update_startline(view, line, From 04daf62dbf9a1668b5eb12b64f90701b11f374ca Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 28 Sep 2018 14:30:39 +0200 Subject: [PATCH 0435/1198] Fix insufficient size of help column when the window width is small --- src/fe-common/core/fe-help.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-help.c b/src/fe-common/core/fe-help.c index 23a6e701..c7566113 100644 --- a/src/fe-common/core/fe-help.c +++ b/src/fe-common/core/fe-help.c @@ -77,7 +77,12 @@ static void help_category(GSList *cmdlist, int items) max_width, 6, 1, 3, &columns, &rows); cmdlist = columns_sort_list(cmdlist, rows); - /* rows in last column */ + /* if the screen is too narrow the window width may be not + enough for even 1 column */ + if (cols == 1 && columns[0] > max_width) + max_width = columns[0]; + + /* rows in last column */ last_col_rows = rows-(cols*rows-g_slist_length(cmdlist)); if (last_col_rows == 0) last_col_rows = rows; From b264540f4ed5e273835a2d5feb10decb18a4fed6 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sat, 29 Sep 2018 07:13:32 -0400 Subject: [PATCH 0436/1198] fe-text: clear hidelevel in layout if default This is required, otherwise setting the hidelevel to the default will not be written in the layout and so won't persist. --- src/fe-text/mainwindows-layout.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index b3f8e741..bb53fdab 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -46,6 +46,8 @@ static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) char *level = bits2level(gui->view->hidden_level); iconfig_node_set_str(node, "hidelevel", level); g_free(level); + } else { + iconfig_node_set_str(node, "hidelevel", NULL); } if (gui->use_scroll) From f5e587a83b0f3569a8024b54713667d55e157370 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sat, 29 Sep 2018 18:37:10 -0400 Subject: [PATCH 0437/1198] Fix 01f961c --- src/fe-common/core/window-activity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 77d6d4a0..48e909a4 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -93,7 +93,7 @@ static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg) } /* we should ask the text view if this line is hidden */ - signal_emit_id(signal_window_hilight_check, 5, dest, msg, &data_level, &cb_ignore); + signal_emit_id(signal_window_hilight_check, 4, dest, msg, &data_level, &cb_ignore); if (cb_ignore) { return; } From c4bf228e6c2a045f4906b38e9eaf2591cc4f984e Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sun, 30 Sep 2018 05:38:13 +0000 Subject: [PATCH 0438/1198] Fix check for C99 in printtext.h --- src/fe-common/core/printtext.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index ab8dfac1..db53c611 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -46,16 +46,16 @@ void printtext_deinit(void); printformat_module_dest(MODULE_NAME, dest, ##formatnum) # define printformat_gui(formatnum...) \ printformat_module_gui(MODULE_NAME, ##formatnum) -#elif defined (_ISOC99_SOURCE) +#elif __STDC_VERSION__ >= 199901L /* C99 */ # define printformat(server, target, level, formatnum, ...) \ - printformat_module(MODULE_NAME, server, target, level, formatnum, __VA_ARGS__) + printformat_module(MODULE_NAME, server, target, level, formatnum, ##__VA_ARGS__) # define printformat_window(window, level, formatnum, ...) \ - printformat_module_window(MODULE_NAME, window, level, formatnum, __VA_ARGS__) + printformat_module_window(MODULE_NAME, window, level, formatnum, ##__VA_ARGS__) # define printformat_dest(dest, formatnum, ...) \ - printformat_module_dest(MODULE_NAME, dest, formatnum, __VA_ARGS__) + printformat_module_dest(MODULE_NAME, dest, formatnum, ##__VA_ARGS__) # define printformat_gui(formatnum, ...) \ - printformat_module_gui(MODULE_NAME, formatnum, __VA_ARGS__) + printformat_module_gui(MODULE_NAME, formatnum, ##__VA_ARGS__) #else /* inline/static */ #ifdef G_CAN_INLINE From ca1ec21dc21563e63a91d4e307dc5ad0490e6cc4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 1 Oct 2018 09:13:15 +0200 Subject: [PATCH 0439/1198] fix and document window width on screen width dependency --- src/fe-text/mainwindows.c | 4 ++-- src/fe-text/mainwindows.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index d1495965..b01f3d04 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -252,9 +252,9 @@ MAIN_WINDOW_REC *mainwindow_create(int right) } g_slist_free(line); } else { - if (MAIN_WINDOW_TEXT_WIDTH(parent) < - 2* NEW_WINDOW_WIDTH) + if (MAIN_WINDOW_TEXT_WIDTH(parent) < 2 * NEW_WINDOW_WIDTH) { parent = find_window_with_room_right(); + } if (parent == NULL) return NULL; /* not enough space */ diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 414275bf..4810c1e3 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -5,7 +5,7 @@ #include "term.h" #define WINDOW_MIN_SIZE 2 -#define NEW_WINDOW_WIDTH 10 +#define NEW_WINDOW_WIDTH 20 /* must be >= MIN_SCREEN_WIDTH defined in term.c */ #define MAIN_WINDOW_TEXT_HEIGHT(window) \ ((window)->height-(window)->statusbar_lines) From ff7f4a2207c19c2d5e67edc61c24b1f9781fe1c5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 2 Oct 2018 16:27:28 +0200 Subject: [PATCH 0440/1198] Remove cubes from irssi.conf This is long and ugly and better done externally (script) --- irssi.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/irssi.conf b/irssi.conf index 61d2e81f..b0ceb8ff 100644 --- a/irssi.conf +++ b/irssi.conf @@ -115,7 +115,6 @@ aliases = { C = "CLEAR"; CALC = "EXEC - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi"; CHAT = "DCC CHAT"; - CUBES = "SCRIPT EXEC Irssi::active_win->print(\"%_bases\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x0\\${_}0\\$_\" } '0'..'9','A'..'F' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_cubes\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { my \\$y = \\$_*6 \\; join '', map { my \\$x = \\$_ \\; map { \"%x\\$x\\$_\\$x\\$_\" } @{['0'..'9','A'..'Z']}[\\$y .. \\$y+5] } 1..6 }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) for 0..5 \\; Irssi::active_win->print(\"%_grays\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x7\\${_}7\\$_\" } 'A'..'X' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_mIRC extended colours\", MSGLEVEL_CLIENTCRAP) \\; my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 0..15 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; for my \\$z (0..6) { my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 16+(\\$z*12)..16+(\\$z*12)+11 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) }"; DATE = "TIME"; DEHIGHLIGHT = "DEHILIGHT"; DESCRIBE = "ACTION"; From 05fd64dd1611610e2efe596718c657343db839e1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Oct 2018 09:21:46 +0200 Subject: [PATCH 0441/1198] improve rawlog perf --- src/core/rawlog.c | 18 +++++++----------- src/core/rawlog.h | 3 +-- src/perl/perl-common.c | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index e6bb7017..8f2d7142 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -48,8 +48,8 @@ void rawlog_destroy(RAWLOG_REC *rawlog) { g_return_if_fail(rawlog != NULL); - g_slist_foreach(rawlog->lines, (GFunc) g_free, NULL); - g_slist_free(rawlog->lines); + g_queue_foreach(rawlog->lines, (GFunc) g_free, NULL); + g_queue_free(rawlog->lines); if (rawlog->logging) { write_buffer_flush(); @@ -61,12 +61,8 @@ void rawlog_destroy(RAWLOG_REC *rawlog) /* NOTE! str must be dynamically allocated and must not be freed after! */ static void rawlog_add(RAWLOG_REC *rawlog, char *str) { - if (rawlog->nlines < rawlog_lines || rawlog_lines <= 2) - rawlog->nlines++; - else { - void *tmp = rawlog->lines->data; - rawlog->lines = g_slist_remove(rawlog->lines, - rawlog->lines->data); + if (rawlog->lines->length >= rawlog_lines && rawlog_lines > 0) { + void *tmp = g_queue_pop_tail(rawlog->lines); g_free(tmp); } @@ -75,7 +71,7 @@ static void rawlog_add(RAWLOG_REC *rawlog, char *str) write_buffer(rawlog->handle, "\n", 1); } - rawlog->lines = g_slist_append(rawlog->lines, str); + g_queue_push_head(rawlog->lines, str); signal_emit_id(signal_rawlog, 2, rawlog, str); } @@ -105,10 +101,10 @@ void rawlog_redirect(RAWLOG_REC *rawlog, const char *str) static void rawlog_dump(RAWLOG_REC *rawlog, int f) { - GSList *tmp; + GList *tmp; ssize_t ret = 0; - for (tmp = rawlog->lines; ret != -1 && tmp != NULL; tmp = tmp->next) { + for (tmp = rawlog->lines->tail; ret != -1 && tmp != NULL; tmp = tmp->prev) { ret = write(f, tmp->data, strlen((char *) tmp->data)); if (ret != -1) ret = write(f, "\n", 1); diff --git a/src/core/rawlog.h b/src/core/rawlog.h index 9e460a83..01175e67 100644 --- a/src/core/rawlog.h +++ b/src/core/rawlog.h @@ -5,8 +5,7 @@ struct _RAWLOG_REC { int logging; int handle; - int nlines; - GSList *lines; + GQueue *lines; }; RAWLOG_REC *rawlog_create(void); diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index 1d08319f..802a771e 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -501,7 +501,7 @@ static void perl_log_item_fill_hash(HV *hv, LOG_ITEM_REC *item) static void perl_rawlog_fill_hash(HV *hv, RAWLOG_REC *rawlog) { (void) hv_store(hv, "logging", 7, newSViv(rawlog->logging), 0); - (void) hv_store(hv, "nlines", 6, newSViv(rawlog->nlines), 0); + (void) hv_store(hv, "nlines", 6, newSViv(rawlog->lines->length), 0); } static void perl_reconnect_fill_hash(HV *hv, RECONNECT_REC *reconnect) From 95692d4d86c4a39697d16e937a452a662e6ba448 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Oct 2018 09:21:54 +0200 Subject: [PATCH 0442/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 8d4da02f..c8fb54df 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 17 +#define IRSSI_ABI_VERSION 18 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From ff0daf5870909b250e377ffa438c4fe0ebc2f8ce Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Oct 2018 09:31:08 +0200 Subject: [PATCH 0443/1198] actually create the queue, too --- src/core/rawlog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index 8f2d7142..dafad057 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -41,7 +41,8 @@ RAWLOG_REC *rawlog_create(void) RAWLOG_REC *rec; rec = g_new0(RAWLOG_REC, 1); - return rec; + rec->lines = g_queue_new(); + return rec; } void rawlog_destroy(RAWLOG_REC *rawlog) From 1e2547eb92e8a681540925a0da3867a879afd696 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 4 Oct 2018 09:33:07 +0200 Subject: [PATCH 0444/1198] fixup perl side --- src/perl/common/Rawlog.xs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/perl/common/Rawlog.xs b/src/perl/common/Rawlog.xs index c405bc37..73845287 100644 --- a/src/perl/common/Rawlog.xs +++ b/src/perl/common/Rawlog.xs @@ -19,9 +19,9 @@ void rawlog_get_lines(rawlog) Irssi::Rawlog rawlog PREINIT: - GSList *tmp; + GList *tmp; PPCODE: - for (tmp = rawlog->lines; tmp != NULL; tmp = tmp->next) { + for (tmp = rawlog->lines->tail; tmp != NULL; tmp = tmp->prev) { XPUSHs(sv_2mortal(new_pv(tmp->data))); } From 2200bd3656f0790554bf3c949cce5224ec588a44 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Oct 2018 13:46:39 +0200 Subject: [PATCH 0445/1198] Make /1/2/3/... a setting --- irssi.conf | 99 --------------------------- src/fe-common/core/fe-core-commands.c | 3 +- src/fe-common/core/window-commands.c | 15 ++++ 3 files changed, 17 insertions(+), 100 deletions(-) diff --git a/irssi.conf b/irssi.conf index 61d2e81f..eb182046 100644 --- a/irssi.conf +++ b/irssi.conf @@ -160,105 +160,6 @@ aliases = { WN = "WINDOW NEW HIDDEN"; WQUERY = "QUERY -window"; WW = "WHOWAS"; - 1 = "WINDOW GOTO 1"; - 2 = "WINDOW GOTO 2"; - 3 = "WINDOW GOTO 3"; - 4 = "WINDOW GOTO 4"; - 5 = "WINDOW GOTO 5"; - 6 = "WINDOW GOTO 6"; - 7 = "WINDOW GOTO 7"; - 8 = "WINDOW GOTO 8"; - 9 = "WINDOW GOTO 9"; - 10 = "WINDOW GOTO 10"; - 11 = "WINDOW GOTO 11"; - 12 = "WINDOW GOTO 12"; - 13 = "WINDOW GOTO 13"; - 14 = "WINDOW GOTO 14"; - 15 = "WINDOW GOTO 15"; - 16 = "WINDOW GOTO 16"; - 17 = "WINDOW GOTO 17"; - 18 = "WINDOW GOTO 18"; - 19 = "WINDOW GOTO 19"; - 20 = "WINDOW GOTO 20"; - 21 = "WINDOW GOTO 21"; - 22 = "WINDOW GOTO 22"; - 23 = "WINDOW GOTO 23"; - 24 = "WINDOW GOTO 24"; - 25 = "WINDOW GOTO 25"; - 26 = "WINDOW GOTO 26"; - 27 = "WINDOW GOTO 27"; - 28 = "WINDOW GOTO 28"; - 29 = "WINDOW GOTO 29"; - 30 = "WINDOW GOTO 30"; - 31 = "WINDOW GOTO 31"; - 32 = "WINDOW GOTO 32"; - 33 = "WINDOW GOTO 33"; - 34 = "WINDOW GOTO 34"; - 35 = "WINDOW GOTO 35"; - 36 = "WINDOW GOTO 36"; - 37 = "WINDOW GOTO 37"; - 38 = "WINDOW GOTO 38"; - 39 = "WINDOW GOTO 39"; - 40 = "WINDOW GOTO 40"; - 41 = "WINDOW GOTO 41"; - 42 = "WINDOW GOTO 42"; - 43 = "WINDOW GOTO 43"; - 44 = "WINDOW GOTO 44"; - 45 = "WINDOW GOTO 45"; - 46 = "WINDOW GOTO 46"; - 47 = "WINDOW GOTO 47"; - 48 = "WINDOW GOTO 48"; - 49 = "WINDOW GOTO 49"; - 50 = "WINDOW GOTO 50"; - 51 = "WINDOW GOTO 51"; - 52 = "WINDOW GOTO 52"; - 53 = "WINDOW GOTO 53"; - 54 = "WINDOW GOTO 54"; - 55 = "WINDOW GOTO 55"; - 56 = "WINDOW GOTO 56"; - 57 = "WINDOW GOTO 57"; - 58 = "WINDOW GOTO 58"; - 59 = "WINDOW GOTO 59"; - 60 = "WINDOW GOTO 60"; - 61 = "WINDOW GOTO 61"; - 62 = "WINDOW GOTO 62"; - 63 = "WINDOW GOTO 63"; - 64 = "WINDOW GOTO 64"; - 65 = "WINDOW GOTO 65"; - 66 = "WINDOW GOTO 66"; - 67 = "WINDOW GOTO 67"; - 68 = "WINDOW GOTO 68"; - 69 = "WINDOW GOTO 69"; - 70 = "WINDOW GOTO 70"; - 71 = "WINDOW GOTO 71"; - 72 = "WINDOW GOTO 72"; - 73 = "WINDOW GOTO 73"; - 74 = "WINDOW GOTO 74"; - 75 = "WINDOW GOTO 75"; - 76 = "WINDOW GOTO 76"; - 77 = "WINDOW GOTO 77"; - 78 = "WINDOW GOTO 78"; - 79 = "WINDOW GOTO 79"; - 80 = "WINDOW GOTO 80"; - 81 = "WINDOW GOTO 81"; - 82 = "WINDOW GOTO 82"; - 83 = "WINDOW GOTO 83"; - 84 = "WINDOW GOTO 84"; - 85 = "WINDOW GOTO 85"; - 86 = "WINDOW GOTO 86"; - 87 = "WINDOW GOTO 87"; - 88 = "WINDOW GOTO 88"; - 89 = "WINDOW GOTO 89"; - 90 = "WINDOW GOTO 90"; - 91 = "WINDOW GOTO 91"; - 92 = "WINDOW GOTO 92"; - 93 = "WINDOW GOTO 93"; - 94 = "WINDOW GOTO 94"; - 95 = "WINDOW GOTO 95"; - 96 = "WINDOW GOTO 96"; - 97 = "WINDOW GOTO 97"; - 98 = "WINDOW GOTO 98"; - 99 = "WINDOW GOTO 99"; }; statusbar = { diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 222543d5..b223db05 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -249,6 +249,7 @@ static void event_default_command(const char *data, void *server, long diff; cmdchars = settings_get_str("cmdchars"); + signal_stop(); ptr = data; while (*ptr != '\0' && *ptr != ' ') { @@ -338,7 +339,7 @@ void fe_core_commands_init(void) signal_add("send command", (SIGNAL_FUNC) event_command); signal_add_last("send command", (SIGNAL_FUNC) event_command_last); - signal_add("default command", (SIGNAL_FUNC) event_default_command); + signal_add_last("default command", (SIGNAL_FUNC) event_default_command); signal_add("error command", (SIGNAL_FUNC) event_cmderror); signal_add("list subcommands", (SIGNAL_FUNC) event_list_subcommands); diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index a81c0180..5e53957d 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -867,9 +867,22 @@ static void cmd_foreach_window(const char *data) g_free(str); } +static void cmd_window_default_command(const char *data, SERVER_REC *server, WI_ITEM_REC *item) +{ + if (!is_numeric(data, 0) || + !settings_get_bool("window_number_commands")) { + return; + } + signal_emit("command window refnum", 3, data, server, item); + signal_stop(); +} + void window_commands_init(void) { settings_add_bool("lookandfeel", "active_window_ignore_refnum", TRUE); + settings_add_bool("misc", "window_number_commands", TRUE); + + signal_add("default command", (SIGNAL_FUNC) cmd_window_default_command); command_bind("window", NULL, (SIGNAL_FUNC) cmd_window); command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new); @@ -944,4 +957,6 @@ void window_commands_deinit(void) command_unbind("layout save", (SIGNAL_FUNC) windows_layout_save); command_unbind("layout reset", (SIGNAL_FUNC) windows_layout_reset); command_unbind("foreach window", (SIGNAL_FUNC) cmd_foreach_window); + + signal_remove("default command", (SIGNAL_FUNC) cmd_window_default_command); } From d2dbcc19993a8cf33258d0989b05305be34336a4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Oct 2018 15:37:27 +0200 Subject: [PATCH 0446/1198] Route notices intended for channels into the channel --- src/fe-common/irc/fe-irc-messages.c | 36 ++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 89c501a8..56e479ab 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -202,6 +202,23 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, static void sig_message_own_notice(IRC_SERVER_REC *server, const char *msg, const char *target) { + if (*msg == '[') { + /* check if this is a cnotice */ + char *end, *channel; + end = strpbrk(msg, " ,]"); + if (end != NULL && *end == ']') { + channel = g_strndup(msg + 1, end - msg - 1); + if (server_ischannel(SERVER(server), channel)) { + printformat(server, channel, + MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, + IRCTXT_OWN_NOTICE, target, msg); + g_free(channel); + return; + } + g_free(channel); + /* fall through. */ + } + } printformat(server, fe_channel_skip_prefix(server, target), MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, IRCTXT_OWN_NOTICE, target, msg); @@ -233,11 +250,28 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg, msg, &level, TRUE)) return; - if (server_ischannel(SERVER(server), target)) { + if (server_ischannel(SERVER(server), target)) { /* notice in some channel */ printformat(server, target, level, IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg); } else { + if (*msg == '[') { + /* check if this is a cnotice */ + char *end, *channel; + end = strpbrk(msg, " ,]"); + if (end != NULL && *end == ']') { + channel = g_strndup(msg + 1, end - msg - 1); + if (server_ischannel(SERVER(server), channel)) { + printformat(server, channel, level, IRCTXT_NOTICE_PRIVATE, + nick, address, msg); + g_free(channel); + return; + } + g_free(channel); + /* fall through. */ + } + } + /* private notice */ privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES); From 08ac2ee5beebdfd374caccf76a7e63da67b40798 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 5 Oct 2018 16:13:47 +0200 Subject: [PATCH 0447/1198] refactor cnotice test into function --- src/fe-common/irc/fe-irc-messages.c | 58 +++++++++++++---------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 56e479ab..21b98e6c 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -199,29 +199,31 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, g_free_not_null(freemsg); } -static void sig_message_own_notice(IRC_SERVER_REC *server, const char *msg, - const char *target) +static char *notice_channel_context(SERVER_REC *server, const char *msg) { if (*msg == '[') { - /* check if this is a cnotice */ char *end, *channel; end = strpbrk(msg, " ,]"); if (end != NULL && *end == ']') { channel = g_strndup(msg + 1, end - msg - 1); if (server_ischannel(SERVER(server), channel)) { - printformat(server, channel, - MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, - IRCTXT_OWN_NOTICE, target, msg); - g_free(channel); - return; + return channel; } g_free(channel); - /* fall through. */ } } - printformat(server, fe_channel_skip_prefix(server, target), MSGLEVEL_NOTICES | - MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, - IRCTXT_OWN_NOTICE, target, msg); + return NULL; +} + +static void sig_message_own_notice(IRC_SERVER_REC *server, const char *msg, const char *target) +{ + char *channel; + /* check if this is a cnotice */ + channel = notice_channel_context((SERVER_REC *) server, msg); + printformat(server, channel != NULL ? channel : fe_channel_skip_prefix(server, target), + MSGLEVEL_NOTICES | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT, IRCTXT_OWN_NOTICE, + target, msg); + g_free(channel); } static void sig_message_irc_notice(SERVER_REC *server, const char *msg, @@ -255,28 +257,18 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg, printformat(server, target, level, IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg); } else { - if (*msg == '[') { - /* check if this is a cnotice */ - char *end, *channel; - end = strpbrk(msg, " ,]"); - if (end != NULL && *end == ']') { - channel = g_strndup(msg + 1, end - msg - 1); - if (server_ischannel(SERVER(server), channel)) { - printformat(server, channel, level, IRCTXT_NOTICE_PRIVATE, - nick, address, msg); - g_free(channel); - return; - } - g_free(channel); - /* fall through. */ - } - } + char *channel; + /* check if this is a cnotice */ + channel = notice_channel_context(server, msg); - /* private notice */ - privmsg_get_query(SERVER(server), nick, FALSE, - MSGLEVEL_NOTICES); - printformat(server, nick, level, - IRCTXT_NOTICE_PRIVATE, nick, address, msg); + if (channel == NULL) { + /* private notice */ + privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES); + } + printformat(server, channel == NULL ? nick : channel, level, IRCTXT_NOTICE_PRIVATE, + nick, address, msg); + + g_free(channel); } } From 8b1afbd3557e605f35cf4dab16d49cb4c89ca496 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 6 Oct 2018 19:26:36 +0200 Subject: [PATCH 0448/1198] revert core changes --- src/core/core.c | 10 ------ src/core/core.h | 3 -- src/irc/core/channel-events.c | 53 +++++++--------------------- tests/irc/core/test-channel-events.c | 6 ++-- 4 files changed, 17 insertions(+), 55 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index d87e86e2..506d6a13 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -73,22 +73,12 @@ const char *get_irssi_dir(void) return irssi_dir; } -void set_irssi_dir(char *const s) -{ - irssi_dir = s; -} - /* return full path for ~/.irssi/config */ const char *get_irssi_config(void) { return irssi_config_file; } -void set_irssi_config(char *const s) -{ - irssi_config_file = s; -} - static void sig_reload_config(int signo) { reload_config = TRUE; diff --git a/src/core/core.h b/src/core/core.h index 395e5c83..982dbaad 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -16,9 +16,6 @@ extern int irssi_init_finished; /* TRUE after "irssi init finished" signal is se extern int reload_config; /* TRUE after received SIGHUP. */ extern time_t client_start_time; -void set_irssi_dir(char *const); -void set_irssi_config(char *const); - void core_preinit(const char *path); void core_register_options(void); diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 85d985ea..6ffe7364 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -29,9 +29,6 @@ #include "irc-servers.h" #include "irc-channels.h" -static void set_topic_info(CHANNEL_REC *const, char const *const, - time_t const); - static void check_join_failure(IRC_SERVER_REC *server, const char *channel) { CHANNEL_REC *chanrec; @@ -130,51 +127,27 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, chanrec = channel_find(SERVER(server), channel); if (chanrec == NULL) return; - - g_free_and_null(chanrec->topic); - g_free_and_null(chanrec->topic_by); - chanrec->topic_time = 0; - - /* the topic may be sent out encoded, so we need to + /* the topic may be send out encoded, so we need to recode it back or /topic will not work properly */ recoded = recode_in(SERVER(server), topic, channel); - if (recoded == NULL || *recoded == '\0') { - signal_emit("channel topic changed", 1, chanrec); - g_free(recoded); - return; + if (topic != NULL) { + g_free_not_null(chanrec->topic); + chanrec->topic = recoded == NULL ? NULL : g_strdup(recoded); } + g_free(recoded); - chanrec->topic = recoded; - set_topic_info(chanrec, setby, settime); - - signal_emit("channel topic changed", 1, chanrec); -} - -static void channel_change_topic_info(IRC_SERVER_REC *server, - const char *channel, const char *setby, time_t settime) -{ - CHANNEL_REC *chanrec; - - chanrec = channel_find(SERVER(server), channel); - if (chanrec == NULL) return; - - g_free_and_null(chanrec->topic_by); - chanrec->topic_time = 0; - - set_topic_info(chanrec, setby, settime); - - signal_emit("channel topic changed", 1, chanrec); -} - -static void set_topic_info(CHANNEL_REC *const chanrec, char const *const setby, - time_t const settime) -{ + g_free_not_null(chanrec->topic_by); chanrec->topic_by = g_strdup(setby); - if (chanrec->topic_by != NULL) { + + if (chanrec->topic_by == NULL) { /* ensure invariant topic_time > 0 <=> topic_by != NULL. this could be triggered by a topic command without sender */ + chanrec->topic_time = 0; + } else { chanrec->topic_time = settime; } + + signal_emit("channel topic changed", 1, chanrec); } static void event_topic_get(IRC_SERVER_REC *server, const char *data) @@ -214,7 +187,7 @@ static void event_topic_info(IRC_SERVER_REC *server, const char *data) &topicby, &topictime); t = (time_t) atol(topictime); - channel_change_topic_info(server, channel, topicby, t); + channel_change_topic(server, channel, NULL, topicby, t); g_free(params); } diff --git a/tests/irc/core/test-channel-events.c b/tests/irc/core/test-channel-events.c index 98c70ce8..9f52c98d 100644 --- a/tests/irc/core/test-channel-events.c +++ b/tests/irc/core/test-channel-events.c @@ -31,6 +31,7 @@ #include #include #include +#include #define MODULE_NAME "test-channel-events" @@ -87,10 +88,11 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); + core_preinit(*argv); + irssi_gui = IRSSI_GUI_NONE; + modules_init(); signals_init(); - set_irssi_dir("/tmp/irssi"); - set_irssi_config("/tmp/irssi/config"); settings_init(); recode_init(); channel_events_init(); From 80f9f16939b65536c5fc3ae1fedb885b84c82855 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 6 Oct 2018 20:14:49 +0200 Subject: [PATCH 0449/1198] Show the proper TXT when topic was unset --- src/fe-common/irc/fe-irc-commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index 7a6b17a6..668367e4 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -305,7 +305,7 @@ static void cmd_topic(const char *data, SERVER_REC *server, WI_ITEM_REC *item) if (channel == NULL) return; printformat(server, channel->visible_name, MSGLEVEL_CRAP, - channel->topic == NULL ? IRCTXT_NO_TOPIC : IRCTXT_TOPIC, + (channel->topic == NULL || *channel->topic == '\0') ? IRCTXT_NO_TOPIC : IRCTXT_TOPIC, channel->visible_name, channel->topic); if (channel->topic_time > 0) { From cdcb50f413537177ff50478b766b570fb7bae057 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 8 Oct 2018 17:41:46 +0200 Subject: [PATCH 0450/1198] add a setting --- src/fe-common/irc/fe-irc-messages.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 21b98e6c..27aee5e2 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -201,12 +201,15 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg, static char *notice_channel_context(SERVER_REC *server, const char *msg) { + if (!settings_get_bool("notice_channel_context")) + return NULL; + if (*msg == '[') { char *end, *channel; end = strpbrk(msg, " ,]"); if (end != NULL && *end == ']') { channel = g_strndup(msg + 1, end - msg - 1); - if (server_ischannel(SERVER(server), channel)) { + if (server_ischannel(server, channel)) { return channel; } g_free(channel); @@ -294,6 +297,8 @@ static void sig_message_irc_ctcp(IRC_SERVER_REC *server, const char *cmd, void fe_irc_messages_init(void) { + settings_add_bool("misc", "notice_channel_context", TRUE); + signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); signal_add_last("message irc op_public", (SIGNAL_FUNC) sig_message_irc_op_public); signal_add_last("message irc own_wall", (SIGNAL_FUNC) sig_message_own_wall); From 08b4d6c031fbc816f35e2cd1d57adfbb6ba4e3db Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 8 Oct 2018 20:23:22 -0700 Subject: [PATCH 0451/1198] Fix some space indentation --- src/fe-common/core/hilight-text.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index b9912457..3d853a90 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -45,7 +45,7 @@ static void reset_level_cache(void) { GSList *tmp; - never_hilight_level = MSGLEVEL_ALL & ~default_hilight_level; + never_hilight_level = MSGLEVEL_ALL & ~default_hilight_level; for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; @@ -180,7 +180,7 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels) /* check that channels match */ for (chan = channels; *chan != NULL; chan++) { if (strarray_find(rec->channels, *chan) == -1) - break; + break; } if (*chan == NULL) @@ -239,10 +239,10 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, const char *nick, const char *address, int level, const char *str, - int *match_beg, int *match_end) + int *match_beg, int *match_end) { GSList *tmp; - CHANNEL_REC *chanrec; + CHANNEL_REC *chanrec; NICK_REC *nickrec; g_return_val_if_fail(str != NULL, NULL); @@ -251,12 +251,12 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, return NULL; if (nick != NULL) { - /* check nick mask hilights */ + /* check nick mask hilights */ chanrec = channel_find(server, channel); nickrec = chanrec == NULL ? NULL : nicklist_find(chanrec, nick); if (nickrec != NULL) { - HILIGHT_REC *rec; + HILIGHT_REC *rec; if (nickrec->host == NULL) nicklist_set_host(chanrec, nickrec, address); @@ -388,10 +388,10 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, /* end of the line */ pos = strip_real_length(text, hilight_end, &color_pos, &color_len); - if (color_pos > 0) + if (color_pos > 0) { g_string_append_len(tmp, text + color_pos, color_len); - else { - /* no colors in line, change back to default */ + } else { + /* no colors in line, change back to default */ g_string_append_c(tmp, 4); g_string_append_c(tmp, FORMAT_STYLE_DEFAULTS); } @@ -413,7 +413,7 @@ HILIGHT_REC *hilight_match_nick(SERVER_REC *server, const char *channel, const char *nick, const char *address, int level, const char *msg) { - HILIGHT_REC *rec; + HILIGHT_REC *rec; rec = hilight_match(server, channel, nick, address, level, msg, NULL, NULL); @@ -431,7 +431,7 @@ static void read_hilight_config(void) node = iconfig_node_traverse("hilights", FALSE); if (node == NULL) { - reset_cache(); + reset_cache(); return; } @@ -545,8 +545,8 @@ static void cmd_hilight_show(void) } /* SYNTAX: HILIGHT [-nick | -word | -line] [-mask | -full | -matchcase | -regexp] - [-color ] [-actcolor ] [-level ] - [-network ] [-channels ] */ + [-color ] [-actcolor ] [-level ] + [-network ] [-channels ] */ static void cmd_hilight(const char *data) { GHashTable *optlist; From 81f3d6dbc1133bc72ec1f3211e7eef7027bae157 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 8 Oct 2018 20:23:36 -0700 Subject: [PATCH 0452/1198] Comment colour code meaning --- src/fe-common/core/formats.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index f7466337..c8d56fd0 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1121,7 +1121,7 @@ int strip_real_length(const char *str, int len, *last_color_len = -1; while (*str != '\0') { - if (*str == 3) { + if (*str == 3) { /* mIRC color */ const char *mircstart = str; if (last_color_pos != NULL) @@ -1132,6 +1132,9 @@ int strip_real_length(const char *str, int len, *last_color_len = (int) (str-mircstart); } else if (*str == 4 && str[1] != '\0') { + /* We expect 4 to indicate an internal Irssi color code. However 4 + * also means hex color, an alternative to mIRC color codes. We + * don't support those. */ #ifdef TERM_TRUECOLOR if (str[1] == FORMAT_COLOR_24 && str[2] != '\0') { if (str[3] == '\0') str++; From da15279fa3ce8a965f6d77e4483811ce94a8f9ea Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 17 Oct 2018 00:58:39 +0200 Subject: [PATCH 0453/1198] fix flood test libs --- tests/irc/flood/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am index 85b52eab..58c0d98d 100644 --- a/tests/irc/flood/Makefile.am +++ b/tests/irc/flood/Makefile.am @@ -33,8 +33,7 @@ test_796_LDADD = \ ../../../src/fe-common/core/libfe_common_core.a \ ../../../src/core/libcore.a \ ../../../src/lib-config/libirssi_config.a \ - @GLIB_LIBS@ \ - @OPENSSL_LIBS@ + @PROG_LIBS@ test_796_SOURCES = \ test-796.c From cbc27062e7f7d501623ee52614bc8012f1d5a97a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 17 Oct 2018 00:58:49 +0200 Subject: [PATCH 0454/1198] fix duplicate include guard --- src/fe-common/core/fe-settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-settings.h b/src/fe-common/core/fe-settings.h index dd33f223..cc628790 100644 --- a/src/fe-common/core/fe-settings.h +++ b/src/fe-common/core/fe-settings.h @@ -1,5 +1,5 @@ -#ifndef __FE_CHANNELS_H -#define __FE_CHANNELS_H +#ifndef __FE_SETTINGS_H +#define __FE_SETTINGS_H void fe_settings_set_print(const char *key); From f11b629b2fa65ce355ce122c7c1482e8cba229db Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sun, 30 Sep 2018 05:54:22 +0000 Subject: [PATCH 0455/1198] Fix issues pointed out by e38774cc --- src/core/commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/commands.c b/src/core/commands.c index 8e21a88a..2eebf0a3 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -305,7 +305,7 @@ void command_runsub(const char *cmd, const char *data, if (*data == '\0') { /* no subcommand given - list the subcommands */ - signal_emit("list subcommands", 2, cmd); + signal_emit("list subcommands", 1, cmd); return; } @@ -891,7 +891,7 @@ static void parse_command(const char *command, int expand_aliases, if (rec != NULL && !cmd_protocol_match(rec, server)) { g_free(orig); - signal_emit("error command", 2, + signal_emit("error command", 1, GINT_TO_POINTER(server == NULL ? CMDERR_NOT_CONNECTED : CMDERR_ILLEGAL_PROTO)); From 2093530e7590f91608d43f4617d8faf76ebf56ee Mon Sep 17 00:00:00 2001 From: vague666 Date: Sat, 27 Oct 2018 16:08:36 +0200 Subject: [PATCH 0456/1198] Make it possible to only autolog saved channels --- src/fe-common/core/fe-log.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 0fed8642..7823d727 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -41,6 +41,8 @@ #include "printtext.h" #include "fe-common-core.h" +#include "channels-setup.h" + /* close autologs after 5 minutes of inactivity */ #define AUTOLOG_INACTIVITY_CLOSE (60*5) @@ -486,6 +488,10 @@ static void autolog_open_check(TEXT_DEST_REC *dest) deftarget = server ? server->nick : "unknown"; + /* log only channels that have been saved to the config */ + if (settings_get_bool("autolog_only_saved_channels") && channel_setup_find(target, server_tag) == NULL) + return; + if (autolog_ignore_targets != NULL && strarray_find_dest(autolog_ignore_targets, dest)) return; @@ -722,6 +728,7 @@ void fe_log_init(void) settings_add_bool("log", "awaylog_colors", TRUE); settings_add_bool("log", "autolog", FALSE); settings_add_bool("log", "autolog_colors", FALSE); + settings_add_bool("log", "autolog_only_saved_channels", FALSE); settings_add_str("log", "autolog_path", "~/irclogs/$tag/$0.log"); settings_add_level("log", "autolog_level", "all -crap -clientcrap -ctcps"); settings_add_str("log", "log_theme", ""); From 3061f5d848f6f487e8c73a5d5846b7a860ca5466 Mon Sep 17 00:00:00 2001 From: vague666 Date: Sat, 27 Oct 2018 20:00:15 +0200 Subject: [PATCH 0457/1198] make sure only channels are checked --- src/fe-common/core/fe-log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 7823d727..d71c62a9 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -24,6 +24,7 @@ #include "commands.h" #include "chat-protocols.h" #include "servers.h" +#include "channels.h" #include "levels.h" #include "misc.h" #include "log.h" @@ -489,7 +490,8 @@ static void autolog_open_check(TEXT_DEST_REC *dest) deftarget = server ? server->nick : "unknown"; /* log only channels that have been saved to the config */ - if (settings_get_bool("autolog_only_saved_channels") && channel_setup_find(target, server_tag) == NULL) + if (settings_get_bool("autolog_only_saved_channels") && IS_CHANNEL(window_item_find(server, target)) + && channel_setup_find(target, server_tag) == NULL) return; if (autolog_ignore_targets != NULL && From f7966d9c081641ff5b1adca2bd8c217a331bcaa6 Mon Sep 17 00:00:00 2001 From: vague666 Date: Sat, 27 Oct 2018 20:51:29 +0200 Subject: [PATCH 0458/1198] allow activity_hide_targets to hide activity in itemless windows --- src/fe-common/core/fe-common-core.c | 4 +++- src/fe-common/core/window-activity.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index ef5d2113..0e654e4d 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -480,7 +480,9 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) g_return_val_if_fail(array != NULL, FALSE); g_return_val_if_fail(dest != NULL, FALSE); g_return_val_if_fail(dest->window != NULL, FALSE); - g_return_val_if_fail(dest->target != NULL, FALSE); + + if (dest->target == NULL) { + return strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; item = window_item_find_window(dest->window, dest->server, dest->target); if (item == NULL) { diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 48e909a4..06c24a2f 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -86,7 +86,7 @@ static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg) DATA_LEVEL_MSG : DATA_LEVEL_TEXT; } - if (hide_targets != NULL && (dest->level & MSGLEVEL_HILIGHT) == 0 && dest->target != NULL) { + if (hide_targets != NULL && (dest->level & MSGLEVEL_HILIGHT) == 0) { /* check for both target and tag/target */ if (strarray_find_dest(hide_targets, dest)) return; From ec577f9265fff6b36b0e25c3e1a04ef8f0aee9d6 Mon Sep 17 00:00:00 2001 From: vague666 Date: Sat, 27 Oct 2018 20:52:14 +0200 Subject: [PATCH 0459/1198] typo --- src/fe-common/core/fe-common-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 0e654e4d..dc3a6f6d 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -481,7 +481,7 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) g_return_val_if_fail(dest != NULL, FALSE); g_return_val_if_fail(dest->window != NULL, FALSE); - if (dest->target == NULL) { + if (dest->target == NULL) return strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; item = window_item_find_window(dest->window, dest->server, dest->target); From 2847b751e359bde8eb5dc3d89f57575c3b5f0948 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 29 Oct 2018 17:51:48 +0100 Subject: [PATCH 0460/1198] design.txt is now sourced from website also run syncdocs, fixes missing placeholder in startup-HOWTO --- docs/Makefile.am | 1 + docs/design.html | 166 ++++++++++++++++++++++++++++++++++++++++ docs/startup-HOWTO.html | 2 +- docs/startup-HOWTO.txt | 3 +- utils/syncdocs.sh | 5 ++ 5 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 docs/design.html diff --git a/docs/Makefile.am b/docs/Makefile.am index 8998ffb4..23d61648 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -3,6 +3,7 @@ man_MANS = \ doc_DATA = \ capsicum.txt \ + design.html \ design.txt \ formats.txt \ manual.txt \ diff --git a/docs/design.html b/docs/design.html new file mode 100644 index 00000000..4be231ee --- /dev/null +++ b/docs/design.html @@ -0,0 +1,166 @@ + +

Design

+ +

Irssi’s hierarchy is something like this:

+ +

+        sub1 sub2
+           \ /
+      xxx  IRC       COMMON ICQ  yyy
+       |    |           |    |    |
+       '----+-----:-----+----+----'
+                  |
+                 GUI (gtk/gnome, qt/kde, text, none)
+                  |
+        sub1 sub2 |
+           \ /    |
+      xxx  IRC    |  COMMON ICQ  yyy
+       '----+-----+-----+----+----'
+                  |
+              COMMON UI
+                  |
+        sub1 sub2 |
+           \ /    |
+      xxx  IRC    |    ICQ  yyy
+       |    |     |     |    |
+       '----+-----+-----+----'
+                  |
+                CORE
+                /
+       lib-config
+
+
+ +

(IRC, ICQ, xxx and yyy are chat protocols ..)

+ +

(sub1 and sub2 are submodules of IRC module, like DCC and flood protect)

+ +

Chat protocols and frontends are kept in separate modules. Common UI +and GUI modules also have the common parts which don’t know anything +about the chat protocols. This should allow implementing modules to +whatever chat protocols and with whatever frontends easily.

+ +

Signals

+ +

Communication between different modules are done with “signals”. They are +not related to UNIX signals in any way, you could more like think of them +as “events” - which might be a better name for them, but I don’t really +want to change it anymore :)

+ +

So, you send signal with signal_emit() and it’s sent to all modules that +have grabbed it by calling signal_add() in their init function. For +example:

+ +
signal_emit("mysignal", 1, "hello");
+
+ +

Sends a “mysignal” function with one argument “hello” - before that, you +should have grabbed the signal somewhere else with:

+ +
static void sig_mysignal(const char *arg1)
+{
+  /* arg1 contains "hello" */
+}
+
+signal_add("mysignal", (SIGNAL_FUNC) sig_mysignal);
+
+ +

There are three different signal_add() functions which you can use to +specify if you want to grab the signal first, “normally” or last. You can +also stop the signal from going any further.

+ +

Emitting signal with it’s name creates a small overhead since it has to +look up the signal’s numeric ID first, after which it looks up the signal +structure. This is done because if you call a signal really often, +it’s faster to find it with it’s numeric ID instead of the string. You +can use signal_get_uniq_id() macro to convert the signal name into ID - +you’ll have to do this only once! - and use signal_emit_id() to emit the +signal. Don’t bother to do this unless your signal is sent (or could be +sent) several times in a second.

+ +

See src/core/signals.h for definition of the signal function, and +signals.txt for a list of signals.

+ +

lib-config

+ +

Irssi depends on this for reading and saving configuration. +(created by me for irssi)

+ +

CORE module

+ +

Provides some functionality that all other modules can use:

+
    +
  • signal handling
  • +
  • keeping list of settings
  • +
  • keeping list of /commands
  • +
  • keeping track of loaded modules
  • +
  • networking functions (with nonblocking connects, IPv6 support)
  • +
  • handles connecting to servers
  • +
  • raw logging of server’s input/output data
  • +
  • /EVAL support
  • +
  • fgets() like function line_split() without any maximum line limits
  • +
  • command line parameter handling
  • +
  • miscellaneous useful little functions
  • +
  • handles logging
  • +
+ +

COMMON UI module

+ +
    +
  • knows basics about windows and window items (=channels, queries, ..)
  • +
  • printtext() - parsing texts and feeding it for GUI to print.
  • +
  • themes
  • +
  • translation tables
  • +
  • text hilighting
  • +
  • command history
  • +
  • user interface (/commands) for CORE’s functionality
  • +
+ +

GUI modules

+ +
    +
  • all the rest of the functionality needed for a working client.
  • +
+ +

IRC module

+ +
    +
  • CORE +
      +
    • IRC specific /commands
    • +
    • flood protecting commands sent to server
    • +
    • creating IRC masks based on nick/address for bans, ignores, etc.
    • +
    • keeps list of channels, nicks, channel modes, bans, etc.
    • +
    • keeps list of servers, server settings, irc networks, +server reconnections and irc network splits
    • +
    • redirection of commands’ replies
    • +
    • lag detection
    • +
    • ctcp support and flood protection
    • +
    • Handles ignoring people
    • +
    +
  • +
  • DCC +
      +
    • DCC chat, send and get
    • +
    +
  • +
  • FLOOD +
      +
    • detects private or channel flooding and sends “flood” signal
    • +
    • automatic ignoring when flooding
    • +
    +
  • +
  • NOTIFYLIST +
      +
    • handles notifylist
    • +
    +
  • +
+ +

IRC UI module

+ +
    +
  • placing channels and queries in windows
  • +
  • nick completion
  • +
  • printing infomation of some events
  • +
\ No newline at end of file diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 8cd7a010..36d8edbf 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -378,7 +378,7 @@ Ctrl-X - set the next server in list active
/SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default)
 
-

By default irssi logs to ~/irclogs//.log. You can change this with

+

By default irssi logs to ~/irclogs/<servertag>/<target>.log. You can change this with

/SET autolog_path ~/irclogs/$tag/$0.log (this is the default)
 
diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 88912ef3..ecfe7ad8 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -416,7 +416,8 @@ requests, etc). You can specify the logging level yourself with /SET autolog_level ALL -CRAP -CLIENTCRAP -CTCPS (this is the default) -By default irssi logs to ~/irclogs//.log. You can change this with +By default irssi logs to ~/irclogs//.log. You can change +this with /SET autolog_path ~/irclogs/$tag/$0.log (this is the default) diff --git a/utils/syncdocs.sh b/utils/syncdocs.sh index ed76bf85..bd92ffab 100755 --- a/utils/syncdocs.sh +++ b/utils/syncdocs.sh @@ -7,6 +7,7 @@ site=https://irssi.org faq=$site/documentation/faq/ howto=$site/documentation/startup/ +design=$site/documentation/design/ # remove everything until H1 and optionally 2 DIVs before the # FOOTER. May need to be adjusted as the source pages change @@ -84,6 +85,7 @@ download_it() { download_it "FAQ" "$faq" "$srcdir"/docs/faq.html download_it "Startup How-To" "$howto" "$srcdir"/docs/startup-HOWTO.html +download_it "Design" "$design" "$srcdir"/docs/design.html # .html -> .txt with lynx or elinks echo "Documentation: html -> txt..." @@ -100,3 +102,6 @@ cat "$srcdir"/docs/faq.html \ cat "$srcdir"/docs/startup-HOWTO.html \ | perl -pe "s/\\bhref=([\"\'])#.*?\\1//" \ | LC_ALL=en_IE.utf8 $converter > "$srcdir"/docs/startup-HOWTO.txt + +cat "$srcdir"/docs/design.html \ + | LC_ALL=en_IE.utf8 $converter > "$srcdir"/docs/design.txt From 9d2429c027770a711aa6ea6be86545e7966ec1ba Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 9 Nov 2018 10:57:37 +0100 Subject: [PATCH 0461/1198] test line joining --- configure.ac | 1 + tests/Makefile.am | 6 ++- tests/fe-text/Makefile.am | 38 ++++++++++++++++ tests/fe-text/mock-irssi.c | 9 ++++ tests/fe-text/test-paste-join-multiline.c | 55 +++++++++++++++++++++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 tests/fe-text/Makefile.am create mode 100644 tests/fe-text/mock-irssi.c create mode 100644 tests/fe-text/test-paste-join-multiline.c diff --git a/configure.ac b/configure.ac index 03e05847..49436bf1 100644 --- a/configure.ac +++ b/configure.ac @@ -732,6 +732,7 @@ scripts/examples/Makefile tests/Makefile tests/fe-common/Makefile tests/fe-common/core/Makefile +tests/fe-text/Makefile tests/irc/Makefile tests/irc/core/Makefile tests/irc/flood/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index e16d190e..8713b38f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1 +1,5 @@ -SUBDIRS = fe-common irc +if BUILD_TEXTUI +TEXTUI=fe-text +endif + +SUBDIRS = fe-common irc $(TEXTUI) diff --git a/tests/fe-text/Makefile.am b/tests/fe-text/Makefile.am new file mode 100644 index 00000000..38979e14 --- /dev/null +++ b/tests/fe-text/Makefile.am @@ -0,0 +1,38 @@ +include $(top_srcdir)/utils/glib-tap.mk + +PACKAGE_STRING=fe-text + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/core \ + -I$(top_srcdir)/src/fe-common/core \ + -I$(top_srcdir)/src/fe-text \ + $(GLIB_CFLAGS) + +test_programs = test-paste-join-multiline + +test_paste_join_multiline_CPPFLAGS = \ + $(AM_CPPFLAGS) + +# test_paste_join_multiline_DEPENDENCIES = + +test_paste_join_multiline_LDADD = \ + ../../src/fe-common/core/libfe_common_core.a \ + ../../src/core/libcore.a \ + ../../src/lib-config/libirssi_config.a \ + @PROG_LIBS@ \ + @TEXTUI_LIBS@ + + +test_paste_join_multiline_SOURCES = \ + ../../src/fe-text/gui-entry.c \ + ../../src/fe-text/mainwindows.c \ + ../../src/fe-text/term-terminfo.c \ + ../../src/fe-text/terminfo-core.c \ + ../../src/fe-text/term.c \ + ../../src/fe-text/textbuffer-view.c \ + ../../src/fe-text/textbuffer.c \ + ../../src/fe-text/gui-windows.c \ + ../../src/fe-text/gui-printtext.c \ + mock-irssi.c \ + test-paste-join-multiline.c diff --git a/tests/fe-text/mock-irssi.c b/tests/fe-text/mock-irssi.c new file mode 100644 index 00000000..d03c371d --- /dev/null +++ b/tests/fe-text/mock-irssi.c @@ -0,0 +1,9 @@ +void irssi_set_dirty(void) +{ +} + +void irssi_redraw(void) +{ +} + +int quitting = 0; diff --git a/tests/fe-text/test-paste-join-multiline.c b/tests/fe-text/test-paste-join-multiline.c new file mode 100644 index 00000000..53fd3708 --- /dev/null +++ b/tests/fe-text/test-paste-join-multiline.c @@ -0,0 +1,55 @@ +#include "common.h" +#include "gui-readline.c" + +typedef struct { + char const *const description; + char const *const input; + char const *const result; +} paste_join_multiline_test_case; + +static void test_paste_join_multiline(const paste_join_multiline_test_case *test); + +paste_join_multiline_test_case const paste_join_multiline_fixture[] = { + { + .description = "Lines should be joined, separator NL", + .input = " hello world\n how are you\n screen is narrow", + .result = " hello world how are you screen is narrow", + }, +}; + +int main(int argc, char **argv) +{ + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS(paste_join_multiline_fixture); i++) { + char *name = g_strdup_printf("/test/paste_join_multiline/%d", i); + g_test_add_data_func(name, &paste_join_multiline_fixture[i], (GTestDataFunc)test_paste_join_multiline); + g_free(name); + } + +#if GLIB_CHECK_VERSION(2,38,0) + g_test_set_nonfatal_assertions(); +#endif + return g_test_run(); +} + +static void test_paste_join_multiline(const paste_join_multiline_test_case *test) +{ + char *resultstr; + GArray *buffer = g_array_new(FALSE, FALSE, sizeof(unichar)); + + g_test_message("Testing: %s", test->description); + + buffer->data = (char *) g_utf8_to_ucs4_fast(test->input, -1, (glong *) &buffer->len); + paste_buffer_join_lines(buffer); + resultstr = g_ucs4_to_utf8((unichar *) buffer->data, buffer->len, NULL, NULL, NULL); + + g_assert_cmpstr(resultstr, ==, test->result); + + g_free(resultstr); + g_array_free(buffer, TRUE); + + return; +} From 83e98da2ffa295723b10f63ec41211f70ea87153 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 9 Nov 2018 11:05:52 +0100 Subject: [PATCH 0462/1198] add test for paste_join_multiline --- tests/fe-text/test-paste-join-multiline.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/fe-text/test-paste-join-multiline.c b/tests/fe-text/test-paste-join-multiline.c index 53fd3708..778e19e9 100644 --- a/tests/fe-text/test-paste-join-multiline.c +++ b/tests/fe-text/test-paste-join-multiline.c @@ -12,8 +12,18 @@ static void test_paste_join_multiline(const paste_join_multiline_test_case *test paste_join_multiline_test_case const paste_join_multiline_fixture[] = { { .description = "Lines should be joined, separator NL", - .input = " hello world\n how are you\n screen is narrow", - .result = " hello world how are you screen is narrow", + .input = " A1\n B22\n C33", + .result = " A1 B22 C33", + }, + { + .description = "Lines should be joined, separator LF", + .input = " A1\r B22\r C33", + .result = " A1 B22 C33", + }, + { + .description = "Lines should be joined, white space should be skipped", + .input = " A1 \n B22 \n C33 ", + .result = " A1 B22 C33 ", }, }; @@ -37,10 +47,12 @@ int main(int argc, char **argv) static void test_paste_join_multiline(const paste_join_multiline_test_case *test) { - char *resultstr; + char *resultstr, *t1; GArray *buffer = g_array_new(FALSE, FALSE, sizeof(unichar)); g_test_message("Testing: %s", test->description); + g_test_message("INPUT: \"%s\"", (t1 = g_strescape(test->input, NULL))); + g_free(t1); buffer->data = (char *) g_utf8_to_ucs4_fast(test->input, -1, (glong *) &buffer->len); paste_buffer_join_lines(buffer); From c1fb9a840201131982f2c2e1ff8737436f495841 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 9 Nov 2018 11:06:13 +0100 Subject: [PATCH 0463/1198] fix paste_join_multiline --- src/fe-text/gui-readline.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 88e827a7..1033339e 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -160,6 +160,7 @@ static void window_next_page(void) gui_window_scroll(active_win, get_scroll_count()); } +#define isnewline(x) ((x) == '\n' || (x) == '\r') static void paste_buffer_join_lines(GArray *buf) { unsigned int i, count, indent, line_len; @@ -199,7 +200,7 @@ static void paste_buffer_join_lines(GArray *buf) /* find the first beginning of indented line */ for (i = 1; i < buf->len; i++) { - if (arr[i-1] == '\n' && isblank(arr[i])) + if (isnewline(arr[i-1]) && isblank(arr[i])) break; } if (i == buf->len) @@ -226,7 +227,7 @@ static void paste_buffer_join_lines(GArray *buf) count = 0; } } - if (arr[i] == '\n') + if (isnewline(arr[i])) last_lf = TRUE; } @@ -236,11 +237,12 @@ static void paste_buffer_join_lines(GArray *buf) for (i = 0; i < buf->len; i++) { if (last_lf && isblank(arr[i])) { /* whitespace, ignore */ - } else if (arr[i] == '\n') { + } else if (isnewline(arr[i])) { if (!last_lf && i+1 != buf->len && isblank(arr[i+1])) { last_lf_pos = dest; - *dest++ = ' '; + if (i != 0 && !isblank(arr[i-1])) + *dest++ = ' '; } else { *dest++ = '\n'; /* double-LF */ line_len = 0; @@ -287,7 +289,7 @@ static void paste_send(void) /* first line has to be kludged kind of to get pasting in the middle of line right.. */ for (i = 0; i < paste_buffer->len; i++) { - if (arr[i] == '\r' || arr[i] == '\n') { + if (isnewline(arr[i])) { i++; break; } @@ -303,7 +305,7 @@ static void paste_send(void) /* rest of the lines */ str = g_string_new(NULL); for (; i < paste_buffer->len; i++) { - if (arr[i] == '\r' || arr[i] == '\n') { + if (isnewline(arr[i])) { paste_send_line(str->str); g_string_truncate(str, 0); } else if (active_entry->utf8) { @@ -769,7 +771,7 @@ static void paste_bracketed_end(int i, gboolean rest) last_char = g_array_index(paste_buffer, unichar, i - 1); - if (paste_line_count > 0 && last_char != '\n' && last_char != '\r') { + if (paste_line_count > 0 && !isnewline(last_char)) { /* there are newlines, but there's also stuff after the newline * adjust line count to reflect this */ paste_line_count++; From 60d2364989b50ed8b76076022dde39690dc95416 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 9 Nov 2018 11:11:10 +0100 Subject: [PATCH 0464/1198] run syncscripts.sh sync buf.pl to version 3.00 sync usercount.pl to version 1.20 --- scripts/buf.pl | 119 +++++++++++++++++++++---------------------- scripts/usercount.pl | 4 +- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/scripts/buf.pl b/scripts/buf.pl index 6d907f12..0b37e9de 100644 --- a/scripts/buf.pl +++ b/scripts/buf.pl @@ -1,22 +1,24 @@ use strict; use vars qw($VERSION %IRSSI); +use Storable; +use 5.014000; use Irssi qw(command signal_add signal_add_first active_win settings_get_str settings_get_bool channels windows - settings_add_str settings_add_bool get_irssi_dir - window_find_refnum signal_stop); -$VERSION = '2.20'; + settings_add_str settings_add_bool get_irssi_dir + window_find_refnum signal_stop); +$VERSION = '3.00'; %IRSSI = ( - authors => 'Juerd', - contact => 'juerd@juerd.nl', - name => 'Scroll buffer restorer', - description => 'Saves the buffer for /upgrade, so that no information is lost', - license => 'Public Domain', - url => 'http://juerd.nl/irssi/', - changed => 'Thu Sep 22 01:37 CEST 2016', - changes => 'Fixed file permissions (leaked everything via filesystem)', - note1 => 'This script HAS TO BE in your scripts/autorun!', - note2 => 'Perl support must be static or in startup', + authors => 'Juerd', + contact => 'juerd@juerd.nl', + name => 'Scroll buffer restorer', + description => 'Saves the buffer for /upgrade, so that no information is lost', + license => 'Public Domain', + url => 'http://juerd.nl/irssi/', + changed => 'Thu Mar 29 10:00 CEST 2018', + changes => 'Fixed file permissions (leaked everything via filesystem), rewritten to use Storable and print to correct levels', + note1 => 'This script HAS TO BE in your scripts/autorun!', + note2 => 'Perl support must be static or in startup', ); # Q: How can I get a very smooth and clean upgrade? @@ -40,30 +42,28 @@ my %suppress; sub _filename { sprintf '%s/scrollbuffer', get_irssi_dir } sub upgrade { - my $fn = _filename; - my $old_umask = umask 0077; - open my $fh, q{>}, $fn or die "open $fn: $!"; - umask $old_umask; - - print $fh join("\0", map $_->{server}->{address} . $_->{name}, channels), "\n"; + my $out = { suppress => [ map $_->{server}->{address} . $_->{name}, channels ] }; for my $window (windows) { - next unless defined $window; - next if $window->{name} eq 'status'; - my $view = $window->view; - my $line = $view->get_lines; - my $lines = 0; - my $buf = ''; - if (defined $line){ - { - $buf .= $line->get_text(1) . "\n"; - $line = $line->next; - $lines++; - redo if defined $line; - } - } - printf $fh "%s:%s\n%s", $window->{refnum}, $lines, $buf; + next unless defined $window; + next if $window->{name} eq 'status'; + my $view = $window->view; + my $line = $view->get_lines; + my $lines = 0; + my $buf = ''; + my $output; + if (defined $line) { + { + push @$output, { level => $line->{info}{level}, data => $line->get_text(1) }; + $line = $line->next; + redo if defined $line; + } + } + push @{$out->{windows}}, { refnum => $window->{refnum}, lines => $output }; } - close $fh; + my $old_umask = umask 0077; + my $fn = _filename; + store($out, $fn) or die "Could not store data to $fn"; + umask $old_umask; unlink sprintf("%s/sessionconfig", get_irssi_dir); command 'layout save'; command 'save'; @@ -71,33 +71,30 @@ sub upgrade { sub restore { my $fn = _filename; - open my $fh, q{<}, $fn or die "open $fn: $!"; + my $in = retrieve($fn) or die "Could not retrieve data from $fn"; unlink $fn or warn "unlink $fn: $!"; - - my @suppress = split /\0/, readline $fh; - if (settings_get_bool 'upgrade_suppress_join') { - chomp $suppress[-1]; - @suppress{@suppress} = (2) x @suppress; - } + + my @suppress = @{$in->{suppress}}; + @suppress{@suppress} = (2) x @suppress if (settings_get_bool 'upgrade_suppress_join'); + active_win->command('^window scroll off'); - while (my $bla = readline $fh){ - chomp $bla; - my ($refnum, $lines) = split /:/, $bla; - next unless $lines; - my $window = window_find_refnum $refnum; - unless (defined $window){ - readline $fh for 1..$lines; - next; - } - my $view = $window->view; - $view->remove_all_lines(); - $view->redraw(); - my $buf = ''; - $buf .= readline $fh for 1..$lines; - my $sep = settings_get_str 'upgrade_separator'; - $sep .= "\n" if $sep ne ''; - $window->gui_printtext_after(undef, MSGLEVEL_CLIENTNOTICE, "$buf\cO$sep"); - $view->redraw(); + for my $win (@{$in->{windows}}) { + my $window = window_find_refnum $win->{refnum}; + next unless $window; + my @lines = @{ $win->{lines} || [] }; + next unless @lines; + + my $view = $window->view; + $view->remove_all_lines(); + $view->redraw(); + for my $line (@lines) { + my $level = $line->{level}; + my $data = $line->{data}; + $window->gui_printtext_after($window->last_line_insert, $level, "$data\n"); + } + my $sep = settings_get_str 'upgrade_separator'; + $window->gui_printtext_after($window->last_line_insert, MSGLEVEL_CLIENTNOTICE, "\cO$sep\n") if $sep ne ''; + $view->redraw(); } active_win->command('^window scroll on'); active_win->command('^scrollback end'); @@ -110,7 +107,7 @@ sub suppress { $key_part =~ s/^://; my $key = $first->{address} . $key_part; if (exists $suppress{$key} and $suppress{$key}--) { - signal_stop(); + signal_stop(); delete $suppress{$key} unless $suppress{$key}; } } diff --git a/scripts/usercount.pl b/scripts/usercount.pl index 650f9f36..7e765c96 100644 --- a/scripts/usercount.pl +++ b/scripts/usercount.pl @@ -1,7 +1,7 @@ use strict; use Irssi 20040119.2359 (); use vars qw($VERSION %IRSSI); -$VERSION = "1.19"; +$VERSION = "1.20"; %IRSSI = ( authors => 'David Leadbeater, Timo Sirainen, Georg Lukas', contact => 'dgl@dgl.cx, tss@iki.fi, georg@boerde.de', @@ -128,7 +128,7 @@ sub calc_users() { } # Server doesn't support halfops? - if($server->isupport("PREFIX") !~ /\%/) { + if($server->can('isupport') && $server->isupport("PREFIX") !~ /\%/) { $halfops = undef; } else { $halfops = undef unless Irssi::settings_get_bool('usercount_show_halfops'); From 4537d85b0b1e3bbd5240e379d015752423381e9a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 9 Nov 2018 11:32:00 +0100 Subject: [PATCH 0465/1198] reverse queue --- src/core/rawlog.c | 6 +++--- src/perl/common/Rawlog.xs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index dafad057..e0c4dd3d 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -63,7 +63,7 @@ void rawlog_destroy(RAWLOG_REC *rawlog) static void rawlog_add(RAWLOG_REC *rawlog, char *str) { if (rawlog->lines->length >= rawlog_lines && rawlog_lines > 0) { - void *tmp = g_queue_pop_tail(rawlog->lines); + void *tmp = g_queue_pop_head(rawlog->lines); g_free(tmp); } @@ -72,7 +72,7 @@ static void rawlog_add(RAWLOG_REC *rawlog, char *str) write_buffer(rawlog->handle, "\n", 1); } - g_queue_push_head(rawlog->lines, str); + g_queue_push_tail(rawlog->lines, str); signal_emit_id(signal_rawlog, 2, rawlog, str); } @@ -105,7 +105,7 @@ static void rawlog_dump(RAWLOG_REC *rawlog, int f) GList *tmp; ssize_t ret = 0; - for (tmp = rawlog->lines->tail; ret != -1 && tmp != NULL; tmp = tmp->prev) { + for (tmp = rawlog->lines->head; ret != -1 && tmp != NULL; tmp = tmp->next) { ret = write(f, tmp->data, strlen((char *) tmp->data)); if (ret != -1) ret = write(f, "\n", 1); diff --git a/src/perl/common/Rawlog.xs b/src/perl/common/Rawlog.xs index 73845287..3c946c7e 100644 --- a/src/perl/common/Rawlog.xs +++ b/src/perl/common/Rawlog.xs @@ -21,7 +21,7 @@ rawlog_get_lines(rawlog) PREINIT: GList *tmp; PPCODE: - for (tmp = rawlog->lines->tail; tmp != NULL; tmp = tmp->prev) { + for (tmp = rawlog->lines->head; tmp != NULL; tmp = tmp->next) { XPUSHs(sv_2mortal(new_pv(tmp->data))); } From 9e5e5d8625714c58546fad00b9d95bce7f3a1afb Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Nov 2018 13:14:02 +0100 Subject: [PATCH 0466/1198] expose wcwidth and related to perl --- src/perl/common/Core.xs | 21 +++++++++++++++++++++ src/perl/textui/TextUI.xs | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index 5d2f7bca..7c72f646 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -2,6 +2,8 @@ #include "module.h" #include "irssi-version.h" #include "core.h" +#include "utf8.h" +#include "recode.h" #include "pidwait.h" #include "session.h" @@ -687,6 +689,25 @@ CODE: OUTPUT: RETVAL +int +string_width(str) + char *str +C_ARGS: + str, is_utf8() ? TREAT_STRING_AS_UTF8 : TREAT_STRING_AS_BYTES + +void +string_chars_for_width(str, width) + char *str + unsigned int width +PREINIT: + int retval; + unsigned int bytes; +PPCODE: + retval = string_chars_for_width(str, is_utf8() ? TREAT_STRING_AS_UTF8 : TREAT_STRING_AS_BYTES, width, &bytes); + mXPUSHi(retval); + mXPUSHu(bytes); + + #******************************* MODULE = Irssi::Core PACKAGE = Irssi::Server #******************************* diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index e2f162a0..71545d14 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -205,6 +205,27 @@ gui_input_set_pos(pos) CODE: gui_entry_set_pos(active_entry, pos); +int +wcwidth(c) + char *c +CODE: + if (term_type == TERM_TYPE_UTF8) { + unichar chr = g_utf8_get_char_validated((const char *) c, -1); + + if (chr & 0x80000000) { + RETVAL = 1; + } else { + RETVAL = i_wcwidth(chr); + } + } else if (term_type != TERM_TYPE_BIG5 || + c[1] == '\0' || !is_big5(c[0], c[1])) { + RETVAL = 1; + } else { + RETVAL = 2; + } +OUTPUT: + RETVAL + MODULE = Irssi::TextUI PACKAGE = Irssi::UI::Window void From deaa1da55e3250badbdb3a769989cf5525b301e2 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Nov 2018 14:11:27 +0100 Subject: [PATCH 0467/1198] cast to unsigned char --- src/perl/textui/TextUI.xs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 71545d14..35ea5759 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -218,7 +218,8 @@ CODE: RETVAL = i_wcwidth(chr); } } else if (term_type != TERM_TYPE_BIG5 || - c[1] == '\0' || !is_big5(c[0], c[1])) { + c[1] == '\0' || + !is_big5((unsigned char) c[0], (unsigned char) c[1])) { RETVAL = 1; } else { RETVAL = 2; From 288f220f875d4e4f00e86dd809c04aa805b49991 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Nov 2018 00:14:15 +0100 Subject: [PATCH 0468/1198] fix width of byte codepoints --- src/perl/textui/TextUI.xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 35ea5759..9f4fd0b0 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -220,7 +220,7 @@ CODE: } else if (term_type != TERM_TYPE_BIG5 || c[1] == '\0' || !is_big5((unsigned char) c[0], (unsigned char) c[1])) { - RETVAL = 1; + RETVAL = i_wcwidth((unsigned char) *c); } else { RETVAL = 2; } From 4380f3820e5504b039d4a1ed0853c4442fa251b1 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 19 Nov 2018 13:58:51 +0000 Subject: [PATCH 0469/1198] Fix compilation of irc/core on AIX and IBM i There's a function in the standard library of these OSes that conflict with this function. Prefix it with `irc_`. --- src/irc/core/irc-cap.c | 2 +- src/irc/core/irc-cap.h | 3 ++- src/irc/core/irc-core.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 5ab8d94f..898a4a20 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -296,7 +296,7 @@ static void event_invalid_cap (IRC_SERVER_REC *server, const char *data, const c irc_send_cmd_now(server, "CAP END"); } -void cap_init (void) +void irc_cap_init (void) { signal_add_first("event cap", (SIGNAL_FUNC) event_cap); signal_add_first("event 410", (SIGNAL_FUNC) event_invalid_cap); diff --git a/src/irc/core/irc-cap.h b/src/irc/core/irc-cap.h index df957cd2..cbfeae62 100644 --- a/src/irc/core/irc-cap.h +++ b/src/irc/core/irc-cap.h @@ -1,7 +1,8 @@ #ifndef __IRC_CAP_H #define __IRC_CAP_H -void cap_init(void); +/* this is prefixed as to not conflict with an AIX/i function in their stdlib */ +void irc_cap_init(void); void cap_deinit(void); int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable); void cap_finish_negotiation (IRC_SERVER_REC *server); diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index a9221e02..ccd84027 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -119,7 +119,7 @@ void irc_core_init(void) lag_init(); netsplit_init(); irc_expandos_init(); - cap_init(); + irc_cap_init(); sasl_init(); settings_check(); From 795e7ec16240613dd13e8378128bb5fa66b6dc93 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 19 Nov 2018 14:18:34 +0000 Subject: [PATCH 0470/1198] Fix build on IBM i * Lots of warnings about subdirectories. Set an automake option to deal with this. * Set an ar flag for explicit 64-bit when on IBM i, due to it defaulting to 64-bit output with official gcc by default. --- configure.ac | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 03e05847..82af3a20 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_PREREQ(2.50) AC_CONFIG_HEADERS([irssi-config.h]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.9 no-define foreign]) +AM_INIT_AUTOMAKE([1.9 no-define foreign subdir-objects]) AM_SILENT_RULES([yes]) @@ -199,6 +199,12 @@ case "$host_os" in hpux*) CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED" ;; + os400*) + dnl IBM i uses ppc64 gcc by default, but binutils defaults to 32-bit. Force + dnl IBM binutils, and force it into ppc64 mode. This isn't set for AIX + dnl because gcc there defaults to ppc32. + AR="/usr/bin/ar -X64" + ;; *) ;; esac From 88b16491956f0a882cc61fffa6a76d469006a87d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 25 Nov 2018 14:16:08 +0100 Subject: [PATCH 0471/1198] add keep_word setting to completion --- src/fe-common/core/completion.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index fd452e5c..2bc65d42 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -240,6 +240,10 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i /* Remove all nulls (from the signal) before doing further processing */ complist = g_list_remove_all(g_list_first(complist), NULL); } + + if (settings_get_bool("completion_keep_word") && complist != NULL) { + complist = g_list_append(complist, g_strdup(word)); + } } g_free(linestart); @@ -897,6 +901,7 @@ void completion_init(void) chat_completion_init(); + settings_add_bool("completion", "completion_keep_word", TRUE); command_bind("completion", NULL, (SIGNAL_FUNC) cmd_completion); signal_add_first("complete word", (SIGNAL_FUNC) sig_complete_word); From 10f41e067eef33e30a211279d69160b5c7721f96 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 25 Nov 2018 14:19:57 +0100 Subject: [PATCH 0472/1198] fix backward completion --- src/fe-common/core/completion.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 2bc65d42..29a052b3 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -229,6 +229,7 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i g_list_first(complist); want_space = last_want_space; } else { + int keep_word = settings_get_bool("completion_keep_word"); /* get new completion list */ free_completions(); @@ -239,10 +240,17 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i if (complist != NULL) { /* Remove all nulls (from the signal) before doing further processing */ complist = g_list_remove_all(g_list_first(complist), NULL); - } - if (settings_get_bool("completion_keep_word") && complist != NULL) { - complist = g_list_append(complist, g_strdup(word)); + if (keep_word) { + complist = g_list_append(complist, g_strdup(word)); + } + + if (backward) { + complist = g_list_last(complist); + if (keep_word) { + complist = complist->prev; + } + } } } From a634b34ba48d7e050bb125d86205e58a5dc00c3d Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Sun, 25 Nov 2018 14:50:47 +0000 Subject: [PATCH 0473/1198] Rename cap_* funcs to irc_cap_* Some systems often "namespace" cap_ for themselves, and so irssi's usage can conflict with their own. Bump ABI for this. --- src/common.h | 2 +- src/irc/core/irc-cap.c | 14 +++++++------- src/irc/core/irc-cap.h | 6 +++--- src/irc/core/irc-core.c | 2 +- src/irc/core/irc-servers.c | 4 ++-- src/irc/core/sasl.c | 10 +++++----- src/perl/irc/Server.xs | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/common.h b/src/common.h index c8fb54df..14bfe42b 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 18 +#define IRSSI_ABI_VERSION 19 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 898a4a20..2d740c59 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -24,7 +24,7 @@ #include "irc-cap.h" #include "irc-servers.h" -int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) +int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) { if (cap == NULL || *cap == '\0') return FALSE; @@ -65,7 +65,7 @@ int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) return FALSE; } -void cap_finish_negotiation (IRC_SERVER_REC *server) +void irc_cap_finish_negotiation (IRC_SERVER_REC *server) { if (server->cap_complete) return; @@ -130,7 +130,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } /* Malformed request, terminate the negotiation */ else { - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); g_warn_if_reached(); return; } @@ -177,7 +177,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add if (multiline == FALSE) { /* No CAP has been requested */ if (server->cap_queue == NULL) { - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); } else { cmd = g_string_new("CAP REQ :"); @@ -204,7 +204,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add signal_emit("server cap req", 2, server, cmd->str + sizeof("CAP REQ :") - 1); irc_send_cmd_now(server, cmd->str); } else { - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); } g_string_free(cmd, TRUE); @@ -233,7 +233,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add * negotiation, unless sasl was requested. In this case we must not terminate the negotiation * until the sasl handshake is over. */ if (got_sasl == FALSE) - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); } else if (!g_ascii_strcasecmp(evt, "NAK")) { g_warning("The server answered with a NAK to our CAP request, this should not happen"); @@ -302,7 +302,7 @@ void irc_cap_init (void) signal_add_first("event 410", (SIGNAL_FUNC) event_invalid_cap); } -void cap_deinit (void) +void irc_cap_deinit (void) { signal_remove("event cap", (SIGNAL_FUNC) event_cap); signal_remove("event 410", (SIGNAL_FUNC) event_invalid_cap); diff --git a/src/irc/core/irc-cap.h b/src/irc/core/irc-cap.h index cbfeae62..716239e2 100644 --- a/src/irc/core/irc-cap.h +++ b/src/irc/core/irc-cap.h @@ -3,8 +3,8 @@ /* this is prefixed as to not conflict with an AIX/i function in their stdlib */ void irc_cap_init(void); -void cap_deinit(void); -int cap_toggle (IRC_SERVER_REC *server, char *cap, int enable); -void cap_finish_negotiation (IRC_SERVER_REC *server); +void irc_cap_deinit(void); +int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable); +void irc_cap_finish_negotiation (IRC_SERVER_REC *server); #endif diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index ccd84027..950e5029 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -131,7 +131,7 @@ void irc_core_deinit(void) signal_emit("chat protocol deinit", 1, chat_protocol_find("IRC")); sasl_deinit(); - cap_deinit(); + irc_cap_deinit(); irc_expandos_deinit(); netsplit_deinit(); lag_deinit(); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 02d971dc..03c73312 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -236,9 +236,9 @@ static void server_init(IRC_SERVER_REC *server) } if (conn->sasl_mechanism != SASL_MECHANISM_NONE) - cap_toggle(server, "sasl", TRUE); + irc_cap_toggle(server, "sasl", TRUE); - cap_toggle(server, "multi-prefix", TRUE); + irc_cap_toggle(server, "multi-prefix", TRUE); irc_send_cmd_now(server, "CAP LS"); diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index b7abe748..92eb6244 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -45,7 +45,7 @@ static gboolean sasl_timeout(IRC_SERVER_REC *server) { /* The authentication timed out, we can't do much beside terminating it */ irc_send_cmd_now(server, "AUTHENTICATE *"); - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); server->sasl_timeout = 0; server->sasl_success = FALSE; @@ -96,7 +96,7 @@ static void sasl_fail(IRC_SERVER_REC *server, const char *data, const char *from signal_emit("server sasl failure", 2, server, error); /* Terminate the negotiation */ - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); g_free(params); } @@ -110,7 +110,7 @@ static void sasl_already(IRC_SERVER_REC *server, const char *data, const char *f signal_emit("server sasl success", 1, server); /* We're already authenticated, do nothing */ - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); } static void sasl_success(IRC_SERVER_REC *server, const char *data, const char *from) @@ -122,7 +122,7 @@ static void sasl_success(IRC_SERVER_REC *server, const char *data, const char *f signal_emit("server sasl success", 1, server); /* The authentication succeeded, time to finish the CAP negotiation */ - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); } /* @@ -263,7 +263,7 @@ static void sasl_step_complete(IRC_SERVER_REC *server, GString *data) static void sasl_step_fail(IRC_SERVER_REC *server) { irc_send_cmd_now(server, "AUTHENTICATE *"); - cap_finish_negotiation(server); + irc_cap_finish_negotiation(server); sasl_timeout_stop(server); diff --git a/src/perl/irc/Server.xs b/src/perl/irc/Server.xs index 33417bf5..a42f5c82 100644 --- a/src/perl/irc/Server.xs +++ b/src/perl/irc/Server.xs @@ -155,6 +155,6 @@ irc_server_cap_toggle(server, cap, enable) char *cap int enable CODE: - RETVAL = cap_toggle(server, cap, enable); + RETVAL = irc_cap_toggle(server, cap, enable); OUTPUT: RETVAL From bed0a3309f4f452f5ebf6d5d5becf869da190d7a Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Sun, 25 Nov 2018 15:00:34 +0000 Subject: [PATCH 0474/1198] Revert back to using original version of the configure script * IBM i rpmbuild environments set the magic variables for building w/ 64-bit binutils automatically, and one can set this for themselves with `OBJECT_MODE=64` when buildings. Remove this. * The subdir-objects change will need to be made due to upstream autotools making it mandatory in the future, but that isn't my decision to make. --- configure.ac | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 82af3a20..03e05847 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_PREREQ(2.50) AC_CONFIG_HEADERS([irssi-config.h]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.9 no-define foreign subdir-objects]) +AM_INIT_AUTOMAKE([1.9 no-define foreign]) AM_SILENT_RULES([yes]) @@ -199,12 +199,6 @@ case "$host_os" in hpux*) CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED" ;; - os400*) - dnl IBM i uses ppc64 gcc by default, but binutils defaults to 32-bit. Force - dnl IBM binutils, and force it into ppc64 mode. This isn't set for AIX - dnl because gcc there defaults to ppc32. - AR="/usr/bin/ar -X64" - ;; *) ;; esac From 482a3a5bdd7bf3755c67d678b7e74f72cfbaaecb Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 26 Nov 2018 09:56:04 -0400 Subject: [PATCH 0475/1198] Remove unneeded comment --- src/irc/core/irc-cap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/irc/core/irc-cap.h b/src/irc/core/irc-cap.h index 716239e2..96efbbee 100644 --- a/src/irc/core/irc-cap.h +++ b/src/irc/core/irc-cap.h @@ -1,7 +1,6 @@ #ifndef __IRC_CAP_H #define __IRC_CAP_H -/* this is prefixed as to not conflict with an AIX/i function in their stdlib */ void irc_cap_init(void); void irc_cap_deinit(void); int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable); From 4f26ad74f50b6d68bee0b75d69507cb8a9c413aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= Date: Tue, 4 Dec 2018 16:03:04 +0100 Subject: [PATCH 0476/1198] Fixed problem found by Coverity Scan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #981 Signed-off-by: Jaroslav Škarvada --- src/irc/dcc/dcc-send.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c index 912129b7..50009287 100644 --- a/src/irc/dcc/dcc-send.c +++ b/src/irc/dcc/dcc-send.c @@ -425,6 +425,7 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname, g_free(str); if (dcc == NULL) { g_warn_if_reached(); + close(hfile); return FALSE; } From 821e8af9fecdda2f25f18d5cc0be965b06e05362 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 7 Dec 2018 09:52:23 +0100 Subject: [PATCH 0477/1198] automake warns that subdir-objects will be enabled in 2.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 49436bf1..50c5520f 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_PREREQ(2.50) AC_CONFIG_HEADERS([irssi-config.h]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.9 no-define foreign]) +AM_INIT_AUTOMAKE([1.9 no-define foreign subdir-objects]) AM_SILENT_RULES([yes]) From 7e6e3cd503b3619a22709db66234cd4aeefa866f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 25 Nov 2018 13:41:46 +0100 Subject: [PATCH 0478/1198] Add escape_string_escape function for expand_escapes To avoid expanding, tab completion escapes the completion list. But the escape_string function escapes too much for the expand_escapes code. Add a function that only escapes the backslashes. --- src/core/misc.c | 16 ++++++++++++++++ src/core/misc.h | 3 +++ src/fe-common/core/completion.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/core/misc.c b/src/core/misc.c index 27741220..bcad890d 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -757,6 +757,22 @@ char *escape_string(const char *str) return ret; } +/* Escape all '\' chars with '\' */ +char *escape_string_escape(const char *str) +{ + char *ret, *p; + + p = ret = g_malloc(strlen(str)*2+1); + while (*str != '\0') { + if (*str == '\\') + *p++ = '\\'; + *p++ = *str++; + } + *p = '\0'; + + return ret; +} + int nearest_power(int num) { int n = 1; diff --git a/src/core/misc.h b/src/core/misc.h index a46a1432..9694819f 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -93,6 +93,9 @@ char *ascii_strdown(char *str); /* Escape all '"', "'" and '\' chars with '\' */ char *escape_string(const char *str); +/* Escape all '\' chars with '\' */ +char *escape_string_escape(const char *str); + /* convert all low-ascii (<32) to ^ combinations */ char *show_lowascii(const char *str); diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index fd452e5c..02d832b0 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -256,7 +256,7 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i /* escape if the word doesn't begin with '/' and expand_escapes are turned on */ data = strchr(cmdchars, *line) == NULL && expand_escapes ? - escape_string(complist->data) : g_strdup(complist->data); + escape_string_escape(complist->data) : g_strdup(complist->data); /* word completed */ *pos = startpos + strlen(data); From 35f5e5f278444ecbbd3610292d9569d3a2f51ce1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 25 Nov 2018 13:57:17 +0100 Subject: [PATCH 0479/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index c8fb54df..14bfe42b 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 18 +#define IRSSI_ABI_VERSION 19 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 8c30367452dd592027917ce92bcebe9301d2c87a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 8 Jan 2019 15:48:12 +0100 Subject: [PATCH 0480/1198] rename function --- src/core/misc.c | 2 +- src/core/misc.h | 2 +- src/fe-common/core/completion.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index bcad890d..e1f199b2 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -758,7 +758,7 @@ char *escape_string(const char *str) } /* Escape all '\' chars with '\' */ -char *escape_string_escape(const char *str) +char *escape_string_backslashes(const char *str) { char *ret, *p; diff --git a/src/core/misc.h b/src/core/misc.h index 9694819f..1545f7a2 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -94,7 +94,7 @@ char *ascii_strdown(char *str); char *escape_string(const char *str); /* Escape all '\' chars with '\' */ -char *escape_string_escape(const char *str); +char *escape_string_backslashes(const char *str); /* convert all low-ascii (<32) to ^ combinations */ char *show_lowascii(const char *str); diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 02d832b0..8a986a28 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -256,7 +256,7 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i /* escape if the word doesn't begin with '/' and expand_escapes are turned on */ data = strchr(cmdchars, *line) == NULL && expand_escapes ? - escape_string_escape(complist->data) : g_strdup(complist->data); + escape_string_backslashes(complist->data) : g_strdup(complist->data); /* word completed */ *pos = startpos + strlen(data); From 3d1980599a9115c095713f1a82edf67afda64e4f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Jan 2019 15:20:45 +0100 Subject: [PATCH 0481/1198] Merge tag '1.1.2' into integrate/1.1.2 --- NEWS | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 72388af8..d6748a12 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,23 @@ -v1.2-head 2018-xx-xx The Irssi team +v1.2-head 2019-xx-xx The Irssi team + +v1.1.2 2019-01-09 The Irssi team + - Fix the resetting of window hiddenlevel (#861) + - Fix clearing of hidelevel in layout (#951) + - Fix accessing unallocated text when checking entry position + (#930) + - Fix uninitialised memory on empty lines (#873, GL#31, #878, + #877, #907, #914) + - Fix use-after-free on expiration of hidden lines (#948) + - Fix use-after-frees. By Maya Rashish (#919) + - Fix out of bounds access in help display when window width + is small (#949) + - Fix paste_join_multiline (#971) + - Correctly check for errno when displaying SSL errors. By + Janik Rabe (#895) + - Fix wrong signal emission argument count (#965) + - Documentation (#920). Sync NEWS, scripts (#849) + - Fix Perl detection on MacOS. By Dominyk Tiller (#927) + - Misc fixes. By Jaroslav Škarvada (#982) v1.1.1 2018-02-15 The Irssi team ! Contains all changes from 1.0.7 @@ -41,8 +60,8 @@ v1.1.0 2018-01-15 The Irssi team * /server does not connect to servers anymore, use /server connect to change servers (#559, #649). * The net_ip_compare API function is now deprecated, and the - previously deprecated net_connect has been removed - (#770). By Will Storey (#770) + previously deprecated net_connect has been removed. By Will + Storey (#770). + Add an option to ignore all channels or ignore all queries using /set activity_hide_targets. By Jari Matilainen (#612, #779) From dfe3c31283df810b4bcdbe2d746a0b3da516689f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Jan 2019 15:33:22 +0100 Subject: [PATCH 0482/1198] update issue references --- NEWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d6748a12..9da96be3 100644 --- a/NEWS +++ b/NEWS @@ -4,20 +4,20 @@ v1.1.2 2019-01-09 The Irssi team - Fix the resetting of window hiddenlevel (#861) - Fix clearing of hidelevel in layout (#951) - Fix accessing unallocated text when checking entry position - (#930) + (#928, #930) - Fix uninitialised memory on empty lines (#873, GL#31, #878, #877, #907, #914) - Fix use-after-free on expiration of hidden lines (#948) - Fix use-after-frees. By Maya Rashish (#919) - Fix out of bounds access in help display when window width is small (#949) - - Fix paste_join_multiline (#971) + - Fix paste_join_multiline (#970, #971) - Correctly check for errno when displaying SSL errors. By Janik Rabe (#895) - Fix wrong signal emission argument count (#965) - Documentation (#920). Sync NEWS, scripts (#849) - Fix Perl detection on MacOS. By Dominyk Tiller (#927) - - Misc fixes. By Jaroslav Škarvada (#982) + - Misc fixes. By Jaroslav Škarvada (#981, #982) v1.1.1 2018-02-15 The Irssi team ! Contains all changes from 1.0.7 From b8cfd9d6affc0f72a82e75a8be5207bb357c76bc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Jan 2019 21:11:01 +0100 Subject: [PATCH 0483/1198] show output of git describe as PACKAGE_VERSION also fixes GNUism in sed call --- utils/irssi-version.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/utils/irssi-version.sh b/utils/irssi-version.sh index 1fc6a558..6b3a46e4 100755 --- a/utils/irssi-version.sh +++ b/utils/irssi-version.sh @@ -18,11 +18,7 @@ if echo "${VERSION}" | grep -q -- -head; then # -head version, get extra details from git if we can git_version=$(GIT_DIR=$1/.git git describe --dirty --long --always --tags) if [ $? = 0 ]; then - new_version="$(echo "${VERSION}" | sed 's/-head//')" - # Because the git tag won't yet include the next release we modify the git - # describe output using the version defined from configure.ac. - version="${new_version}-$(echo "${git_version}" | sed 's/^.*-[0-9]\+-//')" echo "#undef PACKAGE_VERSION" - echo "#define PACKAGE_VERSION \"${version}\"" + echo "#define PACKAGE_VERSION \"${git_version}\"" fi fi From b080405c6ae2e469c8718f77cf6c3e7fd17a6ac5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 9 Jan 2019 23:46:57 +0100 Subject: [PATCH 0484/1198] update sidewayssplit syntax --- docs/help/in/window.in | 20 +- src/fe-common/core/window-commands.c | 4 +- src/fe-text/mainwindows.c | 513 ++++++++++++++++----------- 3 files changed, 306 insertions(+), 231 deletions(-) diff --git a/docs/help/in/window.in b/docs/help/in/window.in index 0e7ed637..aa133766 100644 --- a/docs/help/in/window.in +++ b/docs/help/in/window.in @@ -35,28 +35,20 @@ SHRINK: %|Decrease the size of the active split window by the specified number of lines. SIZE: %|Set the current split window size to the specified numer of lines. BALANCE: %|Balance the heights of all split windows. - RGROW: %|Increase the width of the active split window by the specified number of columns. - RSHRINK: %|Decrease the wodth of the active split window by the specified number of columns. - RSIZE: %|Set the current split window width to the specified numer of columns. - RBALANCE: %|Balance the widths of all split windows in this line. HIDE: %|Hides the current split window, or the split window specified by number or item name. SHOW: %|Show the window specified by number or item name as a new split windows. It is made sticky when autostick_split_windows is turned on. - RSHOW: %|Show the window specified by number or item name as a new windows split to the right of the current window. It is made sticky when autostick_split_windows is turned on. UP: %|Set the split window left or above the current one active. At the top, wraps to the bottom. - DOWN: %|Set the split window right or below the current one active. At the bottom, wraps to the top. - DUP: %|Set the split window above the current one active. At the top, wraps to the bottom. - DDOWN: %|Set the split window below the current one active. At the bottom, wraps to the top. - DLEFT: %|Set the split window left to the current one active. At the left, wraps to the right. - DRIGHT: %|Set the split window right to the current one active. At the right, wraps to the left. + DOWN: %|Set the split window right or below the current one active. At the bottom, wraps teft. LEFT: %|Go to the previous window numerically that is part of the current sticky group (or not part of any sticky group). RIGHT: %|Go to the next window numerically that is part of the current sticky group (or not part of any sticky group). STICK: %|Make the currently active window sticky, or stick the window specified by number to the currently visible split window. Or turn off stickyness of the currently active window or the window specified by number. MOVE LEFT: %|Move the window to the numerically previous location inside the current sticky group. MOVE RIGHT: %|Move the window to the numerically next location inside the current sticky group. - MOVE UP: %|Move the current window to the sticky group of the split window above. If no sticky group remains, the split window collapses. - MOVE DOWN: %|Move the current window to the sticky group of the split window below. If no sticky group remains, the split window collapses. - MOVE DLEFT: %|Move the current window to the sticky group of the split window to the left. If no sticky group remains, the split window collapses. - MOVE DRIGHT: %|Move the current window to the sticky group of the split window to the right. If no sticky group remains, the split window collapses. + MOVE UP: %|Move the current window to the sticky group of the previous split window. If no sticky group remains, the split window collapses. + MOVE DOWN: %|Move the current window to the sticky group of the next split window. If no sticky group remains, the split window collapses. + + -right: %|Makes the command work on the width instead of height, or create the split window to the right instead of top. + -directional: %|Set the split window in the given direction to the current one active, or move the current window to the sticky group of the split window in the given direction. (If no sticky group remains, the split window collapses.) %|Add the required arguments for the given command. Without arguments, the details (size, immortality, levels, server, name and sticky group) of the currently active window are displayed. If used with a number as argument, same as WINDOW REFNUM. diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index 5e53957d..d9956324 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -169,7 +169,7 @@ static void cmd_window(const char *data, void *server, WI_ITEM_REC *item) command_runsub("window", data, server, item); } -/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT|RSPLIT] */ +/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT|-right SPLIT] */ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) { WINDOW_REC *window; @@ -179,7 +179,7 @@ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item) type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? MAIN_WINDOW_TYPE_HIDDEN : g_ascii_strcasecmp(data, "split") == 0 ? MAIN_WINDOW_TYPE_SPLIT : - g_ascii_strncasecmp(data, "rs", 2) == 0 ? MAIN_WINDOW_TYPE_RSPLIT : MAIN_WINDOW_TYPE_DEFAULT; + g_ascii_strncasecmp(data, "-r", 2) == 0 ? MAIN_WINDOW_TYPE_RSPLIT : MAIN_WINDOW_TYPE_DEFAULT; signal_emit("gui window create override", 1, GINT_TO_POINTER(type)); window = window_create(NULL, FALSE); diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index b01f3d04..997cdd22 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -1106,7 +1106,7 @@ static void mainwindows_rresize_two(MAIN_WINDOW_REC *grow_win, shrink_win->dirty = TRUE; } -static int try_rshrink_right(MAIN_WINDOW_REC *window, int count) +static int try_shrink_right(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; @@ -1128,7 +1128,7 @@ static int try_rshrink_right(MAIN_WINDOW_REC *window, int count) return FALSE; } -static int try_rshrink_left(MAIN_WINDOW_REC *window, int count) +static int try_shrink_left(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *shrink_win; @@ -1149,17 +1149,17 @@ static int try_rshrink_left(MAIN_WINDOW_REC *window, int count) return FALSE; } -static int mainwindow_rgrow(MAIN_WINDOW_REC *window, int count) +static int mainwindow_grow_right(MAIN_WINDOW_REC *window, int count) { - if (!try_rshrink_right(window, count)) { - if (!try_rshrink_left(window, count)) + if (!try_shrink_right(window, count)) { + if (!try_shrink_left(window, count)) return FALSE; } return TRUE; } -static int try_rgrow_right(MAIN_WINDOW_REC *window, int count) +static int try_grow_right(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *grow_win; @@ -1174,7 +1174,7 @@ static int try_rgrow_right(MAIN_WINDOW_REC *window, int count) return FALSE; } -static int try_rgrow_left(MAIN_WINDOW_REC *window, int count) +static int try_grow_left(MAIN_WINDOW_REC *window, int count) { MAIN_WINDOW_REC *grow_win; @@ -1189,15 +1189,15 @@ static int try_rgrow_left(MAIN_WINDOW_REC *window, int count) return FALSE; } -static int mainwindow_rshrink(MAIN_WINDOW_REC *window, int count) +static int mainwindow_shrink_right(MAIN_WINDOW_REC *window, int count) { g_return_val_if_fail(count >= 0, FALSE); if (MAIN_WINDOW_TEXT_WIDTH(window)-count < NEW_WINDOW_WIDTH) return FALSE; - if (!try_rgrow_right(window, count)) { - if (!try_rgrow_left(window, count)) + if (!try_grow_right(window, count)) { + if (!try_grow_left(window, count)) return FALSE; } @@ -1220,9 +1220,9 @@ void mainwindow_set_rsize(MAIN_WINDOW_REC *window, int width) { width -= window->width; if (width < 0) - mainwindow_rshrink(window, -width); + mainwindow_shrink_right(window, -width); else - mainwindow_rgrow(window, width); + mainwindow_grow_right(window, width); } void mainwindows_redraw_dirty(void) @@ -1260,44 +1260,7 @@ static void mainwindow_grow_int(int count) } } -/* SYNTAX: WINDOW GROW [] */ -static void cmd_window_grow(const char *data) -{ - int count; - - count = *data == '\0' ? 1 : atoi(data); - - mainwindow_grow_int(count); -} - -/* SYNTAX: WINDOW SHRINK [] */ -static void cmd_window_shrink(const char *data) -{ - int count; - - count = *data == '\0' ? 1 : atoi(data); - if (count < -INT_MAX) count = -INT_MAX; - - mainwindow_grow_int(-count); -} - -/* SYNTAX: WINDOW SIZE */ -static void cmd_window_size(const char *data) -{ - int size; - - if (!is_numeric(data, 0)) return; - size = atoi(data); - - size -= WINDOW_MAIN(active_win)->height - - WINDOW_MAIN(active_win)->statusbar_lines; - if (size < -INT_MAX) size = -INT_MAX; - - mainwindow_grow_int(size); -} - -/* SYNTAX: WINDOW BALANCE */ -static void cmd_window_balance(void) +static void window_balance_vertical(void) { GSList *sorted, *stmp, *line, *ltmp; int avail_size, unit_size, bigger_units; @@ -1393,23 +1356,39 @@ static void cmd_window_hide(const char *data) } } -static void _cmd_window_show_opt(const char *data, int right) +/* SYNTAX: WINDOW SHOW [-right] | */ +static void cmd_window_show(const char *data) { + GHashTable *optlist; MAIN_WINDOW_REC *parent; WINDOW_REC *window; + char *args; + void *free_arg; + int right; - if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window show", &optlist, &args)) + return; - if (is_numeric(data, '\0')) { - window = window_find_refnum(atoi(data)); + right = g_hash_table_lookup(optlist, "right") != NULL; + + if (*args == '\0') { + cmd_params_free(free_arg); + cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); + } + + if (is_numeric(args, '\0')) { + window = window_find_refnum(atoi(args)); if (window == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, - TXT_REFNUM_NOT_FOUND, data); + TXT_REFNUM_NOT_FOUND, args); } } else { - window = window_find_item(active_win->active_server, data); + window = window_find_item(active_win->active_server, args); } + cmd_params_free(free_arg); + if (window == NULL || is_window_visible(window)) return; @@ -1437,69 +1416,103 @@ static void _cmd_window_show_opt(const char *data, int right) window_set_active(window); } -/* SYNTAX: WINDOW SHOW | */ -static void cmd_window_show(const char *data) -{ - _cmd_window_show_opt(data, FALSE); -} - -/* SYNTAX: WINDOW RSHOW | */ -static void cmd_window_rshow(const char *data) -{ - _cmd_window_show_opt(data, TRUE); -} - -static void window_rgrow_int(int count) +static void mainwindow_grow_right_int(int count) { if (count == 0) { return; } else if (count < 0) { - if (!mainwindow_rshrink(WINDOW_MAIN(active_win), -count)) { + if (!mainwindow_shrink_right(WINDOW_MAIN(active_win), -count)) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); } } else { - if (!mainwindow_rgrow(WINDOW_MAIN(active_win), count)) { + if (!mainwindow_grow_right(WINDOW_MAIN(active_win), count)) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); } } } -/* SYNTAX: WINDOW RGROW [] */ -static void cmd_window_rgrow(const char *data) + +/* SYNTAX: WINDOW GROW [-right] [|] */ +static void cmd_window_grow(const char *data) { + GHashTable *optlist; + char *args; + void *free_arg; int count; - count = *data == '\0' ? 1 : atoi(data); + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window grow", &optlist, &args)) + return; - window_rgrow_int(count); + count = *data == '\0' ? 1 : atoi(args); + + if (g_hash_table_lookup(optlist, "right") != NULL) { + mainwindow_grow_right_int(count); + } else { + mainwindow_grow_int(count); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW RSHRINK [] */ -static void cmd_window_rshrink(const char *data) +/* SYNTAX: WINDOW SHRINK [-right] [|] */ +static void cmd_window_shrink(const char *data) { + GHashTable *optlist; + char *args; + void *free_arg; int count; - count = *data == '\0' ? 1 : atoi(data); + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window shrink", &optlist, &args)) + return; + + count = *data == '\0' ? 1 : atoi(args); if (count < -INT_MAX) count = -INT_MAX; - window_rgrow_int(-count); + if (g_hash_table_lookup(optlist, "right") != NULL) { + mainwindow_grow_right_int(-count); + } else { + mainwindow_grow_int(-count); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW RSIZE */ -static void cmd_window_rsize(const char *data) +/* SYNTAX: WINDOW SIZE [-right] | */ +static void cmd_window_size(const char *data) { - int rsize; + GHashTable *optlist; + char *args; + void *free_arg; + int size; - if (!is_numeric(data, 0)) return; - rsize = atoi(data); + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window size", &optlist, &args)) + return; - rsize -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win)); + if (!is_numeric(args, 0)) { + cmd_params_free(free_arg); + return; + } + size = atoi(data); - window_rgrow_int(rsize); + if (g_hash_table_lookup(optlist, "right") != NULL) { + size -= MAIN_WINDOW_TEXT_WIDTH(WINDOW_MAIN(active_win)); + + mainwindow_grow_right_int(size); + } else { + size -= WINDOW_MAIN(active_win)->height - + WINDOW_MAIN(active_win)->statusbar_lines; + if (size < -INT_MAX) size = -INT_MAX; + + mainwindow_grow_int(size); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW RBALANCE */ -static void cmd_window_rbalance(void) +static void window_balance_horizontal(void) { GSList *line, *ltmp; int avail_width, unit_width, bigger_units; @@ -1537,76 +1550,76 @@ static void cmd_window_rbalance(void) mainwindows_redraw(); } -/* SYNTAX: WINDOW UP */ -static void cmd_window_up(void) +/* SYNTAX: WINDOW BALANCE [-right] */ +static void cmd_window_balance(const char *data) { - MAIN_WINDOW_REC *rec; + GHashTable *optlist; + void *free_arg; - rec = mainwindows_find_left_upper(active_mainwin); - if (rec == NULL) - rec = mainwindows_find_left_upper(NULL); - if (rec != NULL) - window_set_active(rec->active); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window balance", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "right") != NULL) { + window_balance_horizontal(); + } else { + window_balance_vertical(); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW DUP */ -static void cmd_window_dup(void) +/* SYNTAX: WINDOW UP [-directional] */ +static void cmd_window_up(const char *data) { MAIN_WINDOW_REC *rec; + GHashTable *optlist; + void *free_arg; - rec = mainwindows_find_upper(active_mainwin); - if (rec == NULL) - rec = mainwindows_find_upper(NULL); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window up", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + rec = mainwindows_find_upper(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_upper(NULL); + } else { + rec = mainwindows_find_left_upper(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_left_upper(NULL); + } if (rec != NULL) window_set_active(rec->active); + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW DLEFT */ -static void cmd_window_dleft(void) +/* SYNTAX: WINDOW DOWN [-directional] */ +static void cmd_window_down(const char *data) { MAIN_WINDOW_REC *rec; + GHashTable *optlist; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window down", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + rec = mainwindows_find_lower(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_lower(NULL); + } else { + rec = mainwindows_find_lower_right(active_mainwin); + if (rec == NULL) + rec = mainwindows_find_lower_right(NULL); + } - rec = mainwindows_find_left(active_mainwin, FALSE); - if (rec == NULL) - rec = mainwindows_find_left(active_mainwin, TRUE); if (rec != NULL) window_set_active(rec->active); -} -/* SYNTAX: WINDOW DOWN */ -static void cmd_window_down(void) -{ - MAIN_WINDOW_REC *rec; - - rec = mainwindows_find_lower_right(active_mainwin); - if (rec == NULL) - rec = mainwindows_find_lower_right(NULL); - if (rec != NULL) - window_set_active(rec->active); -} - -/* SYNTAX: WINDOW DDOWN */ -static void cmd_window_ddown(void) -{ - MAIN_WINDOW_REC *rec; - - rec = mainwindows_find_lower(active_mainwin); - if (rec == NULL) - rec = mainwindows_find_lower(NULL); - if (rec != NULL) - window_set_active(rec->active); -} - -/* SYNTAX: WINDOW DRIGHT */ -static void cmd_window_dright(void) -{ - MAIN_WINDOW_REC *rec; - - rec = mainwindows_find_right(active_mainwin, FALSE); - if (rec == NULL) - rec = mainwindows_find_right(active_mainwin, TRUE); - if (rec != NULL) - window_set_active(rec->active); + cmd_params_free(free_arg); } #define WINDOW_STICKY_MATCH(window, sticky_parent) \ @@ -1658,24 +1671,62 @@ static int window_refnum_right(int refnum, int wrap) return refnum; } -/* SYNTAX: WINDOW LEFT */ +/* SYNTAX: WINDOW LEFT [-directional] */ static void cmd_window_left(const char *data, SERVER_REC *server, void *item) { - int refnum; + GHashTable *optlist; + void *free_arg; - refnum = window_refnum_left(active_win->refnum, TRUE); - if (refnum != -1) - window_set_active(window_find_refnum(refnum)); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window left", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_left(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_left(active_mainwin, TRUE); + if (rec != NULL) + window_set_active(rec->active); + } else { + int refnum; + + refnum = window_refnum_left(active_win->refnum, TRUE); + if (refnum != -1) + window_set_active(window_find_refnum(refnum)); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW RIGHT */ -static void cmd_window_right(void) +/* SYNTAX: WINDOW RIGHT [-directional] */ +static void cmd_window_right(const char *data) { - int refnum; + GHashTable *optlist; + void *free_arg; - refnum = window_refnum_right(active_win->refnum, TRUE); - if (refnum != -1) - window_set_active(window_find_refnum(refnum)); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window right", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_right(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_right(active_mainwin, TRUE); + if (rec != NULL) + window_set_active(rec->active); + } else { + int refnum; + + refnum = window_refnum_right(active_win->refnum, TRUE); + if (refnum != -1) + window_set_active(window_find_refnum(refnum)); + } + + cmd_params_free(free_arg); } static void window_reparent(WINDOW_REC *win, MAIN_WINDOW_REC *mainwin) @@ -1742,68 +1793,108 @@ static void cmd_window_stick(const char *data) } } -/* SYNTAX: WINDOW MOVE LEFT */ -static void cmd_window_move_left(void) +/* SYNTAX: WINDOW MOVE LEFT [-directional] */ +static void cmd_window_move_left(const char *data) { - int refnum; + GHashTable *optlist; + void *free_arg; - refnum = window_refnum_left(active_win->refnum, TRUE); - if (refnum != -1) - window_set_refnum(active_win, refnum); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window move left", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_left(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_left(active_mainwin, TRUE); + if (rec != NULL) + window_reparent(active_win, rec); + } else { + int refnum; + + refnum = window_refnum_left(active_win->refnum, TRUE); + if (refnum != -1) + window_set_refnum(active_win, refnum); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW MOVE RIGHT */ -static void cmd_window_move_right(void) +/* SYNTAX: WINDOW MOVE RIGHT [-directional] */ +static void cmd_window_move_right(const char *data) { - int refnum; + GHashTable *optlist; + void *free_arg; - refnum = window_refnum_right(active_win->refnum, TRUE); - if (refnum != -1) - window_set_refnum(active_win, refnum); + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window move right", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_right(active_mainwin, FALSE); + if (rec == NULL) + rec = mainwindows_find_right(active_mainwin, TRUE); + if (rec != NULL) + window_reparent(active_win, rec); + } else { + int refnum; + + refnum = window_refnum_right(active_win->refnum, TRUE); + if (refnum != -1) + window_set_refnum(active_win, refnum); + } + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW MOVE DLEFT */ -static void cmd_window_move_dleft(void) +/* SYNTAX: WINDOW MOVE UP [-directional] */ +static void cmd_window_move_up(const char *data) { MAIN_WINDOW_REC *rec; + GHashTable *optlist; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window move up", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + rec = mainwindows_find_upper(active_mainwin); + } else { + rec = mainwindows_find_upper_left(active_mainwin); + } - rec = mainwindows_find_left(active_mainwin, FALSE); - if (rec == NULL) - rec = mainwindows_find_left(active_mainwin, TRUE); if (rec != NULL) window_reparent(active_win, rec); + + cmd_params_free(free_arg); } -/* SYNTAX: WINDOW MOVE DRIGHT */ -static void cmd_window_move_dright(void) +/* SYNTAX: WINDOW MOVE DOWN [-directional] */ +static void cmd_window_move_down(const char *data) { MAIN_WINDOW_REC *rec; + GHashTable *optlist; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS, + "window move down", &optlist)) + return; + + if (g_hash_table_lookup(optlist, "directional") != NULL) { + rec = mainwindows_find_lower(active_mainwin); + } else { + rec = mainwindows_find_lower_right(active_mainwin); + } - rec = mainwindows_find_right(active_mainwin, FALSE); - if (rec == NULL) - rec = mainwindows_find_right(active_mainwin, TRUE); if (rec != NULL) window_reparent(active_win, rec); -} -/* SYNTAX: WINDOW MOVE UP */ -static void cmd_window_move_up(void) -{ - MAIN_WINDOW_REC *rec; - - rec = mainwindows_find_upper_left(active_mainwin); - if (rec != NULL) - window_reparent(active_win, rec); -} - -/* SYNTAX: WINDOW MOVE DOWN */ -static void cmd_window_move_down(void) -{ - MAIN_WINDOW_REC *rec; - - rec = mainwindows_find_lower_right(active_mainwin); - if (rec != NULL) - window_reparent(active_win, rec); + cmd_params_free(free_arg); } static void windows_print_sticky(WINDOW_REC *win) @@ -1866,23 +1957,26 @@ void mainwindows_init(void) command_bind("window down", NULL, (SIGNAL_FUNC) cmd_window_down); command_bind("window left", NULL, (SIGNAL_FUNC) cmd_window_left); command_bind("window right", NULL, (SIGNAL_FUNC) cmd_window_right); - command_bind("window dup", NULL, (SIGNAL_FUNC) cmd_window_dup); - command_bind("window ddown", NULL, (SIGNAL_FUNC) cmd_window_ddown); - command_bind("window dleft", NULL, (SIGNAL_FUNC) cmd_window_dleft); - command_bind("window dright", NULL, (SIGNAL_FUNC) cmd_window_dright); command_bind("window stick", NULL, (SIGNAL_FUNC) cmd_window_stick); command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left); command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right); command_bind("window move up", NULL, (SIGNAL_FUNC) cmd_window_move_up); command_bind("window move down", NULL, (SIGNAL_FUNC) cmd_window_move_down); - command_bind("window move dleft", NULL, (SIGNAL_FUNC) cmd_window_move_dleft); - command_bind("window move dright", NULL, (SIGNAL_FUNC) cmd_window_move_dright); - command_bind("window rgrow", NULL, (SIGNAL_FUNC) cmd_window_rgrow); - command_bind("window rshrink", NULL, (SIGNAL_FUNC) cmd_window_rshrink); - command_bind("window rsize", NULL, (SIGNAL_FUNC) cmd_window_rsize); - command_bind("window rbalance", NULL, (SIGNAL_FUNC) cmd_window_rbalance); - command_bind("window rshow", NULL, (SIGNAL_FUNC) cmd_window_rshow); signal_add("window print info", (SIGNAL_FUNC) sig_window_print_info); + + command_set_options("window show", "right"); + command_set_options("window grow", "right"); + command_set_options("window shrink", "right"); + command_set_options("window size", "right"); + command_set_options("window balance", "right"); + command_set_options("window up", "directional"); + command_set_options("window down", "directional"); + command_set_options("window left", "directional"); + command_set_options("window right", "directional"); + command_set_options("window move left", "directional"); + command_set_options("window move right", "directional"); + command_set_options("window move up", "directional"); + command_set_options("window move down", "directional"); } void mainwindows_deinit(void) @@ -1901,21 +1995,10 @@ void mainwindows_deinit(void) command_unbind("window down", (SIGNAL_FUNC) cmd_window_down); command_unbind("window left", (SIGNAL_FUNC) cmd_window_left); command_unbind("window right", (SIGNAL_FUNC) cmd_window_right); - command_unbind("window dup", (SIGNAL_FUNC) cmd_window_dup); - command_unbind("window ddown", (SIGNAL_FUNC) cmd_window_ddown); - command_unbind("window dleft", (SIGNAL_FUNC) cmd_window_dleft); - command_unbind("window dright", (SIGNAL_FUNC) cmd_window_dright); command_unbind("window stick", (SIGNAL_FUNC) cmd_window_stick); command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left); command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right); command_unbind("window move up", (SIGNAL_FUNC) cmd_window_move_up); command_unbind("window move down", (SIGNAL_FUNC) cmd_window_move_down); - command_unbind("window move dleft", (SIGNAL_FUNC) cmd_window_move_dleft); - command_unbind("window move dright", (SIGNAL_FUNC) cmd_window_move_dright); - command_unbind("window rgrow", (SIGNAL_FUNC) cmd_window_rgrow); - command_unbind("window rshrink", (SIGNAL_FUNC) cmd_window_rshrink); - command_unbind("window rsize", (SIGNAL_FUNC) cmd_window_rsize); - command_unbind("window rbalance", (SIGNAL_FUNC) cmd_window_rbalance); - command_unbind("window rshow", (SIGNAL_FUNC) cmd_window_rshow); signal_remove("window print info", (SIGNAL_FUNC) sig_window_print_info); } From 3af2ce8731b721616c5c112434a810bca32a62e1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 15 Jan 2019 21:00:43 +0100 Subject: [PATCH 0485/1198] add activity_hide_visible setting --- src/fe-text/mainwindow-activity.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/fe-text/mainwindow-activity.c b/src/fe-text/mainwindow-activity.c index 3a084110..7f7a0528 100644 --- a/src/fe-text/mainwindow-activity.c +++ b/src/fe-text/mainwindow-activity.c @@ -20,6 +20,7 @@ #include "module.h" #include "signals.h" +#include "settings.h" #include "gui-windows.h" @@ -32,6 +33,9 @@ static void sig_activity(WINDOW_REC *window) if (!is_window_visible(window) || window->data_level == 0) return; + if (!settings_get_bool("activity_hide_visible")) + return; + window->data_level = 0; g_free_and_null(window->hilight_color); @@ -46,6 +50,7 @@ static void sig_activity(WINDOW_REC *window) void mainwindow_activity_init(void) { + settings_add_bool("lookandfeel", "activity_hide_visible", TRUE); signal_add_first("window hilight", (SIGNAL_FUNC) sig_activity); signal_add_first("window activity", (SIGNAL_FUNC) sig_activity); } From f9beedd2d03b7a622e9686c71910e380fab88511 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 22 Jan 2019 15:24:52 +0100 Subject: [PATCH 0486/1198] add more config checks and assertions --- src/fe-text/irssi.c | 5 +++++ src/fe-text/statusbar-config.c | 40 +++++++++++++++++++++++++++------- src/lib-config/get.c | 15 +++++++------ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 728f456e..c979e917 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -161,6 +161,7 @@ static void textui_init(void) static void textui_finish_init(void) { + int loglev; quitting = FALSE; term_refresh_freeze(); @@ -176,7 +177,10 @@ static void textui_finish_init(void) mainwindow_activity_init(); mainwindows_layout_init(); gui_windows_init(); + /* Temporarily raise the fatal level to abort on config errors. */ + loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL); statusbar_init(); + g_log_set_always_fatal(loglev); term_refresh_thaw(); settings_check(); @@ -319,6 +323,7 @@ int main(int argc, char **argv) you have to call setlocale(LC_ALL, "") */ setlocale(LC_ALL, ""); + /* Temporarily raise the fatal level to abort on config errors. */ loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL); textui_init(); diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 314befaa..38372725 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -150,6 +150,9 @@ static void statusbar_read(STATUSBAR_GROUP_REC *group, CONFIG_NODE *node) GSList *tmp; const char *visible_str; + g_return_if_fail(is_node_list(node)); + g_return_if_fail(node->key != NULL); + bar = statusbar_config_find(group, node->key); if (config_node_get_bool(node, "disabled", FALSE)) { /* disabled, destroy it if it already exists */ @@ -191,10 +194,26 @@ static void statusbar_read(STATUSBAR_GROUP_REC *group, CONFIG_NODE *node) } } +#define skip_corrupt_config(parent, node, index, format, ...) \ + if ((node)->type != NODE_TYPE_BLOCK) { \ + if ((node)->key == NULL) { \ + g_critical("Expected %s node at `.." format "/%s[%d]' was of %s type. Corrupt config?", \ + "block", ##__VA_ARGS__, (parent)->key, (index), \ + (node)->type == NODE_TYPE_LIST ? "list" : "scalar"); \ + } else { \ + g_critical("Expected %s node at `.." format "/%s/%s' was of %s type. Corrupt config?", \ + "block", ##__VA_ARGS__, (parent)->key, (node)->key, \ + (node)->type == NODE_TYPE_LIST ? "list" : "scalar"); \ + } \ + continue; \ + } \ + + static void statusbar_read_group(CONFIG_NODE *node) { STATUSBAR_GROUP_REC *group; GSList *tmp; + int i; g_return_if_fail(is_node_list(node)); @@ -205,9 +224,11 @@ static void statusbar_read_group(CONFIG_NODE *node) active_statusbar_group = group; } - tmp = config_node_first(node->value); - for (; tmp != NULL; tmp = config_node_next(tmp)) - statusbar_read(group, tmp->data); + for (tmp = config_node_first(node->value), i = 0; tmp != NULL; tmp = config_node_next(tmp), i++) { + CONFIG_NODE *value = tmp->data; + skip_corrupt_config(node, value, i, "statusbar"); + statusbar_read(group, value); + } } static void create_root_statusbars(void) @@ -228,17 +249,20 @@ static void create_root_statusbars(void) static void read_statusbar_config_from_node(CONFIG_NODE *node) { - CONFIG_NODE *items; + CONFIG_NODE *items, *group; GSList *tmp; + int i; items = iconfig_node_section(node, "items", -1); if (items != NULL) statusbar_read_items(items); - tmp = config_node_first(node->value); - for (; tmp != NULL; tmp = config_node_next(tmp)) { - if (tmp->data != items) - statusbar_read_group(tmp->data); + for (tmp = config_node_first(node->value), i = 0; tmp != NULL; tmp = config_node_next(tmp), i++) { + group = tmp->data; + if (group != items) { + skip_corrupt_config(node, group, i, ""); + statusbar_read_group(group); + } } } diff --git a/src/lib-config/get.c b/src/lib-config/get.c index a83686fd..ac0d0d23 100644 --- a/src/lib-config/get.c +++ b/src/lib-config/get.c @@ -62,20 +62,21 @@ CONFIG_NODE *config_node_section_index(CONFIG_REC *rec, CONFIG_NODE *parent, con parent->value = g_slist_insert(parent->value, node, index); } if (!is_node_list(node)) { - int show_error = 0; + int error = 0; if (new_type != -1) { config_node_remove(rec, parent, node); node = NULL; - show_error = 1; + error = 1; } else if (!g_hash_table_lookup_extended(rec->cache_nodes, node, NULL, NULL)) { g_hash_table_insert(rec->cache_nodes, node, NULL); - show_error = 1; + error = 1; } - if (show_error) - g_critical("Expected %s node at `..%s/%s' was of scalar type. Corrupt config?", - new_type == NODE_TYPE_LIST ? "list" : new_type == NODE_TYPE_BLOCK ? "block" : "section", - parent->key, key); + if (error) + g_critical("Expected %s node at `%s%s/%s' was of scalar type. Corrupt config?", + new_type == NODE_TYPE_LIST ? "list" : new_type == NODE_TYPE_BLOCK ? "block" : "section", + parent == rec->mainnode ? "" : "..", + parent->key == NULL ? "" : parent->key, key); } else { g_return_val_if_fail(new_type == -1 || new_type == node->type, NULL); return node; From 9f9aada83bc3baabdfe70befb78eaf02544a0c7b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 29 Jan 2019 21:33:39 +0100 Subject: [PATCH 0487/1198] do not touch uninitialised protocols on item restore --- src/fe-common/core/windows-layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/windows-layout.c b/src/fe-common/core/windows-layout.c index ce6b9910..77eb26f1 100644 --- a/src/fe-common/core/windows-layout.c +++ b/src/fe-common/core/windows-layout.c @@ -70,7 +70,7 @@ static void sig_layout_restore_item(WINDOW_REC *window, const char *type, restore_win = window; protocol = chat_protocol_find(chat_type); - if (protocol == NULL) + if (protocol == NULL || protocol->not_initialized) window_bind_add(window, tag, name); else if (protocol->query_create != NULL) protocol->query_create(tag, name, TRUE); From b1d6cb7f26c521d3d5f9e7da214bc91b89453a93 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 1 Feb 2019 13:18:50 +0100 Subject: [PATCH 0488/1198] add missing NULL check --- src/fe-common/core/fe-common-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index dc3a6f6d..d6dbf1f7 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -481,7 +481,7 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) g_return_val_if_fail(dest != NULL, FALSE); g_return_val_if_fail(dest->window != NULL, FALSE); - if (dest->target == NULL) + if (dest->target == NULL && dest->window->name != NULL) return strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; item = window_item_find_window(dest->window, dest->server, dest->target); From 5b530737d480eaac5943bcf270aa82b592e7ed3b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 2 Feb 2019 14:51:09 +0100 Subject: [PATCH 0489/1198] correct fix for #997 --- src/fe-common/core/fe-common-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index d6dbf1f7..15d08771 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -481,8 +481,9 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) g_return_val_if_fail(dest != NULL, FALSE); g_return_val_if_fail(dest->window != NULL, FALSE); - if (dest->target == NULL && dest->window->name != NULL) - return strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; + if (dest->target == NULL) + return dest->window->name != NULL && + strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; item = window_item_find_window(dest->window, dest->server, dest->target); if (item == NULL) { From 034752ade3b9d951c716d50d3f4d1e40fe9e110c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 4 Feb 2019 14:33:41 +0100 Subject: [PATCH 0490/1198] fix gui_input_get_extent it was causing a free of data with [transfer=none] --- src/perl/textui/TextUI.xs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index 9f4fd0b0..af978162 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -158,15 +158,13 @@ gui_input_clear_extents(pos, len = 0) CODE: gui_entry_clear_extents(active_entry, pos, len); -void +char * gui_input_get_extent(pos) int pos -PREINIT: - char *ret; -PPCODE: - ret = gui_entry_get_extent(active_entry, pos); - XPUSHs(sv_2mortal(new_pv(ret))); - g_free(ret); +CODE: + RETVAL = gui_entry_get_extent(active_entry, pos); +OUTPUT: + RETVAL void gui_input_get_text_and_extents() From 346211eeeb34e73a931b822f1496f696ed3970f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Sat, 9 Feb 2019 22:42:13 +0100 Subject: [PATCH 0491/1198] Use memcpy() instead of strncpy() to silence the compiler warning. --- src/otr/otr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/otr/otr.c b/src/otr/otr.c index 765bc048..9f0192e1 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -621,8 +621,10 @@ static enum otr_msg_status enqueue_otr_fragment(const char *msg, struct otr_peer opc->msg_size += msg_len + 1; } - /* Copy msg to full message since we already have a part pending. */ - strncpy(opc->full_msg + opc->msg_len, msg, msg_len); + /* Copy msg to full message since we already have a part pending. Note + * that we do not copy `msg`'s trailing nul byte because we explicit + * set opc->full_msg[opc->msg_len] to nul afterwards. */ + memcpy(opc->full_msg + opc->msg_len, msg, msg_len); opc->msg_len += msg_len; opc->full_msg[opc->msg_len] = '\0'; @@ -664,7 +666,7 @@ static enum otr_msg_status enqueue_otr_fragment(const char *msg, struct otr_peer return ret; } /* Copy full message with NULL terminated byte. */ - strncpy(opc->full_msg, msg, msg_len); + memcpy(opc->full_msg, msg, msg_len); opc->msg_len += msg_len; opc->msg_size += ((msg_len * 2) + 1); opc->full_msg[opc->msg_len] = '\0'; From 8543b874a25d0caa2c62db155346a24cdf3c2afa Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 30 Jan 2019 11:17:36 +0100 Subject: [PATCH 0492/1198] store type of window binds --- src/common.h | 2 +- src/fe-common/core/fe-windows.h | 1 + src/fe-common/core/windows-layout.c | 9 +++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/common.h b/src/common.h index 14bfe42b..192e087d 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 19 +#define IRSSI_ABI_VERSION 20 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index aaa773c8..061a999a 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -22,6 +22,7 @@ enum { typedef struct { char *servertag; char *name; + int type; unsigned int sticky:1; } WINDOW_BIND_REC; diff --git a/src/fe-common/core/windows-layout.c b/src/fe-common/core/windows-layout.c index 77eb26f1..5aa60916 100644 --- a/src/fe-common/core/windows-layout.c +++ b/src/fe-common/core/windows-layout.c @@ -70,11 +70,12 @@ static void sig_layout_restore_item(WINDOW_REC *window, const char *type, restore_win = window; protocol = chat_protocol_find(chat_type); - if (protocol == NULL || protocol->not_initialized) - window_bind_add(window, tag, name); - else if (protocol->query_create != NULL) + if (protocol == NULL || protocol->not_initialized) { + WINDOW_BIND_REC *rec = window_bind_add(window, tag, name); + rec->type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); + } else if (protocol->query_create != NULL) { protocol->query_create(tag, name, TRUE); - else { + } else { QUERY_REC *query; query = g_new0(QUERY_REC, 1); From 48a6d04aded516a8eead31b1e78544efb3b7e367 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 11 Feb 2019 18:04:46 +0100 Subject: [PATCH 0493/1198] run syncdocs.sh --- docs/design.txt | 231 +++++++++++++++++++++++------------------------- 1 file changed, 110 insertions(+), 121 deletions(-) diff --git a/docs/design.txt b/docs/design.txt index 3f372829..6888f211 100644 --- a/docs/design.txt +++ b/docs/design.txt @@ -1,150 +1,139 @@ +Design - Irssi's hierarchy is something like this: +Irssi’s hierarchy is something like this: + + sub1 sub2 + \ / + xxx IRC COMMON ICQ yyy + | | | | | + '----+-----:-----+----+----' + | + GUI (gtk/gnome, qt/kde, text, none) + | + sub1 sub2 | + \ / | + xxx IRC | COMMON ICQ yyy + '----+-----+-----+----+----' + | + COMMON UI + | + sub1 sub2 | + \ / | + xxx IRC | ICQ yyy + | | | | | + '----+-----+-----+----' + | + CORE + / + lib-config - sub1 sub2 - \ / - xxx IRC COMMON ICQ yyy - |____|___________|____|____| - | - GUI (gtk/gnome, qt/kde, text, none) - | - sub1 sub2 | - \ / | - xxx IRC | COMMON ICQ yyy - |____|_____|_____|____|____| - | - COMMON UI - | - sub1 sub2 | - \ / | - xxx IRC | ICQ yyy - |____|_____|_____|____| - | - CORE - / - lib-config +(IRC, ICQ, xxx and yyy are chat protocols ..) +(sub1 and sub2 are submodules of IRC module, like DCC and flood protect) - (IRC, ICQ, xxx and yyy are chat protocols ..) - (sub1 and sub2 are submodules of IRC module, like DCC and flood protect) +Chat protocols and frontends are kept in separate modules. Common UI and GUI +modules also have the common parts which don’t know anything about the chat +protocols. This should allow implementing modules to whatever chat protocols +and with whatever frontends easily. +Signals - Chat protocols and frontends are kept in separate modules. Common UI - and GUI modules also have the common parts which don't know anything - about the chat protocols. This should allow implementing modules to - whatever chat protocols and with whatever frontends easily. +Communication between different modules are done with “signals”. They are not +related to UNIX signals in any way, you could more like think of them as +“events” - which might be a better name for them, but I don’t really want to +change it anymore :) - ** Signals +So, you send signal with signal_emit() and it’s sent to all modules that have +grabbed it by calling signal_add() in their init function. For example: - Communication between different modules are done with "signals". They are - not related to UNIX signals in any way, you could more like think of them - as "events" - which might be a better name for them, but I don't really - want to change it anymore :) +signal_emit("mysignal", 1, "hello"); - So, you send signal with signal_emit() and it's sent to all modules that - have grabbed it by calling signal_add() in their init function. For - example: +Sends a “mysignal” function with one argument “hello” - before that, you should +have grabbed the signal somewhere else with: - signal_emit("mysignal", 1, "hello"); +static void sig_mysignal(const char *arg1) +{ + /* arg1 contains "hello" */ +} - Sends a "mysignal" function with one argument "hello" - before that, you - should have grabbed the signal somewhere else with: +signal_add("mysignal", (SIGNAL_FUNC) sig_mysignal); - static void sig_mysignal(const char *arg1) - { - /* arg1 contains "hello" */ - } +There are three different signal_add() functions which you can use to specify +if you want to grab the signal first, “normally” or last. You can also stop the +signal from going any further. - signal_add("mysignal", (SIGNAL_FUNC) sig_mysignal); +Emitting signal with it’s name creates a small overhead since it has to look up +the signal’s numeric ID first, after which it looks up the signal structure. +This is done because if you call a signal really often, it’s faster to find it +with it’s numeric ID instead of the string. You can use signal_get_uniq_id() +macro to convert the signal name into ID - you’ll have to do this only once! - +and use signal_emit_id() to emit the signal. Don’t bother to do this unless +your signal is sent (or could be sent) several times in a second. - There are three different signal_add() functions which you can use to - specify if you want to grab the signal first, "normally" or last. You can - also stop the signal from going any further. +See src/core/signals.h for definition of the signal function, and signals.txt +for a list of signals. - Emitting signal with it's name creates a small overhead since it has to - look up the signal's numeric ID first, after which it looks up the signal - structure. This is done because if you call a signal _really_ often, - it's faster to find it with it's numeric ID instead of the string. You - can use signal_get_uniq_id() macro to convert the signal name into ID - - you'll have to do this only once! - and use signal_emit_id() to emit the - signal. Don't bother to do this unless your signal is sent (or could be - sent) several times in a second. +lib-config - See src/core/signals.h for definition of the signal function, and - signals.txt for a list of signals. +Irssi depends on this for reading and saving configuration. (created by me for +irssi) +CORE module - ** lib-config +Provides some functionality that all other modules can use: - Irssi depends on this for reading and saving configuration. - (created by me for irssi) + • signal handling + • keeping list of settings + • keeping list of /commands + • keeping track of loaded modules + • networking functions (with nonblocking connects, IPv6 support) + • handles connecting to servers + • raw logging of server’s input/output data + • /EVAL support + • fgets() like function line_split() without any maximum line limits + • command line parameter handling + • miscellaneous useful little functions + • handles logging +COMMON UI module - ** CORE module + • knows basics about windows and window items (=channels, queries, ..) + • printtext() - parsing texts and feeding it for GUI to print. + • themes + • translation tables + • text hilighting + • command history + • user interface (/commands) for CORE’s functionality - Provides some functionality that all other modules can use: - - signal handling - - keeping list of settings - - keeping list of /commands - - keeping track of loaded modules - - networking functions (with nonblocking connects, IPv6 support) - - handles connecting to servers - - raw logging of server's input/output data - - /EVAL support - - fgets() like function line_split() without any maximum line limits - - command line parameter handling - - miscellaneous useful little functions - - handles logging +GUI modules + • all the rest of the functionality needed for a working client. - ** COMMON UI module +IRC module - - knows basics about windows and window items (=channels, queries, ..) - - printtext() - parsing texts and feeding it for GUI to print. - - themes - - translation tables - - text hilighting - - command history - - user interface (/commands) for CORE's functionality + • CORE + □ IRC specific /commands + □ flood protecting commands sent to server + □ creating IRC masks based on nick/address for bans, ignores, etc. + □ keeps list of channels, nicks, channel modes, bans, etc. + □ keeps list of servers, server settings, irc networks, server + reconnections and irc network splits + □ redirection of commands’ replies + □ lag detection + □ ctcp support and flood protection + □ Handles ignoring people + • DCC + □ DCC chat, send and get + • FLOOD + □ detects private or channel flooding and sends “flood” signal + □ automatic ignoring when flooding + • NOTIFYLIST + □ handles notifylist +IRC UI module - ** GUI modules + • placing channels and queries in windows + • nick completion + • printing infomation of some events - - all the rest of the functionality needed for a working client. - - - ** IRC module - - * CORE - - - IRC specific /commands - - flood protecting commands sent to server - - creating IRC masks based on nick/address for bans, ignores, etc. - - keeps list of channels, nicks, channel modes, bans, etc. - - keeps list of servers, server settings, irc networks, - server reconnections and irc network splits - - redirection of commands' replies - - lag detection - - ctcp support and flood protection - - Handles ignoring people - - * DCC - - - DCC chat, send and get - - * FLOOD - - - detects private or channel flooding and sends "flood" signal - - automatic ignoring when flooding - - * NOTIFYLIST - - - handles notifylist - - - ** IRC UI module - - - placing channels and queries in windows - - nick completion - - printing infomation of some events From 22fdb94d1b961545e8e35930512b63cf1ff83e2d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 11 Feb 2019 18:04:59 +0100 Subject: [PATCH 0494/1198] run syncscripts.sh --- scripts/dns.pl | 65 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/scripts/dns.pl b/scripts/dns.pl index 989cdc3e..9e9f4789 100644 --- a/scripts/dns.pl +++ b/scripts/dns.pl @@ -1,16 +1,18 @@ # /DNS || ... -# version 2.1.1 -# -# updated the script to fix a bug where the script would let -# a trailing whitespace go through (ex: tab completion) -# - inch +# +# v2.2 +# add ipv6 support +# v2.1.1 +# updated the script to fix a bug where the script would let +# a trailing whitespace go through (ex: tab completion) +# - inch use strict; use Socket; use POSIX; use vars qw($VERSION %IRSSI); -$VERSION = "2.1.1"; +$VERSION = "2.2"; %IRSSI = ( authors => "Timo \'cras\' Sirainen", contact => "tss\@iki.fi", @@ -18,7 +20,7 @@ $VERSION = "2.1.1"; description => "/DNS || ...", license => "Public Domain", url => "http://irssi.org/", - changed => "2002-03-04T22:47+0100" + changed => "2019-01-24" ); my (%resolve_hosts, %resolve_nicks, %resolve_print); # resolve queues @@ -102,6 +104,42 @@ sub sig_userhost { host_lookup() if (!$lookup_waiting); } +sub dns { + my ($host) =@_; + my %hints = (socktype => SOCK_STREAM); + my ($err, @res) = Socket::getaddrinfo($host, "http", \%hints); + my @res1; + if ($err ==0 ) { + foreach(@res) { + if ($_->{family}==AF_INET) { + my ($proto,$ip)=unpack_sockaddr_in($_->{addr}); + push @res1, Socket::inet_ntop(AF_INET,$ip); + } + if ($_->{family}==AF_INET6) { + my ($proto,$ip)=unpack_sockaddr_in6($_->{addr}); + push @res1, Socket::inet_ntop(AF_INET6,$ip); + } + } + return join(' ',@res1); + } +} + +sub rdns { + my ($host) =@_; + my %hints = (socktype => SOCK_STREAM); + my ($err, @res) = Socket::getaddrinfo($host, "http", \%hints); + my @res1; + if ($err ==0 ) { + foreach(@res) { + my ($err, $hostname, $servicename) = Socket::getnameinfo $_->{addr}; + if ($err ==0) { + push @res1, $hostname; + } + } + return join(' ',@res1); + } +} + sub host_lookup { return if (!%resolve_hosts); @@ -145,16 +183,13 @@ sub host_lookup { eval { # child, do the lookup my $name = ""; - if ($host =~ /^[0-9\.]*$/) { + if ($host =~ /^[0-9\.]*$/ || $host =~ m/^[0-9a-f:]*$/) { # ip -> host - $name = gethostbyaddr(inet_aton($host), AF_INET); + #$name = gethostbyaddr(inet_aton($host), AF_INET); + $name = rdns($host); } else { # host -> ip - my @addrs = gethostbyname($host); - if (@addrs) { - @addrs = map { inet_ntoa($_) } @addrs[4 .. $#addrs]; - $name = join (" ", @addrs); - } + $name = dns($host); } $print_name = $input_query if !$print_name; @@ -197,3 +232,5 @@ Irssi::command_bind('dns', 'cmd_dns'); Irssi::signal_add( { 'redir dns failure' => \&sig_failure, 'redir dns host' => \&sig_userhost } ); + +# vim:set sw=2 ts=8: From bd2ff8c99c41f35430a945e888db828a9925dce7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 11 Feb 2019 18:05:57 +0100 Subject: [PATCH 0495/1198] tag as 1.2.0 --- NEWS | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 2 +- 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 9da96be3..1c109748 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,86 @@ -v1.2-head 2019-xx-xx The Irssi team +v1.2.0 2019-02-11 The Irssi team + ! Contains all changes from 1.1.2 + * Improved the /STATUSBAR commands (#858) + * /SET no longer shows `=' between setting and value (#886) + * /CUBES removed from default config (available as script) + (#956) + * /1 /2 /3 ... removed from default config (available as new + setting window_number_commands) (#958) + * Always redraw the screen on resize. By David Phillips (#896) + * Private notices intended for channels are now displayed on + the channel (new setting notice_channel_context) (#959) + + Imported the "Off-the-record" module into Irssi tree (#854, + #589, #196) + + Initial support for sideways split windows (#697, #431, + #224, #807, FS#310, #947, #955, #989) + + Change the implementation of `wcwidth'. This is used to + calculate the width of emojis on your terminal screen (#917, + #720) + + Make the wcwidth functions available from Perl (#973): + string_width(str) + string_chars_for_width(str, width) + wcwidth(char) + + Added completion_keep_word setting (#979) + + Allow activity_hide_targets to hide activity in itemless + windows (#967, #997, #1001, #1003) + + Added activity_hide_visible setting (#990) + + Allow hiding of lines through the /IGNORE system (#901, + #900, #892, #890, #884, #937) + + Add window_default_hidelevel setting. By Doug Freed (#941) + + Add activity_hide_window_hidelevel setting, defaulting to ON + (#938) + + Add autolog_only_saved_channels setting, to autolog only + channels that are in the config (#968) + + Add format support for the input line. By Ben Paxton, + originally by Jonas Hurrelmann (#764, FS#621, #1004) + use Irssi::TextUI; + gui_input_set_extent(pos, text) + gui_input_set_extents(pos, len, left, right) + gui_input_clear_extents(pos, len) + gui_input_get_extent(pos) + gui_input_get_text_and_extents() + gui_input_set_text_and_extents(...) + + Parsing of IRCv3 CAP 3.2 (#775, #869) + + Show CAP-related events in the user interface (#918, #916, + #870, #704) + + Continue using separators when addressing multiple nicks + with tab completion. By Manish Goregaokar (#822) + + Bind Shift-tab by default. By Niklas Luokkala (#830, #829) + + Fuzzing more things (#913, #780, #813) + - Disconnect SASL properly in case the SASL module got + unloaded from server (#931, #629, #618, #616) + - Fix backward completion jumping to the first instead of last + word (#979) + - Improve empty topic handling (#961, #905, #911, #897, #888) + - Prevent config truncation when no space left. By dequis and + Lukas Waymann (#922, #925, #910, #909, #906, #871, #817) + - Also time-out servers in lookup phase (#866, #130) + - Fix build with LibreSSL 2.7. By Dorian Harmans (#865) + - Fix a crash when appending to a textbuffer without + line. Reported by Jari Matilainen (#862) + - Fix segfault on sending large messages (#803, #796, #802) + - Fix segfault on invalid statusbar config (#993, #994) + - Fix random memory writes on restoring queries of foreign + protocols (#999, #1000) + - Make default keybinds deletable (#859, #507) + - Fix freeze when resizing Irssi very small (#946) + - Compare channels case-insensitively, avoiding confusions + with the config file (#857, #856) + - Fix DCC GET on Android. By Martin Staron (#844) + - Improve rawlog performance (#957) + - Fix nick escaping erroneously escaping quotes (#978, #974, + #709) + - Protect against theme recursion, improve padding + performance, limit alignment padding. Credit to Oss-Fuzz + (#835, #851, #850, #846, #848) + - Fix recursive loop in replaces (#833, GL#23) + - Fix headers for compilation of C modules (#939) + - Documentation. By Zero King (#814). (#852) + - Sync NEWS, docs, scripts (#849, #855) + - Build system (#868, #867, #985, #988) + - Fix build on IBM i and AIX. By Calvin Buckley (#975) + - Misc fixes (#840, #839, #843, #953, #962). Tests (#806, + #875, #905, #964, #1011). Fuzzing (#929). v1.1.2 2019-01-09 The Irssi team - Fix the resetting of window hiddenlevel (#861) @@ -30,7 +112,7 @@ v1.0.7 2018-02-15 The Irssi team - Prevent use after free error during the execution of some commands. Found by Joseph Bisch (GL#17, GL!24). - Revert netsplit print optimisation due to crashes (#465, #809, - #812, #819, #824). + #812, #819, #824, #832). - Fix use after free when SASL messages are received in unexpected order (GL#26, GL!33). - Fix null pointer dereference in the tab completion when an diff --git a/configure.ac b/configure.ac index 50c5520f..1c48a6cb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.2-head) +AC_INIT(irssi, 1.2.0) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 63cc937e67214b1f793bc794a7d6fd9721ae2085 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 11 Feb 2019 21:40:09 +0100 Subject: [PATCH 0496/1198] continue head --- NEWS | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1c109748..7c11b0f7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +v1.3-head 2019-xx-xx The Irssi team + v1.2.0 2019-02-11 The Irssi team ! Contains all changes from 1.1.2 * Improved the /STATUSBAR commands (#858) diff --git a/configure.ac b/configure.ac index 1c48a6cb..e8290dfd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.2.0) +AC_INIT(irssi, 1.3-head) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) From 3664484bef20ba841c667ae6137678d5cdffa58c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 12 Feb 2019 13:28:05 +0100 Subject: [PATCH 0497/1198] do not stop autolog_ignore_targets from matching itemless targets --- src/fe-common/core/fe-common-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 15d08771..e47eb446 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -486,9 +486,6 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) strarray_find(array, dest->window->name) != -1 ? TRUE : FALSE; item = window_item_find_window(dest->window, dest->server, dest->target); - if (item == NULL) { - return FALSE; - } server_tag_len = dest->server_tag != NULL ? strlen(dest->server_tag) : 0; for (tmp = array; *tmp != NULL; tmp++) { @@ -507,11 +504,11 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) return TRUE; } else if (g_ascii_strcasecmp(str, dest->target) == 0) { return TRUE; - } else if (item->type == query_type && + } else if (item != NULL && item->type == query_type && g_strcmp0(str, dest->target[0] == '=' ? "::dccqueries" : "::queries") == 0) { return TRUE; - } else if (item->type == channel_type && + } else if (item != NULL && item->type == channel_type && g_strcmp0(str, "::channels") == 0) { return TRUE; } From c1b604ee6a810d8ac5959b4681c0f6da0f14fde3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 12 Feb 2019 13:49:50 +0100 Subject: [PATCH 0498/1198] add issue reference --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7c11b0f7..97cb7dbf 100644 --- a/NEWS +++ b/NEWS @@ -12,7 +12,7 @@ v1.2.0 2019-02-11 The Irssi team * Private notices intended for channels are now displayed on the channel (new setting notice_channel_context) (#959) + Imported the "Off-the-record" module into Irssi tree (#854, - #589, #196) + #589, #196, #881) + Initial support for sideways split windows (#697, #431, #224, #807, FS#310, #947, #955, #989) + Change the implementation of `wcwidth'. This is used to From 80fe52cb593b1993b25ec5c197555594d5938692 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 13 Feb 2019 13:56:03 +0100 Subject: [PATCH 0499/1198] fix test on Big Endian 64bit, due to pointer size mismatch --- tests/fe-text/test-paste-join-multiline.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/fe-text/test-paste-join-multiline.c b/tests/fe-text/test-paste-join-multiline.c index 778e19e9..8a81a9fb 100644 --- a/tests/fe-text/test-paste-join-multiline.c +++ b/tests/fe-text/test-paste-join-multiline.c @@ -54,7 +54,12 @@ static void test_paste_join_multiline(const paste_join_multiline_test_case *test g_test_message("INPUT: \"%s\"", (t1 = g_strescape(test->input, NULL))); g_free(t1); - buffer->data = (char *) g_utf8_to_ucs4_fast(test->input, -1, (glong *) &buffer->len); + { + glong buf_len; + buffer->data = (char *) g_utf8_to_ucs4_fast(test->input, -1, &buf_len); + buffer->len = buf_len; + } + paste_buffer_join_lines(buffer); resultstr = g_ucs4_to_utf8((unichar *) buffer->data, buffer->len, NULL, NULL, NULL); From e793d7af9fd45f4e97736c3681d5ba520ce232d5 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 18 Feb 2019 10:47:08 -0800 Subject: [PATCH 0500/1198] Fix indentation --- src/core/net-nonblock.c | 8 ++++---- src/core/net-nonblock.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 94c53e74..40e14605 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -63,7 +63,7 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, /* child */ srand(time(NULL)); - memset(&rec, 0, sizeof(rec)); + memset(&rec, 0, sizeof(rec)); rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6); if (rec.error == 0) { errorstr = NULL; @@ -79,7 +79,7 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; } - g_io_channel_write_block(pipe, &rec, sizeof(rec)); + g_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.errlen != 0) g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); else { @@ -129,7 +129,7 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) /* read error string, if we can't read everything for some reason, just ignore it. */ rec->errorstr = g_malloc0(rec->errlen+1); - g_io_channel_read_block(pipe, rec->errorstr, rec->errlen); + g_io_channel_read_block(pipe, rec->errorstr, rec->errlen); } else { if (rec->host4) { g_io_channel_read_block(pipe, &len, sizeof(int)); @@ -170,7 +170,7 @@ static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle) if (net_geterror(handle) != 0) { /* failed */ g_io_channel_shutdown(handle, TRUE, NULL); - g_io_channel_unref(handle); + g_io_channel_unref(handle); handle = NULL; } diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index af5968c8..10caa4d4 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -13,7 +13,7 @@ typedef struct { } RESOLVED_IP_REC; typedef struct { - int namelen; + int namelen; char *name; int error; From 2db359fbb35b93f079ee695251421efc87951a40 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 18 Feb 2019 10:52:06 -0800 Subject: [PATCH 0501/1198] Recognise non-zero as error rather than only -1 The error flag can be something other than -1 in the event of an error. Not checking for this could lead to us to try connecting to an unknown IP. --- src/core/net-nonblock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 40e14605..64ff9c0f 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -197,8 +197,7 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) g_io_channel_unref(rec->pipes[1]); ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6; - handle = iprec.error == -1 ? NULL : - net_connect_ip(ip, rec->port, rec->my_ip); + handle = iprec.error ? NULL : net_connect_ip(ip, rec->port, rec->my_ip); g_free_not_null(rec->my_ip); From c25d24220fdf2763385ea6bf81458522ac5775f3 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Mon, 18 Feb 2019 11:39:45 -0800 Subject: [PATCH 0502/1198] Remove unused functions --- src/core/net-nonblock.c | 102 ---------------------------------------- src/core/net-nonblock.h | 17 ------- src/core/server-rec.h | 2 +- src/irc/dcc/dcc-chat.c | 2 +- 4 files changed, 2 insertions(+), 121 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 64ff9c0f..2aca616b 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -25,16 +25,6 @@ #include "pidwait.h" #include "net-nonblock.h" -typedef struct { - NET_CALLBACK func; - void *data; - - GIOChannel *pipes[2]; - int port; - IPADDR *my_ip; - int tag; -} SIMPLE_THREAD_REC; - /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, @@ -146,13 +136,6 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) return 0; } -/* Get host name, call func when finished */ -int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data) -{ - /* FIXME: not implemented */ - return FALSE; -} - /* Kill the resolver child */ void net_disconnect_nonblock(int pid) { @@ -160,88 +143,3 @@ void net_disconnect_nonblock(int pid) kill(pid, SIGKILL); } - -static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle) -{ - g_return_if_fail(rec != NULL); - - g_source_remove(rec->tag); - - if (net_geterror(handle) != 0) { - /* failed */ - g_io_channel_shutdown(handle, TRUE, NULL); - g_io_channel_unref(handle); - handle = NULL; - } - - rec->func(handle, rec->data); - g_free(rec); -} - -static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) -{ - RESOLVED_IP_REC iprec; - GIOChannel *handle; - IPADDR *ip; - - g_return_if_fail(rec != NULL); - - g_source_remove(rec->tag); - - net_gethostbyname_return(pipe, &iprec); - g_free_not_null(iprec.errorstr); - - g_io_channel_shutdown(rec->pipes[0], TRUE, NULL); - g_io_channel_unref(rec->pipes[0]); - g_io_channel_shutdown(rec->pipes[1], TRUE, NULL); - g_io_channel_unref(rec->pipes[1]); - - ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6; - handle = iprec.error ? NULL : net_connect_ip(ip, rec->port, rec->my_ip); - - g_free_not_null(rec->my_ip); - - if (handle == NULL) { - /* failed */ - rec->func(NULL, rec->data); - g_free(rec); - return; - } - - rec->tag = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, - (GInputFunction) simple_init, rec); -} - -/* Connect to server, call func when finished */ -int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, - NET_CALLBACK func, void *data) -{ - SIMPLE_THREAD_REC *rec; - int fd[2]; - - g_return_val_if_fail(server != NULL, FALSE); - g_return_val_if_fail(func != NULL, FALSE); - - if (pipe(fd) != 0) { - g_warning("net_connect_nonblock(): pipe() failed."); - return FALSE; - } - - rec = g_new0(SIMPLE_THREAD_REC, 1); - rec->port = port; - if (my_ip != NULL) { - rec->my_ip = g_malloc(sizeof(IPADDR)); - memcpy(rec->my_ip, my_ip, sizeof(IPADDR)); - } - rec->func = func; - rec->data = data; - rec->pipes[0] = g_io_channel_new(fd[0]); - rec->pipes[1] = g_io_channel_new(fd[1]); - - /* start nonblocking host name lookup */ - net_gethostbyname_nonblock(server, rec->pipes[1], 0); - rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ, - (GInputFunction) simple_readpipe, rec); - - return TRUE; -} diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 10caa4d4..853fcaa6 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -12,29 +12,12 @@ typedef struct { char *host4, *host6; /* dito */ } RESOLVED_IP_REC; -typedef struct { - int namelen; - char *name; - - int error; - int errlen; - char *errorstr; -} RESOLVED_NAME_REC; - -typedef void (*NET_CALLBACK) (GIOChannel *, void *); -typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *); - /* nonblocking gethostbyname(), PID of the resolver child is returned. */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup); -/* Get host's name, call func when finished */ -int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data); /* get the resolved IP address. returns -1 if some error occurred with read() */ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec); -/* Connect to server, call func when finished */ -int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, - NET_CALLBACK func, void *data); /* Kill the resolver child */ void net_disconnect_nonblock(int pid); diff --git a/src/core/server-rec.h b/src/core/server-rec.h index 69e990c6..e2dcf5ce 100644 --- a/src/core/server-rec.h +++ b/src/core/server-rec.h @@ -21,7 +21,7 @@ unsigned int no_reconnect:1; /* Don't reconnect to server */ NET_SENDBUF_REC *handle; int readtag; /* input tag */ -/* for net_connect_nonblock() */ +/* for net_gethostbyname_return() */ GIOChannel *connect_pipe[2]; int connect_tag; int connect_pid; diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index 88c577f7..5e03042f 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -361,7 +361,7 @@ static void dcc_chat_listen(CHAT_DCC_REC *dcc) signal_emit("dcc connected", 1, dcc); } -/* callback: DCC CHAT - net_connect_nonblock() finished */ +/* callback: DCC CHAT - connect finished */ static void sig_chat_connected(CHAT_DCC_REC *dcc) { g_return_if_fail(IS_DCC_CHAT(dcc)); From a37672361a72fbcb27b57cd1edf2c7463c5b1aba Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 20 Feb 2019 16:34:17 +0100 Subject: [PATCH 0503/1198] make utf8proc configurable --- configure.ac | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e8290dfd..9987cad5 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,15 @@ AC_ARG_ENABLE(gregex, fi, want_gregex=yes) +AC_ARG_ENABLE(utf8proc, +[ --disable-utf8proc Build without Julia's utf8proc], + if test x$enableval = xno ; then + want_utf8proc=no + else + want_utf8proc=yes + fi, + want_utf8proc=yes) + AC_ARG_WITH(capsicum, [ --with-capsicum Build with Capsicum support], if test x$withval = xno; then @@ -329,7 +338,18 @@ PKG_CHECK_MODULES([OPENSSL], [openssl], [ dnl ** dnl ** utf8proc dnl ** -AC_CHECK_LIB([utf8proc], [utf8proc_version]) +if test "x$want_utf8proc" != "xno"; then + AC_CHECK_HEADER([utf8proc.h], [ + AC_CHECK_LIB([utf8proc], [utf8proc_version], [ + want_utf8proc=yes + LIBS="$LIBS -lutf8proc" + ], [ + want_utf8proc="no, library not found" + ]) + ], [ + want_utf8proc="no, library header not found" + ]) +fi dnl ** dnl ** curses checks @@ -821,7 +841,7 @@ echo "Building with 64bit DCC support .. : $offt_64bit" echo "Building with true color support.. : $want_truecolor" echo "Building with GRegex ............. : $want_gregex" echo "Building with Capsicum ........... : $want_capsicum" -echo "Building with utf8proc ........... : $ac_cv_lib_utf8proc_utf8proc_version" +echo "Building with utf8proc ........... : $want_utf8proc" if test "x$want_otr" = "xstatic"; then echo "Building with OTR support ........ : static (in irssi binary)" elif test "x$want_otr" = "xmodule"; then From c61a171114e17b770a1a848003ae816156a9673d Mon Sep 17 00:00:00 2001 From: teschi Date: Sat, 23 Feb 2019 22:19:35 +0100 Subject: [PATCH 0504/1198] allow rawlog-buffer to shrink again after lowering "rawlog_lines" --- src/core/rawlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/rawlog.c b/src/core/rawlog.c index e0c4dd3d..be1412c8 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -62,7 +62,7 @@ void rawlog_destroy(RAWLOG_REC *rawlog) /* NOTE! str must be dynamically allocated and must not be freed after! */ static void rawlog_add(RAWLOG_REC *rawlog, char *str) { - if (rawlog->lines->length >= rawlog_lines && rawlog_lines > 0) { + while (rawlog->lines->length >= rawlog_lines && rawlog_lines > 0) { void *tmp = g_queue_pop_head(rawlog->lines); g_free(tmp); } From bc9410011482036f3c551b38087ea0e24f991067 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 8 Mar 2019 11:24:16 +0100 Subject: [PATCH 0505/1198] fix missing AC_DEFINE --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 9987cad5..066f7a07 100644 --- a/configure.ac +++ b/configure.ac @@ -342,6 +342,7 @@ if test "x$want_utf8proc" != "xno"; then AC_CHECK_HEADER([utf8proc.h], [ AC_CHECK_LIB([utf8proc], [utf8proc_version], [ want_utf8proc=yes + AC_DEFINE(HAVE_LIBUTF8PROC,, [Define to 1 if you have the `utf8proc' library (-lutf8proc).]) LIBS="$LIBS -lutf8proc" ], [ want_utf8proc="no, library not found" From 6a2823ad3e2c79ac43d06a0316ace0d4a6744cb0 Mon Sep 17 00:00:00 2001 From: Heikki Orsila Date: Mon, 11 Mar 2019 23:06:53 +0200 Subject: [PATCH 0506/1198] Implement a method to delete messages older than given time in scrollback history. The maximum age of messages is controlled by /set scrollback_max_age variable. E.g. /set scrollback_max_age 7days --- src/fe-text/gui-printtext.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index f860dc1c..e47e4594 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -39,6 +39,13 @@ int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7, /* 76-87 */ 217, 223, 229, 193, 157, 158, 159, 153, 147, 183, 219, 212, /* 88-98 */ 16, 233, 235, 237, 239, 241, 244, 247, 250, 254, 231, -1 }; static int scrollback_lines, scrollback_time, scrollback_burst_remove; +/* + * If positive, remove lines older than scrollback_max_age seconds. + * Deletion is triggered by the "gui print text finished" signal (i.e. a message + * for the window). Note: "Day changed to" message also cause messages to be + * deleted within 1 day latency. + */ +static int scrollback_max_age; static int next_xpos, next_ypos; @@ -182,9 +189,10 @@ void gui_printtext_window_border(int x, int y) static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) { LINE_REC *line; + time_t cur_time = time(NULL); time_t old_time; - old_time = time(NULL)-scrollback_time+1; + old_time = cur_time - scrollback_time + 1; if (view->buffer->lines_count >= scrollback_lines+scrollback_burst_remove) { /* remove lines by line count */ @@ -200,6 +208,21 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) textbuffer_view_remove_line(view, line); } } + + if (scrollback_max_age > 0) { + old_time = cur_time - scrollback_max_age; + while (view->buffer->lines_count > 0) { + line = view->buffer->first_line; + if (line->info.time >= old_time) { + /* + * The first line is newer than the threshold + * time -> no need to remove more lines. + */ + break; + } + textbuffer_view_remove_line(view, line); + } + } } static void get_colors(int flags, int *fg, int *bg, int *attr) @@ -337,6 +360,7 @@ static void read_settings(void) { scrollback_lines = settings_get_int("scrollback_lines"); scrollback_time = settings_get_time("scrollback_time")/1000; + scrollback_max_age = settings_get_time("scrollback_max_age")/1000; scrollback_burst_remove = settings_get_int("scrollback_burst_remove"); } @@ -349,6 +373,7 @@ void gui_printtext_init(void) settings_add_int("history", "scrollback_lines", 500); settings_add_time("history", "scrollback_time", "1day"); + settings_add_time("history", "scrollback_max_age", "0"); settings_add_int("history", "scrollback_burst_remove", 10); signal_add("gui print text", (SIGNAL_FUNC) sig_gui_print_text); From 8479ff7a2e31889129e54df8e11c861eb600780a Mon Sep 17 00:00:00 2001 From: vague666 Date: Fri, 22 Mar 2019 13:11:35 +0100 Subject: [PATCH 0507/1198] Remove unused parameter to /ECHO --- docs/help/in/echo.in | 3 +-- src/fe-common/core/fe-core-commands.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/help/in/echo.in b/docs/help/in/echo.in index 4ff23730..7f080189 100644 --- a/docs/help/in/echo.in +++ b/docs/help/in/echo.in @@ -5,7 +5,6 @@ %9Parameters:%9 - -current: Displays the output in the active window. -window: Displays the output in the target window. -level: Displays the output with a given message level. @@ -18,7 +17,7 @@ %9Examples:%9 /ECHO 1 + 1 = 2 :D - /ECHO -current Testing the ECHO command + /ECHO Testing the ECHO command /ECHO -window #irssi Special variables such as ${N} will not be expanded. %9See also:%9 CAT, EVAL, EXEC, LEVELS diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index b223db05..00c07af6 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -68,7 +68,7 @@ static const char *current_cmdline; static GTimeVal time_command_last, time_command_now; static int last_command_cmd, command_cmd; -/* SYNTAX: ECHO [-current] [-window ] [-level ] */ +/* SYNTAX: ECHO [-window ] [-level ] */ static void cmd_echo(const char *data, void *server, WI_ITEM_REC *item) { WINDOW_REC *window; @@ -343,7 +343,7 @@ void fe_core_commands_init(void) signal_add("error command", (SIGNAL_FUNC) event_cmderror); signal_add("list subcommands", (SIGNAL_FUNC) event_list_subcommands); - command_set_options("echo", "current +level +window"); + command_set_options("echo", "+level +window"); } void fe_core_commands_deinit(void) From 22502abf2cda44d5311ba2fd8424bdfd99fb04c0 Mon Sep 17 00:00:00 2001 From: vague666 Date: Fri, 22 Mar 2019 19:10:10 +0100 Subject: [PATCH 0508/1198] Add setting to choose between window name and visible name in actlist --- src/fe-text/statusbar-items.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 5740a40b..bd715950 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -123,7 +123,9 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) window->hilight_color, window->refnum); if (add_name && window->active != NULL) - g_string_append_printf(format, ":%s", window->active->visible_name); + g_string_append_printf(format, ":%s", + settings_get_bool("actlist_prefer_window_name") && + window->name != NULL ? window->name : window->active->visible_name); g_string_append_c(format, '}'); value = theme_format_expand(theme, format->str); @@ -470,6 +472,7 @@ void statusbar_items_init(void) settings_add_time("misc", "lag_min_show", "1sec"); settings_add_str("lookandfeel", "actlist_sort", "refnum"); settings_add_bool("lookandfeel", "actlist_names", FALSE); + settings_add_bool("lookandfeel", "actlist_prefer_window_name", FALSE); statusbar_item_register("window", NULL, item_window_active); statusbar_item_register("window_empty", NULL, item_window_empty); From 40d800637af3636f218e524025824673170f1905 Mon Sep 17 00:00:00 2001 From: vague666 Date: Fri, 22 Mar 2019 19:24:18 +0100 Subject: [PATCH 0509/1198] add access to set hidden_level from perl --- src/perl/textui/TextBufferView.xs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs index 6e49e453..dc577f02 100644 --- a/src/perl/textui/TextBufferView.xs +++ b/src/perl/textui/TextBufferView.xs @@ -16,6 +16,11 @@ textbuffer_view_set_default_indent(view, default_indent, longword_noindent) CODE: textbuffer_view_set_default_indent(view, default_indent, longword_noindent, NULL); +void +textbuffer_view_set_hidden_level(view, level) + Irssi::TextUI::TextBufferView view + int level + void textbuffer_view_set_scroll(view, scroll) Irssi::TextUI::TextBufferView view From 1fe6fd8057781b3ad76b94d8dfc9429a4929dca6 Mon Sep 17 00:00:00 2001 From: "Jacob V. Rasmussen" Date: Mon, 1 Apr 2019 13:14:58 +0200 Subject: [PATCH 0510/1198] Add tls_* options to manual Add tls_* options to the SERVER section of the manual. --- docs/manual.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/manual.txt b/docs/manual.txt index db40e5d3..0f24ffe3 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -394,10 +394,26 @@ 5.4 Server settings - /SERVER ADD [-auto | -noauto] [-network ] [-host ] + /SERVER ADD [-tls] [-tls_cert ] [-tls_pkey ] + [-tls_pass ] [-tls_verify] [-tls_cafile ] + [-tls_capath ] [-tls_ciphers ] + [-tls_pinned_cert ] [-tls_pinned_pubkey ] + [-auto | -noauto] [-network ] [-host ] [-cmdspeed ] [-cmdmax ] [-port ]
[ []] + -tls: Connects using TLS encryption. + -tls_cert: The TLS client certificate file. + -tls_pkey: The TLS client private key, if not included in the + certificate file. + -tls_pass: The password for the TLS client private key or + certificate. + -tls_verify: Verifies the TLS certificate of the server. + -tls_cafile: The file with the list of CA certificates. + -tls_capath: The directory which contains the CA certificates. + -tls_ciphers: TLS cipher suite preference lists. + -tls_pinned_cert: Pinned x509 certificate fingerprint. + -tls_pinned_pubkey: Pinned public key fingerprint. -auto: Automatically connect to server at startup -noauto: Don't connect to server at startup (default) -network: Specify what IRC network this server belongs to From d0bc5b8cf2361dcefc51cc98261ce1d08f1101df Mon Sep 17 00:00:00 2001 From: Jacob V Rasmussen Date: Mon, 1 Apr 2019 17:52:39 +0200 Subject: [PATCH 0511/1198] Update ssl_* to tls_* in syntax. --- src/fe-common/irc/fe-irc-server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index c4435d8f..c2b9fc0f 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -51,9 +51,9 @@ const char *get_visible_target(IRC_SERVER_REC *server, const char *target) return target; } -/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-ssl] [-ssl_cert ] [-ssl_pkey ] [-ssl_pass ] - [-ssl_verify] [-ssl_cafile ] [-ssl_capath ] - [-ssl_ciphers ] +/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] [-tls_pass ] + [-tls_verify] [-tls_cafile ] [-tls_capath ] + [-tls_ciphers ] [-auto | -noauto] [-network ] [-host ] [-cmdspeed ] [-cmdmax ] [-port ]
[ []] */ From 9cdeed2894abd3b76eed91a70d02510c0f840060 Mon Sep 17 00:00:00 2001 From: vague666 Date: Tue, 2 Apr 2019 09:39:03 +0200 Subject: [PATCH 0512/1198] cache bool value --- src/fe-text/statusbar-items.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index bd715950..7c86c306 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -76,7 +76,7 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) GString *format; GList *tmp; char *ret, *name, *value; - int is_det; + int is_det, pref_name; int add_name = settings_get_bool("actlist_names"); str = g_string_new(NULL); @@ -122,10 +122,12 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) g_string_printf(format, "{sb_act_hilight_color %s %d", window->hilight_color, window->refnum); + + pref_name = settings_get_bool("actlist_prefer_window_name"); if (add_name && window->active != NULL) g_string_append_printf(format, ":%s", - settings_get_bool("actlist_prefer_window_name") && - window->name != NULL ? window->name : window->active->visible_name); + pref_name == 1 && window->name != NULL ? + window->name : window->active->visible_name); g_string_append_c(format, '}'); value = theme_format_expand(theme, format->str); From c66fe616e14ac0cc54e99f35dd1fd6b9c68de9b7 Mon Sep 17 00:00:00 2001 From: vague666 Date: Tue, 2 Apr 2019 09:53:42 +0200 Subject: [PATCH 0513/1198] Bump ABI and add another perl api function --- src/common.h | 2 +- src/perl/textui/TextBufferView.xs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 192e087d..41dc192f 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 20 +#define IRSSI_ABI_VERSION 21 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs index dc577f02..c0dc762d 100644 --- a/src/perl/textui/TextBufferView.xs +++ b/src/perl/textui/TextBufferView.xs @@ -58,6 +58,11 @@ void textbuffer_view_remove_all_lines(view) Irssi::TextUI::TextBufferView view +void +textbuffer_view_remove_lines_by_level(view, level) + Irssi::TextUI::TextBufferView view + int level + void textbuffer_view_set_bookmark(view, name, line) Irssi::TextUI::TextBufferView view From 2f5f3429771a213d2c2d7a57faf5e62db3869746 Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 3 Apr 2019 11:41:12 +0200 Subject: [PATCH 0514/1198] Add special targets to help --- docs/help/in/msg.in | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/help/in/msg.in b/docs/help/in/msg.in index 9e0879e4..6c7dd70f 100644 --- a/docs/help/in/msg.in +++ b/docs/help/in/msg.in @@ -11,8 +11,13 @@ The target nickname or channel and the message to send. - Use the wildcard character '*' if you want to use the active nickname or - channel. + The target can be a comma delimited list of targets, ie + nick1,nick2 or #chan1,#chan2 + + Or one of the following special targets: + * : Use the active nickname or channel + , : Last person who sent you a /msg + . : Last person you sent a /msg to %9Description:%9 From 878902761767e865855d304c00823ecea9eb2444 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 6 Apr 2019 21:52:49 +0300 Subject: [PATCH 0515/1198] Add missing NULL check in mask_match() Fixes #902 --- src/core/masks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/masks.c b/src/core/masks.c index cc28b3bf..dc0064a9 100644 --- a/src/core/masks.c +++ b/src/core/masks.c @@ -68,7 +68,7 @@ int mask_match(SERVER_REC *server, const char *mask, g_return_val_if_fail(server == NULL || IS_SERVER(server), FALSE); g_return_val_if_fail(mask != NULL && nick != NULL && - nick != NULL && host != NULL, FALSE); + user != NULL && host != NULL, FALSE); str = !check_address(mask, &wildcards) ? (char *) nick : g_strdup_printf("%s!%s@%s", nick, user, host); From 2b48ddd3c95d94f91f7452f9e809b4dc95ac2056 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 6 Apr 2019 23:20:44 +0300 Subject: [PATCH 0516/1198] Move NULL check for cert above pubkey This patch was originally proposed by Chi Li. Fixes #944 --- src/core/network-openssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 95697135..265d3574 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -854,14 +854,13 @@ int irssi_ssl_handshake(GIOChannel *handle) } cert = SSL_get_peer_certificate(chan->ssl); - pubkey = X509_get_X509_PUBKEY(cert); - if (cert == NULL) { g_warning("TLS server supplied no certificate"); ret = 0; goto done; } + pubkey = X509_get_X509_PUBKEY(cert); if (pubkey == NULL) { g_warning("TLS server supplied no certificate public key"); ret = 0; From 530393140a67400de34a7636cfd8c641adb7c44a Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 6 Apr 2019 22:59:17 +0300 Subject: [PATCH 0517/1198] Check return value of BIO_read() in set_pubkey_info() Fixes #943 --- src/core/network-openssl.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 265d3574..eec725fa 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -601,18 +601,19 @@ static void set_cipher_info(TLS_REC *tls, SSL *ssl) tls_rec_set_cipher_size(tls, SSL_get_cipher_bits(ssl, NULL)); } -static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_fingerprint, size_t cert_fingerprint_size, unsigned char *public_key_fingerprint, size_t public_key_fingerprint_size) +static gboolean set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_fingerprint, size_t cert_fingerprint_size, unsigned char *public_key_fingerprint, size_t public_key_fingerprint_size) { + gboolean ret = TRUE; EVP_PKEY *pubkey = NULL; char *cert_fingerprint_hex = NULL; char *public_key_fingerprint_hex = NULL; BIO *bio = NULL; char buffer[128]; - size_t length; + ssize_t length; - g_return_if_fail(tls != NULL); - g_return_if_fail(cert != NULL); + g_return_val_if_fail(tls != NULL, FALSE); + g_return_val_if_fail(cert != NULL, FALSE); pubkey = X509_get_pubkey(cert); @@ -648,6 +649,11 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger bio = BIO_new(BIO_s_mem()); ASN1_TIME_print(bio, X509_get_notBefore(cert)); length = BIO_read(bio, buffer, sizeof(buffer)); + if (length < 0) { + ret = FALSE; + BIO_free(bio); + goto done; + } buffer[length] = '\0'; BIO_free(bio); tls_rec_set_not_before(tls, buffer); @@ -656,13 +662,21 @@ static void set_pubkey_info(TLS_REC *tls, X509 *cert, unsigned char *cert_finger bio = BIO_new(BIO_s_mem()); ASN1_TIME_print(bio, X509_get_notAfter(cert)); length = BIO_read(bio, buffer, sizeof(buffer)); + if (length < 0) { + ret = FALSE; + BIO_free(bio); + goto done; + } buffer[length] = '\0'; BIO_free(bio); tls_rec_set_not_after(tls, buffer); +done: g_free(cert_fingerprint_hex); g_free(public_key_fingerprint_hex); EVP_PKEY_free(pubkey); + + return ret; } static void set_peer_cert_chain_info(TLS_REC *tls, SSL *ssl) @@ -881,7 +895,11 @@ int irssi_ssl_handshake(GIOChannel *handle) tls = tls_create_rec(); set_cipher_info(tls, chan->ssl); - set_pubkey_info(tls, cert, cert_fingerprint, cert_fingerprint_size, pubkey_fingerprint, pubkey_fingerprint_size); + if (! set_pubkey_info(tls, cert, cert_fingerprint, cert_fingerprint_size, pubkey_fingerprint, pubkey_fingerprint_size)) { + g_warning("Couldn't set pubkey information"); + ret = 0; + goto done; + } set_peer_cert_chain_info(tls, chan->ssl); set_server_temporary_key_info(tls, chan->ssl); From 9d9d99eeb1c07decbe164cc18e02383f35f19689 Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 8 Apr 2019 12:32:58 +0200 Subject: [PATCH 0518/1198] move caching to correct place :) --- src/fe-text/statusbar-items.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 7c86c306..27efcbd1 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -76,8 +76,9 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) GString *format; GList *tmp; char *ret, *name, *value; - int is_det, pref_name; + int is_det; int add_name = settings_get_bool("actlist_names"); + int pref_name = settings_get_bool("actlist_prefer_window_name"); str = g_string_new(NULL); format = g_string_new(NULL); @@ -123,7 +124,6 @@ static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight) window->hilight_color, window->refnum); - pref_name = settings_get_bool("actlist_prefer_window_name"); if (add_name && window->active != NULL) g_string_append_printf(format, ":%s", pref_name == 1 && window->name != NULL ? From ad3b8df97e10ad38c685a2095fe0c77cc5dee4aa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 27 Mar 2019 18:29:38 +0100 Subject: [PATCH 0519/1198] Add Github Actions support code --- .github/actions.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ .github/main.workflow | 27 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 .github/actions.yml create mode 100644 .github/main.workflow diff --git a/.github/actions.yml b/.github/actions.yml new file mode 100644 index 00000000..ae47fbde --- /dev/null +++ b/.github/actions.yml @@ -0,0 +1,43 @@ +before_install: + - ./autogen.sh --with-proxy=module --with-bot --with-perl=module --with-otr=module + - make dist + - CO_DIR=$(pwd) + - mkdir -p $HOME/src + - cd $HOME/src + - tar xaf $CO_DIR/irssi-*.tar.* + +install: + - cd $HOME/src/irssi-* + - ./configure --with-proxy=module --with-bot --with-perl=module --with-otr=module --prefix=$HOME/irssi-build --enable-always-build-tests + - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" + - make install + +unit_tests: + - cd $HOME/src/irssi-* + - make -C tests -sk check + +after_unit_tests: + - cd $HOME/src/irssi-* + - find -name test-suite.log -exec cat {} + + +before_script: + - cd $HOME + - mkdir irssi-test + - | + echo 'echo automated irssi launch test + ^set settings_autosave off + ^set -clear log_close_string + ^set -clear log_day_changed + ^set -clear log_open_string + ^set log_timestamp * + ^window log on' > irssi-test/startup + - echo load perl >> irssi-test/startup + - echo load proxy >> irssi-test/startup + - echo ^quit >> irssi-test/startup + +script: + - cd $HOME + - irssi-build/bin/irssi --home irssi-test | /tools/render.pl + +after_script: + - cat $HOME/irc.log.* diff --git a/.github/main.workflow b/.github/main.workflow new file mode 100644 index 00000000..0db7e7a1 --- /dev/null +++ b/.github/main.workflow @@ -0,0 +1,27 @@ +workflow "Check Irssi" { + on = "push" + resolves = [ + "script", + "unit_tests", + ] +} + +action "install" { + uses = "irssi-import/actions-irssi/check-irssi@master" + args = "before_install install" +} + +action "script" { + uses = "irssi-import/actions-irssi/check-irssi@master" + needs = ["install"] + args = "before_script script after_script" + env = { + TERM = "xterm" + } +} + +action "unit_tests" { + uses = "irssi-import/actions-irssi/check-irssi@master" + needs = ["install"] + args = "unit_tests after_unit_tests" +} From da266691bb8a3a10c239726b0fa2e4caf98fa0bf Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 24 Apr 2019 13:30:38 +0200 Subject: [PATCH 0520/1198] disable github workflows --- .github/main.workflow | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/main.workflow b/.github/main.workflow index 0db7e7a1..18a6088c 100644 --- a/.github/main.workflow +++ b/.github/main.workflow @@ -1,10 +1,10 @@ -workflow "Check Irssi" { - on = "push" - resolves = [ - "script", - "unit_tests", - ] -} +# workflow "Check Irssi" { +# on = "push" +# resolves = [ +# "script", +# "unit_tests", +# ] +# } action "install" { uses = "irssi-import/actions-irssi/check-irssi@master" From 7e6e1f2e10029d963033a91a54cc19e37d78ac0d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 1 May 2019 16:33:47 +0200 Subject: [PATCH 0521/1198] Use full paths to includes --- configure.ac | 7 +++ src/common.h | 4 +- src/core/Makefile.am | 2 - src/core/args.c | 2 +- src/core/capsicum.c | 16 +++--- src/core/channel-rec.h | 2 +- src/core/channels-setup.c | 14 +++--- src/core/channels-setup.h | 4 +- src/core/channels.c | 14 +++--- src/core/channels.h | 4 +- src/core/chat-commands.c | 26 +++++----- src/core/chat-protocols.c | 14 +++--- src/core/chatnets.c | 16 +++--- src/core/chatnets.h | 4 +- src/core/commands.c | 18 +++---- src/core/commands.h | 2 +- src/core/core.c | 44 ++++++++-------- src/core/core.h | 2 +- src/core/expandos.c | 24 ++++----- src/core/expandos.h | 2 +- src/core/ignore.c | 24 ++++----- src/core/ignore.h | 2 +- src/core/iregex-gregex.c | 2 +- src/core/iregex-regexh.c | 2 +- src/core/iregex.h | 2 +- src/core/levels.c | 2 +- src/core/line-split.c | 2 +- src/core/log-away.c | 12 ++--- src/core/log.c | 20 ++++---- src/core/masks.c | 6 +-- src/core/misc.c | 4 +- src/core/module.h | 2 +- src/core/modules-load.c | 12 ++--- src/core/modules-load.h | 2 +- src/core/modules.c | 4 +- src/core/net-disconnect.c | 2 +- src/core/net-nonblock.c | 4 +- src/core/net-nonblock.h | 2 +- src/core/net-sendbuffer.c | 6 +-- src/core/network-openssl.c | 14 +++--- src/core/network.c | 4 +- src/core/nicklist.c | 12 ++--- src/core/nicklist.h | 2 +- src/core/nickmatch-cache.c | 8 +-- src/core/pidwait.c | 4 +- src/core/queries.c | 8 +-- src/core/queries.h | 4 +- src/core/query-rec.h | 2 +- src/core/rawlog.c | 20 ++++---- src/core/recode.c | 10 ++-- src/core/servers-reconnect.c | 16 +++--- src/core/servers-setup.c | 16 +++--- src/core/servers-setup.h | 4 +- src/core/servers.c | 28 +++++------ src/core/servers.h | 6 +-- src/core/session.c | 24 ++++----- src/core/settings.c | 14 +++--- src/core/signals.c | 4 +- src/core/special-vars.c | 14 +++--- src/core/special-vars.h | 2 +- src/core/tls.c | 2 +- src/core/utf8.c | 4 +- src/core/wcwidth-wrapper.c | 6 +-- src/core/wcwidth.c | 2 +- src/core/window-item-def.h | 2 +- src/core/write-buffer.c | 8 +-- src/fe-common/core/Makefile.am | 1 - src/fe-common/core/chat-completion.c | 32 ++++++------ src/fe-common/core/command-history.c | 14 +++--- src/fe-common/core/command-history.h | 2 +- src/fe-common/core/completion.c | 18 +++---- src/fe-common/core/completion.h | 2 +- src/fe-common/core/fe-capsicum.c | 10 ++-- src/fe-common/core/fe-channels.c | 38 +++++++------- src/fe-common/core/fe-common-core.c | 50 +++++++++---------- src/fe-common/core/fe-core-commands.c | 24 ++++----- src/fe-common/core/fe-exec.c | 32 ++++++------ src/fe-common/core/fe-exec.h | 4 +- src/fe-common/core/fe-expandos.c | 4 +- src/fe-common/core/fe-help.c | 14 +++--- src/fe-common/core/fe-ignore-messages.c | 8 +-- src/fe-common/core/fe-ignore.c | 16 +++--- src/fe-common/core/fe-log.c | 40 +++++++-------- src/fe-common/core/fe-messages.c | 30 +++++------ src/fe-common/core/fe-modules.c | 16 +++--- src/fe-common/core/fe-queries.c | 26 +++++----- src/fe-common/core/fe-queries.h | 2 +- src/fe-common/core/fe-recode.c | 18 +++---- src/fe-common/core/fe-server.c | 24 ++++----- src/fe-common/core/fe-settings.c | 22 ++++---- src/fe-common/core/fe-tls.c | 14 +++--- src/fe-common/core/fe-windows.c | 22 ++++---- src/fe-common/core/fe-windows.h | 4 +- src/fe-common/core/formats.c | 26 +++++----- src/fe-common/core/formats.h | 4 +- src/fe-common/core/hilight-text.c | 30 +++++------ src/fe-common/core/hilight-text.h | 4 +- src/fe-common/core/keyboard.c | 20 ++++---- src/fe-common/core/keyboard.h | 2 +- src/fe-common/core/module-formats.c | 2 +- src/fe-common/core/module-formats.h | 2 +- src/fe-common/core/module.h | 4 +- src/fe-common/core/printtext.c | 20 ++++---- src/fe-common/core/printtext.h | 4 +- src/fe-common/core/themes.c | 20 ++++---- src/fe-common/core/window-activity.c | 24 ++++----- src/fe-common/core/window-commands.c | 26 +++++----- src/fe-common/core/window-items.c | 20 ++++---- src/fe-common/core/window-items.h | 2 +- src/fe-common/core/windows-layout.c | 28 +++++------ src/fe-common/irc/Makefile.am | 4 -- src/fe-common/irc/dcc/Makefile.am | 5 -- src/fe-common/irc/dcc/fe-dcc-chat-messages.c | 16 +++--- src/fe-common/irc/dcc/fe-dcc-chat.c | 26 +++++----- src/fe-common/irc/dcc/fe-dcc-get.c | 18 +++---- src/fe-common/irc/dcc/fe-dcc-send.c | 22 ++++---- src/fe-common/irc/dcc/fe-dcc-server.c | 16 +++--- src/fe-common/irc/dcc/fe-dcc.c | 24 ++++----- src/fe-common/irc/dcc/module-formats.c | 2 +- src/fe-common/irc/dcc/module-formats.h | 2 +- src/fe-common/irc/dcc/module.h | 4 +- src/fe-common/irc/fe-cap.c | 12 ++--- src/fe-common/irc/fe-common-irc.c | 18 +++---- src/fe-common/irc/fe-ctcp.c | 22 ++++---- src/fe-common/irc/fe-events-numeric.c | 28 +++++------ src/fe-common/irc/fe-events.c | 40 +++++++-------- src/fe-common/irc/fe-irc-channels.c | 18 +++---- src/fe-common/irc/fe-irc-commands.c | 36 ++++++------- src/fe-common/irc/fe-irc-messages.c | 32 ++++++------ src/fe-common/irc/fe-irc-queries.c | 10 ++-- src/fe-common/irc/fe-irc-server.c | 26 +++++----- src/fe-common/irc/fe-ircnet.c | 22 ++++---- src/fe-common/irc/fe-modes.c | 20 ++++---- src/fe-common/irc/fe-netjoin.c | 20 ++++---- src/fe-common/irc/fe-netsplit.c | 18 +++---- src/fe-common/irc/fe-sasl.c | 16 +++--- src/fe-common/irc/fe-whois.c | 16 +++--- src/fe-common/irc/irc-completion.c | 4 +- src/fe-common/irc/module-formats.c | 2 +- src/fe-common/irc/module-formats.h | 2 +- src/fe-common/irc/module.h | 4 +- src/fe-common/irc/notifylist/Makefile.am | 4 -- src/fe-common/irc/notifylist/fe-notifylist.c | 26 +++++----- src/fe-common/irc/notifylist/module-formats.c | 2 +- src/fe-common/irc/notifylist/module-formats.h | 2 +- src/fe-common/irc/notifylist/module.h | 4 +- src/fe-fuzz/Makefile.am | 4 -- src/fe-fuzz/fe-common/core/Makefile.am | 4 -- src/fe-fuzz/irc/core/Makefile.am | 4 -- src/fe-none/Makefile.am | 3 -- src/fe-none/irssi.c | 10 ++-- src/fe-none/module.h | 2 +- src/fe-text/Makefile.am | 3 -- src/fe-text/gui-entry.c | 14 +++--- src/fe-text/gui-expandos.c | 6 +-- src/fe-text/gui-printtext.c | 16 +++--- src/fe-text/gui-printtext.h | 6 +-- src/fe-text/gui-readline.c | 30 +++++------ src/fe-text/gui-windows.c | 18 +++---- src/fe-text/gui-windows.h | 4 +- src/fe-text/irssi.c | 42 ++++++++-------- src/fe-text/lastlog.c | 18 +++---- src/fe-text/mainwindow-activity.c | 6 +-- src/fe-text/mainwindows-layout.c | 16 +++--- src/fe-text/mainwindows.c | 18 +++---- src/fe-text/mainwindows.h | 4 +- src/fe-text/module-formats.c | 2 +- src/fe-text/module-formats.h | 2 +- src/fe-text/module.h | 4 +- src/fe-text/statusbar-config.c | 18 +++---- src/fe-text/statusbar-config.h | 2 +- src/fe-text/statusbar-items.c | 14 +++--- src/fe-text/statusbar.c | 16 +++--- src/fe-text/statusbar.h | 4 +- src/fe-text/term-terminfo.c | 12 ++--- src/fe-text/term.c | 10 ++-- src/fe-text/term.h | 2 +- src/fe-text/terminfo-core.c | 4 +- src/fe-text/textbuffer-commands.c | 18 +++---- src/fe-text/textbuffer-view.c | 6 +-- src/fe-text/textbuffer-view.h | 4 +- src/fe-text/textbuffer.c | 10 ++-- src/irc/core/Makefile.am | 2 - src/irc/core/bans.c | 20 ++++---- src/irc/core/channel-events.c | 16 +++--- src/irc/core/channel-events.h | 2 +- src/irc/core/channel-rejoin.c | 14 +++--- src/irc/core/channels-query.c | 18 +++---- src/irc/core/ctcp.c | 18 +++---- src/irc/core/irc-cap.c | 8 +-- src/irc/core/irc-channels-setup.c | 4 +- src/irc/core/irc-channels.c | 22 ++++---- src/irc/core/irc-channels.h | 6 +-- src/irc/core/irc-chatnets.c | 8 +-- src/irc/core/irc-chatnets.h | 6 +-- src/irc/core/irc-commands.c | 28 +++++------ src/irc/core/irc-commands.h | 2 +- src/irc/core/irc-core.c | 26 +++++----- src/irc/core/irc-expandos.c | 12 ++--- src/irc/core/irc-masks.c | 4 +- src/irc/core/irc-masks.h | 2 +- src/irc/core/irc-nicklist.c | 16 +++--- src/irc/core/irc-nicklist.h | 2 +- src/irc/core/irc-queries.c | 10 ++-- src/irc/core/irc-queries.h | 4 +- src/irc/core/irc-servers-reconnect.c | 12 ++--- src/irc/core/irc-servers-setup.c | 18 +++---- src/irc/core/irc-servers-setup.h | 6 +-- src/irc/core/irc-servers.c | 40 +++++++-------- src/irc/core/irc-servers.h | 10 ++-- src/irc/core/irc-session.c | 16 +++--- src/irc/core/irc.c | 16 +++--- src/irc/core/irc.h | 2 +- src/irc/core/lag.c | 10 ++-- src/irc/core/massjoin.c | 10 ++-- src/irc/core/mode-lists.c | 10 ++-- src/irc/core/modes.c | 18 +++---- src/irc/core/modes.h | 4 +- src/irc/core/module.h | 4 +- src/irc/core/netsplit.c | 12 ++--- src/irc/core/netsplit.h | 2 +- src/irc/core/sasl.c | 10 ++-- src/irc/core/servers-idle.c | 8 +-- src/irc/core/servers-redirect.c | 10 ++-- src/irc/dcc/Makefile.am | 3 -- src/irc/dcc/dcc-autoget.c | 12 ++--- src/irc/dcc/dcc-chat.c | 22 ++++---- src/irc/dcc/dcc-chat.h | 4 +- src/irc/dcc/dcc-file-rec.h | 2 +- src/irc/dcc/dcc-file.h | 4 +- src/irc/dcc/dcc-get.c | 18 +++---- src/irc/dcc/dcc-get.h | 4 +- src/irc/dcc/dcc-queue.c | 16 +++--- src/irc/dcc/dcc-queue.h | 2 +- src/irc/dcc/dcc-resume.c | 16 +++--- src/irc/dcc/dcc-send.c | 20 ++++---- src/irc/dcc/dcc-send.h | 4 +- src/irc/dcc/dcc-server.c | 18 +++---- src/irc/dcc/dcc-server.h | 4 +- src/irc/dcc/dcc.c | 26 +++++----- src/irc/dcc/dcc.h | 6 +-- src/irc/dcc/module.h | 4 +- src/irc/flood/Makefile.am | 3 -- src/irc/flood/autoignore.c | 16 +++--- src/irc/flood/flood.c | 16 +++--- src/irc/flood/module.h | 4 +- src/irc/notifylist/Makefile.am | 3 -- src/irc/notifylist/module.h | 6 +-- src/irc/notifylist/notify-commands.c | 10 ++-- src/irc/notifylist/notify-ison.c | 14 +++--- src/irc/notifylist/notify-setup.c | 8 +-- src/irc/notifylist/notify-whois.c | 12 ++--- src/irc/notifylist/notifylist.c | 20 ++++---- src/irc/proxy/Makefile.am | 3 -- src/irc/proxy/dump.c | 18 +++---- src/irc/proxy/listen.c | 18 +++---- src/irc/proxy/module.h | 10 ++-- src/irc/proxy/proxy.c | 8 +-- src/irc/proxy/proxy.h | 8 +-- src/lib-config/Makefile.am | 1 - src/lib-config/module.h | 4 +- src/otr/Makefile.am | 5 -- src/otr/key.c | 14 +++--- src/otr/key.h | 6 +-- src/otr/module.h | 4 +- src/otr/otr-fe.c | 22 ++++---- src/otr/otr-formats.c | 4 +- src/otr/otr-formats.h | 2 +- src/otr/otr-module.c | 26 +++++----- src/otr/otr-ops.c | 16 +++--- src/otr/otr.c | 16 +++--- src/otr/otr.h | 4 +- src/perl/Makefile.am | 3 -- src/perl/common/Core.xs | 12 ++--- src/perl/common/Expando.xs | 2 +- src/perl/common/Makefile.PL.in | 2 +- src/perl/common/Settings.xs | 2 +- src/perl/common/module.h | 46 ++++++++--------- src/perl/irc/Ctcp.xs | 2 +- src/perl/irc/Makefile.PL.in | 2 +- src/perl/irc/module.h | 40 +++++++-------- src/perl/module-formats.c | 2 +- src/perl/module-formats.h | 2 +- src/perl/module.h | 2 +- src/perl/perl-common.c | 38 +++++++------- src/perl/perl-core.c | 18 +++---- src/perl/perl-fe.c | 18 +++---- src/perl/perl-signals.c | 14 +++--- src/perl/perl-sources.c | 10 ++-- src/perl/textui/Makefile.PL.in | 2 +- src/perl/textui/module.h | 16 +++--- src/perl/ui/Makefile.PL.in | 2 +- src/perl/ui/Window.xs | 2 +- src/perl/ui/module.h | 16 +++--- tests/fe-common/core/Makefile.am | 3 -- tests/fe-common/core/test-formats.c | 4 +- tests/fe-text/Makefile.am | 4 -- tests/fe-text/test-paste-join-multiline.c | 4 +- tests/irc/core/Makefile.am | 3 -- tests/irc/core/test-channel-events.c | 22 ++++---- tests/irc/core/test-irc.c | 2 +- tests/irc/flood/Makefile.am | 5 -- tests/irc/flood/test-796.c | 20 ++++---- 303 files changed, 1702 insertions(+), 1769 deletions(-) diff --git a/configure.ac b/configure.ac index 066f7a07..a3a60a88 100644 --- a/configure.ac +++ b/configure.ac @@ -765,6 +765,13 @@ themes/Makefile irssi-config ]) +dnl ** make the paths like include headers later +AC_CONFIG_LINKS([ +irssi/irssi-config.h:irssi-config.h +irssi/irssi-version.h:irssi-version.h +]) +AC_LINK_FILES([$srcdir/src],[irssi/src]) + AC_OUTPUT dnl ** for building from objdir diff --git a/src/common.h b/src/common.h index 41dc192f..313b2c9f 100644 --- a/src/common.h +++ b/src/common.h @@ -11,9 +11,7 @@ #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 -#ifdef HAVE_CONFIG_H -#include "irssi-config.h" -#endif +#include #include #include diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 4cc2226c..c01b8f10 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -1,8 +1,6 @@ noinst_LIBRARIES = libcore.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ $(GLIB_CFLAGS) \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DMODULEDIR=\""$(libdir)/irssi/modules"\" diff --git a/src/core/args.c b/src/core/args.c index 9894b6c8..5e2b1412 100644 --- a/src/core/args.c +++ b/src/core/args.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "args.h" +#include static GOptionContext *context = NULL; diff --git a/src/core/capsicum.c b/src/core/capsicum.c index 568b5542..d73d15fb 100644 --- a/src/core/capsicum.c +++ b/src/core/capsicum.c @@ -23,14 +23,14 @@ */ #include "module.h" -#include "capsicum.h" -#include "commands.h" -#include "log.h" -#include "misc.h" -#include "network.h" -#include "network-openssl.h" -#include "settings.h" -#include "signals.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/core/channel-rec.h b/src/core/channel-rec.h index f3ec5f8d..f1e30fa0 100644 --- a/src/core/channel-rec.h +++ b/src/core/channel-rec.h @@ -1,6 +1,6 @@ /* CHANNEL_REC definition, used for inheritance */ -#include "window-item-rec.h" +#include char *topic; char *topic_by; diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index 8002646d..55b4533e 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers-setup.h" -#include "channels-setup.h" +#include +#include +#include +#include GSList *setupchannels; diff --git a/src/core/channels-setup.h b/src/core/channels-setup.h index 3bb7da7f..fcc099c6 100644 --- a/src/core/channels-setup.h +++ b/src/core/channels-setup.h @@ -1,7 +1,7 @@ #ifndef __CHANNELS_SETUP_H #define __CHANNELS_SETUP_H -#include "modules.h" +#include #define CHANNEL_SETUP(server) \ MODULE_CHECK_CAST(server, CHANNEL_SETUP_REC, type, "CHANNEL SETUP") @@ -10,7 +10,7 @@ (CHANNEL_SETUP(server) ? TRUE : FALSE) struct _CHANNEL_SETUP_REC { -#include "channel-setup-rec.h" +#include }; extern GSList *setupchannels; diff --git a/src/core/channels.c b/src/core/channels.c index 9c3b92ba..edc30544 100644 --- a/src/core/channels.c +++ b/src/core/channels.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "special-vars.h" +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "channels-setup.h" -#include "nicklist.h" +#include +#include +#include +#include GSList *channels; /* List of all channels */ diff --git a/src/core/channels.h b/src/core/channels.h index bd136fe2..276c69fa 100644 --- a/src/core/channels.h +++ b/src/core/channels.h @@ -1,7 +1,7 @@ #ifndef __CHANNELS_H #define __CHANNELS_H -#include "modules.h" +#include /* Returns CHANNEL_REC if it's channel, NULL if it isn't. */ #define CHANNEL(channel) \ @@ -13,7 +13,7 @@ #define STRUCT_SERVER_REC SERVER_REC struct _CHANNEL_REC { -#include "channel-rec.h" +#include }; extern GSList *channels; diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index d5a133f8..0b4b6591 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -19,20 +19,20 @@ */ #include "module.h" -#include "network.h" -#include "signals.h" -#include "commands.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "servers-setup.h" -#include "servers-reconnect.h" -#include "channels.h" -#include "queries.h" -#include "window-item-def.h" -#include "rawlog.h" +#include +#include +#include +#include +#include +#include +#include +#include static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, char **rawlog_file) diff --git a/src/core/chat-protocols.c b/src/core/chat-protocols.c index ee15c087..c53b01b3 100644 --- a/src/core/chat-protocols.c +++ b/src/core/chat-protocols.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" -#include "chat-protocols.h" +#include +#include +#include -#include "chatnets.h" -#include "servers.h" -#include "servers-setup.h" -#include "channels-setup.h" +#include +#include +#include +#include GSList *chat_protocols; diff --git a/src/core/chatnets.c b/src/core/chatnets.c index e0a7a8d9..2d49a6df 100644 --- a/src/core/chatnets.c +++ b/src/core/chatnets.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "network.h" -#include "signals.h" -#include "special-vars.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" +#include +#include +#include GSList *chatnets; /* list of available chat networks */ diff --git a/src/core/chatnets.h b/src/core/chatnets.h index 2b78f64a..785b487e 100644 --- a/src/core/chatnets.h +++ b/src/core/chatnets.h @@ -1,7 +1,7 @@ #ifndef __CHATNETS_H #define __CHATNETS_H -#include "modules.h" +#include /* Returns CHATNET_REC if it's chatnet, NULL if it isn't. */ #define CHATNET(chatnet) \ @@ -11,7 +11,7 @@ (CHATNET(chatnet) ? TRUE : FALSE) struct _CHATNET_REC { -#include "chatnet-rec.h" +#include }; extern GSList *chatnets; /* list of available chat networks */ diff --git a/src/core/commands.c b/src/core/commands.c index 2eebf0a3..4ba1ea1c 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "special-vars.h" -#include "window-item-def.h" +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" +#include +#include -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include GSList *commands; char *current_command; diff --git a/src/core/commands.h b/src/core/commands.h index 93d6276b..b70e77ca 100644 --- a/src/core/commands.h +++ b/src/core/commands.h @@ -1,7 +1,7 @@ #ifndef __COMMANDS_H #define __COMMANDS_H -#include "signals.h" +#include typedef struct { SIGNAL_FUNC func; diff --git a/src/core/core.c b/src/core/core.c index 3c335fd2..8562836a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -21,33 +21,33 @@ #include "module.h" #include -#include "args.h" -#include "pidwait.h" -#include "misc.h" +#include +#include +#include -#include "net-disconnect.h" -#include "signals.h" -#include "settings.h" -#include "session.h" +#include +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif -#include "chat-protocols.h" -#include "servers.h" -#include "chatnets.h" -#include "commands.h" -#include "expandos.h" -#include "write-buffer.h" -#include "log.h" -#include "rawlog.h" -#include "ignore.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "channels.h" -#include "queries.h" -#include "nicklist.h" -#include "nickmatch-cache.h" +#include +#include +#include +#include #ifdef HAVE_SYS_RESOURCE_H # include diff --git a/src/core/core.h b/src/core/core.h index 982dbaad..406070e0 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -1,7 +1,7 @@ #ifndef __IRSSI_CORE_H #define __IRSSI_CORE_H -#include "common.h" +#include /* for determining what GUI is currently in use: */ #define IRSSI_GUI_NONE 0 diff --git a/src/core/expandos.c b/src/core/expandos.c index 2e4265d5..96e2d9f3 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -18,20 +18,20 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "core.h" +#include #include "module.h" -#include "modules.h" -#include "signals.h" -#include "expandos.h" -#include "settings.h" -#include "commands.h" -#include "misc.h" -#include "irssi-version.h" +#include +#include +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "queries.h" -#include "window-item-def.h" +#include +#include +#include +#include #ifdef HAVE_SYS_UTSNAME_H # include diff --git a/src/core/expandos.h b/src/core/expandos.h index 45608a26..3466a44a 100644 --- a/src/core/expandos.h +++ b/src/core/expandos.h @@ -1,7 +1,7 @@ #ifndef __EXPANDOS_H #define __EXPANDOS_H -#include "signals.h" +#include /* first argument of signal must match to active .. */ typedef enum { diff --git a/src/core/ignore.c b/src/core/ignore.c index 371da83b..14fa585e 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -19,20 +19,20 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "levels.h" -#include "lib-config/iconfig.h" -#include "settings.h" -#include "iregex.h" +#include +#include +#include +#include +#include +#include -#include "masks.h" -#include "servers.h" -#include "channels.h" -#include "nicklist.h" -#include "nickmatch-cache.h" +#include +#include +#include +#include +#include -#include "ignore.h" +#include GSList *ignores; diff --git a/src/core/ignore.h b/src/core/ignore.h index 20c5475e..fea38205 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,7 +1,7 @@ #ifndef __IGNORE_H #define __IGNORE_H -#include "iregex.h" +#include typedef struct _IGNORE_REC IGNORE_REC; diff --git a/src/core/iregex-gregex.c b/src/core/iregex-gregex.c index 36b4faa4..60b4ec58 100644 --- a/src/core/iregex-gregex.c +++ b/src/core/iregex-gregex.c @@ -1,6 +1,6 @@ #include -#include "iregex.h" +#include struct _MatchInfo { const char *valid_string; diff --git a/src/core/iregex-regexh.c b/src/core/iregex-regexh.c index 897eb7e2..aae8ecdf 100644 --- a/src/core/iregex-regexh.c +++ b/src/core/iregex-regexh.c @@ -1,4 +1,4 @@ -#include "iregex.h" +#include Regex * i_regex_new (const gchar *pattern, diff --git a/src/core/iregex.h b/src/core/iregex.h index e67378d7..d6d6c17f 100644 --- a/src/core/iregex.h +++ b/src/core/iregex.h @@ -1,7 +1,7 @@ #ifndef __REGEX_H #define __REGEX_H -#include "common.h" +#include #ifdef USE_GREGEX diff --git a/src/core/levels.c b/src/core/levels.c index eb7efcf7..9102696e 100644 --- a/src/core/levels.c +++ b/src/core/levels.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "levels.h" +#include /* the order of these levels must match the bits in levels.h */ static const char *levels[] = { diff --git a/src/core/line-split.c b/src/core/line-split.c index 0ee87d23..da84a334 100644 --- a/src/core/line-split.c +++ b/src/core/line-split.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "misc.h" +#include /* Maximum line length - split to two lines if it's longer than this. diff --git a/src/core/log-away.c b/src/core/log-away.c index e2a0120b..d6dac4d9 100644 --- a/src/core/log-away.c +++ b/src/core/log-away.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "log.h" -#include "servers.h" -#include "settings.h" -#include "write-buffer.h" +#include +#include +#include +#include +#include +#include static LOG_REC *awaylog; static int away_filepos; diff --git a/src/core/log.c b/src/core/log.c index f7741d3d..3e260fe7 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "servers.h" -#include "log.h" -#include "write-buffer.h" +#include +#include +#include +#include +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include #define DEFAULT_LOG_FILE_CREATE_MODE 600 diff --git a/src/core/masks.c b/src/core/masks.c index dc0064a9..a84ac44d 100644 --- a/src/core/masks.c +++ b/src/core/masks.c @@ -19,10 +19,10 @@ */ #include "module.h" -#include "network.h" -#include "misc.h" +#include +#include -#include "servers.h" +#include /* Returns TRUE if mask contains '!' ie. address should be checked too. Also checks if mask contained any wildcards. */ diff --git a/src/core/misc.c b/src/core/misc.c index e1f199b2..d612f587 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "misc.h" -#include "commands.h" +#include +#include typedef struct { int condition; diff --git a/src/core/module.h b/src/core/module.h index 89784389..639e7e29 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -1,3 +1,3 @@ -#include "common.h" +#include #define MODULE_NAME "core" diff --git a/src/core/modules-load.c b/src/core/modules-load.c index 9baac1d7..a3598c65 100644 --- a/src/core/modules-load.c +++ b/src/core/modules-load.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "modules.h" -#include "modules-load.h" -#include "signals.h" +#include +#include +#include -#include "settings.h" -#include "commands.h" -#include "misc.h" +#include +#include +#include #ifdef HAVE_GMODULE diff --git a/src/core/modules-load.h b/src/core/modules-load.h index 42e14382..683d30e3 100644 --- a/src/core/modules-load.h +++ b/src/core/modules-load.h @@ -1,7 +1,7 @@ #ifndef __MODULES_LOAD_H #define __MODULES_LOAD_H -#include "modules.h" +#include /* Load module - automatically tries to load also the related non-core modules given in `prefixes' (like irc, fe, fe_text, ..) */ diff --git a/src/core/modules.c b/src/core/modules.c index 9b531899..c625071a 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" +#include +#include GSList *modules; diff --git a/src/core/net-disconnect.c b/src/core/net-disconnect.c index 6476e776..889563c5 100644 --- a/src/core/net-disconnect.c +++ b/src/core/net-disconnect.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "network.h" +#include /* when quitting, wait for max. 5 seconds before forcing to close the socket */ #define MAX_QUIT_CLOSE_WAIT 5 diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 2aca616b..31fbf985 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -22,8 +22,8 @@ #include -#include "pidwait.h" -#include "net-nonblock.h" +#include +#include /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 853fcaa6..649232ae 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -1,7 +1,7 @@ #ifndef __NET_NONBLOCK_H #define __NET_NONBLOCK_H -#include "network.h" +#include typedef struct { IPADDR ip4, ip6; /* resolved ip addresses */ diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c index 97fb551f..2272de1d 100644 --- a/src/core/net-sendbuffer.c +++ b/src/core/net-sendbuffer.c @@ -20,9 +20,9 @@ #include "module.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "line-split.h" +#include +#include +#include /* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE is used */ diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index eec725fa..92507e14 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "network.h" -#include "network-openssl.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "servers.h" -#include "signals.h" -#include "tls.h" +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/core/network.c b/src/core/network.c index 0e326e22..87b91698 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -19,9 +19,9 @@ */ #include "module.h" -#include "network.h" +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif #include diff --git a/src/core/nicklist.c b/src/core/nicklist.c index 0bc88ab8..bf845c0d 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" +#include +#include -#include "servers.h" -#include "channels.h" -#include "nicklist.h" -#include "masks.h" +#include +#include +#include +#include #define isalnumhigh(a) \ (i_isalnum(a) || (unsigned char) (a) >= 128) diff --git a/src/core/nicklist.h b/src/core/nicklist.h index 5e0f4f75..913cc0d1 100644 --- a/src/core/nicklist.h +++ b/src/core/nicklist.h @@ -11,7 +11,7 @@ #define MAX_USER_PREFIXES 7 /* Max prefixes kept for any user-in-chan. 7+1 is a memory unit */ struct _NICK_REC { -#include "nick-rec.h" +#include }; /* Add new nick to list */ diff --git a/src/core/nickmatch-cache.c b/src/core/nickmatch-cache.c index 36a6c241..cae6620d 100644 --- a/src/core/nickmatch-cache.c +++ b/src/core/nickmatch-cache.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" +#include -#include "channels.h" -#include "nicklist.h" +#include +#include -#include "nickmatch-cache.h" +#include static GSList *lists; diff --git a/src/core/pidwait.c b/src/core/pidwait.c index 7fc06195..f421c1d6 100644 --- a/src/core/pidwait.c +++ b/src/core/pidwait.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "signals.h" -#include "modules.h" +#include +#include static GHashTable *child_pids; static GSList *pids; diff --git a/src/core/queries.c b/src/core/queries.c index a2fd4b0a..fe86271f 100644 --- a/src/core/queries.c +++ b/src/core/queries.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" +#include +#include -#include "servers.h" -#include "queries.h" +#include +#include GSList *queries; diff --git a/src/core/queries.h b/src/core/queries.h index 77ef9c37..16f92588 100644 --- a/src/core/queries.h +++ b/src/core/queries.h @@ -1,7 +1,7 @@ #ifndef __QUERIES_H #define __QUERIES_H -#include "modules.h" +#include /* Returns QUERY_REC if it's query, NULL if it isn't. */ #define QUERY(query) \ @@ -13,7 +13,7 @@ #define STRUCT_SERVER_REC SERVER_REC struct _QUERY_REC { -#include "query-rec.h" +#include }; extern GSList *queries; diff --git a/src/core/query-rec.h b/src/core/query-rec.h index 59519ad4..cc15c9ec 100644 --- a/src/core/query-rec.h +++ b/src/core/query-rec.h @@ -1,6 +1,6 @@ /* QUERY_REC definition, used for inheritance */ -#include "window-item-rec.h" +#include char *address; char *server_tag; diff --git a/src/core/rawlog.c b/src/core/rawlog.c index e0c4dd3d..f1938ea6 100644 --- a/src/core/rawlog.c +++ b/src/core/rawlog.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "rawlog.h" -#include "log.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "write-buffer.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif -#include "servers.h" +#include static int rawlog_lines; static int signal_rawlog; diff --git a/src/core/recode.c b/src/core/recode.c index d3fc91e7..7185dd99 100644 --- a/src/core/recode.c +++ b/src/core/recode.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "settings.h" -#include "servers.h" -#include "signals.h" -#include "lib-config/iconfig.h" -#include "misc.h" +#include +#include +#include +#include +#include static char *translit_charset; static gboolean term_is_utf8; diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 5f609cf5..97175f78 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "commands.h" -#include "network.h" -#include "signals.h" +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "servers-setup.h" -#include "servers-reconnect.h" +#include +#include +#include +#include -#include "settings.h" +#include GSList *reconnects; static int last_reconnect_tag; diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 2a92a367..a505df5b 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "network.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" -#include "servers-setup.h" +#include +#include +#include +#include GSList *setupservers; diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index e7ff7abf..9bedfe25 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -1,7 +1,7 @@ #ifndef __SERVERS_SETUP_H #define __SERVERS_SETUP_H -#include "modules.h" +#include #define SERVER_SETUP(server) \ MODULE_CHECK_CAST(server, SERVER_SETUP_REC, type, "SERVER SETUP") @@ -11,7 +11,7 @@ /* servers */ struct _SERVER_SETUP_REC { -#include "server-setup-rec.h" +#include }; extern GSList *setupservers; diff --git a/src/core/servers.c b/src/core/servers.c index 81bdb89e..20452f8c 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "net-disconnect.h" -#include "net-nonblock.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "rawlog.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "servers-reconnect.h" -#include "servers-setup.h" -#include "channels.h" -#include "queries.h" +#include +#include +#include +#include +#include +#include GSList *servers, *lookup_servers; diff --git a/src/core/servers.h b/src/core/servers.h index f39c650b..daf155b3 100644 --- a/src/core/servers.h +++ b/src/core/servers.h @@ -1,7 +1,7 @@ #ifndef __SERVERS_H #define __SERVERS_H -#include "modules.h" +#include /* Returns SERVER_REC if it's server, NULL if it isn't. */ #define SERVER(server) \ @@ -23,12 +23,12 @@ /* all strings should be either NULL or dynamically allocated */ /* address and nick are mandatory, rest are optional */ struct _SERVER_CONNECT_REC { -#include "server-connect-rec.h" +#include }; #define STRUCT_SERVER_CONNECT_REC SERVER_CONNECT_REC struct _SERVER_REC { -#include "server-rec.h" +#include }; #define SEND_TARGET_CHANNEL 0 diff --git a/src/core/session.c b/src/core/session.c index 34190c52..0dc36fef 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "args.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "pidwait.h" -#include "lib-config/iconfig.h" +#include +#include +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "servers-setup.h" -#include "channels.h" -#include "nicklist.h" +#include +#include +#include +#include +#include static char *session_file; char *irssi_binary = NULL; diff --git a/src/core/settings.c b/src/core/settings.c index 5fc37ded..2bd6c06a 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" +#include +#include +#include +#include -#include "lib-config/iconfig.h" -#include "recode.h" -#include "settings.h" +#include +#include +#include #include "default-config.h" #include diff --git a/src/core/signals.c b/src/core/signals.c index 1f425ba4..e52e6907 100644 --- a/src/core/signals.c +++ b/src/core/signals.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "signals.h" -#include "modules.h" +#include +#include typedef struct _SignalHook { struct _SignalHook *next; diff --git a/src/core/special-vars.c b/src/core/special-vars.c index 7081b602..d84912d2 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "signals.h" -#include "special-vars.h" -#include "expandos.h" -#include "settings.h" -#include "servers.h" -#include "misc.h" -#include "utf8.h" +#include +#include +#include +#include +#include +#include +#include #define isvarchar(c) \ (i_isalnum(c) || (c) == '_') diff --git a/src/core/special-vars.h b/src/core/special-vars.h index 300dae0e..caec5ec0 100644 --- a/src/core/special-vars.h +++ b/src/core/special-vars.h @@ -1,7 +1,7 @@ #ifndef __SPECIAL_VARS_H #define __SPECIAL_VARS_H -#include "signals.h" +#include #define PARSE_FLAG_GETNAME 0x01 /* return argument name instead of it's value */ #define PARSE_FLAG_ISSET_ANY 0x02 /* arg_used field specifies that at least one of the $variables was non-empty */ diff --git a/src/core/tls.c b/src/core/tls.c index 3bddd773..bd5c8329 100644 --- a/src/core/tls.c +++ b/src/core/tls.c @@ -18,7 +18,7 @@ #include "module.h" -#include "tls.h" +#include TLS_REC *tls_create_rec() { diff --git a/src/core/utf8.c b/src/core/utf8.c index c44fdbd6..5ef030d3 100644 --- a/src/core/utf8.c +++ b/src/core/utf8.c @@ -22,11 +22,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "utf8.h" +#include #include "module.h" /* Provide is_utf8(): */ -#include "recode.h" +#include int string_advance(char const **str, int policy) { diff --git a/src/core/wcwidth-wrapper.c b/src/core/wcwidth-wrapper.c index 03d0dc0c..b3881d38 100644 --- a/src/core/wcwidth-wrapper.c +++ b/src/core/wcwidth-wrapper.c @@ -22,9 +22,9 @@ #include #include "module.h" -#include "signals.h" -#include "settings.h" -#include "utf8.h" +#include +#include +#include #ifdef HAVE_LIBUTF8PROC #include diff --git a/src/core/wcwidth.c b/src/core/wcwidth.c index 711c4646..5226d695 100644 --- a/src/core/wcwidth.c +++ b/src/core/wcwidth.c @@ -59,7 +59,7 @@ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c */ -#include "utf8.h" +#include struct interval { int first; diff --git a/src/core/window-item-def.h b/src/core/window-item-def.h index 4364c66e..1309f975 100644 --- a/src/core/window-item-def.h +++ b/src/core/window-item-def.h @@ -3,7 +3,7 @@ #define STRUCT_SERVER_REC SERVER_REC struct _WI_ITEM_REC { -#include "window-item-rec.h" +#include }; #endif diff --git a/src/core/write-buffer.c b/src/core/write-buffer.c index ffc3ae63..475e41b8 100644 --- a/src/core/write-buffer.c +++ b/src/core/write-buffer.c @@ -19,10 +19,10 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "settings.h" -#include "write-buffer.h" +#include +#include +#include +#include #define BUFFER_BLOCK_SIZE 2048 diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index cf4e8ee3..4e8fdcb2 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -1,7 +1,6 @@ noinst_LIBRARIES = libfe_common_core.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src -I$(top_srcdir)/src/core/ \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DTHEMESDIR=\""$(datadir)/irssi/themes"\" diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index d610008f..144ed0f4 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -19,24 +19,24 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "levels.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "chatnets.h" -#include "servers.h" -#include "servers-setup.h" -#include "channels.h" -#include "channels-setup.h" -#include "queries.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include +#include -#include "completion.h" -#include "chat-completion.h" -#include "window-items.h" +#include +#include +#include enum { COMPLETE_MCASE_NEVER = 0, diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index 32d7adaa..43d86354 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include -#include "fe-windows.h" -#include "window-items.h" +#include +#include -#include "command-history.h" +#include /* command history */ static GList *history_entries; diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index ed093415..3b9de941 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -1,7 +1,7 @@ #ifndef __COMMAND_HISTORY_H #define __COMMAND_HISTORY_H -#include "common.h" +#include typedef struct { char *name; diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index a6513d58..7778d8a4 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "completion.h" -#include "printtext.h" +#include +#include static GList *complist; /* list of commands we're currently completing */ static char *last_line; diff --git a/src/fe-common/core/completion.h b/src/fe-common/core/completion.h index 5c1e6958..dce3a2f1 100644 --- a/src/fe-common/core/completion.h +++ b/src/fe-common/core/completion.h @@ -1,7 +1,7 @@ #ifndef __COMPLETION_H #define __COMPLETION_H -#include "window-items.h" +#include /* automatic word completion - called when space/enter is pressed */ char *auto_word_complete(const char *line, int *pos); diff --git a/src/fe-common/core/fe-capsicum.c b/src/fe-common/core/fe-capsicum.c index 54a43d27..d7ea95ee 100644 --- a/src/fe-common/core/fe-capsicum.c +++ b/src/fe-common/core/fe-capsicum.c @@ -23,11 +23,11 @@ */ #include "module.h" -#include "fe-capsicum.h" -#include "levels.h" -#include "module-formats.h" -#include "printtext.h" -#include "signals.h" +#include +#include +#include +#include +#include static void capability_mode_enabled(void) { diff --git a/src/fe-common/core/fe-channels.c b/src/fe-common/core/fe-channels.c index 5cad51a7..8c914cb8 100644 --- a/src/fe-common/core/fe-channels.c +++ b/src/fe-common/core/fe-channels.c @@ -19,27 +19,27 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" -#include "special-vars.h" -#include "utf8.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" -#include "channels.h" -#include "channels-setup.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include -#include "fe-windows.h" -#include "fe-channels.h" -#include "window-items.h" -#include "printtext.h" +#include +#include +#include +#include static void signal_channel_created(CHANNEL_REC *channel, void *automatic) { diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index e47eb446..c7cdd995 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -19,35 +19,35 @@ */ #include "module.h" -#include "module-formats.h" -#include "args.h" -#include "misc.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "servers-setup.h" +#include +#include +#include -#include "special-vars.h" -#include "fe-core-commands.h" -#include "fe-queries.h" +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "fe-capsicum.h" +#include #endif -#include "hilight-text.h" -#include "command-history.h" -#include "completion.h" -#include "keyboard.h" -#include "printtext.h" -#include "formats.h" -#include "themes.h" -#include "fe-channels.h" -#include "fe-windows.h" -#include "window-activity.h" -#include "window-items.h" -#include "windows-layout.h" -#include "fe-recode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 00c07af6..7e09cded 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -18,22 +18,22 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "core.h" +#include #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" -#include "irssi-version.h" -#include "servers.h" +#include +#include +#include +#include +#include +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif -#include "fe-windows.h" -#include "printtext.h" +#include +#include #define PASTE_CHECK_SPEED 200 /* 0.2 sec */ diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index c1739d39..0da4ac89 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -19,24 +19,24 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "pidwait.h" -#include "line-split.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "levels.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "queries.h" +#include +#include +#include -#include "printtext.h" -#include "fe-exec.h" -#include "fe-windows.h" -#include "window-items.h" +#include +#include +#include +#include #include #include diff --git a/src/fe-common/core/fe-exec.h b/src/fe-common/core/fe-exec.h index 20219d5a..21b1e18b 100644 --- a/src/fe-common/core/fe-exec.h +++ b/src/fe-common/core/fe-exec.h @@ -1,7 +1,7 @@ #ifndef __FE_EXEC_H #define __FE_EXEC_H -#include "fe-windows.h" +#include #define EXEC_WI(query) \ MODULE_CHECK_CAST_MODULE(query, EXEC_WI_REC, type, \ @@ -14,7 +14,7 @@ typedef struct PROCESS_REC PROCESS_REC; #define STRUCT_SERVER_REC void typedef struct { -#include "window-item-rec.h" +#include PROCESS_REC *process; unsigned int destroying:1; } EXEC_WI_REC; diff --git a/src/fe-common/core/fe-expandos.c b/src/fe-common/core/fe-expandos.c index d054a633..9a48b4b1 100644 --- a/src/fe-common/core/fe-expandos.c +++ b/src/fe-common/core/fe-expandos.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "expandos.h" -#include "fe-windows.h" +#include +#include /* Window ref# */ static char *expando_winref(SERVER_REC *server, void *item, int *free_ret) diff --git a/src/fe-common/core/fe-help.c b/src/fe-common/core/fe-help.c index c7566113..9c428062 100644 --- a/src/fe-common/core/fe-help.c +++ b/src/fe-common/core/fe-help.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "printtext.h" -#include "formats.h" +#include +#include static int commands_equal(COMMAND_REC *rec, COMMAND_REC *rec2) { diff --git a/src/fe-common/core/fe-ignore-messages.c b/src/fe-common/core/fe-ignore-messages.c index fd889783..73ebd01f 100644 --- a/src/fe-common/core/fe-ignore-messages.c +++ b/src/fe-common/core/fe-ignore-messages.c @@ -19,10 +19,10 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "ignore.h" -#include "servers.h" +#include +#include +#include +#include static void sig_message_public(SERVER_REC *server, const char *msg, const char *nick, const char *address, diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 39c4dd9f..54ab6a55 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" +#include +#include +#include +#include +#include -#include "servers.h" -#include "ignore.h" -#include "printtext.h" +#include +#include +#include static char *ignore_get_key(IGNORE_REC *rec) { diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index d71c62a9..12b6b643 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -19,30 +19,30 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "chat-protocols.h" -#include "servers.h" -#include "channels.h" -#include "levels.h" -#include "misc.h" -#include "log.h" -#include "special-vars.h" -#include "settings.h" -#include "lib-config/iconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef HAVE_CAPSICUM -#include "capsicum.h" +#include #endif -#include "fe-windows.h" -#include "window-items.h" -#include "formats.h" -#include "themes.h" -#include "printtext.h" -#include "fe-common-core.h" +#include +#include +#include +#include +#include +#include -#include "channels-setup.h" +#include /* close autologs after 5 minutes of inactivity */ #define AUTOLOG_INACTIVITY_CLOSE (60*5) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 12cb1055..5edac26d 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -19,23 +19,23 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "nicklist.h" -#include "ignore.h" +#include +#include +#include +#include -#include "window-items.h" -#include "fe-queries.h" -#include "hilight-text.h" -#include "printtext.h" +#include +#include +#include +#include #define ishighalnum(c) ((unsigned char) (c) >= 128 || i_isalnum(c)) #define isnickchar(a) \ diff --git a/src/fe-common/core/fe-modules.c b/src/fe-common/core/fe-modules.c index 27b6b4c1..9ad594cb 100644 --- a/src/fe-common/core/fe-modules.c +++ b/src/fe-common/core/fe-modules.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "modules.h" -#include "modules-load.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "chat-protocols.h" +#include +#include +#include +#include +#include +#include +#include -#include "printtext.h" +#include #ifdef HAVE_GMODULE diff --git a/src/fe-common/core/fe-queries.c b/src/fe-common/core/fe-queries.c index 121417e4..77f07474 100644 --- a/src/fe-common/core/fe-queries.c +++ b/src/fe-common/core/fe-queries.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "queries.h" +#include +#include +#include -#include "fe-core-commands.h" -#include "fe-windows.h" -#include "window-items.h" -#include "printtext.h" +#include +#include +#include +#include static int queryclose_tag, query_auto_close, querycreate_level; diff --git a/src/fe-common/core/fe-queries.h b/src/fe-common/core/fe-queries.h index 6db9cb44..1dc7e81a 100644 --- a/src/fe-common/core/fe-queries.h +++ b/src/fe-common/core/fe-queries.h @@ -1,7 +1,7 @@ #ifndef __FE_QUERIES_H #define __FE_QUERIES_H -#include "queries.h" +#include /* Return query where to put the private message. */ QUERY_REC *privmsg_get_query(SERVER_REC *server, const char *nick, diff --git a/src/fe-common/core/fe-recode.c b/src/fe-common/core/fe-recode.c index 829c89e7..5e7c1e47 100644 --- a/src/fe-common/core/fe-recode.c +++ b/src/fe-common/core/fe-recode.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "modules.h" -#include "module-formats.h" -#include "commands.h" -#include "levels.h" -#include "lib-config/iconfig.h" -#include "settings.h" -#include "printtext.h" -#include "formats.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include static char *recode_fallback = NULL; static char *recode_out_default = NULL; diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 074a83f3..be5ea4ab 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -19,20 +19,20 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" -#include "servers-setup.h" -#include "servers-reconnect.h" +#include +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" +#include +#include static void print_servers(void) { diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index de9f67a1..ad4747e8 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "servers.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" -#include "fe-settings.h" -#include "levels.h" -#include "printtext.h" -#include "keyboard.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static void set_print(SETTINGS_REC *rec) { diff --git a/src/fe-common/core/fe-tls.c b/src/fe-common/core/fe-tls.c index ed206d18..d72a13b0 100644 --- a/src/fe-common/core/fe-tls.c +++ b/src/fe-common/core/fe-tls.c @@ -17,15 +17,15 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" -#include "levels.h" -#include "tls.h" +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" +#include +#include -#include "fe-tls.h" +#include static void tls_handshake_finished(SERVER_REC *server, TLS_REC *tls) { diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 93f2e3f3..88fc0711 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "servers.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "levels.h" +#include -#include "printtext.h" -#include "fe-windows.h" -#include "window-items.h" +#include +#include +#include GSList *windows; /* first in the list is the active window, next is the last active, etc. */ diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 061a999a..782b5430 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -1,8 +1,8 @@ #ifndef __WINDOWS_H #define __WINDOWS_H -#include "window-item-def.h" -#include "command-history.h" +#include +#include enum { DATA_LEVEL_NONE = 0, diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index c8d56fd0..414c6582 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include -#include "levels.h" -#include "servers.h" +#include +#include -#include "fe-windows.h" -#include "window-items.h" -#include "formats.h" -#include "themes.h" -#include "recode.h" -#include "utf8.h" -#include "misc.h" +#include +#include +#include +#include +#include +#include +#include static const char *format_backs = "04261537"; static const char *format_fores = "kbgcrmyw"; diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 8efd204c..a52a3bbd 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -1,8 +1,8 @@ #ifndef __FORMATS_H #define __FORMATS_H -#include "themes.h" -#include "fe-windows.h" +#include +#include #define GUI_PRINT_FLAG_BOLD 0x0001 #define GUI_PRINT_FLAG_REVERSE 0x0002 diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 3d853a90..2fe6068b 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -19,23 +19,23 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" -#include "iregex.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "servers.h" -#include "channels.h" -#include "nicklist.h" +#include +#include +#include -#include "hilight-text.h" -#include "nickmatch-cache.h" -#include "printtext.h" -#include "formats.h" +#include +#include +#include +#include static NICKMATCH_REC *nickmatch; static int never_hilight_level, default_hilight_level; diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 1d942f29..1ffce6b9 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,8 +1,8 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H -#include "iregex.h" -#include "formats.h" +#include +#include struct _HILIGHT_REC { char *text; diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index c3df5ed7..8f90b1ad 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "keyboard.h" -#include "fe-windows.h" -#include "printtext.h" +#include +#include +#include #define MAX_EXPAND_RECURSION 100 diff --git a/src/fe-common/core/keyboard.h b/src/fe-common/core/keyboard.h index 970dc7b7..06b11bba 100644 --- a/src/fe-common/core/keyboard.h +++ b/src/fe-common/core/keyboard.h @@ -1,7 +1,7 @@ #ifndef __KEYBOARD_H #define __KEYBOARD_H -#include "signals.h" +#include typedef struct _KEYBOARD_REC KEYBOARD_REC; typedef struct _KEYINFO_REC KEYINFO_REC; diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index d3c7251b..0c41e68b 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC fecommon_core_formats[] = { { MODULE_NAME, "Core", 0 }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index 97ac60bb..181aa4c2 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { TXT_MODULE_NAME, diff --git a/src/fe-common/core/module.h b/src/fe-common/core/module.h index db712ec7..e629dc51 100644 --- a/src/fe-common/core/module.h +++ b/src/fe-common/core/module.h @@ -1,8 +1,8 @@ -#include "common.h" +#include #define MODULE_NAME "fe-common/core" -#include "utf8.h" +#include typedef struct { time_t time; char *nick; diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 01ef2dcd..3e215d72 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "levels.h" -#include "servers.h" +#include +#include -#include "themes.h" -#include "fe-windows.h" -#include "printtext.h" +#include +#include +#include static int beep_msg_level, beep_when_away, beep_when_window_active; diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index db53c611..ff52b374 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -1,8 +1,8 @@ #ifndef __PRINTTEXT_H #define __PRINTTEXT_H -#include "fe-windows.h" -#include "formats.h" +#include +#include void printformat_module(const char *module, void *server, const char *target, int level, int formatnum, ...); void printformat_module_window(const char *module, WINDOW_REC *window, int level, int formatnum, ...); diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index a95f6180..ff737c41 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "special-vars.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "themes.h" -#include "printtext.h" +#include +#include #include "default-theme.h" diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 06c24a2f..7a2903fd 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "servers.h" -#include "channels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "fe-windows.h" -#include "window-items.h" -#include "nicklist.h" -#include "hilight-text.h" -#include "formats.h" -#include "fe-common-core.h" +#include +#include +#include +#include +#include +#include static char **hide_targets; static int hide_level, msg_level, hilight_level, signal_window_hilight_check; diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index d9956324..7c542d37 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "servers.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "levels.h" +#include -#include "themes.h" -#include "fe-windows.h" -#include "window-items.h" -#include "windows-layout.h" -#include "printtext.h" -#include "command-history.h" +#include +#include +#include +#include +#include +#include static void window_print_binds(WINDOW_REC *win) { diff --git a/src/fe-common/core/window-items.c b/src/fe-common/core/window-items.c index 8eab7124..c60c796c 100644 --- a/src/fe-common/core/window-items.c +++ b/src/fe-common/core/window-items.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules.h" -#include "signals.h" -#include "servers.h" -#include "channels.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "levels.h" +#include -#include "fe-windows.h" -#include "window-items.h" -#include "printtext.h" +#include +#include +#include static void window_item_add_signal(WINDOW_REC *window, WI_ITEM_REC *item, int automatic, int send_signal) { diff --git a/src/fe-common/core/window-items.h b/src/fe-common/core/window-items.h index f8db3c39..77ffe680 100644 --- a/src/fe-common/core/window-items.h +++ b/src/fe-common/core/window-items.h @@ -1,7 +1,7 @@ #ifndef __WINDOW_ITEMS_H #define __WINDOW_ITEMS_H -#include "fe-windows.h" +#include /* Add/remove/destroy window item from `window' */ void window_item_add(WINDOW_REC *window, WI_ITEM_REC *item, int automatic); diff --git a/src/fe-common/core/windows-layout.c b/src/fe-common/core/windows-layout.c index 5aa60916..745453d5 100644 --- a/src/fe-common/core/windows-layout.c +++ b/src/fe-common/core/windows-layout.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "levels.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "servers.h" -#include "channels.h" -#include "queries.h" +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" -#include "themes.h" -#include "fe-windows.h" -#include "window-items.h" +#include +#include +#include +#include +#include static WINDOW_REC *restore_win; diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index a5e95885..704de297 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -3,10 +3,6 @@ SUBDIRS = dcc notifylist noinst_LIBRARIES = libfe_common_irc.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-common/irc/dcc/Makefile.am b/src/fe-common/irc/dcc/Makefile.am index e0ad6296..c6a5d79d 100644 --- a/src/fe-common/irc/dcc/Makefile.am +++ b/src/fe-common/irc/dcc/Makefile.am @@ -1,11 +1,6 @@ noinst_LIBRARIES = libfe_irc_dcc.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/irc/dcc/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c index 41cea64c..8dd67f7b 100644 --- a/src/fe-common/irc/dcc/fe-dcc-chat-messages.c +++ b/src/fe-common/irc/dcc/fe-dcc-chat-messages.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" +#include +#include -#include "irc-servers.h" -#include "irc-queries.h" -#include "dcc-chat.h" -#include "ignore.h" +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" +#include +#include static void sig_message_dcc_own(CHAT_DCC_REC *dcc, const char *msg) { diff --git a/src/fe-common/irc/dcc/fe-dcc-chat.c b/src/fe-common/irc/dcc/fe-dcc-chat.c index 5bcb3475..4099e2f1 100644 --- a/src/fe-common/irc/dcc/fe-dcc-chat.c +++ b/src/fe-common/irc/dcc/fe-dcc-chat.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "settings.h" -#include "misc.h" +#include +#include +#include +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "irc-queries.h" -#include "dcc-chat.h" +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" -#include "fe-messages.h" +#include +#include +#include -#include "chat-completion.h" +#include void fe_dcc_chat_messages_init(void); void fe_dcc_chat_messages_deinit(void); diff --git a/src/fe-common/irc/dcc/fe-dcc-get.c b/src/fe-common/irc/dcc/fe-dcc-get.c index 99b6b963..e75640bc 100644 --- a/src/fe-common/irc/dcc/fe-dcc-get.c +++ b/src/fe-common/irc/dcc/fe-dcc-get.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "servers.h" +#include +#include +#include -#include "irc.h" -#include "dcc-file.h" -#include "dcc-get.h" +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" +#include +#include -#include "fe-dcc.h" +#include static void dcc_request(GET_DCC_REC *dcc) { diff --git a/src/fe-common/irc/dcc/fe-dcc-send.c b/src/fe-common/irc/dcc/fe-dcc-send.c index 7920bedc..cf9b634e 100644 --- a/src/fe-common/irc/dcc/fe-dcc-send.c +++ b/src/fe-common/irc/dcc/fe-dcc-send.c @@ -19,20 +19,20 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include -#include "dcc-file.h" -#include "dcc-send.h" -#include "dcc-queue.h" +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" -#include "completion.h" +#include +#include +#include -#include "fe-dcc.h" +#include static void dcc_connected(SEND_DCC_REC *dcc) { diff --git a/src/fe-common/irc/dcc/fe-dcc-server.c b/src/fe-common/irc/dcc/fe-dcc-server.c index 919d8665..eaab9637 100644 --- a/src/fe-common/irc/dcc/fe-dcc-server.c +++ b/src/fe-common/irc/dcc/fe-dcc-server.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "levels.h" +#include +#include +#include +#include -#include "dcc-server.h" +#include -#include "module-formats.h" -#include "printtext.h" -#include "themes.h" +#include +#include +#include static void dcc_server_started(SERVER_DCC_REC *dcc) { diff --git a/src/fe-common/irc/dcc/fe-dcc.c b/src/fe-common/irc/dcc/fe-dcc.c index 0a46a595..51fb5eea 100644 --- a/src/fe-common/irc/dcc/fe-dcc.c +++ b/src/fe-common/irc/dcc/fe-dcc.c @@ -19,20 +19,20 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "dcc-chat.h" -#include "dcc-file.h" -#include "dcc-get.h" -#include "dcc-send.h" +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" -#include "themes.h" +#include +#include +#include void fe_dcc_chat_init(void); void fe_dcc_chat_deinit(void); diff --git a/src/fe-common/irc/dcc/module-formats.c b/src/fe-common/irc/dcc/module-formats.c index 225c5429..f973cd9e 100644 --- a/src/fe-common/irc/dcc/module-formats.c +++ b/src/fe-common/irc/dcc/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC fecommon_irc_dcc_formats[] = { { MODULE_NAME, "IRC", 0 }, diff --git a/src/fe-common/irc/dcc/module-formats.h b/src/fe-common/irc/dcc/module-formats.h index d1bcc3ba..204c7dd5 100644 --- a/src/fe-common/irc/dcc/module-formats.h +++ b/src/fe-common/irc/dcc/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { IRCTXT_MODULE_NAME, diff --git a/src/fe-common/irc/dcc/module.h b/src/fe-common/irc/dcc/module.h index 58e65b25..54934469 100644 --- a/src/fe-common/irc/dcc/module.h +++ b/src/fe-common/irc/dcc/module.h @@ -1,4 +1,4 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "fe-common/irc/dcc" diff --git a/src/fe-common/irc/fe-cap.c b/src/fe-common/irc/fe-cap.c index 4f9d8ea9..a75f2bb3 100644 --- a/src/fe-common/irc/fe-cap.c +++ b/src/fe-common/irc/fe-cap.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" +#include +#include +#include +#include -#include "irc-servers.h" +#include -#include "printtext.h" +#include static const struct { const char *command; diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c index b1bfb525..0db2d98e 100644 --- a/src/fe-common/irc/fe-common-irc.c +++ b/src/fe-common/irc/fe-common-irc.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "modules.h" -#include "module-formats.h" -#include "signals.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "themes.h" -#include "fe-irc-server.h" -#include "fe-irc-channels.h" +#include +#include +#include void fe_irc_modules_init(void); void fe_irc_modules_deinit(void); diff --git a/src/fe-common/irc/fe-ctcp.c b/src/fe-common/irc/fe-ctcp.c index cbb591ba..63d7ecd3 100644 --- a/src/fe-common/irc/fe-ctcp.c +++ b/src/fe-common/irc/fe-ctcp.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "module-formats.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include -#include "levels.h" -#include "servers.h" -#include "channels.h" -#include "queries.h" -#include "ignore.h" +#include +#include +#include +#include +#include -#include "fe-windows.h" -#include "window-items.h" -#include "printtext.h" +#include +#include +#include static void ctcp_default_msg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index 3eb124fc..b4525db5 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" -#include "levels.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "nicklist.h" -#include "mode-lists.h" +#include +#include +#include +#include -#include "../core/module-formats.h" -#include "printtext.h" -#include "fe-channels.h" -#include "fe-irc-server.h" +#include +#include +#include +#include static void print_event_received(IRC_SERVER_REC *server, const char *data, const char *nick, int target_param); diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index 850174c5..30f00efc 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -19,29 +19,29 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include -#include "levels.h" -#include "servers.h" -#include "servers-redirect.h" -#include "servers-reconnect.h" -#include "queries.h" -#include "ignore.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-nicklist.h" -#include "irc-masks.h" +#include +#include +#include +#include -#include "printtext.h" -#include "fe-queries.h" -#include "fe-windows.h" -#include "fe-irc-server.h" -#include "fe-irc-channels.h" +#include +#include +#include +#include +#include static void event_privmsg(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) diff --git a/src/fe-common/irc/fe-irc-channels.c b/src/fe-common/irc/fe-irc-channels.c index 0ec30003..93ff3603 100644 --- a/src/fe-common/irc/fe-irc-channels.c +++ b/src/fe-common/irc/fe-irc-channels.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "channel-rejoin.h" +#include +#include +#include -#include "printtext.h" -#include "fe-windows.h" -#include "window-items.h" +#include +#include +#include int fe_channel_is_opchannel(IRC_SERVER_REC *server, const char *target) { diff --git a/src/fe-common/irc/fe-irc-commands.c b/src/fe-common/irc/fe-irc-commands.c index 668367e4..40ad36e0 100644 --- a/src/fe-common/irc/fe-irc-commands.c +++ b/src/fe-common/irc/fe-irc-commands.c @@ -19,26 +19,26 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "misc.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "levels.h" -#include "servers.h" -#include "mode-lists.h" -#include "nicklist.h" -#include "irc-commands.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-queries.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "fe-queries.h" -#include "fe-windows.h" -#include "window-items.h" -#include "printtext.h" -#include "keyboard.h" +#include +#include +#include +#include +#include /* SYNTAX: ME */ static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 27aee5e2..ddd4311e 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -19,25 +19,25 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "channels.h" -#include "ignore.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-queries.h" +#include +#include +#include -#include "../core/module-formats.h" -#include "module-formats.h" -#include "printtext.h" -#include "fe-messages.h" +#include +#include +#include +#include -#include "fe-queries.h" -#include "window-items.h" -#include "fe-irc-channels.h" -#include "fe-irc-server.h" +#include +#include +#include +#include static void sig_message_own_public(SERVER_REC *server, const char *msg, const char *target, const char *origtarget) diff --git a/src/fe-common/irc/fe-irc-queries.c b/src/fe-common/irc/fe-irc-queries.c index c928a94a..7a13542a 100644 --- a/src/fe-common/irc/fe-irc-queries.c +++ b/src/fe-common/irc/fe-irc-queries.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" -#include "servers.h" -#include "queries.h" -#include "nicklist.h" +#include +#include +#include +#include +#include static QUERY_REC *query_find_address(SERVER_REC *server, const char *address) { diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index c2b9fc0f..7e3a6300 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" +#include +#include +#include +#include -#include "servers-setup.h" +#include -#include "levels.h" -#include "irc-chatnets.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "servers-reconnect.h" -#include "irc-servers-setup.h" +#include +#include +#include +#include +#include +#include -#include "fe-windows.h" -#include "printtext.h" +#include +#include const char *get_visible_target(IRC_SERVER_REC *server, const char *target) { diff --git a/src/fe-common/irc/fe-ircnet.c b/src/fe-common/irc/fe-ircnet.c index 5ae5ac05..3484d923 100644 --- a/src/fe-common/irc/fe-ircnet.c +++ b/src/fe-common/irc/fe-ircnet.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "chatnets.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-chatnets.h" -#include "printtext.h" -#include "servers-setup.h" -#include "channels-setup.h" +#include +#include +#include +#include +#include static void cmd_network_list(void) { diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c index dfe65c2d..61ea6c38 100644 --- a/src/fe-common/irc/fe-modes.c +++ b/src/fe-common/irc/fe-modes.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "modes.h" -#include "ignore.h" +#include +#include +#include +#include -#include "printtext.h" +#include #define MODE_WAIT_TIME 3 /* how many seconds to wait for identical modes */ diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index 9ea633b4..602eaf20 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "modes.h" -#include "ignore.h" -#include "netsplit.h" +#include +#include +#include +#include -#include "printtext.h" +#include #define NETJOIN_WAIT_TIME 5 /* how many seconds to wait for the netsplitted JOIN messages to stop */ #define NETJOIN_MAX_WAIT 30 /* how many seconds to wait for nick to join to the rest of the channels she was before the netsplit */ diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 258d0d57..4b7850da 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-commands.h" -#include "ignore.h" -#include "netsplit.h" +#include +#include +#include +#include -#include "printtext.h" +#include #define SPLIT_WAIT_TIME 5 /* how many seconds to wait for the QUIT split messages to stop */ diff --git a/src/fe-common/irc/fe-sasl.c b/src/fe-common/irc/fe-sasl.c index ed11f047..72fec58e 100644 --- a/src/fe-common/irc/fe-sasl.c +++ b/src/fe-common/irc/fe-sasl.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "sasl.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "settings.h" +#include +#include -#include "printtext.h" +#include static void sig_sasl_success(IRC_SERVER_REC *server) { diff --git a/src/fe-common/irc/fe-whois.c b/src/fe-common/irc/fe-whois.c index 117df120..9a31cd9e 100644 --- a/src/fe-common/irc/fe-whois.c +++ b/src/fe-common/irc/fe-whois.c @@ -1,16 +1,16 @@ /* Copyright (C) 1999-2004 Timo Sirainen */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" +#include -#include "printtext.h" +#include static void event_whois(IRC_SERVER_REC *server, const char *data) { diff --git a/src/fe-common/irc/irc-completion.c b/src/fe-common/irc/irc-completion.c index 1593ff3d..71e2e0c8 100644 --- a/src/fe-common/irc/irc-completion.c +++ b/src/fe-common/irc/irc-completion.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "signals.h" -#include "chat-completion.h" +#include +#include static void sig_complete_stats(GList **list, WINDOW_REC *window, const char *word, const char *line, diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index 722aed73..a0f6bd29 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC fecommon_irc_formats[] = { { MODULE_NAME, "IRC", 0 }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 7969b5ac..66a9804f 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { IRCTXT_MODULE_NAME, diff --git a/src/fe-common/irc/module.h b/src/fe-common/irc/module.h index 9583b81b..ad63c95e 100644 --- a/src/fe-common/irc/module.h +++ b/src/fe-common/irc/module.h @@ -1,4 +1,4 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "fe-common/irc" diff --git a/src/fe-common/irc/notifylist/Makefile.am b/src/fe-common/irc/notifylist/Makefile.am index b990dcd2..b0f35fdf 100644 --- a/src/fe-common/irc/notifylist/Makefile.am +++ b/src/fe-common/irc/notifylist/Makefile.am @@ -1,10 +1,6 @@ noinst_LIBRARIES = libfe_irc_notifylist.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-common/irc/notifylist/fe-notifylist.c b/src/fe-common/irc/notifylist/fe-notifylist.c index 1cfe9ed4..1f136a97 100644 --- a/src/fe-common/irc/notifylist/fe-notifylist.c +++ b/src/fe-common/irc/notifylist/fe-notifylist.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "chatnets.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "levels.h" -#include "irc-servers.h" -#include "irc-chatnets.h" -#include "irc/notifylist/notifylist.h" +#include +#include +#include +#include -#include "themes.h" -#include "printtext.h" +#include +#include /* add the nick of a hostmask to list if it isn't there already */ static GSList *mask_add_once(GSList *list, const char *mask) diff --git a/src/fe-common/irc/notifylist/module-formats.c b/src/fe-common/irc/notifylist/module-formats.c index 700a846f..12f41fb5 100644 --- a/src/fe-common/irc/notifylist/module-formats.c +++ b/src/fe-common/irc/notifylist/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC fecommon_irc_notifylist_formats[] = { diff --git a/src/fe-common/irc/notifylist/module-formats.h b/src/fe-common/irc/notifylist/module-formats.h index 042b54ae..ff3085e1 100644 --- a/src/fe-common/irc/notifylist/module-formats.h +++ b/src/fe-common/irc/notifylist/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { IRCTXT_MODULE_NAME, diff --git a/src/fe-common/irc/notifylist/module.h b/src/fe-common/irc/notifylist/module.h index 3c74a998..0e5ca451 100644 --- a/src/fe-common/irc/notifylist/module.h +++ b/src/fe-common/irc/notifylist/module.h @@ -1,4 +1,4 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "fe-common/irc/notifylist" diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index f52d9c47..e72b8723 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -6,10 +6,6 @@ bin_PROGRAMS = irssi-fuzz server-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) irssi_fuzz_DEPENDENCIES = @COMMON_LIBS@ diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am index 9aa39a84..692e95cf 100644 --- a/src/fe-fuzz/fe-common/core/Makefile.am +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -4,10 +4,6 @@ bin_PROGRAMS = theme-load-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) LDADD = \ diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am index cb8b7e31..b2e1ea97 100644 --- a/src/fe-fuzz/irc/core/Makefile.am +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -4,10 +4,6 @@ bin_PROGRAMS = event-get-params-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) LDADD = \ diff --git a/src/fe-none/Makefile.am b/src/fe-none/Makefile.am index 1233fc91..570d6261 100644 --- a/src/fe-none/Makefile.am +++ b/src/fe-none/Makefile.am @@ -1,9 +1,6 @@ bin_PROGRAMS = botti AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ $(GLIB_CFLAGS) botti_DEPENDENCIES = @COMMON_NOUI_LIBS@ diff --git a/src/fe-none/irssi.c b/src/fe-none/irssi.c index 6c601627..c61d74f7 100644 --- a/src/fe-none/irssi.c +++ b/src/fe-none/irssi.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "modules.h" -#include "modules-load.h" -#include "args.h" -#include "signals.h" -#include "core.h" +#include +#include +#include +#include +#include #ifdef HAVE_STATIC_PERL void perl_core_init(void); diff --git a/src/fe-none/module.h b/src/fe-none/module.h index 1bb9e252..cf956eaa 100644 --- a/src/fe-none/module.h +++ b/src/fe-none/module.h @@ -1,3 +1,3 @@ -#include "common.h" +#include #define MODULE_NAME "fe-none" diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index 448a9389..94ce1a3c 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -1,9 +1,6 @@ bin_PROGRAMS = irssi AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ $(GLIB_CFLAGS) irssi_DEPENDENCIES = \ diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index ee3de77d..1a721397 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "misc.h" -#include "utf8.h" -#include "formats.h" +#include +#include +#include -#include "gui-entry.h" -#include "gui-printtext.h" -#include "term.h" -#include "recode.h" +#include +#include +#include +#include #undef i_toupper #undef i_tolower diff --git a/src/fe-text/gui-expandos.c b/src/fe-text/gui-expandos.c index 064a0955..a6b11418 100644 --- a/src/fe-text/gui-expandos.c +++ b/src/fe-text/gui-expandos.c @@ -19,10 +19,10 @@ */ #include "module.h" -#include "expandos.h" +#include -#include "gui-entry.h" -#include "gui-readline.h" +#include +#include /* idle time */ static char *expando_idletime(SERVER_REC *server, void *item, int *free_ret) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index e47e4594..9b472bff 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" +#include +#include -#include "formats.h" -#include "printtext.h" -#include "themes.h" +#include +#include +#include -#include "term.h" -#include "gui-printtext.h" -#include "gui-windows.h" +#include +#include +#include int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7, /* 16-27 */ 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89, diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 64595bbe..90f82220 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -1,9 +1,9 @@ #ifndef __GUI_PRINTTEXT_H #define __GUI_PRINTTEXT_H -#include "gui-windows.h" -#include "textbuffer-view.h" -#include "formats.h" +#include +#include +#include extern int mirc_colors[]; diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 1033339e..8f5594cb 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -19,23 +19,23 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" -#include "special-vars.h" -#include "levels.h" -#include "servers.h" +#include +#include +#include +#include +#include +#include +#include -#include "completion.h" -#include "command-history.h" -#include "keyboard.h" -#include "printtext.h" +#include +#include +#include +#include -#include "term.h" -#include "gui-entry.h" -#include "gui-windows.h" -#include "utf8.h" +#include +#include +#include +#include #include #include diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 0890fe6f..9ca2dfdb 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" -#include "special-vars.h" -#include "levels.h" +#include +#include +#include +#include +#include -#include "term.h" -#include "gui-entry.h" -#include "gui-windows.h" -#include "gui-printtext.h" +#include +#include +#include +#include static int window_create_override; static int wcwidth_impl; diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h index 94c0d28b..9fc3fbd5 100644 --- a/src/fe-text/gui-windows.h +++ b/src/fe-text/gui-windows.h @@ -1,8 +1,8 @@ #ifndef __GUI_WINDOWS_H #define __GUI_WINDOWS_H -#include "mainwindows.h" -#include "textbuffer-view.h" +#include +#include #define WINDOW_GUI(a) ((GUI_WINDOW_REC *) ((a)->gui_data)) #define WINDOW_MAIN(a) (WINDOW_GUI(a)->parent) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index c979e917..8b466905 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -19,29 +19,29 @@ */ #include "module.h" -#include "module-formats.h" -#include "modules-load.h" -#include "args.h" -#include "signals.h" -#include "levels.h" -#include "core.h" -#include "settings.h" -#include "session.h" -#include "servers.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "printtext.h" -#include "fe-common-core.h" -#include "fe-settings.h" -#include "themes.h" +#include +#include +#include +#include -#include "term.h" -#include "gui-entry.h" -#include "mainwindows.h" -#include "gui-printtext.h" -#include "gui-readline.h" -#include "statusbar.h" -#include "gui-windows.h" -#include "irssi-version.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/fe-text/lastlog.c b/src/fe-text/lastlog.c index c0b1dde8..d5aa298a 100644 --- a/src/fe-text/lastlog.c +++ b/src/fe-text/lastlog.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "levels.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "module-formats.h" -#include "printtext.h" +#include +#include -#include "gui-windows.h" -#include "gui-printtext.h" +#include +#include #define DEFAULT_LASTLOG_BEFORE 3 #define DEFAULT_LASTLOG_AFTER 3 diff --git a/src/fe-text/mainwindow-activity.c b/src/fe-text/mainwindow-activity.c index 7f7a0528..d3759ace 100644 --- a/src/fe-text/mainwindow-activity.c +++ b/src/fe-text/mainwindow-activity.c @@ -19,10 +19,10 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" +#include +#include -#include "gui-windows.h" +#include /* Don't send window activity if window is already visible in another mainwindow */ diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c index bb53fdab..ef13892f 100644 --- a/src/fe-text/mainwindows-layout.c +++ b/src/fe-text/mainwindows-layout.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" -#include "levels.h" +#include +#include +#include +#include +#include -#include "mainwindows.h" -#include "gui-windows.h" -#include "textbuffer-view.h" +#include +#include +#include static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) { diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 997cdd22..677e0e14 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" -#include "printtext.h" +#include +#include +#include +#include +#include +#include +#include -#include "term.h" -#include "gui-windows.h" +#include +#include #define NEW_WINDOW_SIZE (WINDOW_MIN_SIZE + 1) diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 4810c1e3..3a7fb1ed 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -1,8 +1,8 @@ #ifndef __MAINWINDOWS_H #define __MAINWINDOWS_H -#include "fe-windows.h" -#include "term.h" +#include +#include #define WINDOW_MIN_SIZE 2 #define NEW_WINDOW_WIDTH 20 /* must be >= MIN_SCREEN_WIDTH defined in term.c */ diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index 277872c6..7cdc5654 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC gui_text_formats[] = { diff --git a/src/fe-text/module-formats.h b/src/fe-text/module-formats.h index ac60fdb7..59c877b8 100644 --- a/src/fe-text/module-formats.h +++ b/src/fe-text/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { TXT_MODULE_NAME, diff --git a/src/fe-text/module.h b/src/fe-text/module.h index 0ca9f703..b1eeeb0e 100644 --- a/src/fe-text/module.h +++ b/src/fe-text/module.h @@ -1,5 +1,5 @@ -#include "common.h" -#include "term.h" +#include +#include #define MODULE_NAME "fe-text" diff --git a/src/fe-text/statusbar-config.c b/src/fe-text/statusbar-config.c index 38372725..3cfa5379 100644 --- a/src/fe-text/statusbar-config.c +++ b/src/fe-text/statusbar-config.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "settings.h" -#include "levels.h" -#include "lib-config/iconfig.h" -#include "misc.h" +#include +#include +#include +#include +#include +#include +#include -#include "statusbar.h" -#include "printtext.h" +#include +#include static void read_statusbar_config_from_node(CONFIG_NODE *node); diff --git a/src/fe-text/statusbar-config.h b/src/fe-text/statusbar-config.h index a2a0b049..ebba7da1 100644 --- a/src/fe-text/statusbar-config.h +++ b/src/fe-text/statusbar-config.h @@ -1,7 +1,7 @@ #ifndef __STATUSBAR_CONFIG_H #define __STATUSBAR_CONFIG_H -#include "statusbar.h" +#include void statusbar_config_destroy(STATUSBAR_GROUP_REC *group, STATUSBAR_CONFIG_REC *config); diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 27efcbd1..c6770e32 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" -#include "servers.h" +#include +#include +#include -#include "themes.h" -#include "statusbar.h" -#include "gui-entry.h" -#include "gui-windows.h" +#include +#include +#include +#include /* how often to redraw lagging time (seconds) */ #define LAG_REFRESH_TIME 10 diff --git a/src/fe-text/statusbar.c b/src/fe-text/statusbar.c index 40837eea..2439d101 100644 --- a/src/fe-text/statusbar.c +++ b/src/fe-text/statusbar.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "expandos.h" -#include "special-vars.h" +#include +#include +#include -#include "themes.h" +#include -#include "statusbar.h" -#include "statusbar-config.h" -#include "gui-windows.h" -#include "gui-printtext.h" +#include +#include +#include +#include void statusbar_items_init(void); void statusbar_items_deinit(void); diff --git a/src/fe-text/statusbar.h b/src/fe-text/statusbar.h index b0048cc4..eae29900 100644 --- a/src/fe-text/statusbar.h +++ b/src/fe-text/statusbar.h @@ -1,8 +1,8 @@ #ifndef __STATUSBAR_H #define __STATUSBAR_H -#include "mainwindows.h" -#include "statusbar-item.h" +#include +#include #define STATUSBAR_PRIORITY_HIGH 100 #define STATUSBAR_PRIORITY_NORMAL 0 diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 6e031ebf..5235f72d 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "term.h" -#include "terminfo-core.h" -#include "fe-windows.h" -#include "gui-printtext.h" -#include "utf8.h" +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/fe-text/term.c b/src/fe-text/term.c index 408dc7ef..1d5c2bef 100644 --- a/src/fe-text/term.c +++ b/src/fe-text/term.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "settings.h" +#include +#include +#include -#include "term.h" -#include "mainwindows.h" +#include +#include #ifdef HAVE_SYS_IOCTL_H # include diff --git a/src/fe-text/term.h b/src/fe-text/term.h index f25154c2..af866bea 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -27,7 +27,7 @@ typedef struct _TERM_WINDOW TERM_WINDOW; #define TERM_TYPE_UTF8 1 #define TERM_TYPE_BIG5 2 -#include "utf8.h" +#include extern TERM_WINDOW *root_window; extern int term_width, term_height; diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index 9c9179a5..d2273d71 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -1,6 +1,6 @@ #include "module.h" -#include "signals.h" -#include "terminfo-core.h" +#include +#include #ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE 0 diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c index 7278772c..318ee077 100644 --- a/src/fe-text/textbuffer-commands.c +++ b/src/fe-text/textbuffer-commands.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "levels.h" -#include "settings.h" -#include "servers.h" +#include +#include +#include +#include +#include +#include +#include -#include "printtext.h" -#include "gui-windows.h" +#include +#include static int activity_hide_window_hidelevel; diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index e5141430..ec518cbf 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -21,9 +21,9 @@ #define G_LOG_DOMAIN "TextBufferView" #include "module.h" -#include "textbuffer-view.h" -#include "signals.h" -#include "utf8.h" +#include +#include +#include typedef struct { char *name; diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index 1ae7c163..54775783 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -1,8 +1,8 @@ #ifndef __TEXTBUFFER_VIEW_H #define __TEXTBUFFER_VIEW_H -#include "textbuffer.h" -#include "term.h" +#include +#include typedef struct _TEXT_BUFFER_VIEW_REC TEXT_BUFFER_VIEW_REC; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 5f9e68ad..470c0b00 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -21,12 +21,12 @@ #define G_LOG_DOMAIN "TextBuffer" #include "module.h" -#include "misc.h" -#include "formats.h" -#include "utf8.h" -#include "iregex.h" +#include +#include +#include +#include -#include "textbuffer.h" +#include #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am index c668faea..63b41113 100644 --- a/src/irc/core/Makefile.am +++ b/src/irc/core/Makefile.am @@ -1,8 +1,6 @@ noinst_LIBRARIES = libirc_core.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) diff --git a/src/irc/core/bans.c b/src/irc/core/bans.c index 198fdc4a..a61742f3 100644 --- a/src/irc/core/bans.c +++ b/src/irc/core/bans.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-masks.h" -#include "irc-commands.h" -#include "modes.h" -#include "mode-lists.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include +#include #define BAN_TYPE_NORMAL (IRC_MASK_USER | IRC_MASK_DOMAIN) #define BAN_TYPE_USER (IRC_MASK_USER) diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 6ffe7364..7603a14f 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "channel-events.h" -#include "channels-setup.h" -#include "settings.h" -#include "recode.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" +#include +#include static void check_join_failure(IRC_SERVER_REC *server, const char *channel) { diff --git a/src/irc/core/channel-events.h b/src/irc/core/channel-events.h index 6d01c48e..d13c9760 100644 --- a/src/irc/core/channel-events.h +++ b/src/irc/core/channel-events.h @@ -1,7 +1,7 @@ #ifndef __CHANNEL_EVENTS_H #define __CHANNEL_EVENTS_H -#include "irc.h" +#include void channel_events_init(void); void channel_events_deinit(void); diff --git a/src/irc/core/channel-rejoin.c b/src/irc/core/channel-rejoin.c index 154035ae..f49c69b6 100644 --- a/src/irc/core/channel-rejoin.c +++ b/src/irc/core/channel-rejoin.c @@ -20,14 +20,14 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" -#include "misc.h" +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-commands.h" -#include "channel-rejoin.h" +#include +#include +#include +#include #define REJOIN_TIMEOUT (1000*60*5) /* try to rejoin every 5 minutes */ diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index d7dadf04..8f90af64 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -39,16 +39,16 @@ loop: */ #include "module.h" -#include "misc.h" -#include "signals.h" -#include "settings.h" +#include +#include +#include -#include "modes.h" -#include "mode-lists.h" -#include "nicklist.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "servers-redirect.h" +#include +#include +#include +#include +#include +#include enum { CHANNEL_QUERY_MODE, diff --git a/src/irc/core/ctcp.c b/src/irc/core/ctcp.c index accbb57f..42b93411 100644 --- a/src/irc/core/ctcp.c +++ b/src/irc/core/ctcp.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "special-vars.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "servers-idle.h" -#include "ignore.h" -#include "ctcp.h" +#include +#include +#include +#include typedef struct { char *name; diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 2d740c59..21a27324 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -18,11 +18,11 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" +#include +#include -#include "irc-cap.h" -#include "irc-servers.h" +#include +#include int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) { diff --git a/src/irc/core/irc-channels-setup.c b/src/irc/core/irc-channels-setup.c index bbbc095c..93874d35 100644 --- a/src/irc/core/irc-channels-setup.c +++ b/src/irc/core/irc-channels-setup.c @@ -19,8 +19,8 @@ */ #include "module.h" -#include "signals.h" -#include "channels.h" +#include +#include void irc_channels_setup_init(void) { diff --git a/src/irc/core/irc-channels.c b/src/irc/core/irc-channels.c index e775f530..b2ee3772 100644 --- a/src/irc/core/irc-channels.c +++ b/src/irc/core/irc-channels.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "levels.h" -#include "channels-setup.h" +#include +#include +#include +#include -#include "bans.h" -#include "modes.h" -#include "mode-lists.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-nicklist.h" -#include "channel-rejoin.h" +#include +#include +#include +#include +#include +#include +#include void channels_query_init(void); void channels_query_deinit(void); diff --git a/src/irc/core/irc-channels.h b/src/irc/core/irc-channels.h index 8cfc4992..2262b484 100644 --- a/src/irc/core/irc-channels.h +++ b/src/irc/core/irc-channels.h @@ -1,8 +1,8 @@ #ifndef __IRC_CHANNELS_H #define __IRC_CHANNELS_H -#include "chat-protocols.h" -#include "channels.h" +#include +#include /* Returns IRC_CHANNEL_REC if it's IRC channel, NULL if it isn't. */ #define IRC_CHANNEL(channel) \ @@ -13,7 +13,7 @@ #define STRUCT_SERVER_REC IRC_SERVER_REC struct _IRC_CHANNEL_REC { -#include "channel-rec.h" +#include GSList *banlist; /* list of bans */ diff --git a/src/irc/core/irc-chatnets.c b/src/irc/core/irc-chatnets.c index 98ce89c3..c3b24a11 100644 --- a/src/irc/core/irc-chatnets.c +++ b/src/irc/core/irc-chatnets.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "signals.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include -#include "irc-chatnets.h" +#include void ircnet_create(IRC_CHATNET_REC *rec) { diff --git a/src/irc/core/irc-chatnets.h b/src/irc/core/irc-chatnets.h index 3fd44472..00aea848 100644 --- a/src/irc/core/irc-chatnets.h +++ b/src/irc/core/irc-chatnets.h @@ -1,8 +1,8 @@ #ifndef __IRC_CHATNETS_H #define __IRC_CHATNETS_H -#include "chat-protocols.h" -#include "chatnets.h" +#include +#include /* returns IRC_CHATNET_REC if it's IRC network, NULL if it isn't */ #define IRC_CHATNET(chatnet) \ @@ -15,7 +15,7 @@ #define IRCNET(ircnet) IRC_CHATNET(ircnet) struct _IRC_CHATNET_REC { -#include "chatnet-rec.h" +#include char *usermode; char *alternate_nick; diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 32ee8845..4062b1da 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "misc.h" -#include "recode.h" -#include "special-vars.h" -#include "settings.h" -#include "window-item-def.h" +#include +#include +#include +#include +#include -#include "servers-reconnect.h" -#include "servers-redirect.h" -#include "servers-setup.h" -#include "nicklist.h" +#include +#include +#include +#include -#include "bans.h" -#include "irc-commands.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-queries.h" +#include +#include +#include +#include +#include /* How often to check if there's anyone to be unbanned in knockout list */ #define KNOCKOUT_TIMECHECK 10000 diff --git a/src/irc/core/irc-commands.h b/src/irc/core/irc-commands.h index 739bd443..3e24c5a8 100644 --- a/src/irc/core/irc-commands.h +++ b/src/irc/core/irc-commands.h @@ -1,7 +1,7 @@ #ifndef __IRC_COMMANDS_H #define __IRC_COMMANDS_H -#include "commands.h" +#include #define command_bind_irc(cmd, section, signal) \ command_bind_proto(cmd, IRC_PROTOCOL, section, signal) diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index 950e5029..e65abe25 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -19,22 +19,22 @@ */ #include "module.h" -#include "chat-protocols.h" -#include "settings.h" +#include +#include -#include "irc-servers.h" -#include "irc-chatnets.h" -#include "irc-channels.h" -#include "irc-queries.h" -#include "irc-cap.h" -#include "sasl.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers-setup.h" -#include "channels-setup.h" +#include +#include -#include "ctcp.h" -#include "irc-commands.h" -#include "netsplit.h" +#include +#include +#include void irc_expandos_init(void); void irc_expandos_deinit(void); diff --git a/src/irc/core/irc-expandos.c b/src/irc/core/irc-expandos.c index 62ef577a..625e6e8b 100644 --- a/src/irc/core/irc-expandos.c +++ b/src/irc/core/irc-expandos.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "misc.h" -#include "expandos.h" -#include "settings.h" +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "nicklist.h" +#include +#include +#include #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 diff --git a/src/irc/core/irc-masks.c b/src/irc/core/irc-masks.c index d93a083d..e2c5aea6 100644 --- a/src/irc/core/irc-masks.c +++ b/src/irc/core/irc-masks.c @@ -19,9 +19,9 @@ */ #include "module.h" -#include "network.h" +#include -#include "irc-masks.h" +#include static char *get_domain_mask(char *host) { diff --git a/src/irc/core/irc-masks.h b/src/irc/core/irc-masks.h index 680877c9..e152c52a 100644 --- a/src/irc/core/irc-masks.h +++ b/src/irc/core/irc-masks.h @@ -1,7 +1,7 @@ #ifndef __IRC_MASKS_H #define __IRC_MASKS_H -#include "masks.h" +#include #define IRC_MASK_NICK 0x01 #define IRC_MASK_USER 0x02 diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 3e16db80..54a9bd3b 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-masks.h" -#include "irc-nicklist.h" -#include "modes.h" -#include "servers.h" +#include +#include +#include +#include +#include +#include /* Add new nick to list */ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, diff --git a/src/irc/core/irc-nicklist.h b/src/irc/core/irc-nicklist.h index 2ae17d2c..e9b30f30 100644 --- a/src/irc/core/irc-nicklist.h +++ b/src/irc/core/irc-nicklist.h @@ -1,7 +1,7 @@ #ifndef __IRC_NICKLIST_H #define __IRC_NICKLIST_H -#include "nicklist.h" +#include /* Add new nick to list */ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, diff --git a/src/irc/core/irc-queries.c b/src/irc/core/irc-queries.c index 64995ead..9c7eb6a9 100644 --- a/src/irc/core/irc-queries.c +++ b/src/irc/core/irc-queries.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" +#include +#include -#include "irc-nicklist.h" -#include "irc-servers.h" -#include "irc-queries.h" +#include +#include +#include QUERY_REC *irc_query_create(const char *server_tag, const char *nick, int automatic) diff --git a/src/irc/core/irc-queries.h b/src/irc/core/irc-queries.h index 0a3cc7a5..323006ad 100644 --- a/src/irc/core/irc-queries.h +++ b/src/irc/core/irc-queries.h @@ -1,8 +1,8 @@ #ifndef __IRC_QUERIES_H #define __IRC_QUERIES_H -#include "chat-protocols.h" -#include "queries.h" +#include +#include /* Returns IRC_QUERY_REC if it's IRC query, NULL if it isn't. */ #define IRC_QUERY(query) \ diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index ca61492d..3d2933f4 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "commands.h" -#include "network.h" -#include "signals.h" +#include +#include +#include -#include "modes.h" -#include "irc-servers.h" +#include +#include -#include "settings.h" +#include static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, IRC_SERVER_CONNECT_REC *src) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 0af93902..56e52edd 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "network.h" -#include "servers-setup.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc-chatnets.h" -#include "irc-servers-setup.h" -#include "irc-servers.h" -#include "sasl.h" +#include +#include +#include +#include /* Fill information to connection from server setup record */ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn, diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index 92629c2b..ac2ca2fc 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -1,8 +1,8 @@ #ifndef __IRC_SERVERS_SETUP_H #define __IRC_SERVERS_SETUP_H -#include "chat-protocols.h" -#include "servers-setup.h" +#include +#include #define IRC_SERVER_SETUP(server) \ PROTO_CHECK_CAST(SERVER_SETUP(server), IRC_SERVER_SETUP_REC, \ @@ -12,7 +12,7 @@ (IRC_SERVER_SETUP(server) ? TRUE : FALSE) typedef struct { -#include "server-setup-rec.h" +#include /* override the default if > 0 */ int max_cmds_at_once; diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 03c73312..7057c02a 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -20,30 +20,30 @@ #include "module.h" -#include "net-sendbuffer.h" -#include "signals.h" -#include "rawlog.h" -#include "misc.h" +#include +#include +#include +#include -#include "channels.h" -#include "queries.h" +#include +#include -#include "irc-nicklist.h" -#include "irc-queries.h" -#include "irc-servers-setup.h" -#include "irc-servers.h" -#include "irc-cap.h" -#include "sasl.h" +#include +#include +#include +#include +#include +#include -#include "channels-setup.h" -#include "channel-rejoin.h" -#include "servers-idle.h" -#include "servers-reconnect.h" -#include "servers-redirect.h" -#include "modes.h" +#include +#include +#include +#include +#include +#include -#include "settings.h" -#include "recode.h" +#include +#include #define DEFAULT_MAX_KICKS 1 #define DEFAULT_MAX_MODES 3 diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 1374e846..c798a03b 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -1,9 +1,9 @@ #ifndef __IRC_SERVERS_H #define __IRC_SERVERS_H -#include "chat-protocols.h" -#include "servers.h" -#include "modes.h" +#include +#include +#include /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ @@ -22,7 +22,7 @@ /* all strings should be either NULL or dynamically allocated */ /* address and nick are mandatory, rest are optional */ struct _IRC_SERVER_CONNECT_REC { -#include "server-connect-rec.h" +#include char *usermode; char *alternate_nick; @@ -40,7 +40,7 @@ struct _IRC_SERVER_CONNECT_REC { #define STRUCT_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC struct _IRC_SERVER_REC { -#include "server-rec.h" +#include /* For deciding if event should be redirected */ GSList *redirects; diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index 18e8e5c7..ec2c86ee 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "net-sendbuffer.h" -#include "lib-config/iconfig.h" -#include "misc.h" +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-nicklist.h" +#include +#include +#include -#include "sasl.h" +#include struct _isupport_data { CONFIG_REC *config; CONFIG_NODE *node; }; diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index a740b0da..4940fcb4 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "modules.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "rawlog.h" -#include "misc.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "servers-redirect.h" +#include +#include +#include char *current_server_event; static int signal_default_event; diff --git a/src/irc/core/irc.h b/src/irc/core/irc.h index b5bd833a..d018b90c 100644 --- a/src/irc/core/irc.h +++ b/src/irc/core/irc.h @@ -49,7 +49,7 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int send_now, int immediate, int raw); /* Get count parameters from data */ -#include "commands.h" +#include char *event_get_param(char **data); char *event_get_params(const char *data, int count, ...); diff --git a/src/irc/core/lag.c b/src/irc/core/lag.c index 787505f0..d3d6118d 100644 --- a/src/irc/core/lag.c +++ b/src/irc/core/lag.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include -#include "irc-servers.h" -#include "servers-redirect.h" +#include +#include static int timeout_tag; diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 6cc2b7c7..ec63a0b3 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-nicklist.h" +#include +#include +#include static int massjoin_tag; static int massjoin_max_joins; diff --git a/src/irc/core/mode-lists.c b/src/irc/core/mode-lists.c index 73b7a6b2..d2d7234f 100644 --- a/src/irc/core/mode-lists.c +++ b/src/irc/core/mode-lists.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "misc.h" -#include "signals.h" +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "mode-lists.h" +#include +#include +#include static void ban_free(GSList **list, BAN_REC *rec) { diff --git a/src/irc/core/modes.c b/src/irc/core/modes.c index cc3d0faf..b0de2f18 100644 --- a/src/irc/core/modes.c +++ b/src/irc/core/modes.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" +#include +#include -#include "irc-commands.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "servers-redirect.h" -#include "modes.h" -#include "mode-lists.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include +#include /* Change nick's mode in channel */ static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick, diff --git a/src/irc/core/modes.h b/src/irc/core/modes.h index bef017ba..9442dd5e 100644 --- a/src/irc/core/modes.h +++ b/src/irc/core/modes.h @@ -1,8 +1,8 @@ #ifndef __MODES_H #define __MODES_H -#include "irc-channels.h" -#include "nicklist.h" /* MAX_USER_PREFIXES */ +#include +#include /* MAX_USER_PREFIXES */ typedef void mode_func_t(IRC_CHANNEL_REC *, const char *, char, char, char *, GString *); diff --git a/src/irc/core/module.h b/src/irc/core/module.h index 19c0b3cc..41800038 100644 --- a/src/irc/core/module.h +++ b/src/irc/core/module.h @@ -1,4 +1,4 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "irc/core" diff --git a/src/irc/core/netsplit.c b/src/irc/core/netsplit.c index 0642846f..1463f962 100644 --- a/src/irc/core/netsplit.c +++ b/src/irc/core/netsplit.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "netsplit.h" +#include +#include +#include /* How long to keep netsplits in memory (seconds) */ #define NETSPLIT_MAX_REMEMBER (60*60) diff --git a/src/irc/core/netsplit.h b/src/irc/core/netsplit.h index cbe3f26f..7cdee694 100644 --- a/src/irc/core/netsplit.h +++ b/src/irc/core/netsplit.h @@ -1,7 +1,7 @@ #ifndef __NETSPLIT_H #define __NETSPLIT_H -#include "nicklist.h" +#include typedef struct { char *server; diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 92eb6244..22a10ec7 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "misc.h" -#include "settings.h" +#include +#include -#include "irc-cap.h" -#include "irc-servers.h" -#include "sasl.h" +#include +#include +#include /* * Based on IRCv3 SASL Extension Specification: diff --git a/src/irc/core/servers-idle.c b/src/irc/core/servers-idle.c index 2b1851af..93c8f05a 100644 --- a/src/irc/core/servers-idle.c +++ b/src/irc/core/servers-idle.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "signals.h" +#include -#include "irc-servers.h" -#include "servers-idle.h" -#include "servers-redirect.h" +#include +#include +#include typedef struct { char *cmd; diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c index aeb9c010..770aa4c2 100644 --- a/src/irc/core/servers-redirect.c +++ b/src/irc/core/servers-redirect.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "rawlog.h" +#include +#include +#include -#include "irc-servers.h" -#include "servers-redirect.h" +#include +#include #define DEFAULT_REDIRECT_TIMEOUT 60 diff --git a/src/irc/dcc/Makefile.am b/src/irc/dcc/Makefile.am index cf1e2ff5..a81bf84d 100644 --- a/src/irc/dcc/Makefile.am +++ b/src/irc/dcc/Makefile.am @@ -1,9 +1,6 @@ noinst_LIBRARIES = libirc_dcc.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ $(GLIB_CFLAGS) libirc_dcc_a_SOURCES = \ diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c index dd12f438..ba0bed0b 100644 --- a/src/irc/dcc/dcc-autoget.c +++ b/src/irc/dcc/dcc-autoget.c @@ -19,13 +19,13 @@ */ #include "module.h" -#include "signals.h" -#include "masks.h" -#include "settings.h" -#include "servers.h" -#include "misc.h" +#include +#include +#include +#include +#include -#include "dcc-get.h" +#include static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr) { diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index 5e03042f..987a5ba9 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -19,19 +19,19 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "recode.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-queries.h" -#include "masks.h" +#include +#include +#include -#include "dcc-chat.h" +#include static char *dcc_chat_get_new_id(const char *nick) { diff --git a/src/irc/dcc/dcc-chat.h b/src/irc/dcc/dcc-chat.h index c8f2cea9..a22fe75d 100644 --- a/src/irc/dcc/dcc-chat.h +++ b/src/irc/dcc/dcc-chat.h @@ -1,7 +1,7 @@ #ifndef __DCC_CHAT_H #define __DCC_CHAT_H -#include "dcc.h" +#include #define DCC_CHAT(dcc) \ MODULE_CHECK_CAST_MODULE(dcc, CHAT_DCC_REC, type, "DCC", "CHAT") @@ -10,7 +10,7 @@ (DCC_CHAT(dcc) ? TRUE : FALSE) struct CHAT_DCC_REC { -#include "dcc-rec.h" +#include char *id; /* unique identifier - usually same as nick. */ NET_SENDBUF_REC *sendbuf; diff --git a/src/irc/dcc/dcc-file-rec.h b/src/irc/dcc/dcc-file-rec.h index fe66a985..28a488e4 100644 --- a/src/irc/dcc/dcc-file-rec.h +++ b/src/irc/dcc/dcc-file-rec.h @@ -1,4 +1,4 @@ -#include "dcc-rec.h" +#include uoff_t size, skipped; /* file size / skipped at start */ int fhandle; /* file handle */ diff --git a/src/irc/dcc/dcc-file.h b/src/irc/dcc/dcc-file.h index 4ff4a2e9..ef32f07c 100644 --- a/src/irc/dcc/dcc-file.h +++ b/src/irc/dcc/dcc-file.h @@ -1,10 +1,10 @@ #ifndef __DCC_FILE_H #define __DCC_FILE_H -#include "dcc.h" +#include typedef struct { -#include "dcc-file-rec.h" +#include } FILE_DCC_REC; #endif diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index ee8b9a49..0191c679 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "misc.h" -#include "settings.h" -#include "net-sendbuffer.h" -#include "irc-servers.h" +#include +#include +#include +#include +#include +#include +#include -#include "dcc-get.h" -#include "dcc-send.h" +#include +#include static char *dcc_get_recv_buffer; diff --git a/src/irc/dcc/dcc-get.h b/src/irc/dcc/dcc-get.h index 7ac7b3c1..b6ee385c 100644 --- a/src/irc/dcc/dcc-get.h +++ b/src/irc/dcc/dcc-get.h @@ -1,7 +1,7 @@ #ifndef __DCC_GET_H #define __DCC_GET_H -#include "dcc.h" +#include #define DCC_GET(dcc) \ MODULE_CHECK_CAST_MODULE(dcc, GET_DCC_REC, type, "DCC", "GET") @@ -18,7 +18,7 @@ enum { }; typedef struct { -#include "dcc-file-rec.h" +#include int get_type; /* what to do if file exists? */ char *file; /* file name we're really moving, arg is just the reference */ diff --git a/src/irc/dcc/dcc-queue.c b/src/irc/dcc/dcc-queue.c index 895f9e44..0253be4f 100644 --- a/src/irc/dcc/dcc-queue.c +++ b/src/irc/dcc/dcc-queue.c @@ -21,15 +21,15 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "settings.h" -#include "irc-servers.h" +#include +#include +#include +#include +#include +#include +#include -#include "dcc-queue.h" +#include static GPtrArray *queuelist; diff --git a/src/irc/dcc/dcc-queue.h b/src/irc/dcc/dcc-queue.h index b05beb47..8c1a9b46 100644 --- a/src/irc/dcc/dcc-queue.h +++ b/src/irc/dcc/dcc-queue.h @@ -1,7 +1,7 @@ #ifndef __DCC_QUEUE_H_ #define __DCC_QUEUE_H_ -#include "dcc-chat.h" +#include enum { DCC_QUEUE_NORMAL, diff --git a/src/irc/dcc/dcc-resume.c b/src/irc/dcc/dcc-resume.c index ce0ac925..b0438e79 100644 --- a/src/irc/dcc/dcc-resume.c +++ b/src/irc/dcc/dcc-resume.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "misc.h" +#include +#include +#include +#include -#include "dcc-file.h" -#include "dcc-get.h" -#include "dcc-send.h" -#include "dcc-chat.h" +#include +#include +#include +#include static FILE_DCC_REC *dcc_resume_find(int type, const char *nick, int port) { diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c index 50009287..6eabd25f 100644 --- a/src/irc/dcc/dcc-send.c +++ b/src/irc/dcc/dcc-send.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" +#include -#include "dcc-send.h" -#include "dcc-chat.h" -#include "dcc-queue.h" +#include +#include +#include #include diff --git a/src/irc/dcc/dcc-send.h b/src/irc/dcc/dcc-send.h index 378f1c54..a0ee1ade 100644 --- a/src/irc/dcc/dcc-send.h +++ b/src/irc/dcc/dcc-send.h @@ -1,7 +1,7 @@ #ifndef __DCC_SEND_H #define __DCC_SEND_H -#include "dcc.h" +#include #define DCC_SEND(dcc) \ MODULE_CHECK_CAST_MODULE(dcc, SEND_DCC_REC, type, "DCC", "SEND") @@ -10,7 +10,7 @@ (DCC_SEND(dcc) ? TRUE : FALSE) typedef struct { -#include "dcc-file-rec.h" +#include unsigned int file_quoted:1; /* file name was received quoted ("file name") */ diff --git a/src/irc/dcc/dcc-server.c b/src/irc/dcc/dcc-server.c index 7ae572cd..0a6c0acf 100644 --- a/src/irc/dcc/dcc-server.c +++ b/src/irc/dcc/dcc-server.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "misc.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" +#include -#include "dcc-chat.h" -#include "dcc-get.h" -#include "dcc-server.h" +#include +#include +#include void sig_dccget_connected(GET_DCC_REC *dcc); GET_DCC_REC *dcc_get_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat, diff --git a/src/irc/dcc/dcc-server.h b/src/irc/dcc/dcc-server.h index 72435cbf..a1973b5f 100644 --- a/src/irc/dcc/dcc-server.h +++ b/src/irc/dcc/dcc-server.h @@ -1,7 +1,7 @@ #ifndef __DCC_SERVER_H #define __DCC_SERVER_H -#include "dcc.h" +#include #define DCC_SERVER(dcc) \ MODULE_CHECK_CAST_MODULE(dcc, SERVER_DCC_REC, type, "DCC", "SERVER") @@ -10,7 +10,7 @@ (DCC_SERVER(dcc) ? TRUE : FALSE) struct SERVER_DCC_REC { -#include "dcc-rec.h" +#include NET_SENDBUF_REC *sendbuf; unsigned int accept_send:1; /* Accept SEND connections */ diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index 01ab0e59..006a2b77 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -19,21 +19,21 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "network.h" -#include "misc.h" -#include "settings.h" -#include "ignore.h" -#include "levels.h" +#include +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "servers-setup.h" +#include +#include -#include "dcc-chat.h" -#include "dcc-get.h" -#include "dcc-send.h" -#include "dcc-server.h" +#include +#include +#include +#include void dcc_resume_init(void); void dcc_resume_deinit(void); diff --git a/src/irc/dcc/dcc.h b/src/irc/dcc/dcc.h index 144cc89b..5f54ee18 100644 --- a/src/irc/dcc/dcc.h +++ b/src/irc/dcc/dcc.h @@ -1,15 +1,15 @@ #ifndef __DCC_H #define __DCC_H -#include "modules.h" -#include "network.h" +#include +#include #define DCC(dcc) ((DCC_REC *) (dcc)) typedef struct CHAT_DCC_REC CHAT_DCC_REC; typedef struct { -#include "dcc-rec.h" +#include } DCC_REC; /* fully connected? */ diff --git a/src/irc/dcc/module.h b/src/irc/dcc/module.h index 8436945d..4330d0a3 100644 --- a/src/irc/dcc/module.h +++ b/src/irc/dcc/module.h @@ -1,4 +1,4 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "irc/dcc" diff --git a/src/irc/flood/Makefile.am b/src/irc/flood/Makefile.am index 1c4d786a..b582ffe4 100644 --- a/src/irc/flood/Makefile.am +++ b/src/irc/flood/Makefile.am @@ -1,9 +1,6 @@ noinst_LIBRARIES = libirc_flood.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ $(GLIB_CFLAGS) libirc_flood_a_SOURCES = \ diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 86ff3ec5..33bd91f4 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "ignore.h" +#include +#include void autoignore_update(IGNORE_REC *rec, int level) { diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c index b528f707..886a266c 100644 --- a/src/irc/flood/flood.c +++ b/src/irc/flood/flood.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" -#include "levels.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "ignore.h" +#include +#include +#include void autoignore_init(void); void autoignore_deinit(void); diff --git a/src/irc/flood/module.h b/src/irc/flood/module.h index fc7eceeb..a80c46f7 100644 --- a/src/irc/flood/module.h +++ b/src/irc/flood/module.h @@ -1,5 +1,5 @@ -#include "common.h" -#include "irc.h" +#include +#include typedef struct { /* Flood protection */ diff --git a/src/irc/notifylist/Makefile.am b/src/irc/notifylist/Makefile.am index abd9d18d..421bc7d4 100644 --- a/src/irc/notifylist/Makefile.am +++ b/src/irc/notifylist/Makefile.am @@ -1,9 +1,6 @@ noinst_LIBRARIES = libirc_notifylist.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ $(GLIB_CFLAGS) libirc_notifylist_a_SOURCES = \ diff --git a/src/irc/notifylist/module.h b/src/irc/notifylist/module.h index c7239a88..f109afff 100644 --- a/src/irc/notifylist/module.h +++ b/src/irc/notifylist/module.h @@ -1,5 +1,5 @@ -#include "common.h" -#include "irc.h" +#include +#include #define MODULE_NAME "irc/notifylist" @@ -23,7 +23,7 @@ typedef struct { GSList *ison_tempusers; /* Temporary list for saving /ISON events.. */ } MODULE_SERVER_REC; -#include "irc-servers.h" +#include NOTIFY_NICK_REC *notify_nick_create(IRC_SERVER_REC *server, const char *nick); void notify_nick_destroy(NOTIFY_NICK_REC *rec); diff --git a/src/irc/notifylist/notify-commands.c b/src/irc/notifylist/notify-commands.c index 0d4fd4f2..e7bceaac 100644 --- a/src/irc/notifylist/notify-commands.c +++ b/src/irc/notifylist/notify-commands.c @@ -19,12 +19,12 @@ */ #include "module.h" -#include "signals.h" -#include "commands.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include -#include "notifylist.h" +#include /* SYNTAX: NOTIFY [-away] [] */ static void cmd_notify(gchar *data) diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index 8a8865cc..39292896 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -19,15 +19,15 @@ */ #include "module.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "servers-redirect.h" +#include +#include +#include -#include "notifylist.h" +#include #define DEFAULT_NOTIFY_CHECK_TIME "1min" #define DEFAULT_NOTIFY_WHOIS_TIME "5min" diff --git a/src/irc/notifylist/notify-setup.c b/src/irc/notifylist/notify-setup.c index 9ea481ca..62f983e2 100644 --- a/src/irc/notifylist/notify-setup.c +++ b/src/irc/notifylist/notify-setup.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "lib-config/iconfig.h" -#include "settings.h" +#include +#include -#include "irc-servers.h" -#include "notifylist.h" +#include +#include void notifylist_add_config(NOTIFYLIST_REC *rec) { diff --git a/src/irc/notifylist/notify-whois.c b/src/irc/notifylist/notify-whois.c index 2d0736b5..bdfd72b4 100644 --- a/src/irc/notifylist/notify-whois.c +++ b/src/irc/notifylist/notify-whois.c @@ -19,14 +19,14 @@ */ #include "module.h" -#include "signals.h" -#include "expandos.h" +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "masks.h" +#include +#include +#include -#include "notifylist.h" +#include static char *last_notify_nick; diff --git a/src/irc/notifylist/notifylist.c b/src/irc/notifylist/notifylist.c index 4fd5ef1a..475e92c8 100644 --- a/src/irc/notifylist/notifylist.c +++ b/src/irc/notifylist/notifylist.c @@ -19,18 +19,18 @@ */ #include "module.h" -#include "modules.h" -#include "signals.h" -#include "settings.h" +#include +#include +#include -#include "irc.h" -#include "irc-channels.h" -#include "servers-redirect.h" -#include "masks.h" -#include "nicklist.h" +#include +#include +#include +#include +#include -#include "notifylist.h" -#include "notify-setup.h" +#include +#include GSList *notifies; diff --git a/src/irc/proxy/Makefile.am b/src/irc/proxy/Makefile.am index 4eb73bb8..6411f49d 100644 --- a/src/irc/proxy/Makefile.am +++ b/src/irc/proxy/Makefile.am @@ -2,9 +2,6 @@ moduledir = $(libdir)/irssi/modules module_LTLIBRARIES = libirc_proxy.la AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ $(GLIB_CFLAGS) libirc_proxy.a: diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c index e39c21a6..82dc1fe5 100644 --- a/src/irc/proxy/dump.c +++ b/src/irc/proxy/dump.c @@ -19,16 +19,16 @@ */ #include "module.h" -#include "network.h" -#include "net-sendbuffer.h" -#include "settings.h" -#include "irssi-version.h" -#include "recode.h" +#include +#include +#include +#include +#include -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-nicklist.h" -#include "modes.h" +#include +#include +#include +#include void proxy_outdata(CLIENT_REC *client, const char *data, ...) { diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index cde4c0be..37e2a939 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -19,17 +19,17 @@ */ #include "module.h" -#include "signals.h" -#include "net-sendbuffer.h" -#include "servers-redirect.h" -#include "levels.h" -#include "settings.h" -#include "misc.h" +#include +#include +#include +#include +#include +#include -#include "irc.h" -#include "irc-channels.h" +#include +#include -#include "fe-common/core/printtext.h" /* FIXME: evil. need to do fe-proxy */ +#include /* FIXME: evil. need to do fe-proxy */ #include diff --git a/src/irc/proxy/module.h b/src/irc/proxy/module.h index ff95227f..b6ad3a4c 100644 --- a/src/irc/proxy/module.h +++ b/src/irc/proxy/module.h @@ -1,12 +1,12 @@ -#include "common.h" +#include #define MODULE_NAME "proxy" -#include "network.h" -#include "irc.h" -#include "irc-servers.h" +#include +#include +#include -#include "proxy.h" +#include extern GSList *proxy_listens; extern GSList *proxy_clients; diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index 2875d2c2..d32b6009 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -19,11 +19,11 @@ */ #include "module.h" -#include "signals.h" -#include "settings.h" -#include "levels.h" +#include +#include +#include -#include "fe-common/core/printtext.h" +#include /* SYNTAX: IRSSIPROXY STATUS */ static void cmd_irssiproxy_status(const char *data, IRC_SERVER_REC *server) diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index 620ea605..2cbaf69d 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -1,11 +1,11 @@ #ifndef PROXY_H #define PROXY_H -#include "common.h" +#include -#include "network.h" -#include "irc.h" -#include "irc-servers.h" +#include +#include +#include typedef struct { int port; diff --git a/src/lib-config/Makefile.am b/src/lib-config/Makefile.am index 06c7787c..d644eae5 100644 --- a/src/lib-config/Makefile.am +++ b/src/lib-config/Makefile.am @@ -1,7 +1,6 @@ noinst_LIBRARIES = libirssi_config.a AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ $(GLIB_CFLAGS) libirssi_config_a_SOURCES = \ diff --git a/src/lib-config/module.h b/src/lib-config/module.h index 22e0e7c7..eb09d70e 100644 --- a/src/lib-config/module.h +++ b/src/lib-config/module.h @@ -1,5 +1,5 @@ -#include "common.h" -#include "iconfig.h" +#include +#include /* private */ int config_error(CONFIG_REC *rec, const char *msg); diff --git a/src/otr/Makefile.am b/src/otr/Makefile.am index 7cc02d6d..ac40cbac 100644 --- a/src/otr/Makefile.am +++ b/src/otr/Makefile.am @@ -8,11 +8,6 @@ EXTRA_LTLIBRARIES = \ libotr_core_static.la AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core/ \ - -I$(top_srcdir)/src/irc/core/ \ - -I$(top_srcdir)/src/fe-common/core/ \ - -I$(top_srcdir)/src/fe-text/ \ $(GLIB_CFLAGS) \ $(OTR_CFLAGS) diff --git a/src/otr/key.c b/src/otr/key.c index 7fee4084..27de0226 100644 --- a/src/otr/key.c +++ b/src/otr/key.c @@ -28,15 +28,15 @@ #include #include -#include "key.h" +#include -#include "levels.h" -#include "network.h" -#include "pidwait.h" -#include "printtext.h" +#include +#include +#include +#include -#include "irssi-otr.h" -#include "otr-formats.h" +#include +#include /* * Status of key generation. diff --git a/src/otr/key.h b/src/otr/key.h index 259a8e67..e9476953 100644 --- a/src/otr/key.h +++ b/src/otr/key.h @@ -21,10 +21,10 @@ #ifndef IRSSI_OTR_KEY_H #define IRSSI_OTR_KEY_H -#include "common.h" -#include "servers.h" +#include +#include -#include "otr.h" +#include void key_gen_run(struct otr_user_state *ustate, const char *account_name); void key_load(struct otr_user_state *ustate); diff --git a/src/otr/module.h b/src/otr/module.h index 513ee03b..dab26345 100644 --- a/src/otr/module.h +++ b/src/otr/module.h @@ -21,8 +21,8 @@ #ifndef IRSSI_OTR_MODULE #define IRSSI_OTR_MODULE -#include "common.h" -#include "servers.h" +#include +#include void sig_message_private(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target); diff --git a/src/otr/otr-fe.c b/src/otr/otr-fe.c index 13e37576..80b50ae5 100644 --- a/src/otr/otr-fe.c +++ b/src/otr/otr-fe.c @@ -20,18 +20,18 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA */ -#include "common.h" -#include "levels.h" -#include "printtext.h" -#include "commands.h" -#include "irc.h" -#include "irc-servers.h" -#include "irc-queries.h" -#include "statusbar-item.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "otr.h" -#include "otr-formats.h" -#include "key.h" +#include +#include +#include static void cmd_otr(const char *data, SERVER_REC *server, void *item) { diff --git a/src/otr/otr-formats.c b/src/otr/otr-formats.c index e430b6b5..d26edbba 100644 --- a/src/otr/otr-formats.c +++ b/src/otr/otr-formats.c @@ -19,8 +19,8 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA */ -#include "otr.h" -#include "otr-formats.h" +#include +#include FORMAT_REC fe_otr_formats[] = { { MODULE_NAME, "Core", 0 }, diff --git a/src/otr/otr-formats.h b/src/otr/otr-formats.h index 454b2f6c..cf895dcb 100644 --- a/src/otr/otr-formats.h +++ b/src/otr/otr-formats.h @@ -22,7 +22,7 @@ #ifndef IRSSI_OTR_FORMATS_H #define IRSSI_OTR_FORMATS_H -#include "formats.h" +#include /* * Must be in sync with the fe_otr_formats array. diff --git a/src/otr/otr-module.c b/src/otr/otr-module.c index f561b91c..6fe4c9f2 100644 --- a/src/otr/otr-module.c +++ b/src/otr/otr-module.c @@ -24,21 +24,21 @@ #include "module.h" -#include "common.h" -#include "signals.h" -#include "queries.h" -#include "commands.h" +#include +#include +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "irc-queries.h" -#include "irc-commands.h" +#include +#include +#include +#include -#include "key.h" -#include "otr.h" -#include "otr-formats.h" -#include "otr-fe.h" -#include "misc.h" +#include +#include +#include +#include +#include /* * Global state for the user. Init when the module loads. diff --git a/src/otr/otr-ops.c b/src/otr/otr-ops.c index 4e8c4e81..f87e6e94 100644 --- a/src/otr/otr-ops.c +++ b/src/otr/otr-ops.c @@ -17,17 +17,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA */ -#include "common.h" +#include -#include "signals.h" -#include "levels.h" -#include "printtext.h" -#include "fe-windows.h" +#include +#include +#include +#include -#include "key.h" +#include #include "module.h" -#include "otr-formats.h" -#include "irssi-otr.h" +#include +#include static OtrlPolicy OTR_DEFAULT_POLICY = OTRL_POLICY_MANUAL | OTRL_POLICY_WHITESPACE_START_AKE; diff --git a/src/otr/otr.c b/src/otr/otr.c index 9f0192e1..80604513 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -24,15 +24,15 @@ #include #include -#include "common.h" -#include "levels.h" -#include "signals.h" -#include "printtext.h" -#include "statusbar-item.h" +#include +#include +#include +#include +#include -#include "irssi-otr.h" -#include "otr-formats.h" -#include "key.h" +#include +#include +#include static int otr_debug = 0; diff --git a/src/otr/otr.h b/src/otr/otr.h index 60a08184..e0324a13 100644 --- a/src/otr/otr.h +++ b/src/otr/otr.h @@ -28,8 +28,8 @@ #include #include -#include "common.h" -#include "servers.h" +#include +#include /* irssi module name */ #define MODULE_NAME "otr/core" diff --git a/src/perl/Makefile.am b/src/perl/Makefile.am index db52744e..0e56d7a3 100644 --- a/src/perl/Makefile.am +++ b/src/perl/Makefile.am @@ -15,9 +15,6 @@ perl-core.lo: irssi-core.pl.h perl-signals.lo: perl-signals-list.h AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ - -I$(top_srcdir)/src/fe-common/core \ $(GLIB_CFLAGS) \ -DSCRIPTDIR=\""$(datadir)/irssi/scripts"\" \ -DPERL_USE_LIB=\""$(PERL_USE_LIB)"\" \ diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index 7c72f646..75b851d6 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -1,12 +1,12 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -#include "irssi-version.h" -#include "core.h" -#include "utf8.h" -#include "recode.h" +#include +#include +#include +#include -#include "pidwait.h" -#include "session.h" +#include +#include #define DEFAULT_COMMAND_CATEGORY "Perl scripts' commands" diff --git a/src/perl/common/Expando.xs b/src/perl/common/Expando.xs index 84853a02..1dc36d27 100644 --- a/src/perl/common/Expando.xs +++ b/src/perl/common/Expando.xs @@ -1,6 +1,6 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -#include "expandos.h" +#include typedef struct { PERL_SCRIPT_REC *script; diff --git a/src/perl/common/Makefile.PL.in b/src/perl/common/Makefile.PL.in index 70b1d258..2b087d08 100644 --- a/src/perl/common/Makefile.PL.in +++ b/src/perl/common/Makefile.PL.in @@ -3,5 +3,5 @@ use ExtUtils::MakeMaker;our $AM_DEFAULT_VERBOSITY='@AM_DEFAULT_VERBOSITY@';requi WriteMakefile('NAME' => 'Irssi', 'LIBS' => '', 'OBJECT' => '$(O_FILES)', - 'INC' => '-I../../.. -I@top_srcdir@ -I@top_srcdir@/src -I@top_srcdir@/src/core @GLIB_CFLAGS@', + 'INC' => '-I../../.. @GLIB_CFLAGS@', 'VERSION_FROM' => '@srcdir@/Irssi.pm'); diff --git a/src/perl/common/Settings.xs b/src/perl/common/Settings.xs index eb81b627..d1bce856 100644 --- a/src/perl/common/Settings.xs +++ b/src/perl/common/Settings.xs @@ -1,6 +1,6 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -#include "misc.h" +#include static GHashTable *perl_settings; diff --git a/src/perl/common/module.h b/src/perl/common/module.h index 07ecc56f..92a712f8 100644 --- a/src/perl/common/module.h +++ b/src/perl/common/module.h @@ -1,32 +1,32 @@ #define NEED_PERL_H #define HAVE_CONFIG_H -#include "../module.h" +#include #include -#include "network.h" -#include "levels.h" -#include "commands.h" -#include "log.h" -#include "rawlog.h" -#include "ignore.h" -#include "settings.h" -#include "masks.h" -#include "special-vars.h" -#include "window-item-def.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" -#include "servers-reconnect.h" -#include "servers-setup.h" -#include "channels.h" -#include "queries.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "perl/perl-core.h" -#include "perl/perl-common.h" -#include "perl/perl-signals.h" -#include "perl/perl-sources.h" +#include +#include +#include +#include typedef COMMAND_REC *Irssi__Command; typedef LOG_REC *Irssi__Log; diff --git a/src/perl/irc/Ctcp.xs b/src/perl/irc/Ctcp.xs index d1bf8ba4..34978870 100644 --- a/src/perl/irc/Ctcp.xs +++ b/src/perl/irc/Ctcp.xs @@ -1,6 +1,6 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -#include "ctcp.h" +#include MODULE = Irssi::Irc::Ctcp PACKAGE = Irssi PROTOTYPES: ENABLE diff --git a/src/perl/irc/Makefile.PL.in b/src/perl/irc/Makefile.PL.in index 582160a0..561308c7 100644 --- a/src/perl/irc/Makefile.PL.in +++ b/src/perl/irc/Makefile.PL.in @@ -4,5 +4,5 @@ WriteMakefile('NAME' => 'Irssi::Irc', 'LIBS' => '', 'OBJECT' => '$(O_FILES)', 'TYPEMAPS' => ['../common/typemap'], - 'INC' => '-I../../.. -I@top_srcdir@/src -I@top_srcdir@/src/core -I@top_srcdir@/src/irc/core -I@top_srcdir@/src/irc @GLIB_CFLAGS@', + 'INC' => '-I../../.. @GLIB_CFLAGS@', 'VERSION_FROM' => '@srcdir@/Irc.pm'); diff --git a/src/perl/irc/module.h b/src/perl/irc/module.h index a2454545..71801419 100644 --- a/src/perl/irc/module.h +++ b/src/perl/irc/module.h @@ -1,27 +1,27 @@ -#include "../common/module.h" +#include -#include "irc.h" -#include "irc-servers.h" -#include "irc-channels.h" -#include "irc-queries.h" -#include "irc-nicklist.h" -#include "irc-masks.h" -#include "irc-cap.h" +#include +#include +#include +#include +#include +#include +#include -#include "bans.h" -#include "modes.h" -#include "mode-lists.h" -#include "netsplit.h" -#include "servers-redirect.h" +#include +#include +#include +#include +#include -#include "dcc/dcc.h" -#include "dcc/dcc-file.h" -#include "dcc/dcc-chat.h" -#include "dcc/dcc-get.h" -#include "dcc/dcc-send.h" -#include "notifylist/notifylist.h" +#include +#include +#include +#include +#include +#include -#include "proxy/proxy.h" +#include typedef IRC_SERVER_REC *Irssi__Irc__Server; typedef IRC_SERVER_CONNECT_REC *Irssi__Irc__Connect; diff --git a/src/perl/module-formats.c b/src/perl/module-formats.c index e1a7aa74..0b8b7b4c 100644 --- a/src/perl/module-formats.c +++ b/src/perl/module-formats.c @@ -19,7 +19,7 @@ */ #include "module.h" -#include "formats.h" +#include FORMAT_REC feperl_formats[] = { { MODULE_NAME, "Core", 0 }, diff --git a/src/perl/module-formats.h b/src/perl/module-formats.h index 74d2e13b..43b2f4ae 100644 --- a/src/perl/module-formats.h +++ b/src/perl/module-formats.h @@ -1,4 +1,4 @@ -#include "formats.h" +#include enum { IRCTXT_MODULE_NAME, diff --git a/src/perl/module.h b/src/perl/module.h index 3cbdf3d5..0a4d78f6 100644 --- a/src/perl/module.h +++ b/src/perl/module.h @@ -1,4 +1,4 @@ -#include "common.h" +#include #ifdef NEED_PERL_H # include diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index 802a771e..6fd1705b 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -21,28 +21,28 @@ #define NEED_PERL_H #define PERL_NO_GET_CONTEXT #include "module.h" -#include "modules.h" -#include "signals.h" -#include "core.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "commands.h" -#include "ignore.h" -#include "log.h" -#include "rawlog.h" -#include "servers-reconnect.h" +#include +#include +#include +#include +#include -#include "window-item-def.h" -#include "chat-protocols.h" -#include "chatnets.h" -#include "servers.h" -#include "channels.h" -#include "queries.h" -#include "nicklist.h" +#include +#include +#include +#include +#include +#include +#include -#include "perl-core.h" -#include "perl-common.h" +#include +#include typedef struct { char *stash; diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 39389157..866b86e8 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -21,16 +21,16 @@ #define NEED_PERL_H #define PERL_NO_GET_CONTEXT #include "module.h" -#include "modules.h" -#include "core.h" -#include "signals.h" -#include "misc.h" -#include "settings.h" +#include +#include +#include +#include +#include -#include "perl-core.h" -#include "perl-common.h" -#include "perl-signals.h" -#include "perl-sources.h" +#include +#include +#include +#include #include "XSUB.h" #include "irssi-core.pl.h" diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c index 396c80b7..ac84d67a 100644 --- a/src/perl/perl-fe.c +++ b/src/perl/perl-fe.c @@ -18,17 +18,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "module-fe.h" -#include "modules.h" -#include "module-formats.h" -#include "signals.h" -#include "commands.h" -#include "levels.h" +#include +#include +#include +#include +#include +#include -#include "printtext.h" -#include "completion.h" +#include +#include -#include "perl-core.h" +#include static void cmd_script(const char *data, SERVER_REC *server, void *item) { diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 8f993660..59289588 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -21,14 +21,14 @@ #define NEED_PERL_H #define PERL_NO_GET_CONTEXT #include "module.h" -#include "modules.h" -#include "signals.h" -#include "commands.h" -#include "servers.h" +#include +#include +#include +#include -#include "perl-core.h" -#include "perl-common.h" -#include "perl-signals.h" +#include +#include +#include typedef struct { PERL_SCRIPT_REC *script; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 0b49a608..3c72be22 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -21,12 +21,12 @@ #define NEED_PERL_H #define PERL_NO_GET_CONTEXT #include "module.h" -#include "signals.h" +#include -#include "perl-core.h" -#include "perl-common.h" -#include "perl-sources.h" -#include "misc.h" +#include +#include +#include +#include typedef struct { PERL_SCRIPT_REC *script; diff --git a/src/perl/textui/Makefile.PL.in b/src/perl/textui/Makefile.PL.in index ffdda21a..2b0a148a 100644 --- a/src/perl/textui/Makefile.PL.in +++ b/src/perl/textui/Makefile.PL.in @@ -4,5 +4,5 @@ WriteMakefile('NAME' => 'Irssi::TextUI', 'LIBS' => '', 'OBJECT' => '$(O_FILES)', 'TYPEMAPS' => ['../common/typemap', '../ui/typemap'], - 'INC' => '-I../../.. -I@top_srcdir@/src -I@top_srcdir@/src/core -I@top_srcdir@/src/fe-common/core -I@top_srcdir@/src/fe-text @GLIB_CFLAGS@', + 'INC' => '-I../../.. @GLIB_CFLAGS@', 'VERSION_FROM' => '@srcdir@/TextUI.pm'); diff --git a/src/perl/textui/module.h b/src/perl/textui/module.h index d8af5b48..394c2839 100644 --- a/src/perl/textui/module.h +++ b/src/perl/textui/module.h @@ -1,12 +1,12 @@ -#include "../ui/module.h" +#include -#include "mainwindows.h" -#include "gui-windows.h" -#include "gui-printtext.h" -#include "statusbar.h" -#include "textbuffer.h" -#include "textbuffer-view.h" -#include "gui-entry.h" +#include +#include +#include +#include +#include +#include +#include typedef MAIN_WINDOW_REC *Irssi__TextUI__MainWindow; typedef TEXT_BUFFER_REC *Irssi__TextUI__TextBuffer; diff --git a/src/perl/ui/Makefile.PL.in b/src/perl/ui/Makefile.PL.in index ceed51c3..9507e74d 100644 --- a/src/perl/ui/Makefile.PL.in +++ b/src/perl/ui/Makefile.PL.in @@ -4,5 +4,5 @@ WriteMakefile('NAME' => 'Irssi::UI', 'LIBS' => '', 'OBJECT' => '$(O_FILES)', 'TYPEMAPS' => ['../common/typemap'], - 'INC' => '-I../../.. -I@top_srcdir@/src -I@top_srcdir@/src/core -I@top_srcdir@/src/fe-common/core @GLIB_CFLAGS@', + 'INC' => '-I../../.. @GLIB_CFLAGS@', 'VERSION_FROM' => '@srcdir@/UI.pm'); diff --git a/src/perl/ui/Window.xs b/src/perl/ui/Window.xs index 85e284bb..d001f382 100644 --- a/src/perl/ui/Window.xs +++ b/src/perl/ui/Window.xs @@ -1,7 +1,7 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -#include "window-activity.h" +#include MODULE = Irssi::UI::Window PACKAGE = Irssi PROTOTYPES: ENABLE diff --git a/src/perl/ui/module.h b/src/perl/ui/module.h index 31775039..4e19d4c0 100644 --- a/src/perl/ui/module.h +++ b/src/perl/ui/module.h @@ -1,12 +1,12 @@ -#include "../common/module.h" +#include -#include "fe-windows.h" -#include "fe-exec.h" -#include "formats.h" -#include "printtext.h" -#include "window-items.h" -#include "themes.h" -#include "keyboard.h" +#include +#include +#include +#include +#include +#include +#include typedef WINDOW_REC *Irssi__UI__Window; typedef TEXT_DEST_REC *Irssi__UI__TextDest; diff --git a/tests/fe-common/core/Makefile.am b/tests/fe-common/core/Makefile.am index f048e95c..ddd619a0 100644 --- a/tests/fe-common/core/Makefile.am +++ b/tests/fe-common/core/Makefile.am @@ -3,14 +3,11 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=fe-common/core AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ $(GLIB_CFLAGS) test_programs = test-formats test_formats_CPPFLAGS = \ - -I$(top_srcdir)/src/fe-common/core \ $(AM_CPPFLAGS) test_formats_DEPENDENCIES = \ diff --git a/tests/fe-common/core/test-formats.c b/tests/fe-common/core/test-formats.c index aee5a219..d1164f91 100644 --- a/tests/fe-common/core/test-formats.c +++ b/tests/fe-common/core/test-formats.c @@ -1,5 +1,5 @@ -#include "common.h" -#include "formats.h" +#include +#include #define MAX_LENGTH 5 diff --git a/tests/fe-text/Makefile.am b/tests/fe-text/Makefile.am index 38979e14..b1762c7d 100644 --- a/tests/fe-text/Makefile.am +++ b/tests/fe-text/Makefile.am @@ -3,10 +3,6 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=fe-text AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ - -I$(top_srcdir)/src/fe-common/core \ - -I$(top_srcdir)/src/fe-text \ $(GLIB_CFLAGS) test_programs = test-paste-join-multiline diff --git a/tests/fe-text/test-paste-join-multiline.c b/tests/fe-text/test-paste-join-multiline.c index 8a81a9fb..87669598 100644 --- a/tests/fe-text/test-paste-join-multiline.c +++ b/tests/fe-text/test-paste-join-multiline.c @@ -1,5 +1,5 @@ -#include "common.h" -#include "gui-readline.c" +#include +#include typedef struct { char const *const description; diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index f60da03f..23c1ef2c 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -3,15 +3,12 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=irc/core AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/core \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) test_programs = test-channel-events test-irc CPPFLAGS = \ - -I$(top_srcdir)/src/irc/core \ $(AM_CPPFLAGS) DEPENDENCIES = \ diff --git a/tests/irc/core/test-channel-events.c b/tests/irc/core/test-channel-events.c index 9f52c98d..c6490e6b 100644 --- a/tests/irc/core/test-channel-events.c +++ b/tests/irc/core/test-channel-events.c @@ -20,18 +20,18 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #define MODULE_NAME "test-channel-events" diff --git a/tests/irc/core/test-irc.c b/tests/irc/core/test-irc.c index 3eaf7020..4845d54c 100644 --- a/tests/irc/core/test-irc.c +++ b/tests/irc/core/test-irc.c @@ -19,7 +19,7 @@ */ #include -#include +#include #include typedef struct { diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am index 58c0d98d..17885d53 100644 --- a/tests/irc/flood/Makefile.am +++ b/tests/irc/flood/Makefile.am @@ -3,8 +3,6 @@ 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) @@ -12,9 +10,6 @@ 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 = \ diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 0c98509b..6f0f3ac8 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -18,18 +18,18 @@ 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 +#include +#include +#include +#include -#include "formats.h" -#include "fe-common-core.h" +#include +#include -#include "irc.h" -#include "irc-servers.h" -#include "irc-channels.h" +#include +#include +#include /* irc.c */ void irc_init(void); From 03ca37c12e6cc06bc6df728d44efef7efd391b4d Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 1 May 2019 22:04:04 +0200 Subject: [PATCH 0522/1198] Use full paths to includes in fe-fuzz --- src/fe-fuzz/fe-common/core/theme-load.c | 22 +++++++++---------- src/fe-fuzz/irc/core/event-get-params.c | 20 +++++++++--------- src/fe-fuzz/irssi.c | 18 ++++++++-------- src/fe-fuzz/server.c | 28 ++++++++++++------------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/fe-fuzz/fe-common/core/theme-load.c b/src/fe-fuzz/fe-common/core/theme-load.c index 14df74c6..87429ac4 100644 --- a/src/fe-fuzz/fe-common/core/theme-load.c +++ b/src/fe-fuzz/fe-common/core/theme-load.c @@ -18,17 +18,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "module.h" -#include "modules-load.h" -#include "levels.h" -#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text -#include "themes.h" -#include "core.h" -#include "fe-common-core.h" -#include "args.h" -#include "printtext.h" -#include "irc.h" -#include "themes.h" +#include +#include +#include +#include // need to explicitly grab from fe-text +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index c50b6205..36aeacf7 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -18,16 +18,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "module.h" -#include "modules-load.h" -#include "levels.h" -#include "../fe-text/module-formats.h" // need to explicitly grab from fe-text -#include "themes.h" -#include "core.h" -#include "fe-common-core.h" -#include "args.h" -#include "printtext.h" -#include "irc.h" +#include +#include +#include +#include // need to explicitly grab from fe-text +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c index c1b2ca9b..1c9f6c5f 100644 --- a/src/fe-fuzz/irssi.c +++ b/src/fe-fuzz/irssi.c @@ -18,15 +18,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "module.h" -#include "modules-load.h" -#include "levels.h" -#include "../fe-text/module-formats.h" /* need to explicitly grab from fe-text */ -#include "themes.h" -#include "core.h" -#include "fe-common-core.h" -#include "args.h" -#include "printtext.h" +#include +#include +#include +#include /* need to explicitly grab from fe-text */ +#include +#include +#include +#include +#include #include #include diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 76eeb17e..2e8cd3d2 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -18,17 +18,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "module.h" -#include "modules-load.h" -#include "module-formats.h" -#include "levels.h" -#include "themes.h" -#include "core.h" -#include "fe-common-core.h" -#include "args.h" -#include "printtext.h" -#include "misc.h" -#include "servers-setup.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -36,9 +36,9 @@ #include #include -#include "irc.h" -#include "irc-servers.h" -#include "irc-channels.h" +#include +#include +#include /* irc.c */ void irc_init(void); From 37f7c7f37489122e6ec4f870af428f7675042dfd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 1 May 2019 22:22:22 +0200 Subject: [PATCH 0523/1198] update include guard names --- src/common.h | 4 ++-- src/core/args.h | 4 ++-- src/core/capsicum.h | 6 +++--- src/core/channels-setup.h | 4 ++-- src/core/channels.h | 4 ++-- src/core/chat-protocols.h | 4 ++-- src/core/chatnets.h | 4 ++-- src/core/commands.h | 4 ++-- src/core/core.h | 4 ++-- src/core/expandos.h | 4 ++-- src/core/ignore.h | 4 ++-- src/core/iregex.h | 4 ++-- src/core/levels.h | 4 ++-- src/core/line-split.h | 4 ++-- src/core/log.h | 4 ++-- src/core/masks.h | 4 ++-- src/core/misc.h | 4 ++-- src/core/modules-load.h | 4 ++-- src/core/modules.h | 4 ++-- src/core/net-disconnect.h | 4 ++-- src/core/net-nonblock.h | 4 ++-- src/core/net-sendbuffer.h | 4 ++-- src/core/network-openssl.h | 6 +++--- src/core/network.h | 4 ++-- src/core/nicklist.h | 4 ++-- src/core/nickmatch-cache.h | 4 ++-- src/core/pidwait.h | 4 ++-- src/core/queries.h | 4 ++-- src/core/rawlog.h | 4 ++-- src/core/recode.h | 6 +++--- src/core/servers-reconnect.h | 4 ++-- src/core/servers-setup.h | 4 ++-- src/core/servers.h | 4 ++-- src/core/session.h | 4 ++-- src/core/settings.h | 4 ++-- src/core/signals.h | 4 ++-- src/core/special-vars.h | 4 ++-- src/core/tls.h | 4 ++-- src/core/utf8.h | 4 ++-- src/core/window-item-def.h | 4 ++-- src/core/write-buffer.h | 4 ++-- src/fe-common/core/chat-completion.h | 4 ++-- src/fe-common/core/command-history.h | 4 ++-- src/fe-common/core/completion.h | 4 ++-- src/fe-common/core/fe-capsicum.h | 4 ++-- src/fe-common/core/fe-channels.h | 4 ++-- src/fe-common/core/fe-common-core.h | 4 ++-- src/fe-common/core/fe-core-commands.h | 4 ++-- src/fe-common/core/fe-exec.h | 4 ++-- src/fe-common/core/fe-messages.h | 4 ++-- src/fe-common/core/fe-queries.h | 4 ++-- src/fe-common/core/fe-recode.h | 6 +++--- src/fe-common/core/fe-settings.h | 4 ++-- src/fe-common/core/fe-tls.h | 4 ++-- src/fe-common/core/fe-windows.h | 4 ++-- src/fe-common/core/formats.h | 4 ++-- src/fe-common/core/hilight-text.h | 4 ++-- src/fe-common/core/keyboard.h | 4 ++-- src/fe-common/core/printtext.h | 4 ++-- src/fe-common/core/themes.h | 4 ++-- src/fe-common/core/window-activity.h | 4 ++-- src/fe-common/core/window-items.h | 4 ++-- src/fe-common/core/windows-layout.h | 4 ++-- src/fe-common/irc/dcc/fe-dcc.h | 4 ++-- src/fe-common/irc/fe-irc-channels.h | 4 ++-- src/fe-common/irc/fe-irc-server.h | 4 ++-- src/fe-text/gui-entry.h | 4 ++-- src/fe-text/gui-printtext.h | 4 ++-- src/fe-text/gui-readline.h | 4 ++-- src/fe-text/gui-windows.h | 4 ++-- src/fe-text/mainwindows.h | 4 ++-- src/fe-text/statusbar-config.h | 4 ++-- src/fe-text/statusbar.h | 4 ++-- src/fe-text/term.h | 4 ++-- src/fe-text/terminfo-core.h | 4 ++-- src/fe-text/textbuffer-view.h | 4 ++-- src/fe-text/textbuffer.h | 4 ++-- src/irc/core/bans.h | 4 ++-- src/irc/core/channel-events.h | 4 ++-- src/irc/core/channel-rejoin.h | 4 ++-- src/irc/core/ctcp.h | 4 ++-- src/irc/core/irc-cap.h | 4 ++-- src/irc/core/irc-channels.h | 4 ++-- src/irc/core/irc-chatnets.h | 4 ++-- src/irc/core/irc-commands.h | 4 ++-- src/irc/core/irc-masks.h | 4 ++-- src/irc/core/irc-nicklist.h | 4 ++-- src/irc/core/irc-queries.h | 4 ++-- src/irc/core/irc-servers-setup.h | 4 ++-- src/irc/core/irc-servers.h | 4 ++-- src/irc/core/irc.h | 4 ++-- src/irc/core/mode-lists.h | 4 ++-- src/irc/core/modes.h | 4 ++-- src/irc/core/netsplit.h | 4 ++-- src/irc/core/sasl.h | 4 ++-- src/irc/core/servers-idle.h | 4 ++-- src/irc/core/servers-redirect.h | 4 ++-- src/irc/dcc/dcc-chat.h | 4 ++-- src/irc/dcc/dcc-file.h | 4 ++-- src/irc/dcc/dcc-get.h | 4 ++-- src/irc/dcc/dcc-queue.h | 4 ++-- src/irc/dcc/dcc-send.h | 4 ++-- src/irc/dcc/dcc-server.h | 4 ++-- src/irc/dcc/dcc.h | 4 ++-- src/irc/flood/autoignore.h | 4 ++-- src/irc/flood/flood.h | 4 ++-- src/irc/notifylist/notify-setup.h | 4 ++-- src/irc/notifylist/notifylist.h | 4 ++-- src/irc/proxy/proxy.h | 4 ++-- src/lib-config/iconfig.h | 4 ++-- src/perl/perl-common.h | 4 ++-- src/perl/perl-core.h | 4 ++-- src/perl/perl-signals.h | 4 ++-- src/perl/perl-sources.h | 4 ++-- 114 files changed, 232 insertions(+), 232 deletions(-) diff --git a/src/common.h b/src/common.h index 313b2c9f..ef4b0c15 100644 --- a/src/common.h +++ b/src/common.h @@ -1,5 +1,5 @@ -#ifndef __COMMON_H -#define __COMMON_H +#ifndef IRSSI_COMMON_H +#define IRSSI_COMMON_H #define IRSSI_DIR_FULL "%s/.irssi" /* %s == g_get_home_dir() */ diff --git a/src/core/args.h b/src/core/args.h index bbe16b5f..aeaf5714 100644 --- a/src/core/args.h +++ b/src/core/args.h @@ -1,5 +1,5 @@ -#ifndef __ARGS_H -#define __ARGS_H +#ifndef IRSSI_CORE_ARGS_H +#define IRSSI_CORE_ARGS_H void args_register(GOptionEntry *options); void args_execute(int argc, char *argv[]); diff --git a/src/core/capsicum.h b/src/core/capsicum.h index 7d89f2aa..ab980a43 100644 --- a/src/core/capsicum.h +++ b/src/core/capsicum.h @@ -1,5 +1,5 @@ -#ifndef __CAPSICUM_H -#define __CAPSICUM_H +#ifndef IRSSI_CORE_CAPSICUM_H +#define IRSSI_CORE_CAPSICUM_H gboolean capsicum_enabled(void); int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); @@ -12,4 +12,4 @@ void capsicum_mkdir_with_parents_wrapper(const char *path, int mode); void capsicum_init(void); void capsicum_deinit(void); -#endif /* !__CAPSICUM_H */ +#endif /* !IRSSI_CORE_CAPSICUM_H */ diff --git a/src/core/channels-setup.h b/src/core/channels-setup.h index fcc099c6..c0297aec 100644 --- a/src/core/channels-setup.h +++ b/src/core/channels-setup.h @@ -1,5 +1,5 @@ -#ifndef __CHANNELS_SETUP_H -#define __CHANNELS_SETUP_H +#ifndef IRSSI_CORE_CHANNELS_SETUP_H +#define IRSSI_CORE_CHANNELS_SETUP_H #include diff --git a/src/core/channels.h b/src/core/channels.h index 276c69fa..197d2254 100644 --- a/src/core/channels.h +++ b/src/core/channels.h @@ -1,5 +1,5 @@ -#ifndef __CHANNELS_H -#define __CHANNELS_H +#ifndef IRSSI_CORE_CHANNELS_H +#define IRSSI_CORE_CHANNELS_H #include diff --git a/src/core/chat-protocols.h b/src/core/chat-protocols.h index 8b7dc170..ab7327bd 100644 --- a/src/core/chat-protocols.h +++ b/src/core/chat-protocols.h @@ -1,5 +1,5 @@ -#ifndef __CHAT_PROTOCOLS_H -#define __CHAT_PROTOCOLS_H +#ifndef IRSSI_CORE_CHAT_PROTOCOLS_H +#define IRSSI_CORE_CHAT_PROTOCOLS_H struct _CHAT_PROTOCOL_REC { int id; diff --git a/src/core/chatnets.h b/src/core/chatnets.h index 785b487e..6f36fe33 100644 --- a/src/core/chatnets.h +++ b/src/core/chatnets.h @@ -1,5 +1,5 @@ -#ifndef __CHATNETS_H -#define __CHATNETS_H +#ifndef IRSSI_CORE_CHATNETS_H +#define IRSSI_CORE_CHATNETS_H #include diff --git a/src/core/commands.h b/src/core/commands.h index b70e77ca..7c6bd87b 100644 --- a/src/core/commands.h +++ b/src/core/commands.h @@ -1,5 +1,5 @@ -#ifndef __COMMANDS_H -#define __COMMANDS_H +#ifndef IRSSI_CORE_COMMANDS_H +#define IRSSI_CORE_COMMANDS_H #include diff --git a/src/core/core.h b/src/core/core.h index 406070e0..6c6c7b61 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -1,5 +1,5 @@ -#ifndef __IRSSI_CORE_H -#define __IRSSI_CORE_H +#ifndef IRSSI_CORE_CORE_H +#define IRSSI_CORE_CORE_H #include diff --git a/src/core/expandos.h b/src/core/expandos.h index 3466a44a..05dfcf11 100644 --- a/src/core/expandos.h +++ b/src/core/expandos.h @@ -1,5 +1,5 @@ -#ifndef __EXPANDOS_H -#define __EXPANDOS_H +#ifndef IRSSI_CORE_EXPANDOS_H +#define IRSSI_CORE_EXPANDOS_H #include diff --git a/src/core/ignore.h b/src/core/ignore.h index fea38205..bf55a76b 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,5 +1,5 @@ -#ifndef __IGNORE_H -#define __IGNORE_H +#ifndef IRSSI_CORE_IGNORE_H +#define IRSSI_CORE_IGNORE_H #include diff --git a/src/core/iregex.h b/src/core/iregex.h index d6d6c17f..53263944 100644 --- a/src/core/iregex.h +++ b/src/core/iregex.h @@ -1,5 +1,5 @@ -#ifndef __REGEX_H -#define __REGEX_H +#ifndef IRSSI_CORE_IREGEX_H +#define IRSSI_CORE_IREGEX_H #include diff --git a/src/core/levels.h b/src/core/levels.h index b0ebafba..385ecd0c 100644 --- a/src/core/levels.h +++ b/src/core/levels.h @@ -1,5 +1,5 @@ -#ifndef __LEVELS_H -#define __LEVELS_H +#ifndef IRSSI_CORE_LEVELS_H +#define IRSSI_CORE_LEVELS_H /* This is pretty much IRC specific, but I think it would be easier for other chats to try to use these same levels instead of implementing too diff --git a/src/core/line-split.h b/src/core/line-split.h index 7c101ddd..cf957423 100644 --- a/src/core/line-split.h +++ b/src/core/line-split.h @@ -1,5 +1,5 @@ -#ifndef __LINE_SPLIT_H -#define __LINE_SPLIT_H +#ifndef IRSSI_CORE_LINE_SPLIT_H +#define IRSSI_CORE_LINE_SPLIT_H /* line-split `data'. Initially `*buffer' should contain NULL. */ int line_split(const char *data, int len, char **output, LINEBUF_REC **buffer); diff --git a/src/core/log.h b/src/core/log.h index 5a07859b..1c529670 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -1,5 +1,5 @@ -#ifndef __LOG_H -#define __LOG_H +#ifndef IRSSI_CORE_LOG_H +#define IRSSI_CORE_LOG_H enum { LOG_ITEM_TARGET, /* channel, query, .. */ diff --git a/src/core/masks.h b/src/core/masks.h index b6ce20d8..e3a0437a 100644 --- a/src/core/masks.h +++ b/src/core/masks.h @@ -1,5 +1,5 @@ -#ifndef __MASKS_H -#define __MASKS_H +#ifndef IRSSI_CORE_MASKS_H +#define IRSSI_CORE_MASKS_H int mask_match(SERVER_REC *server, const char *mask, const char *nick, const char *user, const char *host); diff --git a/src/core/misc.h b/src/core/misc.h index 1545f7a2..9e06c707 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -1,5 +1,5 @@ -#ifndef __MISC_H -#define __MISC_H +#ifndef IRSSI_CORE_MISC_H +#define IRSSI_CORE_MISC_H int g_input_add_poll(int fd, int priority, int condition, GInputFunction function, void *data); diff --git a/src/core/modules-load.h b/src/core/modules-load.h index 683d30e3..a99bcdfe 100644 --- a/src/core/modules-load.h +++ b/src/core/modules-load.h @@ -1,5 +1,5 @@ -#ifndef __MODULES_LOAD_H -#define __MODULES_LOAD_H +#ifndef IRSSI_CORE_MODULES_LOAD_H +#define IRSSI_CORE_MODULES_LOAD_H #include diff --git a/src/core/modules.h b/src/core/modules.h index b2fa2fa4..e3deaee2 100644 --- a/src/core/modules.h +++ b/src/core/modules.h @@ -1,5 +1,5 @@ -#ifndef __MODULES_H -#define __MODULES_H +#ifndef IRSSI_CORE_MODULES_H +#define IRSSI_CORE_MODULES_H #define MODULE_DATA_INIT(rec) \ (rec)->module_data = g_hash_table_new(g_str_hash, g_str_equal) diff --git a/src/core/net-disconnect.h b/src/core/net-disconnect.h index 37a46846..78b03c16 100644 --- a/src/core/net-disconnect.h +++ b/src/core/net-disconnect.h @@ -1,5 +1,5 @@ -#ifndef __NET_DISCONNECT_H -#define __NET_DISCONNECT_H +#ifndef IRSSI_CORE_NET_DISCONNECT_H +#define IRSSI_CORE_NET_DISCONNECT_H /* Try to let the other side close the connection, if it still isn't disconnected after certain amount of time, close it ourself */ diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 649232ae..086c9dab 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -1,5 +1,5 @@ -#ifndef __NET_NONBLOCK_H -#define __NET_NONBLOCK_H +#ifndef IRSSI_CORE_NET_NONBLOCK_H +#define IRSSI_CORE_NET_NONBLOCK_H #include diff --git a/src/core/net-sendbuffer.h b/src/core/net-sendbuffer.h index bdeb7156..7cf1ef6d 100644 --- a/src/core/net-sendbuffer.h +++ b/src/core/net-sendbuffer.h @@ -1,5 +1,5 @@ -#ifndef __NET_SENDBUFFER_H -#define __NET_SENDBUFFER_H +#ifndef IRSSI_CORE_NET_SENDBUFFER_H +#define IRSSI_CORE_NET_SENDBUFFER_H #define DEFAULT_BUFFER_SIZE 8192 #define MAX_BUFFER_SIZE 1048576 diff --git a/src/core/network-openssl.h b/src/core/network-openssl.h index 4cd6d711..2c204fb8 100644 --- a/src/core/network-openssl.h +++ b/src/core/network-openssl.h @@ -1,6 +1,6 @@ -#ifndef __NETWORK_OPENSSL_H -#define __NETWORK_OPENSSL_H +#ifndef IRSSI_CORE_NETWORK_OPENSSL_H +#define IRSSI_CORE_NETWORK_OPENSSL_H gboolean irssi_ssl_init(void); -#endif /* !__NETWORK_OPENSSL_H */ +#endif /* !IRSSI_CORE_NETWORK_OPENSSL_H */ diff --git a/src/core/network.h b/src/core/network.h index 30fd6aab..1776005d 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -1,5 +1,5 @@ -#ifndef __NETWORK_H -#define __NETWORK_H +#ifndef IRSSI_CORE_NETWORK_H +#define IRSSI_CORE_NETWORK_H #ifdef HAVE_SOCKS_H #include diff --git a/src/core/nicklist.h b/src/core/nicklist.h index 913cc0d1..62afa5ff 100644 --- a/src/core/nicklist.h +++ b/src/core/nicklist.h @@ -1,5 +1,5 @@ -#ifndef __NICKLIST_H -#define __NICKLIST_H +#ifndef IRSSI_CORE_NICKLIST_H +#define IRSSI_CORE_NICKLIST_H /* Returns NICK_REC if it's nick, NULL if it isn't. */ #define NICK(server) \ diff --git a/src/core/nickmatch-cache.h b/src/core/nickmatch-cache.h index c4140a49..ff58d853 100644 --- a/src/core/nickmatch-cache.h +++ b/src/core/nickmatch-cache.h @@ -1,5 +1,5 @@ -#ifndef __NICKMATCH_CACHE_H -#define __NICKMATCH_CACHE_H +#ifndef IRSSI_CORE_NICKMATCH_CACHE_H +#define IRSSI_CORE_NICKMATCH_CACHE_H typedef void (*NICKMATCH_REBUILD_FUNC) (GHashTable *list, CHANNEL_REC *channel, NICK_REC *nick); diff --git a/src/core/pidwait.h b/src/core/pidwait.h index ae1ba01e..148c65d7 100644 --- a/src/core/pidwait.h +++ b/src/core/pidwait.h @@ -1,5 +1,5 @@ -#ifndef __PIDWAIT_H -#define __PIDWAIT_H +#ifndef IRSSI_CORE_PIDWAIT_H +#define IRSSI_CORE_PIDWAIT_H void pidwait_init(void); void pidwait_deinit(void); diff --git a/src/core/queries.h b/src/core/queries.h index 16f92588..c6170361 100644 --- a/src/core/queries.h +++ b/src/core/queries.h @@ -1,5 +1,5 @@ -#ifndef __QUERIES_H -#define __QUERIES_H +#ifndef IRSSI_CORE_QUERIES_H +#define IRSSI_CORE_QUERIES_H #include diff --git a/src/core/rawlog.h b/src/core/rawlog.h index 01175e67..53c0d3c3 100644 --- a/src/core/rawlog.h +++ b/src/core/rawlog.h @@ -1,5 +1,5 @@ -#ifndef __RAWLOG_H -#define __RAWLOG_H +#ifndef IRSSI_CORE_RAWLOG_H +#define IRSSI_CORE_RAWLOG_H struct _RAWLOG_REC { int logging; diff --git a/src/core/recode.h b/src/core/recode.h index 719e8f54..ce1b9daf 100644 --- a/src/core/recode.h +++ b/src/core/recode.h @@ -1,5 +1,5 @@ -#ifndef __RECODE_H -#define __RECODE_H +#ifndef IRSSI_CORE_RECODE_H +#define IRSSI_CORE_RECODE_H char *recode_in (const SERVER_REC *server, const char *str, const char *target); char *recode_out (const SERVER_REC *server, const char *str, const char *target); @@ -12,4 +12,4 @@ void recode_update_charset(void); void recode_init (void); void recode_deinit (void); -#endif /* __RECODE_H */ +#endif /* IRSSI_CORE_RECODE_H */ diff --git a/src/core/servers-reconnect.h b/src/core/servers-reconnect.h index 835d58d5..b98f5176 100644 --- a/src/core/servers-reconnect.h +++ b/src/core/servers-reconnect.h @@ -1,5 +1,5 @@ -#ifndef __SERVER_RECONNECT_H -#define __SERVER_RECONNECT_H +#ifndef IRSSI_CORE_SERVERS_RECONNECT_H +#define IRSSI_CORE_SERVERS_RECONNECT_H /* wait for half an hour before trying to reconnect to host where last connection failed */ diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index 9bedfe25..296a94fa 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -1,5 +1,5 @@ -#ifndef __SERVERS_SETUP_H -#define __SERVERS_SETUP_H +#ifndef IRSSI_CORE_SERVERS_SETUP_H +#define IRSSI_CORE_SERVERS_SETUP_H #include diff --git a/src/core/servers.h b/src/core/servers.h index daf155b3..7b998c8d 100644 --- a/src/core/servers.h +++ b/src/core/servers.h @@ -1,5 +1,5 @@ -#ifndef __SERVERS_H -#define __SERVERS_H +#ifndef IRSSI_CORE_SERVERS_H +#define IRSSI_CORE_SERVERS_H #include diff --git a/src/core/session.h b/src/core/session.h index a3c8d67c..28c5cec8 100644 --- a/src/core/session.h +++ b/src/core/session.h @@ -1,5 +1,5 @@ -#ifndef __SESSION_H -#define __SESSION_H +#ifndef IRSSI_CORE_SESSION_H +#define IRSSI_CORE_SESSION_H extern char *irssi_binary; diff --git a/src/core/settings.h b/src/core/settings.h index b67a9e44..3a8a4646 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -1,5 +1,5 @@ -#ifndef __SETTINGS_H -#define __SETTINGS_H +#ifndef IRSSI_CORE_SETTINGS_H +#define IRSSI_CORE_SETTINGS_H typedef enum { SETTING_TYPE_STRING, diff --git a/src/core/signals.h b/src/core/signals.h index 384af66f..0fa005a1 100644 --- a/src/core/signals.h +++ b/src/core/signals.h @@ -1,5 +1,5 @@ -#ifndef __SIGNAL_H -#define __SIGNAL_H +#ifndef IRSSI_CORE_SIGNALS_H +#define IRSSI_CORE_SIGNALS_H #define SIGNAL_PRIORITY_LOW 100 #define SIGNAL_PRIORITY_DEFAULT 0 diff --git a/src/core/special-vars.h b/src/core/special-vars.h index caec5ec0..f4bd926d 100644 --- a/src/core/special-vars.h +++ b/src/core/special-vars.h @@ -1,5 +1,5 @@ -#ifndef __SPECIAL_VARS_H -#define __SPECIAL_VARS_H +#ifndef IRSSI_CORE_SPECIAL_VARS_H +#define IRSSI_CORE_SPECIAL_VARS_H #include diff --git a/src/core/tls.h b/src/core/tls.h index 9ba4ac47..791bde86 100644 --- a/src/core/tls.h +++ b/src/core/tls.h @@ -16,8 +16,8 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA */ -#ifndef __TLS_H -#define __TLS_H +#ifndef IRSSI_CORE_TLS_H +#define IRSSI_CORE_TLS_H #include diff --git a/src/core/utf8.h b/src/core/utf8.h index 9f7d1aaa..372c5d27 100644 --- a/src/core/utf8.h +++ b/src/core/utf8.h @@ -1,5 +1,5 @@ -#ifndef __UTF8_H -#define __UTF8_H +#ifndef IRSSI_CORE_UTF8_H +#define IRSSI_CORE_UTF8_H /* XXX I didn't check the encoding range of big5+. This is standard big5. */ #define is_big5_los(lo) (0x40 <= (lo) && (lo) <= 0x7E) /* standard */ diff --git a/src/core/window-item-def.h b/src/core/window-item-def.h index 1309f975..6944c921 100644 --- a/src/core/window-item-def.h +++ b/src/core/window-item-def.h @@ -1,5 +1,5 @@ -#ifndef __WINDOW_ITEM_DEF_H -#define __WINDOW_ITEM_DEF_H +#ifndef IRSSI_CORE_WINDOW_ITEM_DEF_H +#define IRSSI_CORE_WINDOW_ITEM_DEF_H #define STRUCT_SERVER_REC SERVER_REC struct _WI_ITEM_REC { diff --git a/src/core/write-buffer.h b/src/core/write-buffer.h index ef527440..8c60dc77 100644 --- a/src/core/write-buffer.h +++ b/src/core/write-buffer.h @@ -1,5 +1,5 @@ -#ifndef __WRITE_BUFFER_H -#define __WRITE_BUFFER_H +#ifndef IRSSI_CORE_WRITE_BUFFER_H +#define IRSSI_CORE_WRITE_BUFFER_H int write_buffer(int handle, const void *data, int size); void write_buffer_flush(void); diff --git a/src/fe-common/core/chat-completion.h b/src/fe-common/core/chat-completion.h index 17c1408d..2976b962 100644 --- a/src/fe-common/core/chat-completion.h +++ b/src/fe-common/core/chat-completion.h @@ -1,5 +1,5 @@ -#ifndef __CHAT_COMPLETION_H -#define __CHAT_COMPLETION_H +#ifndef IRSSI_FE_COMMON_CORE_CHAT_COMPLETION_H +#define IRSSI_FE_COMMON_CORE_CHAT_COMPLETION_H GList *completion_get_chatnets(const char *word); GList *completion_get_servers(const char *word); diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 3b9de941..04922d2d 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -1,5 +1,5 @@ -#ifndef __COMMAND_HISTORY_H -#define __COMMAND_HISTORY_H +#ifndef IRSSI_FE_COMMON_CORE_COMMAND_HISTORY_H +#define IRSSI_FE_COMMON_CORE_COMMAND_HISTORY_H #include diff --git a/src/fe-common/core/completion.h b/src/fe-common/core/completion.h index dce3a2f1..d505aa84 100644 --- a/src/fe-common/core/completion.h +++ b/src/fe-common/core/completion.h @@ -1,5 +1,5 @@ -#ifndef __COMPLETION_H -#define __COMPLETION_H +#ifndef IRSSI_FE_COMMON_CORE_COMPLETION_H +#define IRSSI_FE_COMMON_CORE_COMPLETION_H #include diff --git a/src/fe-common/core/fe-capsicum.h b/src/fe-common/core/fe-capsicum.h index a7cb743b..c0471296 100644 --- a/src/fe-common/core/fe-capsicum.h +++ b/src/fe-common/core/fe-capsicum.h @@ -1,5 +1,5 @@ -#ifndef __FE_CAPSICUM_H -#define __FE_CAPSICUM_H +#ifndef IRSSI_FE_COMMON_CORE_FE_CAPSICUM_H +#define IRSSI_FE_COMMON_CORE_FE_CAPSICUM_H void fe_capsicum_init(void); void fe_capsicum_deinit(void); diff --git a/src/fe-common/core/fe-channels.h b/src/fe-common/core/fe-channels.h index e9a03a12..34b24ac6 100644 --- a/src/fe-common/core/fe-channels.h +++ b/src/fe-common/core/fe-channels.h @@ -1,5 +1,5 @@ -#ifndef __FE_CHANNELS_H -#define __FE_CHANNELS_H +#ifndef IRSSI_FE_COMMON_CORE_FE_CHANNELS_H +#define IRSSI_FE_COMMON_CORE_FE_CHANNELS_H #define CHANNEL_NICKLIST_FLAG_OPS 0x01 #define CHANNEL_NICKLIST_FLAG_HALFOPS 0x02 diff --git a/src/fe-common/core/fe-common-core.h b/src/fe-common/core/fe-common-core.h index 88b2e94b..a9a74b0f 100644 --- a/src/fe-common/core/fe-common-core.h +++ b/src/fe-common/core/fe-common-core.h @@ -1,5 +1,5 @@ -#ifndef __FE_COMMON_CORE_H -#define __FE_COMMON_CORE_H +#ifndef IRSSI_FE_COMMON_CORE_FE_COMMON_CORE_H +#define IRSSI_FE_COMMON_CORE_FE_COMMON_CORE_H void fe_common_core_register_options(void); void fe_common_core_init(void); diff --git a/src/fe-common/core/fe-core-commands.h b/src/fe-common/core/fe-core-commands.h index 261303de..d711b5d6 100644 --- a/src/fe-common/core/fe-core-commands.h +++ b/src/fe-common/core/fe-core-commands.h @@ -1,5 +1,5 @@ -#ifndef __FE_CORE_COMMANDS_H -#define __FE_CORE_COMMANDS_H +#ifndef IRSSI_FE_COMMON_CORE_FE_CORE_COMMANDS_H +#define IRSSI_FE_COMMON_CORE_FE_CORE_COMMANDS_H extern int command_hide_output; diff --git a/src/fe-common/core/fe-exec.h b/src/fe-common/core/fe-exec.h index 21b1e18b..824d3d8a 100644 --- a/src/fe-common/core/fe-exec.h +++ b/src/fe-common/core/fe-exec.h @@ -1,5 +1,5 @@ -#ifndef __FE_EXEC_H -#define __FE_EXEC_H +#ifndef IRSSI_FE_COMMON_CORE_FE_EXEC_H +#define IRSSI_FE_COMMON_CORE_FE_EXEC_H #include diff --git a/src/fe-common/core/fe-messages.h b/src/fe-common/core/fe-messages.h index 07ecef80..03f7da7b 100644 --- a/src/fe-common/core/fe-messages.h +++ b/src/fe-common/core/fe-messages.h @@ -1,5 +1,5 @@ -#ifndef __FE_MESSAGES_H -#define __FE_MESSAGES_H +#ifndef IRSSI_FE_COMMON_CORE_FE_MESSAGES_H +#define IRSSI_FE_COMMON_CORE_FE_MESSAGES_H /* convert _underlined_ and *bold* words (and phrases) to use real underlining or bolding */ diff --git a/src/fe-common/core/fe-queries.h b/src/fe-common/core/fe-queries.h index 1dc7e81a..30c45e4e 100644 --- a/src/fe-common/core/fe-queries.h +++ b/src/fe-common/core/fe-queries.h @@ -1,5 +1,5 @@ -#ifndef __FE_QUERIES_H -#define __FE_QUERIES_H +#ifndef IRSSI_FE_COMMON_CORE_FE_QUERIES_H +#define IRSSI_FE_COMMON_CORE_FE_QUERIES_H #include diff --git a/src/fe-common/core/fe-recode.h b/src/fe-common/core/fe-recode.h index 9fc73289..50775f2c 100644 --- a/src/fe-common/core/fe-recode.h +++ b/src/fe-common/core/fe-recode.h @@ -1,7 +1,7 @@ -#ifndef __FE_RECODE_H -#define __FE_RECODE_H +#ifndef IRSSI_FE_COMMON_CORE_FE_RECODE_H +#define IRSSI_FE_COMMON_CORE_FE_RECODE_H void fe_recode_init (void); void fe_recode_deinit (void); -#endif /* __FE_RECODE_H */ +#endif /* IRSSI_FE_COMMON_CORE_FE_RECODE_H */ diff --git a/src/fe-common/core/fe-settings.h b/src/fe-common/core/fe-settings.h index cc628790..61797bcd 100644 --- a/src/fe-common/core/fe-settings.h +++ b/src/fe-common/core/fe-settings.h @@ -1,5 +1,5 @@ -#ifndef __FE_SETTINGS_H -#define __FE_SETTINGS_H +#ifndef IRSSI_FE_COMMON_CORE_FE_SETTINGS_H +#define IRSSI_FE_COMMON_CORE_FE_SETTINGS_H void fe_settings_set_print(const char *key); diff --git a/src/fe-common/core/fe-tls.h b/src/fe-common/core/fe-tls.h index f0082477..b0a3ea99 100644 --- a/src/fe-common/core/fe-tls.h +++ b/src/fe-common/core/fe-tls.h @@ -16,8 +16,8 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA */ -#ifndef __FE_TLS_H -#define __FE_TLS_H +#ifndef IRSSI_FE_COMMON_CORE_FE_TLS_H +#define IRSSI_FE_COMMON_CORE_FE_TLS_H void fe_tls_init(void); void fe_tls_deinit(void); diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 782b5430..d5c60c81 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -1,5 +1,5 @@ -#ifndef __WINDOWS_H -#define __WINDOWS_H +#ifndef IRSSI_FE_COMMON_CORE_FE_WINDOWS_H +#define IRSSI_FE_COMMON_CORE_FE_WINDOWS_H #include #include diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index a52a3bbd..2e6133be 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -1,5 +1,5 @@ -#ifndef __FORMATS_H -#define __FORMATS_H +#ifndef IRSSI_FE_COMMON_CORE_FORMATS_H +#define IRSSI_FE_COMMON_CORE_FORMATS_H #include #include diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 1ffce6b9..0dfe78f3 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,5 +1,5 @@ -#ifndef __HILIGHT_TEXT_H -#define __HILIGHT_TEXT_H +#ifndef IRSSI_FE_COMMON_CORE_HILIGHT_TEXT_H +#define IRSSI_FE_COMMON_CORE_HILIGHT_TEXT_H #include #include diff --git a/src/fe-common/core/keyboard.h b/src/fe-common/core/keyboard.h index 06b11bba..b19536a0 100644 --- a/src/fe-common/core/keyboard.h +++ b/src/fe-common/core/keyboard.h @@ -1,5 +1,5 @@ -#ifndef __KEYBOARD_H -#define __KEYBOARD_H +#ifndef IRSSI_FE_COMMON_CORE_KEYBOARD_H +#define IRSSI_FE_COMMON_CORE_KEYBOARD_H #include diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index ff52b374..845bfc6c 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -1,5 +1,5 @@ -#ifndef __PRINTTEXT_H -#define __PRINTTEXT_H +#ifndef IRSSI_FE_COMMON_CORE_PRINTTEXT_H +#define IRSSI_FE_COMMON_CORE_PRINTTEXT_H #include #include diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h index 31cfe943..53426f3b 100644 --- a/src/fe-common/core/themes.h +++ b/src/fe-common/core/themes.h @@ -1,5 +1,5 @@ -#ifndef __THEMES_H -#define __THEMES_H +#ifndef IRSSI_FE_COMMON_CORE_THEMES_H +#define IRSSI_FE_COMMON_CORE_THEMES_H typedef struct { char *name; diff --git a/src/fe-common/core/window-activity.h b/src/fe-common/core/window-activity.h index b904872f..42a4cda5 100644 --- a/src/fe-common/core/window-activity.h +++ b/src/fe-common/core/window-activity.h @@ -1,5 +1,5 @@ -#ifndef __WINDOW_ACTIVITY_H -#define __WINDOW_ACTIVITY_H +#ifndef IRSSI_FE_COMMON_CORE_WINDOW_ACTIVITY_H +#define IRSSI_FE_COMMON_CORE_WINDOW_ACTIVITY_H void window_activity(WINDOW_REC *window, int data_level, const char *hilight_color); diff --git a/src/fe-common/core/window-items.h b/src/fe-common/core/window-items.h index 77ffe680..5bfa92fa 100644 --- a/src/fe-common/core/window-items.h +++ b/src/fe-common/core/window-items.h @@ -1,5 +1,5 @@ -#ifndef __WINDOW_ITEMS_H -#define __WINDOW_ITEMS_H +#ifndef IRSSI_FE_COMMON_CORE_WINDOW_ITEMS_H +#define IRSSI_FE_COMMON_CORE_WINDOW_ITEMS_H #include diff --git a/src/fe-common/core/windows-layout.h b/src/fe-common/core/windows-layout.h index d33fda52..706fb781 100644 --- a/src/fe-common/core/windows-layout.h +++ b/src/fe-common/core/windows-layout.h @@ -1,5 +1,5 @@ -#ifndef __WINDOWS_LAYOUT_H -#define __WINDOWS_LAYOUT_H +#ifndef IRSSI_FE_COMMON_CORE_WINDOWS_LAYOUT_H +#define IRSSI_FE_COMMON_CORE_WINDOWS_LAYOUT_H void windows_layout_restore(void); void windows_layout_save(void); diff --git a/src/fe-common/irc/dcc/fe-dcc.h b/src/fe-common/irc/dcc/fe-dcc.h index f18b4a80..4d792966 100644 --- a/src/fe-common/irc/dcc/fe-dcc.h +++ b/src/fe-common/irc/dcc/fe-dcc.h @@ -1,5 +1,5 @@ -#ifndef __FE_DCC_H -#define __FE_DCC_H +#ifndef IRSSI_FE_COMMON_IRC_DCC_FE_DCC_H +#define IRSSI_FE_COMMON_IRC_DCC_FE_DCC_H char *dcc_get_size_str(uoff_t size); void dcc_list_print_file(FILE_DCC_REC *dcc); diff --git a/src/fe-common/irc/fe-irc-channels.h b/src/fe-common/irc/fe-irc-channels.h index d05c91a5..a5770107 100644 --- a/src/fe-common/irc/fe-irc-channels.h +++ b/src/fe-common/irc/fe-irc-channels.h @@ -1,5 +1,5 @@ -#ifndef __FE_IRC_CHANNELS_H -#define __FE_IRC_CHANNELS_H +#ifndef IRSSI_FE_COMMON_IRC_FE_IRC_CHANNELS_H +#define IRSSI_FE_COMMON_IRC_FE_IRC_CHANNELS_H int fe_channel_is_opchannel(IRC_SERVER_REC *server, const char *target); const char *fe_channel_skip_prefix(IRC_SERVER_REC *server, const char *target); diff --git a/src/fe-common/irc/fe-irc-server.h b/src/fe-common/irc/fe-irc-server.h index 7d9425be..28a709e3 100644 --- a/src/fe-common/irc/fe-irc-server.h +++ b/src/fe-common/irc/fe-irc-server.h @@ -1,5 +1,5 @@ -#ifndef __FE_IRC_SERVER_H -#define __FE_IRC_SERVER_H +#ifndef IRSSI_FE_COMMON_IRC_FE_IRC_SERVER_H +#define IRSSI_FE_COMMON_IRC_FE_IRC_SERVER_H const char *get_visible_target(IRC_SERVER_REC *server, const char *target); diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index dff860d3..97dcee22 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -1,5 +1,5 @@ -#ifndef __GUI_ENTRY_H -#define __GUI_ENTRY_H +#ifndef IRSSI_FE_TEXT_GUI_ENTRY_H +#define IRSSI_FE_TEXT_GUI_ENTRY_H typedef struct { int cutbuffer_len; diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 90f82220..ba5d6f8f 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -1,5 +1,5 @@ -#ifndef __GUI_PRINTTEXT_H -#define __GUI_PRINTTEXT_H +#ifndef IRSSI_FE_TEXT_GUI_PRINTTEXT_H +#define IRSSI_FE_TEXT_GUI_PRINTTEXT_H #include #include diff --git a/src/fe-text/gui-readline.h b/src/fe-text/gui-readline.h index 9ce3a742..dc497b8f 100644 --- a/src/fe-text/gui-readline.h +++ b/src/fe-text/gui-readline.h @@ -1,5 +1,5 @@ -#ifndef __GUI_READLINE_H -#define __GUI_READLINE_H +#ifndef IRSSI_FE_TEXT_GUI_READLINE_H +#define IRSSI_FE_TEXT_GUI_READLINE_H extern char *cutbuffer; diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h index 9fc3fbd5..52a64cea 100644 --- a/src/fe-text/gui-windows.h +++ b/src/fe-text/gui-windows.h @@ -1,5 +1,5 @@ -#ifndef __GUI_WINDOWS_H -#define __GUI_WINDOWS_H +#ifndef IRSSI_FE_TEXT_GUI_WINDOWS_H +#define IRSSI_FE_TEXT_GUI_WINDOWS_H #include #include diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 3a7fb1ed..52cf2df3 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -1,5 +1,5 @@ -#ifndef __MAINWINDOWS_H -#define __MAINWINDOWS_H +#ifndef IRSSI_FE_TEXT_MAINWINDOWS_H +#define IRSSI_FE_TEXT_MAINWINDOWS_H #include #include diff --git a/src/fe-text/statusbar-config.h b/src/fe-text/statusbar-config.h index ebba7da1..239918db 100644 --- a/src/fe-text/statusbar-config.h +++ b/src/fe-text/statusbar-config.h @@ -1,5 +1,5 @@ -#ifndef __STATUSBAR_CONFIG_H -#define __STATUSBAR_CONFIG_H +#ifndef IRSSI_FE_TEXT_STATUSBAR_CONFIG_H +#define IRSSI_FE_TEXT_STATUSBAR_CONFIG_H #include diff --git a/src/fe-text/statusbar.h b/src/fe-text/statusbar.h index eae29900..140d355d 100644 --- a/src/fe-text/statusbar.h +++ b/src/fe-text/statusbar.h @@ -1,5 +1,5 @@ -#ifndef __STATUSBAR_H -#define __STATUSBAR_H +#ifndef IRSSI_FE_TEXT_STATUSBAR_H +#define IRSSI_FE_TEXT_STATUSBAR_H #include #include diff --git a/src/fe-text/term.h b/src/fe-text/term.h index af866bea..7758fea3 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -1,5 +1,5 @@ -#ifndef __TERM_H -#define __TERM_H +#ifndef IRSSI_FE_TEXT_TERM_H +#define IRSSI_FE_TEXT_TERM_H typedef struct _TERM_WINDOW TERM_WINDOW; diff --git a/src/fe-text/terminfo-core.h b/src/fe-text/terminfo-core.h index 1253fd9d..a077d0bf 100644 --- a/src/fe-text/terminfo-core.h +++ b/src/fe-text/terminfo-core.h @@ -1,5 +1,5 @@ -#ifndef __TERMINFO_CORE_H -#define __TERMINFO_CORE_H +#ifndef IRSSI_FE_TEXT_TERMINFO_CORE_H +#define IRSSI_FE_TEXT_TERMINFO_CORE_H #include diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index 54775783..607016ac 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -1,5 +1,5 @@ -#ifndef __TEXTBUFFER_VIEW_H -#define __TEXTBUFFER_VIEW_H +#ifndef IRSSI_FE_TEXT_TEXTBUFFER_VIEW_H +#define IRSSI_FE_TEXT_TEXTBUFFER_VIEW_H #include #include diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 2aa22f1a..cbe4fbf0 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -1,5 +1,5 @@ -#ifndef __TEXTBUFFER_H -#define __TEXTBUFFER_H +#ifndef IRSSI_FE_TEXT_TEXTBUFFER_H +#define IRSSI_FE_TEXT_TEXTBUFFER_H /* Make sure TEXT_CHUNK_REC is not slightly more than a page, as that wastes a lot of memory. */ diff --git a/src/irc/core/bans.h b/src/irc/core/bans.h index 0b00f19d..5f052667 100644 --- a/src/irc/core/bans.h +++ b/src/irc/core/bans.h @@ -1,5 +1,5 @@ -#ifndef __BANS_H -#define __BANS_H +#ifndef IRSSI_IRC_CORE_BANS_H +#define IRSSI_IRC_CORE_BANS_H void bans_init(void); void bans_deinit(void); diff --git a/src/irc/core/channel-events.h b/src/irc/core/channel-events.h index d13c9760..ada3e3a1 100644 --- a/src/irc/core/channel-events.h +++ b/src/irc/core/channel-events.h @@ -1,5 +1,5 @@ -#ifndef __CHANNEL_EVENTS_H -#define __CHANNEL_EVENTS_H +#ifndef IRSSI_IRC_CORE_CHANNEL_EVENTS_H +#define IRSSI_IRC_CORE_CHANNEL_EVENTS_H #include diff --git a/src/irc/core/channel-rejoin.h b/src/irc/core/channel-rejoin.h index 0b9cd151..3c465799 100644 --- a/src/irc/core/channel-rejoin.h +++ b/src/irc/core/channel-rejoin.h @@ -1,5 +1,5 @@ -#ifndef __CHANNEL_REJOIN_H -#define __CHANNEL_REJOIN_H +#ifndef IRSSI_IRC_CORE_CHANNEL_REJOIN_H +#define IRSSI_IRC_CORE_CHANNEL_REJOIN_H typedef struct { char *channel; diff --git a/src/irc/core/ctcp.h b/src/irc/core/ctcp.h index a146b15f..c8a8a84e 100644 --- a/src/irc/core/ctcp.h +++ b/src/irc/core/ctcp.h @@ -1,5 +1,5 @@ -#ifndef __CTCP_H -#define __CTCP_H +#ifndef IRSSI_IRC_CORE_CTCP_H +#define IRSSI_IRC_CORE_CTCP_H /* Register/unregister CTCP command, so it shows in CTCP CLIENTINFO */ void ctcp_register(const char *name); diff --git a/src/irc/core/irc-cap.h b/src/irc/core/irc-cap.h index 96efbbee..aa13023a 100644 --- a/src/irc/core/irc-cap.h +++ b/src/irc/core/irc-cap.h @@ -1,5 +1,5 @@ -#ifndef __IRC_CAP_H -#define __IRC_CAP_H +#ifndef IRSSI_IRC_CORE_IRC_CAP_H +#define IRSSI_IRC_CORE_IRC_CAP_H void irc_cap_init(void); void irc_cap_deinit(void); diff --git a/src/irc/core/irc-channels.h b/src/irc/core/irc-channels.h index 2262b484..4ed7fd73 100644 --- a/src/irc/core/irc-channels.h +++ b/src/irc/core/irc-channels.h @@ -1,5 +1,5 @@ -#ifndef __IRC_CHANNELS_H -#define __IRC_CHANNELS_H +#ifndef IRSSI_IRC_CORE_IRC_CHANNELS_H +#define IRSSI_IRC_CORE_IRC_CHANNELS_H #include #include diff --git a/src/irc/core/irc-chatnets.h b/src/irc/core/irc-chatnets.h index 00aea848..10e98921 100644 --- a/src/irc/core/irc-chatnets.h +++ b/src/irc/core/irc-chatnets.h @@ -1,5 +1,5 @@ -#ifndef __IRC_CHATNETS_H -#define __IRC_CHATNETS_H +#ifndef IRSSI_IRC_CORE_IRC_CHATNETS_H +#define IRSSI_IRC_CORE_IRC_CHATNETS_H #include #include diff --git a/src/irc/core/irc-commands.h b/src/irc/core/irc-commands.h index 3e24c5a8..6f689313 100644 --- a/src/irc/core/irc-commands.h +++ b/src/irc/core/irc-commands.h @@ -1,5 +1,5 @@ -#ifndef __IRC_COMMANDS_H -#define __IRC_COMMANDS_H +#ifndef IRSSI_IRC_CORE_IRC_COMMANDS_H +#define IRSSI_IRC_CORE_IRC_COMMANDS_H #include diff --git a/src/irc/core/irc-masks.h b/src/irc/core/irc-masks.h index e152c52a..5696bbb5 100644 --- a/src/irc/core/irc-masks.h +++ b/src/irc/core/irc-masks.h @@ -1,5 +1,5 @@ -#ifndef __IRC_MASKS_H -#define __IRC_MASKS_H +#ifndef IRSSI_IRC_CORE_IRC_MASKS_H +#define IRSSI_IRC_CORE_IRC_MASKS_H #include diff --git a/src/irc/core/irc-nicklist.h b/src/irc/core/irc-nicklist.h index e9b30f30..7ac3176d 100644 --- a/src/irc/core/irc-nicklist.h +++ b/src/irc/core/irc-nicklist.h @@ -1,5 +1,5 @@ -#ifndef __IRC_NICKLIST_H -#define __IRC_NICKLIST_H +#ifndef IRSSI_IRC_CORE_IRC_NICKLIST_H +#define IRSSI_IRC_CORE_IRC_NICKLIST_H #include diff --git a/src/irc/core/irc-queries.h b/src/irc/core/irc-queries.h index 323006ad..f6680ed2 100644 --- a/src/irc/core/irc-queries.h +++ b/src/irc/core/irc-queries.h @@ -1,5 +1,5 @@ -#ifndef __IRC_QUERIES_H -#define __IRC_QUERIES_H +#ifndef IRSSI_IRC_CORE_IRC_QUERIES_H +#define IRSSI_IRC_CORE_IRC_QUERIES_H #include #include diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index ac2ca2fc..d3bafdef 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -1,5 +1,5 @@ -#ifndef __IRC_SERVERS_SETUP_H -#define __IRC_SERVERS_SETUP_H +#ifndef IRSSI_IRC_CORE_IRC_SERVERS_SETUP_H +#define IRSSI_IRC_CORE_IRC_SERVERS_SETUP_H #include #include diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index c798a03b..57b65527 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -1,5 +1,5 @@ -#ifndef __IRC_SERVERS_H -#define __IRC_SERVERS_H +#ifndef IRSSI_IRC_CORE_IRC_SERVERS_H +#define IRSSI_IRC_CORE_IRC_SERVERS_H #include #include diff --git a/src/irc/core/irc.h b/src/irc/core/irc.h index d018b90c..3f1a9887 100644 --- a/src/irc/core/irc.h +++ b/src/irc/core/irc.h @@ -1,5 +1,5 @@ -#ifndef __IRC_H -#define __IRC_H +#ifndef IRSSI_IRC_CORE_IRC_H +#define IRSSI_IRC_CORE_IRC_H typedef struct _IRC_CHATNET_REC IRC_CHATNET_REC; typedef struct _IRC_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC; diff --git a/src/irc/core/mode-lists.h b/src/irc/core/mode-lists.h index cd3bc0bf..2c9f20b1 100644 --- a/src/irc/core/mode-lists.h +++ b/src/irc/core/mode-lists.h @@ -1,5 +1,5 @@ -#ifndef __MODE_LISTS_H -#define __MODE_LISTS_H +#ifndef IRSSI_IRC_CORE_MODE_LISTS_H +#define IRSSI_IRC_CORE_MODE_LISTS_H typedef struct { char *ban; diff --git a/src/irc/core/modes.h b/src/irc/core/modes.h index 9442dd5e..f899a06d 100644 --- a/src/irc/core/modes.h +++ b/src/irc/core/modes.h @@ -1,5 +1,5 @@ -#ifndef __MODES_H -#define __MODES_H +#ifndef IRSSI_IRC_CORE_MODES_H +#define IRSSI_IRC_CORE_MODES_H #include #include /* MAX_USER_PREFIXES */ diff --git a/src/irc/core/netsplit.h b/src/irc/core/netsplit.h index 7cdee694..50edf63b 100644 --- a/src/irc/core/netsplit.h +++ b/src/irc/core/netsplit.h @@ -1,5 +1,5 @@ -#ifndef __NETSPLIT_H -#define __NETSPLIT_H +#ifndef IRSSI_IRC_CORE_NETSPLIT_H +#define IRSSI_IRC_CORE_NETSPLIT_H #include diff --git a/src/irc/core/sasl.h b/src/irc/core/sasl.h index 0693989d..04d0cd9d 100644 --- a/src/irc/core/sasl.h +++ b/src/irc/core/sasl.h @@ -18,8 +18,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __SASL_H -#define __SASL_H +#ifndef IRSSI_IRC_CORE_SASL_H +#define IRSSI_IRC_CORE_SASL_H enum { SASL_MECHANISM_NONE = 0, diff --git a/src/irc/core/servers-idle.h b/src/irc/core/servers-idle.h index 9d2eacec..b0aed721 100644 --- a/src/irc/core/servers-idle.h +++ b/src/irc/core/servers-idle.h @@ -1,5 +1,5 @@ -#ifndef __SERVERS_IDLE_H -#define __SERVERS_IDLE_H +#ifndef IRSSI_IRC_CORE_SERVERS_IDLE_H +#define IRSSI_IRC_CORE_SERVERS_IDLE_H /* Add new idle command to queue */ int server_idle_add_redir(IRC_SERVER_REC *server, const char *cmd, diff --git a/src/irc/core/servers-redirect.h b/src/irc/core/servers-redirect.h index 6182e3ab..f8ca605f 100644 --- a/src/irc/core/servers-redirect.h +++ b/src/irc/core/servers-redirect.h @@ -1,5 +1,5 @@ -#ifndef __SERVERS_REDIRECT_H -#define __SERVERS_REDIRECT_H +#ifndef IRSSI_IRC_CORE_SERVERS_REDIRECT_H +#define IRSSI_IRC_CORE_SERVERS_REDIRECT_H /* Register new redirection command. diff --git a/src/irc/dcc/dcc-chat.h b/src/irc/dcc/dcc-chat.h index a22fe75d..ef992bb8 100644 --- a/src/irc/dcc/dcc-chat.h +++ b/src/irc/dcc/dcc-chat.h @@ -1,5 +1,5 @@ -#ifndef __DCC_CHAT_H -#define __DCC_CHAT_H +#ifndef IRSSI_IRC_DCC_DCC_CHAT_H +#define IRSSI_IRC_DCC_DCC_CHAT_H #include diff --git a/src/irc/dcc/dcc-file.h b/src/irc/dcc/dcc-file.h index ef32f07c..38986354 100644 --- a/src/irc/dcc/dcc-file.h +++ b/src/irc/dcc/dcc-file.h @@ -1,5 +1,5 @@ -#ifndef __DCC_FILE_H -#define __DCC_FILE_H +#ifndef IRSSI_IRC_DCC_DCC_FILE_H +#define IRSSI_IRC_DCC_DCC_FILE_H #include diff --git a/src/irc/dcc/dcc-get.h b/src/irc/dcc/dcc-get.h index b6ee385c..3624f2c8 100644 --- a/src/irc/dcc/dcc-get.h +++ b/src/irc/dcc/dcc-get.h @@ -1,5 +1,5 @@ -#ifndef __DCC_GET_H -#define __DCC_GET_H +#ifndef IRSSI_IRC_DCC_DCC_GET_H +#define IRSSI_IRC_DCC_DCC_GET_H #include diff --git a/src/irc/dcc/dcc-queue.h b/src/irc/dcc/dcc-queue.h index 8c1a9b46..1ab4ecbf 100644 --- a/src/irc/dcc/dcc-queue.h +++ b/src/irc/dcc/dcc-queue.h @@ -1,5 +1,5 @@ -#ifndef __DCC_QUEUE_H_ -#define __DCC_QUEUE_H_ +#ifndef IRSSI_IRC_DCC_DCC_QUEUE_H_ +#define IRSSI_IRC_DCC_DCC_QUEUE_H_ #include diff --git a/src/irc/dcc/dcc-send.h b/src/irc/dcc/dcc-send.h index a0ee1ade..881ef64e 100644 --- a/src/irc/dcc/dcc-send.h +++ b/src/irc/dcc/dcc-send.h @@ -1,5 +1,5 @@ -#ifndef __DCC_SEND_H -#define __DCC_SEND_H +#ifndef IRSSI_IRC_DCC_DCC_SEND_H +#define IRSSI_IRC_DCC_DCC_SEND_H #include diff --git a/src/irc/dcc/dcc-server.h b/src/irc/dcc/dcc-server.h index a1973b5f..1a4449d4 100644 --- a/src/irc/dcc/dcc-server.h +++ b/src/irc/dcc/dcc-server.h @@ -1,5 +1,5 @@ -#ifndef __DCC_SERVER_H -#define __DCC_SERVER_H +#ifndef IRSSI_IRC_DCC_DCC_SERVER_H +#define IRSSI_IRC_DCC_DCC_SERVER_H #include diff --git a/src/irc/dcc/dcc.h b/src/irc/dcc/dcc.h index 5f54ee18..258d3395 100644 --- a/src/irc/dcc/dcc.h +++ b/src/irc/dcc/dcc.h @@ -1,5 +1,5 @@ -#ifndef __DCC_H -#define __DCC_H +#ifndef IRSSI_IRC_DCC_DCC_H +#define IRSSI_IRC_DCC_DCC_H #include #include diff --git a/src/irc/flood/autoignore.h b/src/irc/flood/autoignore.h index b00829a1..6c7a86e8 100644 --- a/src/irc/flood/autoignore.h +++ b/src/irc/flood/autoignore.h @@ -1,5 +1,5 @@ -#ifndef __AUTOIGNORE_H -#define __AUTOIGNORE_H +#ifndef IRSSI_IRC_FLOOD_AUTOIGNORE_H +#define IRSSI_IRC_FLOOD_AUTOIGNORE_H void autoignore_add(IRC_SERVER_REC *server, char *nick, int level); diff --git a/src/irc/flood/flood.h b/src/irc/flood/flood.h index e6454729..6bfc7850 100644 --- a/src/irc/flood/flood.h +++ b/src/irc/flood/flood.h @@ -1,5 +1,5 @@ -#ifndef __FLOOD_H -#define __FLOOD_H +#ifndef IRSSI_IRC_FLOOD_FLOOD_H +#define IRSSI_IRC_FLOOD_FLOOD_H void flood_init(void); void flood_deinit(void); diff --git a/src/irc/notifylist/notify-setup.h b/src/irc/notifylist/notify-setup.h index bfaef0c8..8540d1c2 100644 --- a/src/irc/notifylist/notify-setup.h +++ b/src/irc/notifylist/notify-setup.h @@ -1,5 +1,5 @@ -#ifndef __NOTIFY_SETUP_H -#define __NOTIFY_SETUP_H +#ifndef IRSSI_IRC_NOTIFYLIST_NOTIFY_SETUP_H +#define IRSSI_IRC_NOTIFYLIST_NOTIFY_SETUP_H void notifylist_add_config(NOTIFYLIST_REC *rec); void notifylist_remove_config(NOTIFYLIST_REC *rec); diff --git a/src/irc/notifylist/notifylist.h b/src/irc/notifylist/notifylist.h index 1094a105..fe2a1aac 100644 --- a/src/irc/notifylist/notifylist.h +++ b/src/irc/notifylist/notifylist.h @@ -1,5 +1,5 @@ -#ifndef __NOTIFYLIST_H -#define __NOTIFYLIST_H +#ifndef IRSSI_IRC_NOTIFYLIST_NOTIFYLIST_H +#define IRSSI_IRC_NOTIFYLIST_NOTIFYLIST_H typedef struct { char *mask; /* nick part must not contain wildcards */ diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h index 2cbaf69d..5b3d25f5 100644 --- a/src/irc/proxy/proxy.h +++ b/src/irc/proxy/proxy.h @@ -1,5 +1,5 @@ -#ifndef PROXY_H -#define PROXY_H +#ifndef IRSSI_IRC_PROXY_PROXY_H +#define IRSSI_IRC_PROXY_PROXY_H #include diff --git a/src/lib-config/iconfig.h b/src/lib-config/iconfig.h index 91583e40..92662d8d 100644 --- a/src/lib-config/iconfig.h +++ b/src/lib-config/iconfig.h @@ -1,5 +1,5 @@ -#ifndef __ICONFIG_H -#define __ICONFIG_H +#ifndef IRSSI_LIB_CONFIG_ICONFIG_H +#define IRSSI_LIB_CONFIG_ICONFIG_H enum { NODE_TYPE_KEY, diff --git a/src/perl/perl-common.h b/src/perl/perl-common.h index e2992ee9..88adaa7e 100644 --- a/src/perl/perl-common.h +++ b/src/perl/perl-common.h @@ -1,5 +1,5 @@ -#ifndef __PERL_COMMON_H -#define __PERL_COMMON_H +#ifndef IRSSI_PERL_PERL_COMMON_H +#define IRSSI_PERL_PERL_COMMON_H /* helper defines */ #define new_pv(a) \ diff --git a/src/perl/perl-core.h b/src/perl/perl-core.h index 7390a6fd..0d3a1a2f 100644 --- a/src/perl/perl-core.h +++ b/src/perl/perl-core.h @@ -1,5 +1,5 @@ -#ifndef __PERL_CORE_H -#define __PERL_CORE_H +#ifndef IRSSI_PERL_PERL_CORE_H +#define IRSSI_PERL_PERL_CORE_H typedef struct { char *name; /* unique name */ diff --git a/src/perl/perl-signals.h b/src/perl/perl-signals.h index 78a95bed..8191a917 100644 --- a/src/perl/perl-signals.h +++ b/src/perl/perl-signals.h @@ -1,5 +1,5 @@ -#ifndef __PERL_SIGNALS_H -#define __PERL_SIGNALS_H +#ifndef IRSSI_PERL_PERL_SIGNALS_H +#define IRSSI_PERL_PERL_SIGNALS_H void perl_signal_args_to_c(void (*callback)(void *, void **), void *cb_arg, int signal_id, SV **args, size_t n_args); diff --git a/src/perl/perl-sources.h b/src/perl/perl-sources.h index a83a65a6..0addb35d 100644 --- a/src/perl/perl-sources.h +++ b/src/perl/perl-sources.h @@ -1,5 +1,5 @@ -#ifndef __PERL_SOURCES_H -#define __PERL_SOURCES_H +#ifndef IRSSI_PERL_PERL_SOURCES_H +#define IRSSI_PERL_PERL_SOURCES_H int perl_timeout_add(int msecs, SV *func, SV *data, int once); int perl_input_add(int source, int condition, SV *func, SV *data, int once); From 9bbacf861b9ade8ae41536c9068557b0a43a0cda Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 May 2019 22:35:08 +0200 Subject: [PATCH 0524/1198] fix irssi-version link --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index a3a60a88..e1671e0c 100644 --- a/configure.ac +++ b/configure.ac @@ -766,13 +766,11 @@ irssi-config ]) dnl ** make the paths like include headers later -AC_CONFIG_LINKS([ -irssi/irssi-config.h:irssi-config.h -irssi/irssi-version.h:irssi-version.h -]) +AC_CONFIG_LINKS([irssi/irssi-config.h:irssi-config.h]) AC_LINK_FILES([$srcdir/src],[irssi/src]) AC_OUTPUT +$LN_S ../irssi-version.h irssi/irssi-version.h dnl ** for building from objdir old_dir=`pwd` && cd $srcdir && whole_dir=`pwd` && cd $old_dir From 845431aa31b622ce524898d27f30aa9c33f08a6f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 2 May 2019 17:14:23 +0200 Subject: [PATCH 0525/1198] Install pkg-config file add a copy of pkg-config-0.29.2 pkg.m4 --- Makefile.am | 3 +- configure.ac | 4 +- irssi-1.pc.in | 20 ++++ irssi-config.in | 9 -- m4/pkg.m4 | 275 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 300 insertions(+), 11 deletions(-) create mode 100644 irssi-1.pc.in delete mode 100644 irssi-config.in create mode 100644 m4/pkg.m4 diff --git a/Makefile.am b/Makefile.am index ba45d8ac..8bfa362e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,8 @@ SUBDIRS = src tests docs scripts themes utils confdir = $(sysconfdir) conf_DATA = irssi.conf +pkgconfig_DATA = irssi-1.pc + pkginclude_HEADERS = irssi-config.h irssi-version.h EXTRA_DIST = \ @@ -28,5 +30,4 @@ EXTRA_DIST = \ autogen.sh \ README.md \ $(conf_DATA) \ - irssi-config.in \ irssi-icon.png diff --git a/configure.ac b/configure.ac index e1671e0c..9c0243f7 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,8 @@ AM_PROG_LIBTOOL AC_PATH_PROG(sedpath, sed) AC_PATH_PROG(perlpath, perl) +PKG_INSTALLDIR + AC_CHECK_HEADERS(unistd.h dirent.h sys/ioctl.h sys/resource.h) # check posix headers.. @@ -762,7 +764,7 @@ docs/help/Makefile docs/help/in/Makefile utils/Makefile themes/Makefile -irssi-config +irssi-1.pc ]) dnl ** make the paths like include headers later diff --git a/irssi-1.pc.in b/irssi-1.pc.in new file mode 100644 index 00000000..a1c00f5c --- /dev/null +++ b/irssi-1.pc.in @@ -0,0 +1,20 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +prog_libs="@PROG_LIBS@" +common_libs="@COMMON_LIBS@" + +perl_link_libs="@PERL_LINK_LIBS@" +perl_fe_link_libs="@PERL_FE_LINK_LIBS@" +perl_link_flags="@PERL_LINK_FLAGS@" + +chat_modules="@CHAT_MODULES@" +irc_modules="@irc_MODULES@" + +Name: Irssi +Description: Irssi chat client +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} @OPENSSL_CFLAGS@ +Requires: glib-2.0 \ No newline at end of file diff --git a/irssi-config.in b/irssi-config.in deleted file mode 100644 index cd529ed0..00000000 --- a/irssi-config.in +++ /dev/null @@ -1,9 +0,0 @@ -PROG_LIBS="@PROG_LIBS@" -COMMON_LIBS="@COMMON_LIBS@" - -PERL_LINK_LIBS="@PERL_LINK_LIBS@" -PERL_FE_LINK_LIBS="@PERL_FE_LINK_LIBS@" -PERL_LINK_FLAGS="@PERL_LINK_FLAGS@" - -CHAT_MODULES="@CHAT_MODULES@" -irc_MODULES="@irc_MODULES@" diff --git a/m4/pkg.m4 b/m4/pkg.m4 new file mode 100644 index 00000000..13a88901 --- /dev/null +++ b/m4/pkg.m4 @@ -0,0 +1,275 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR From 4a3a064d55e9136fa5ad31f89f74dbe8752fe7e0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 7 May 2019 13:37:31 +0200 Subject: [PATCH 0526/1198] fix reconnect of multiplexed proxy --- src/irc/proxy/listen.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 37e2a939..1c53369c 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -27,6 +27,7 @@ #include #include +#include #include #include /* FIXME: evil. need to do fe-proxy */ @@ -176,7 +177,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client, if (!client->multiplex) { args_pass = args; } else { - IRC_SERVER_REC *server; + IRC_CHATNET_REC *chatnet; char *tag; const char *tag_end; @@ -188,18 +189,19 @@ static void handle_client_connect_cmd(CLIENT_REC *client, } tag = g_strndup(args, tag_end - args); - server = IRC_SERVER(server_find_chatnet(tag)); - g_free(tag); + chatnet = IRC_CHATNET(chatnet_find(tag)); - if (!server) { + if (!chatnet) { /* an invalid network was specified */ remove_client(client); + g_free(tag); return; } - client->server = server; + client->server = IRC_SERVER(server_find_chatnet(tag)); g_free(client->proxy_address); - client->proxy_address = g_strdup_printf("%.*s.proxy", (int)(tag_end - args), args); + client->proxy_address = g_strdup_printf("%s.proxy", tag); + g_free(tag); } if (g_strcmp0(password, args_pass) != 0) { @@ -578,7 +580,8 @@ static void event_connected(IRC_SERVER_REC *server) if (rec->connected && rec->server == NULL && (g_strcmp0(rec->listen->ircnet, "*") == 0 || (chatnet != NULL && - g_ascii_strcasecmp(chatnet, rec->listen->ircnet) == 0))) { + strstr(rec->proxy_address, chatnet) == rec->proxy_address && + rec->proxy_address[strlen(chatnet)] == '.'))) { proxy_outdata(rec, ":%s NOTICE %s :Connected to server\r\n", rec->proxy_address, rec->nick); rec->server = server; From d45993dba438fe52d21aca365ea3dceb40d9beb7 Mon Sep 17 00:00:00 2001 From: vague666 Date: Fri, 22 Mar 2019 12:30:46 +0100 Subject: [PATCH 0527/1198] Add -out parameter to /CAT Change flag to -window Updated help Typo call printtext with server Only use server when target is not NULL --- docs/help/in/cat.in | 7 +++++-- src/fe-common/core/fe-core-commands.c | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/help/in/cat.in b/docs/help/in/cat.in index 9f9f242f..370c1796 100644 --- a/docs/help/in/cat.in +++ b/docs/help/in/cat.in @@ -5,19 +5,22 @@ %9Parameters:%9 + -window: Displays the output in the active window. + 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. + Displays the contents of the specified file in the active window if -window + is specified, otherwise to the closest matching window depending on levels. The seek position parameter is used internally to display away logs, if omitted the whole file is shown. %9Examples:%9 - /CAT /etc/network/interfaces + /CAT -window /etc/network/interfaces /CAT /home/mike/resume.txt /CAT contact_details.txt diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 7e09cded..3da998bf 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -114,10 +114,11 @@ static void cmd_version(char *data) } } -/* SYNTAX: CAT [] */ -static void cmd_cat(const char *data) +/* SYNTAX: CAT [-window] [] */ +static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { - char *fname, *fposstr; + char *fname, *fposstr, *target; + GHashTable *optlist; void *free_arg; int fpos; GIOChannel *handle; @@ -127,12 +128,14 @@ static void cmd_cat(const char *data) int fd; #endif - if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr)) + g_return_if_fail(data != NULL); + + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS, + "cat", &optlist, &fname, &fposstr)) return; fname = convert_home(fname); fpos = atoi(fposstr); - cmd_params_free(free_arg); #ifdef HAVE_CAPSICUM fd = capsicum_open_wrapper(fname, O_RDONLY, 0); @@ -152,15 +155,18 @@ static void cmd_cat(const char *data) return; } + target = g_hash_table_lookup(optlist, "window") != NULL ? item->name : NULL; + g_io_channel_set_encoding(handle, NULL, NULL); g_io_channel_seek_position(handle, fpos, G_SEEK_SET, NULL); buf = g_string_sized_new(512); while (g_io_channel_read_line_string(handle, buf, &tpos, NULL) == G_IO_STATUS_NORMAL) { buf->str[tpos] = '\0'; - printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP | + printtext(target != NULL ? server : NULL, target, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); } g_string_free(buf, TRUE); + cmd_params_free(free_arg); g_io_channel_unref(handle); } @@ -344,6 +350,7 @@ void fe_core_commands_init(void) signal_add("list subcommands", (SIGNAL_FUNC) event_list_subcommands); command_set_options("echo", "+level +window"); + command_set_options("cat", "window"); } void fe_core_commands_deinit(void) From 9e13892e280cf848abf022430f2cbc1f8e214298 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 13 May 2019 15:15:46 +0200 Subject: [PATCH 0528/1198] fix realpath on old solaris POSIX.1-2001 did not implement realpath(..., NULL) yet. Fixes #1042 --- src/lib-config/write.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index b8ef6156..5dbbd1ed 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -315,6 +315,15 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) /* expand all symlinks; else we may replace a symlink with a regular file */ dest_name = realpath(base_name, NULL); + if (errno == EINVAL) { + /* variable path length not supported by glibc < 2.3, Solaris < 11 */ + char resolved_path[PATH_MAX] = { 0 }; + errno = 0; + if ((dest_name = realpath(base_name, resolved_path)) != NULL) { + dest_name = g_strdup(dest_name); + } + } + if (dest_name == NULL) { if (errno == ENOENT) { dest_name = g_strdup(base_name); From 78ae00910e0c10090ba0120ae5e74d88c120f499 Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 15 May 2019 14:24:10 +0200 Subject: [PATCH 0529/1198] Make MSGLEVEL_HIDDEN accessible from scripts Empty line in wrong place Expose MSGLEVEL_HIDDEN to scripts --- src/perl/common/Core.xs | 7 +++++++ src/perl/common/Irssi.pm | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index 75b851d6..8e26f105 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -303,6 +303,13 @@ CODE: perl_source_remove(tag); # maybe there's some easier way than this..? :) +int +MSGLEVEL_HIDDEN() +CODE: + RETVAL = MSGLEVEL_HIDDEN; +OUTPUT: + RETVAL + int MSGLEVEL_CRAP() CODE: diff --git a/src/perl/common/Irssi.pm b/src/perl/common/Irssi.pm index 1d7ed2f3..786d0e52 100644 --- a/src/perl/common/Irssi.pm +++ b/src/perl/common/Irssi.pm @@ -142,7 +142,7 @@ require DynaLoader; MSGLEVEL_TOPICS MSGLEVEL_WALLOPS MSGLEVEL_INVITES MSGLEVEL_NICKS MSGLEVEL_DCC MSGLEVEL_DCCMSGS MSGLEVEL_CLIENTNOTICE MSGLEVEL_CLIENTCRAP MSGLEVEL_CLIENTERROR MSGLEVEL_HILIGHT MSGLEVEL_ALL MSGLEVEL_NOHILIGHT - MSGLEVEL_NO_ACT MSGLEVEL_NEVER MSGLEVEL_LASTLOG + MSGLEVEL_NO_ACT MSGLEVEL_NEVER MSGLEVEL_LASTLOG MSGLEVEL_HIDDEN ); my $static = 0; From 38a81026b9fe09f22d41acefcfb2412d828bf4ff Mon Sep 17 00:00:00 2001 From: David Gall Date: Sun, 26 May 2019 18:59:21 +0200 Subject: [PATCH 0530/1198] Syntax Issue "was is" changed to "was" for otr_msg_not_in_private --- src/otr/otr-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/otr/otr-formats.c b/src/otr/otr-formats.c index d26edbba..d4d273d1 100644 --- a/src/otr/otr-formats.c +++ b/src/otr/otr-formats.c @@ -78,7 +78,7 @@ FORMAT_REC fe_otr_formats[] = { { "otr_msg_error", "Error in private conversation: {error $0}", 1, { 0 }}, { "otr_msg_general_error", "General Error: {error $0}", 1, { 0 }}, { "otr_msg_malformed", "Malformed message from {hilight $0}", 1, { 0 }}, - { "otr_msg_not_in_private", "The encrypted message from {hilight $0} was is unreadable because you're not communicating privately", 1, { 0 }}, + { "otr_msg_not_in_private", "The encrypted message from {hilight $0} was unreadable because you're not communicating privately", 1, { 0 }}, { "otr_msg_reflected", "Received reflected message from {hilight $0}", 0, { 0 }}, { "otr_msg_resent", "The last message to {hilight $0} was resent: $1", 2, { 0, 0 }}, { "otr_msg_unencrypted", "The following message from {hilight $0} was {error not} encrypted", 1, { 0 }}, From cd5958079ccdbe5e5bc34474dddc0bb14f9c2c8f Mon Sep 17 00:00:00 2001 From: vague666 Date: Tue, 28 May 2019 14:00:04 +0200 Subject: [PATCH 0531/1198] Make it possible to list specific section with /set update help Allow partial matching --- docs/help/in/set.in | 2 ++ src/fe-common/core/fe-settings.c | 36 +++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/docs/help/in/set.in b/docs/help/in/set.in index b2a4551b..097ace7e 100644 --- a/docs/help/in/set.in +++ b/docs/help/in/set.in @@ -7,6 +7,7 @@ -clear: Removes the setting's value from the configuration. -default: Restore the setting to its default value. + -section: Print settings under the specified section The setting and the value; if no value is given, the list of settings that matched will be returned. If no arguments are given, all the settings will @@ -27,6 +28,7 @@ /SET -clear nick /SET log_timestamp %%H:%%H:%%S /SET -default log_timestamp + /SET -section lookandfeel /SET close %9See also:%9 SAVE, TOGGLE diff --git a/src/fe-common/core/fe-settings.c b/src/fe-common/core/fe-settings.c index ad4747e8..f686916f 100644 --- a/src/fe-common/core/fe-settings.c +++ b/src/fe-common/core/fe-settings.c @@ -69,6 +69,29 @@ static void set_print_pattern(const char *pattern) g_slist_free(sets); } +static void set_print_section(const char *pattern) +{ + GSList *sets, *tmp; + const char *last_section; + + last_section = ""; + sets = settings_get_sorted(); + for (tmp = sets; tmp != NULL; tmp = tmp->next) { + SETTINGS_REC *rec = tmp->data; + + if (stristr(rec->section, pattern) != NULL) { + if (g_strcmp0(last_section, rec->section) != 0) { + /* print section */ + printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, + TXT_SET_TITLE, rec->section); + last_section = rec->section; + } + set_print(rec); + } + } + g_slist_free(sets); +} + static void set_boolean(const char *key, const char *value) { char *stripped_value; @@ -123,13 +146,13 @@ static void set_choice(const char *key, const char *value) g_free(stripped_value); } -/* SYNTAX: SET [-clear | -default] [ []] */ +/* SYNTAX: SET [-clear | -default | -section] [ []] */ static void cmd_set(char *data) { GHashTable *optlist; char *key, *value; void *free_arg; - int clear, set_default; + int clear, set_default, list_section; SETTINGS_REC *rec; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | @@ -139,11 +162,14 @@ static void cmd_set(char *data) clear = g_hash_table_lookup(optlist, "clear") != NULL; set_default = g_hash_table_lookup(optlist, "default") != NULL; + list_section = g_hash_table_lookup(optlist, "section") != NULL; if (*key == '\0') - clear = set_default = FALSE; + clear = set_default = list_section = FALSE; - if (!(clear || set_default || *value != '\0')) + if (list_section) + set_print_section(key); + else if (!(clear || set_default || *value != '\0')) set_print_pattern(key); else { rec = settings_get_record(key); @@ -408,7 +434,7 @@ void fe_settings_init(void) command_bind("unalias", NULL, (SIGNAL_FUNC) cmd_unalias); command_bind("reload", NULL, (SIGNAL_FUNC) cmd_reload); command_bind("save", NULL, (SIGNAL_FUNC) cmd_save); - command_set_options("set", "clear default"); + command_set_options("set", "clear default section"); signal_add("settings errors", (SIGNAL_FUNC) sig_settings_errors); } From 1910b67b979d2b66b6bc7bb9d2e847a8539063cf Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Thu, 30 May 2019 17:24:02 +0300 Subject: [PATCH 0532/1198] Clarify statusbar priorities I was misled by the documentation a little bit and thought that status bar items of lower priority will be removed rather than truncated if they didn't fit. Also, I had a hard time lowering priority below 0 because I didn't realize negative numbers have to be quoted so they won't be interpreted as option flags. --- docs/help/in/statusbar.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/help/in/statusbar.in b/docs/help/in/statusbar.in index 9d68d1c9..fd764537 100644 --- a/docs/help/in/statusbar.in +++ b/docs/help/in/statusbar.in @@ -30,7 +30,9 @@ -before: This item is added before the other item. -after: This item is added after the other item. -priority: When the statusbar items overflow, the item with the - lowest priority is removed first + lowest priority is removed or truncated first. + Priority can be negative, in which case it'll have to be + quoted (e.g. -priority "-1") -alignment: Display the item on the right side. Where statusbar refers to the name of the statusbar; if no argument is From d9fef37131df945b0e6086152553f1921aae3dcf Mon Sep 17 00:00:00 2001 From: Alex Shafer Date: Mon, 3 Jun 2019 20:58:18 -0600 Subject: [PATCH 0533/1198] Fix #1051 - Document Irssi::get_irssi_dir() --- docs/perl.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/perl.txt b/docs/perl.txt index 4f875c97..761b2f4d 100644 --- a/docs/perl.txt +++ b/docs/perl.txt @@ -178,6 +178,9 @@ listed after the generic ones. Window active_win() - return active window Server active_server() - return server in active window +get_irssi_dir() - returns the absolute path to the user configuration + directory - either the value passed to --home at startup, or ~/.irssi + windows() - return list of all windows servers() - return list of all servers reconnects() - return list of all server reconnections From 1d6aeb08fd8b732a7403ff0b53fe40e7f679caf7 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sun, 9 Jun 2019 23:03:31 +0000 Subject: [PATCH 0534/1198] fe-text/mainwindows: fix /window balance warning mainwindow_resize() expects that the mainwindow's height has not yet been updated, as it updates it itself, and throws a warning otherwise. --- src/fe-text/mainwindows.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 677e0e14..051c63ae 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -1298,9 +1298,7 @@ static void window_balance_vertical(void) rec->last_line++; } - rec->height = rec->last_line-rec->first_line+1; - - mainwindow_resize(rec, 0, rec->height-old_size); + mainwindow_resize(rec, 0, rec->last_line - rec->first_line + 1 - old_size); } if (line != NULL && bigger_units > 0) { bigger_units--; From 38b6284535e228c9dd7296a4ec2a4a9da64e230a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Jun 2019 14:53:42 +0200 Subject: [PATCH 0535/1198] restore 8bit support in input entry --- src/fe-text/gui-entry.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 1a721397..095c48a1 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -379,11 +379,19 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos) if (new_xpos > end_xpos) break; - if (entry->hidden) + if (entry->hidden) { g_string_append_c(str, ' '); - else if (unichar_isprint(c)) - g_string_append_unichar(str, c); - else { + } else if (unichar_isprint(c)) { + if (entry->utf8) { + g_string_append_unichar(str, c); + } else if (term_type == TERM_TYPE_BIG5) { + if(c > 0xff) + g_string_append_c(str, (c >> 8) & 0xff); + g_string_append_c(str, c & 0xff); + } else { + g_string_append_c(str, c); + } + } else { g_string_append_c(str, 4); g_string_append_c(str, FORMAT_STYLE_REVERSE); g_string_append_c(str, (c & 127)+'A'-1); From 5a67b983dc97caeb5df1139aabd0bc4f260a47d8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 17 Jun 2019 15:22:27 +0200 Subject: [PATCH 0536/1198] copy sasl username and password values --- src/irc/core/irc-core.c | 2 ++ src/irc/core/irc-servers-reconnect.c | 4 ++-- src/irc/core/irc-servers-setup.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index e65abe25..b5e80f2a 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -75,6 +75,8 @@ static void destroy_server_connect(SERVER_CONNECT_REC *conn) g_free_not_null(ircconn->usermode); g_free_not_null(ircconn->alternate_nick); + g_free_not_null(ircconn->sasl_username); + g_free_not_null(ircconn->sasl_password); } void irc_core_init(void) diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index 3d2933f4..cfe28a1a 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -49,8 +49,8 @@ static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, 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; + rec->sasl_username = g_strdup(src->sasl_username); + rec->sasl_password = g_strdup(src->sasl_password); *dest = (SERVER_CONNECT_REC *) rec; } diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 56e52edd..5f1290a2 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -101,8 +101,8 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, conn->sasl_mechanism = SASL_MECHANISM_PLAIN; if (ircnet->sasl_username != NULL && *ircnet->sasl_username && ircnet->sasl_password != NULL && *ircnet->sasl_password) { - conn->sasl_username = ircnet->sasl_username; - conn->sasl_password = ircnet->sasl_password; + conn->sasl_username = g_strdup(ircnet->sasl_username); + conn->sasl_password = g_strdup(ircnet->sasl_password); } else g_warning("The fields sasl_username and sasl_password are either missing or empty"); } From 8d11060fbc698e843148b6b07fe2ef60ddca71c8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 18 Jun 2019 14:55:47 +0200 Subject: [PATCH 0537/1198] Use the 24bit mIRC colour mappings if colors_ansi_24bit is enabled --- src/fe-text/gui-printtext.c | 66 ++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 9b472bff..24e91624 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -30,6 +30,7 @@ #include #include +/* Terminal indexed colour map */ int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7, /* 16-27 */ 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89, /* 28-39 */ 88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125, @@ -38,6 +39,17 @@ int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7, /* 64-75 */ 203, 215, 227, 191, 83, 122, 87, 111, 63, 177, 207, 205, /* 76-87 */ 217, 223, 229, 193, 157, 158, 159, 153, 147, 183, 219, 212, /* 88-98 */ 16, 233, 235, 237, 239, 241, 244, 247, 250, 254, 231, -1 }; + +/* RGB colour map */ +int mirc_colors24[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 16-27 */ 0x470000, 0x472100, 0x474700, 0x324700, 0x004700, 0x00472c, 0x004747, 0x002747, 0x000047, 0x2e0047, 0x470047, 0x47002a, + /* 28-39 */ 0x740000, 0x743a00, 0x747400, 0x517400, 0x007400, 0x007449, 0x007474, 0x004074, 0x000074, 0x4b0074, 0x740074, 0x740045, + /* 40-51 */ 0xb50000, 0xb56300, 0xb5b500, 0x7db500, 0x00b500, 0x00b571, 0x00b5b5, 0x0063b5, 0x0000b5, 0x7500b5, 0xb500b5, 0xb5006b, + /* 52-63 */ 0xff0000, 0xff8c00, 0xffff00, 0xb2ff00, 0x00ff00, 0x00ffa0, 0x00ffff, 0x008cff, 0x0000ff, 0xa500ff, 0xff00ff, 0xff0098, + /* 64-75 */ 0xff5959, 0xffb459, 0xffff71, 0xcfff60, 0x6fff6f, 0x65ffc9, 0x6dffff, 0x59b4ff, 0x5959ff, 0xc459ff, 0xff66ff, 0xff59bc, + /* 76-87 */ 0xff9c9c, 0xffd39c, 0xffff9c, 0xe2ff9c, 0x9cff9c, 0x9cffdb, 0x9cffff, 0x9cd3ff, 0x9c9cff, 0xdc9cff, 0xff9cff, 0xff94d3, + /* 88-98 */ 0x000000, 0x131313, 0x282828, 0x363636, 0x4d4d4d, 0x656565, 0x818181, 0x9f9f9f, 0xbcbcbc, 0xe2e2e2, 0xffffff, -1 }; + static int scrollback_lines, scrollback_time, scrollback_burst_remove; /* * If positive, remove lines older than scrollback_max_age seconds. @@ -225,28 +237,42 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) } } -static void get_colors(int flags, int *fg, int *bg, int *attr) +static void get_colors(int *flags, int *fg, int *bg, int *attr) { *attr = 0; - if (flags & GUI_PRINT_FLAG_MIRC_COLOR) { + if (*flags & GUI_PRINT_FLAG_MIRC_COLOR) { /* mirc colors - extended colours proposal */ - if (*bg >= 0) { - *bg = mirc_colors[*bg % 100]; - flags &= ~GUI_PRINT_FLAG_COLOR_24_BG; - /* ignore mirc color 99 = -1 (reset) */ - if (*bg != -1 && settings_get_bool("mirc_blink_fix")) { - if (*bg < 16) /* ansi bit flip :-( */ - *bg = (*bg&8) | (*bg&4)>>2 | (*bg&2) | (*bg&1)<<2; - *bg = term_color256map[*bg&0xff] & 7; + gboolean use_24_map = FALSE; +#ifdef TERM_TRUECOLOR + use_24_map = settings_get_bool("colors_ansi_24bit"); +#endif + if (*bg >= 0) { + if (use_24_map && mirc_colors24[*bg % 100] != -1) { + *bg = mirc_colors24[*bg % 100]; + *flags |= GUI_PRINT_FLAG_COLOR_24_BG; + } else { + *bg = mirc_colors[*bg % 100]; + *flags &= ~GUI_PRINT_FLAG_COLOR_24_BG; + /* ignore mirc color 99 = -1 (reset) */ + if (*bg != -1 && settings_get_bool("mirc_blink_fix")) { + if (*bg < 16) /* ansi bit flip :-( */ + *bg = (*bg&8) | (*bg&4)>>2 | (*bg&2) | (*bg&1)<<2; + *bg = term_color256map[*bg&0xff] & 7; + } } } if (*fg >= 0) { - *fg = mirc_colors[*fg % 100]; - flags &= ~GUI_PRINT_FLAG_COLOR_24_FG; + if (use_24_map && mirc_colors24[*fg % 100] != -1) { + *fg = mirc_colors24[*fg % 100]; + *flags |= GUI_PRINT_FLAG_COLOR_24_FG; + } else { + *fg = mirc_colors[*fg % 100]; + *flags &= ~GUI_PRINT_FLAG_COLOR_24_FG; + } } } - if (flags & GUI_PRINT_FLAG_COLOR_24_FG) + if (*flags & GUI_PRINT_FLAG_COLOR_24_FG) *attr |= ATTR_FGCOLOR24; else if (*fg < 0 || *fg > 255) { *fg = -1; @@ -255,7 +281,7 @@ static void get_colors(int flags, int *fg, int *bg, int *attr) else *attr |= *fg; - if (flags & GUI_PRINT_FLAG_COLOR_24_BG) + if (*flags & GUI_PRINT_FLAG_COLOR_24_BG) *attr |= ATTR_BGCOLOR24; else if (*bg < 0 || *bg > 255) { *bg = -1; @@ -264,11 +290,11 @@ static void get_colors(int flags, int *fg, int *bg, int *attr) else *attr |= (*bg << BG_SHIFT); - if (flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE; - if (flags & GUI_PRINT_FLAG_ITALIC) *attr |= ATTR_ITALIC; - if (flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD; - if (flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE; - if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK; + if (*flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE; + if (*flags & GUI_PRINT_FLAG_ITALIC) *attr |= ATTR_ITALIC; + if (*flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD; + if (*flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE; + if (*flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK; } static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line) @@ -309,7 +335,7 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); - get_colors(flags, &fg, &bg, &attr); + get_colors(&flags, &fg, &bg, &attr); if (window == NULL) { print_text_no_window(flags, fg, bg, attr, str); From beea28bbbc9d8a67e157e70cd9d9dbd1fa98decd Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 28 Jun 2019 11:31:19 +0200 Subject: [PATCH 0538/1198] fix code block NEWS formatting --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 97cb7dbf..f8d1a50e 100644 --- a/NEWS +++ b/NEWS @@ -19,9 +19,11 @@ v1.2.0 2019-02-11 The Irssi team calculate the width of emojis on your terminal screen (#917, #720) + Make the wcwidth functions available from Perl (#973): + string_width(str) string_chars_for_width(str, width) wcwidth(char) + + Added completion_keep_word setting (#979) + Allow activity_hide_targets to hide activity in itemless windows (#967, #997, #1001, #1003) @@ -35,6 +37,7 @@ v1.2.0 2019-02-11 The Irssi team channels that are in the config (#968) + Add format support for the input line. By Ben Paxton, originally by Jonas Hurrelmann (#764, FS#621, #1004) + use Irssi::TextUI; gui_input_set_extent(pos, text) gui_input_set_extents(pos, len, left, right) @@ -42,6 +45,7 @@ v1.2.0 2019-02-11 The Irssi team gui_input_get_extent(pos) gui_input_get_text_and_extents() gui_input_set_text_and_extents(...) + + Parsing of IRCv3 CAP 3.2 (#775, #869) + Show CAP-related events in the user interface (#918, #916, #870, #704) From 87a2ceb27d2f20eb0f38858aad5614406a648f44 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 28 Jun 2019 23:14:15 +0200 Subject: [PATCH 0539/1198] Merge tag '1.0.8' into integrate/1.0.8 --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index f8d1a50e..5f35309d 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ v1.3-head 2019-xx-xx The Irssi team +v1.0.8 2019-06-29 The Irssi team + - Fix a use after free issue when sending the SASL login on + (automatic and manual) reconnects (#1055, #1058). Reported + by ilbelkyr + v1.2.0 2019-02-11 The Irssi team ! Contains all changes from 1.1.2 * Improved the /STATUSBAR commands (#858) From 7286da0f9e52d36a8359134c8bcacd4d6a1ecb79 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 28 Jun 2019 23:12:45 +0200 Subject: [PATCH 0540/1198] Merge tag '1.1.3' into integrate/1.1.3 --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 5f35309d..c0835b93 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ v1.3-head 2019-xx-xx The Irssi team +v1.1.3 2019-06-29 The Irssi team + ! Contains all changes from 1.0.8 + - Fix regression of #779 where autolog_ignore_targets would + not matching itemless windows anymore (#1012, #1013) + v1.0.8 2019-06-29 The Irssi team - Fix a use after free issue when sending the SASL login on (automatic and manual) reconnects (#1055, #1058). Reported From fb85fdec5ca48a9a24d8dc9482ac7c5490c5dffc Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 28 Jun 2019 23:04:45 +0200 Subject: [PATCH 0541/1198] Merge tag '1.2.1' into integrate/1.2.1 --- NEWS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NEWS b/NEWS index c0835b93..2df16223 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,16 @@ v1.3-head 2019-xx-xx The Irssi team +v1.2.1 2019-06-29 The Irssi team + ! Contains all changes from 1.1.3 + - Fix a test on big endian machines (#1014) + - Fix the compile time conditionality of wcwidth + implementation (#1019, gentoo#677804, #720) + - Fix /save no longer working on old Solaris (pre + POSIX.1-2008) (#1042, #1043) + - Fix regression of #764 where display of 8-bit (legacy + encoding) in the input prompt was broken (#1018, + #1057). Initial patch by Артём Курашов + v1.1.3 2019-06-29 The Irssi team ! Contains all changes from 1.0.8 - Fix regression of #779 where autolog_ignore_targets would From db16a0a8536f5583a0f22f4e5cf6308aa1df2ba1 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 8 Jul 2019 00:02:53 +0200 Subject: [PATCH 0542/1198] meson build support --- .gitignore | 4 +- configure.ac | 16 - docs/help/in/meson.build | 1 + docs/help/meson.build | 121 ++++++ docs/meson.build | 18 + meson.build | 454 +++++++++++++++++++++++ meson_options.txt | 14 + scripts/meson.build | 14 + src/common.h | 11 +- src/core/meson.build | 129 +++++++ src/fe-common/core/meson.build | 99 +++++ src/fe-common/core/printtext.c | 2 +- src/fe-common/irc/dcc/meson.build | 27 ++ src/fe-common/irc/irc-modules.c | 4 + src/fe-common/irc/meson.build | 44 +++ src/fe-common/irc/notifylist/meson.build | 21 ++ src/fe-common/meson.build | 6 + src/fe-fuzz/fe-common/core/meson.build | 21 ++ src/fe-fuzz/fe-common/core/theme-load.c | 7 +- src/fe-fuzz/fe-common/meson.build | 3 + src/fe-fuzz/irc/core/event-get-params.c | 12 +- src/fe-fuzz/irc/core/meson.build | 23 ++ src/fe-fuzz/irc/meson.build | 3 + src/fe-fuzz/meson.build | 46 +++ src/fe-fuzz/server.c | 13 +- src/fe-none/meson.build | 21 ++ src/fe-text/meson.build | 68 ++++ src/irc/core/meson.build | 66 ++++ src/irc/dcc/meson.build | 31 ++ src/irc/flood/meson.build | 14 + src/irc/irc.c | 5 + src/irc/meson.build | 24 ++ src/irc/notifylist/meson.build | 21 ++ src/irc/proxy/meson.build | 20 + src/lib-config/meson.build | 19 + src/meson.build | 29 ++ src/otr/meson.build | 26 ++ src/perl/common/meson.build | 37 ++ src/perl/get-signals.pl | 2 +- src/perl/irc/meson.build | 39 ++ src/perl/meson.build | 73 ++++ src/perl/textui/meson.build | 35 ++ src/perl/ui/meson.build | 33 ++ subprojects/glib.wrap | 4 + subprojects/libffi.wrap | 1 + subprojects/proxy-libintl.wrap | 1 + subprojects/zlib.wrap | 1 + tests/fe-common/core/meson.build | 19 + tests/fe-common/meson.build | 1 + tests/fe-text/meson.build | 30 ++ tests/irc/core/meson.build | 45 +++ tests/irc/flood/meson.build | 25 ++ tests/irc/meson.build | 2 + tests/meson.build | 5 + themes/meson.build | 6 + utils/irssi-version.sh | 16 +- utils/syntax.pl | 1 + 57 files changed, 1787 insertions(+), 46 deletions(-) create mode 100644 docs/help/in/meson.build create mode 100644 docs/help/meson.build create mode 100644 docs/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 scripts/meson.build create mode 100644 src/core/meson.build create mode 100644 src/fe-common/core/meson.build create mode 100644 src/fe-common/irc/dcc/meson.build create mode 100644 src/fe-common/irc/irc-modules.c create mode 100644 src/fe-common/irc/meson.build create mode 100644 src/fe-common/irc/notifylist/meson.build create mode 100644 src/fe-common/meson.build create mode 100644 src/fe-fuzz/fe-common/core/meson.build create mode 100644 src/fe-fuzz/fe-common/meson.build create mode 100644 src/fe-fuzz/irc/core/meson.build create mode 100644 src/fe-fuzz/irc/meson.build create mode 100644 src/fe-fuzz/meson.build create mode 100644 src/fe-none/meson.build create mode 100644 src/fe-text/meson.build create mode 100644 src/irc/core/meson.build create mode 100644 src/irc/dcc/meson.build create mode 100644 src/irc/flood/meson.build create mode 100644 src/irc/irc.c create mode 100644 src/irc/meson.build create mode 100644 src/irc/notifylist/meson.build create mode 100644 src/irc/proxy/meson.build create mode 100644 src/lib-config/meson.build create mode 100644 src/meson.build create mode 100644 src/otr/meson.build create mode 100644 src/perl/common/meson.build create mode 100644 src/perl/irc/meson.build create mode 100644 src/perl/meson.build create mode 100644 src/perl/textui/meson.build create mode 100644 src/perl/ui/meson.build create mode 100644 subprojects/glib.wrap create mode 120000 subprojects/libffi.wrap create mode 120000 subprojects/proxy-libintl.wrap create mode 120000 subprojects/zlib.wrap create mode 100644 tests/fe-common/core/meson.build create mode 100644 tests/fe-common/meson.build create mode 100644 tests/fe-text/meson.build create mode 100644 tests/irc/core/meson.build create mode 100644 tests/irc/flood/meson.build create mode 100644 tests/irc/meson.build create mode 100644 tests/meson.build create mode 100644 themes/meson.build diff --git a/.gitignore b/.gitignore index ee1480cb..f42839eb 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ MYMETA.* docs/help/Makefile.am docs/help/[a-z]* +!docs/help/meson.build !docs/help/in docs/help/in/Makefile.am @@ -35,9 +36,6 @@ src/fe-fuzz/irssi-fuzz src/fe-fuzz/irc/core/event-get-params-fuzz src/fe-fuzz/fe-common/core/theme-load-fuzz -src/fe-common/irc/irc-modules.c -src/irc/irc.c - src/perl/perl-signals-list.h src/perl/irssi-core.pl.h diff --git a/configure.ac b/configure.ac index 9c0243f7..7d35aefa 100644 --- a/configure.ac +++ b/configure.ac @@ -243,22 +243,6 @@ else offt_64bit=no fi -if test x$ac_cv_sizeof_off_t = x$ac_cv_sizeof_long; then - # try to use unsigned long always first - AC_DEFINE_UNQUOTED(PRIuUOFF_T, "lu") - AC_DEFINE(UOFF_T_LONG) -elif test x$ac_cv_sizeof_off_t = x$ac_cv_sizeof_int; then - # next try int - AC_DEFINE_UNQUOTED(PRIuUOFF_T, "u") - AC_DEFINE(UOFF_T_INT) -elif test x$ac_cv_sizeof_off_t = x$ac_cv_sizeof_long_long; then - # and finally long long - AC_DEFINE_UNQUOTED(PRIuUOFF_T, "llu") - AC_DEFINE(UOFF_T_LONG_LONG) -else - AC_ERROR([Couldn't find integer type for off_t]) -fi - dnl ** dnl ** check for socks dnl ** diff --git a/docs/help/in/meson.build b/docs/help/in/meson.build new file mode 100644 index 00000000..aa459b7d --- /dev/null +++ b/docs/help/in/meson.build @@ -0,0 +1 @@ +# don't forget to add new help files to ../meson.build diff --git a/docs/help/meson.build b/docs/help/meson.build new file mode 100644 index 00000000..7fe95d43 --- /dev/null +++ b/docs/help/meson.build @@ -0,0 +1,121 @@ +install_data( + files( + 'accept', + 'action', + 'admin', + 'alias', + 'away', + 'ban', + 'beep', + 'bind', + 'cat', + 'cd', + 'channel', + 'clear', + 'completion', + 'connect', + 'ctcp', + 'cycle', + 'dcc', + 'dehilight', + 'deop', + 'devoice', + 'die', + 'disconnect', + 'echo', + 'eval', + 'exec', + 'flushbuffer', + 'format', + 'hash', + 'help', + 'hilight', + 'ignore', + 'info', + 'invite', + 'irssiproxy', + 'ison', + 'join', + 'kick', + 'kickban', + 'kill', + 'knock', + 'knockout', + 'lastlog', + 'layout', + 'levels', + 'links', + 'list', + 'load', + 'log', + 'lusers', + 'map', + 'me', + 'mircdcc', + 'mode', + 'motd', + 'msg', + 'names', + 'nctcp', + 'netsplit', + 'network', + 'nick', + 'notice', + 'notify', + 'op', + 'oper', + 'otr', + 'part', + 'ping', + 'query', + 'quit', + 'quote', + 'rawlog', + 'recode', + 'reconnect', + 'rehash', + 'reload', + 'restart', + 'rmreconns', + 'rmrejoins', + 'save', + 'sconnect', + 'script', + 'scrollback', + 'server', + 'servlist', + 'set', + 'silence', + 'squery', + 'squit', + 'stats', + 'statusbar', + 'time', + 'toggle', + 'topic', + 'trace', + 'ts', + 'unalias', + 'unban', + 'unignore', + 'unload', + 'unnotify', + 'unquery', + 'unsilence', + 'upgrade', + 'uptime', + 'userhost', + 'ver', + 'version', + 'voice', + 'wait', + 'wall', + 'wallops', + 'who', + 'whois', + 'whowas', + 'window', + ), + install_dir : helpdir) + +# subdir('in') diff --git a/docs/meson.build b/docs/meson.build new file mode 100644 index 00000000..a58faed3 --- /dev/null +++ b/docs/meson.build @@ -0,0 +1,18 @@ +install_data( + files( + 'capsicum.txt', + 'design.html', + 'design.txt', + 'faq.html', + 'faq.txt', + 'formats.txt', + 'manual.txt', + 'perl.txt', + 'signals.txt', + 'special_vars.txt', + 'startup-HOWTO.html', + 'startup-HOWTO.txt', + ), + install_dir : docdir) + +subdir('help') diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..95a0f874 --- /dev/null +++ b/meson.build @@ -0,0 +1,454 @@ +project('irssi', 'c', + version : '1.3-head', + meson_version : '>=0.49', + default_options : ['warning_level=1']) + +############################ +############################ + +cc = meson.get_compiler('c') +rootinc = include_directories('.') +dep = [] +textui_dep = [] + +includedir = get_option('includedir') +incdir = 'irssi' +moduledir = get_option('libdir') / incdir / 'modules' +helpdir = get_option('datadir') / incdir / 'help' +themedir = get_option('datadir') / incdir / 'themes' +scriptdir = get_option('datadir') / incdir / 'scripts' +docdir = get_option('docdir') != '' ? get_option('docdir') : (get_option('datadir') / 'doc' / incdir) + +want_textui = get_option('without-textui') != 'yes' +want_bot = get_option('with-bot') == 'yes' +want_fuzzer = get_option('with-fuzzer') == 'yes' +fuzzer_lib = get_option('with-fuzzer-lib') +want_proxy = get_option('with-proxy') == 'yes' +want_truecolor = get_option('enable-true-color') == 'yes' +want_gregex = get_option('disable-gregex') != 'yes' + +require_capsicum = get_option('with-capsicum') == 'yes' +want_capsicum = get_option('with-capsicum') != 'no' + +require_libutf8proc = get_option('disable-utf8proc') == 'no' +want_libutf8proc = get_option('disable-utf8proc') != 'yes' + +require_perl = get_option('with-perl') == 'yes' +want_perl = get_option('with-perl') != 'no' +with_perl_lib = get_option('with-perl-lib') + +require_otr = get_option('with-otr') == 'yes' +want_otr = get_option('with-otr') != 'no' + +want_glib_internal = get_option('install-glib') == 'yes' + +chat_modules = ['irc'] + +run_command('mkdir', meson.current_build_dir() / incdir) +run_command('ln', '-s', meson.current_source_dir() / 'src', meson.current_build_dir() / incdir) +run_command('ln', '-s', meson.current_build_dir() / 'irssi-config.h', meson.current_build_dir() / incdir) +run_command('ln', '-s', meson.current_build_dir() / 'irssi-version.h', meson.current_build_dir() / incdir) + +def_moduledir = '-D' + 'MODULEDIR' + '="' + (get_option('prefix') / moduledir) + '"' +def_sysconfdir = '-D' + 'SYSCONFDIR' + '="' + (get_option('prefix') / get_option('sysconfdir')) + '"' +def_helpdir = '-D' + 'HELPDIR' + '="' + (get_option('prefix') / helpdir) + '"' +def_themesdir = '-D' + 'THEMESDIR' + '="' + (get_option('prefix') / themedir) + '"' +def_scriptdir = '-D' + 'SCRIPTDIR' + '="' + (get_option('prefix') / scriptdir) + '"' + +def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK' + +############## +# Help files # +############## + +perl = find_program('perl') +run_command(perl, files('utils/syntax.pl')) + +################### +# irssi-version.h # +################### + +env = find_program('env') +irssi_version_sh = find_program('utils/irssi-version.sh') +irssi_version_h = custom_target('irssi-version.h', + build_by_default : true, + build_always_stale : true, + capture : true, + command : [env, 'VERSION=' + meson.project_version(), + irssi_version_sh, meson.current_source_dir()], + output : 'irssi-version.h', + install : true, + install_dir : includedir / incdir, +) + +#################### +# default-config.h # +#################### + +file2header = find_program('utils/file2header.sh') +default_config_h = custom_target('default-config.h', + input : files('irssi.conf'), + output : 'default-config.h', + capture : true, + command : [file2header, '@INPUT@', 'default_config'], +) + +################### +# default-theme.h # +################### + +default_theme_h = custom_target('default-theme.h', + input : files('themes/default.theme'), + output : 'default-theme.h', + capture : true, + command : [file2header, '@INPUT@', 'default_theme'], +) + +################ +# Dependencies # +################ + +#### inet_addr #### +inet_addr_found = false +foreach inet_addr_provider : ['', 'nsl'] + prov_lib = inet_addr_provider != '' ? [cc.find_library(inet_addr_provider, required : false)] : [] + if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('inet_addr', dependencies : prov_lib) + dep += prov_lib + inet_addr_found = true + break + endif +endforeach +if not inet_addr_found + error('inet_addr not found') +endif + +#### socket #### +socket_found = false +foreach socket_provider : ['', 'socket', 'network'] + prov_lib = socket_provider != '' ? [cc.find_library(socket_provider, required : false)] : [] + if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('socket', dependencies : prov_lib) + dep += prov_lib + socket_found = true + break + endif +endforeach +if not socket_found + error('socket not found') +endif + +glib_internal = false +message('*** If you don\'t have GLib, you can run meson ... -Dinstall-glib=yes') +message('*** to download and build it automatically') +message('*** Or alternatively install your distribution\'s package') +message('*** On Debian: sudo apt-get install libglib2.0-dev') +message('*** On Redhat: dnf install glib2-devel') +glib_dep = dependency('glib-2.0', version : '>=2.58', required : not want_glib_internal) +if not glib_dep.found() + glib_internal = true + glib_proj = subproject('glib', default_options : [ + 'libmount=false', + ]) + glib_dep = glib_proj.get_variable('libglib_dep') + gmodule_dep = glib_proj.get_variable('libgmodule_dep') +else + gmodule_dep = dependency('gmodule-2.0') +endif +dep += glib_dep +dep += gmodule_dep + +openssl_dep = dependency('openssl') +dep += openssl_dep + +############ +# utf8proc # +############ + +have_libutf8proc = false +libutf8proc = [] +if want_libutf8proc + libutf8proc = cc.find_library('utf8proc', required : require_libutf8proc) + have_libutf8proc = cc.has_function('utf8proc_version', dependencies : libutf8proc) + if have_libutf8proc + dep += libutf8proc + endif +endif + +############################ +############################ + +############ +# terminfo # +############ + +if want_textui + setupterm_found = false + foreach setupterm_provider : ['tinfo', 'ncursesw', 'ncurses', 'terminfo'] + prov_lib = cc.find_library(setupterm_provider, required : false) + if prov_lib.found() and cc.has_function('setupterm', dependencies : prov_lib) + textui_dep += prov_lib + setupterm_found = true + break + endif + endforeach + if not setupterm_found + error('Terminfo not found') + endif +endif + +######## +# perl # +######## + +have_perl = false +if want_perl + perl_cflags = [] + perl_ldflags = [] + perl_rpath = '' + + #### ccopts #### + res = run_command(perl, '-MExtUtils::Embed', '-e', 'ccopts') + foreach fl : res.stdout().strip().split() + if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m') + perl_cflags += fl + endif + endforeach + + perl_cflags += cc.get_supported_arguments('-fPIC') + + #### ldopts #### + res = run_command(perl, '-MExtUtils::Embed', '-e', 'ldopts') + skip_libs = ['-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic'] + foreach fl : res.stdout().strip().split() + if not fl.startswith('-A') and not skip_libs.contains(fl) + if fl.startswith('-Wl,-rpath,') + perl_rpath = fl.split(',')[2] + else + perl_ldflags += fl + endif + endif + endforeach + + perl_dep = declare_dependency(compile_args : perl_cflags, link_args : perl_ldflags, + version : run_command(perl, '-V::version:').stdout().split('\'')[1]) + + #### + if not cc.run(''' +#include +#include +int main() +{ + perl_alloc(); + return 0; +} +''', args : perl_cflags + perl_ldflags, name : 'working Perl support').compiled() + if require_perl + error('error linking with perl libraries') + else + warning('error linking with perl libraries') + endif + else + xsubpp_file_c = run_command(perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout() + xsubpp = generator(perl, + output : '@BASENAME@.c', + capture : true, + arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ], + ) + xsubpp_file = files(xsubpp_file_c) + + if with_perl_lib == 'module' + perl_install_base = run_command(perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}').stdout() + if perl_install_base == '' + with_perl_lib = '' + endif + endif + if with_perl_lib == '' + if get_option('prefix') in ['/usr/local', 'C:/'] + with_perl_lib = 'site' + elif get_option('prefix') in ['/usr'] + with_perl_lib = 'vendor' + endif + endif + if with_perl_lib in ['site', 'vendor', 'module'] + set_perl_use_lib = false + perl_library_dir = with_perl_lib + ' default' + if with_perl_lib in ['site', 'vendor'] + perlmoddir = run_command(perl, '-V::install' + with_perl_lib + 'arch:').stdout().split('\'')[1] + elif with_perl_lib == 'module' + perlmoddir = perl_install_base / 'lib' / 'perl5' / run_command(perl, '-V::archname:').stdout().split('\'')[1] + endif + elif with_perl_lib == '' + set_perl_use_lib = true + perl_library_dir = 'in prefix' + perlmoddir = get_option('libdir') / incdir / 'perl' + elif with_perl_lib.startswith('/') + set_perl_use_lib = true + perl_library_dir = 'custom' + perlmoddir = with_perl_lib + else + error('Unrecognised with-perl-lib value: ' + with_perl_lib) + endif + + perl_use_lib = get_option('prefix') / perlmoddir + if set_perl_use_lib + set_perl_use_lib = run_command(perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib).returncode() != 0 + if not set_perl_use_lib + perl_library_dir += ' - other path in @INC' + else + perl_library_dir += ' - prepends to @INC with /set perl_use_lib' + endif + endif + + have_perl = true + endif +endif + +####### +# OTR # +####### + +have_otr = false +if want_otr + libgcrypt = dependency('libgcrypt', version : '>=1.2.0', required : require_otr) + libotr = dependency('libotr', version : '>=4.1.0', required : require_otr) + if libgcrypt.found() and libotr.found() + dep += libgcrypt + dep += libotr + have_otr = true + endif +endif + +############ +# capsicum # +############ + +have_capsicum = false +if want_capsicum + if cc.has_function('cap_enter', dependencies : cc.find_library('c')) + libnv = cc.find_library('nv', required : require_capsicum) + nvlist_create_found = libnv.found() and cc.has_function('nvlist_create_found', dependencies : libnv) + if nvlist_create_found + dep += libnv + have_capsicum = true + else + if require_capsicum + error('nvlist_create not found') + endif + endif + else + if require_capsicum + error('cap_enter not found') + endif + endif +endif + +################## +# irssi-config.h # +################## + +conf = configuration_data() + +conf.set('HAVE_CAPSICUM', have_capsicum, description : 'Build with Capsicum support') +conf.set('HAVE_GMODULE', true) +conf.set('HAVE_SOCKS', false, description : 'Build with socks support') +conf.set('TERM_TRUECOLOR', want_truecolor, description : 'true color support in terminal') +conf.set('USE_GREGEX', want_gregex, description : 'use GRegex for regular expressions') +conf.set10('_DARWIN_USE_64_BIT_INODE', true, description : 'Enable large inode numbers on Mac OS X 10.5.') + +headers = [ + 'sys/ioctl.h', + 'sys/resource.h', + 'sys/time.h', + 'sys/utsname.h', + 'dirent.h', + 'unistd.h', +] +foreach h : headers + if cc.has_header(h) + conf.set('HAVE_' + h.underscorify().to_upper(), 1, description : 'Define to 1 if you have the <' + h + '> header file.') + endif +endforeach + +conf.set('HAVE_LIBUTF8PROC', have_libutf8proc) +conf.set_quoted('PACKAGE_VERSION', meson.project_version()) +conf.set_quoted('PACKAGE_TARNAME', meson.project_name()) + +configure_file(output : 'irssi-config.h', + configuration : conf, + install_dir : includedir / incdir) + +########## +# CFLAGS # +########## + +#### warnings #### +add_project_arguments('-Wall', language : 'c') +add_project_arguments(cc.get_supported_arguments('-Werror=declaration-after-statement'), language : 'c') + +#### personality #### +add_project_arguments(cc.get_supported_arguments('-fno-strict-aliasing'), language : 'c') + +if want_fuzzer + if not cc.has_argument('-fsanitize=fuzzer-no-link') + error('compiler does not support -fsanitize=fuzzer-no-link, try clang?') + endif + add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c') + add_project_link_arguments('-fsanitize=fuzzer-no-link', language : 'c') +endif + +############## +# irssi-1.pc # +############## + +pc = import('pkgconfig') +pc.generate(filebase : 'irssi-1', name : 'Irssi', description : 'Irssi chat client', requires : glib_internal ? [] : glib_dep) + +########### +# irssi.1 # +########### + +install_man('docs/irssi.1') + +########### +# subdirs # +########### + +subdir('src') +subdir('tests') +subdir('docs') +subdir('scripts') +subdir('themes') +# subdir('utils') + +############################ +############################ + +message('*** Irssi configured ***') +message('') +message('Building text frontend ........... : ' + want_textui.to_string('yes', 'no')) +message('Building irssi bot ............... : ' + want_bot.to_string('yes', 'no')) +message('Building irssi proxy ............. : ' + want_proxy.to_string('yes', 'no')) +if want_perl and not have_perl + message('Building with Perl support ....... : NO!') + message(' - Try: sudo apt-get install libperl-dev') + message(' - Or: dnf install perl-devel') +else + message('Building with Perl support ....... : ' + have_perl.to_string('yes', 'no')) +endif +if have_perl + message('Perl library directory ........... : ' + perl_use_lib) + message(' ' + perl_library_dir) +endif +message('Install prefix ................... : ' + get_option('prefix')) +message('') +message('Building with true color support.. : ' + want_truecolor.to_string('yes', 'no')) +message('Building with GRegex ............. : ' + want_gregex.to_string('yes', 'no')) +message('Building with Capsicum ........... : ' + have_capsicum.to_string('yes', 'no')) +message('Building with utf8proc ........... : ' + have_libutf8proc.to_string('yes', 'no')) +message('Building with OTR support ........ : ' + have_otr.to_string('yes', 'no')) +message('') +message('If there are any problems, read the INSTALL file.') +message('Now type ninja -C ' + meson.current_build_dir() + ' to build Irssi') +message('') + +############################ +############################ diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..579b9cda --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,14 @@ +option('without-textui', type : 'combo', description : 'Build without text frontend', choices : ['no', 'yes']) +option('with-bot', type : 'combo', description : 'Build irssi-bot', choices : ['no', 'yes']) +option('with-fuzzer', type : 'combo', description : 'Build irssi-fuzzer', choices : ['no', 'yes']) +option('with-fuzzer-lib', type : 'string', description : 'Specify path to fuzzer library', value : '-fsanitize=fuzzer') +option('with-proxy', type : 'combo', description : 'Build irssi-proxy', choices : ['no', 'yes']) +option('with-perl-lib', type : 'string', description : 'Specify where to install the Perl libraries for Irssi') +option('with-perl', type : 'combo', description : 'Build with Perl support', choices : ['auto', 'yes', 'no']) +option('with-otr', type : 'combo', description : 'Build with OTR support', choices : ['auto', 'yes', 'no']) +option('enable-true-color', type : 'combo', description : 'Build with true color support in terminal', choices : ['no', 'yes']) +option('disable-gregex', type : 'combo', description : 'Build without GRegex (fall back to regex.h)', choices : ['no', 'yes']) +option('disable-utf8proc', type : 'combo', description : 'Build without Julia\'s utf8proc', choices : ['auto', 'yes', 'no']) +option('with-capsicum', type : 'combo', description : 'Build with Capsicum support', choices : ['auto', 'yes', 'no']) +option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes']) +option('docdir', type : 'string', description : 'Documentation directory') diff --git a/scripts/meson.build b/scripts/meson.build new file mode 100644 index 00000000..072ac3ea --- /dev/null +++ b/scripts/meson.build @@ -0,0 +1,14 @@ +install_data( + files( + 'autoop.pl', + 'autorejoin.pl', + 'buf.pl', + 'dns.pl', + 'kills.pl', + 'mail.pl', + 'mlock.pl', + 'quitmsg.pl', + 'scriptassist.pl', + 'usercount.pl', + ), + install_dir : scriptdir) diff --git a/src/common.h b/src/common.h index ef4b0c15..d7eaac45 100644 --- a/src/common.h +++ b/src/common.h @@ -41,15 +41,8 @@ # include #endif -#if defined (UOFF_T_INT) -typedef unsigned int uoff_t; -#elif defined (UOFF_T_LONG) -typedef unsigned long uoff_t; -#elif defined (UOFF_T_LONG_LONG) -typedef unsigned long long uoff_t; -#else -# error uoff_t size not set -#endif +typedef guint64 uoff_t; +#define PRIuUOFF_T G_GUINT64_FORMAT /* input functions */ #define G_INPUT_READ (1 << 0) diff --git a/src/core/meson.build b/src/core/meson.build new file mode 100644 index 00000000..dd5a4d49 --- /dev/null +++ b/src/core/meson.build @@ -0,0 +1,129 @@ +# this file is part of irssi + +if want_gregex + regex_impl = files('iregex-gregex.c') +else + regex_impl = files('iregex-regexh.c') +endif + +if have_capsicum + core_capsicum_source = files('fe-capsicum.c') +else + core_capsicum_source = [] +endif + +libcore_a = static_library('core', + files( + 'args.c', + 'channels-setup.c', + 'channels.c', + 'chat-commands.c', + 'chat-protocols.c', + 'chatnets.c', + 'commands.c', + 'core.c', + 'expandos.c', + 'ignore.c', + 'levels.c', + 'line-split.c', + 'log-away.c', + 'log.c', + 'masks.c', + 'misc.c', + 'modules-load.c', + 'modules.c', + 'net-disconnect.c', + 'net-nonblock.c', + 'net-sendbuffer.c', + 'network-openssl.c', + 'network.c', + 'nicklist.c', + 'nickmatch-cache.c', + 'pidwait.c', + 'queries.c', + 'rawlog.c', + 'recode.c', + 'servers-reconnect.c', + 'servers-setup.c', + 'servers.c', + 'session.c', + 'settings.c', + 'signals.c', + 'special-vars.c', + 'tls.c', + 'utf8.c', + 'wcwidth-wrapper.c', + 'wcwidth.c', + 'write-buffer.c', + ) + + core_capsicum_source + + regex_impl + + [ + default_config_h, + irssi_version_h, + ], + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_moduledir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + #### structure_headers #### + 'channel-rec.h', + 'channel-setup-rec.h', + 'chatnet-rec.h', + 'query-rec.h', + 'server-connect-rec.h', + 'server-rec.h', + 'server-setup-rec.h', + 'window-item-rec.h', + + #### + 'args.h', + 'capsicum.h', + 'channels-setup.h', + 'channels.h', + 'chat-protocols.h', + 'chatnets.h', + 'commands.h', + 'core.h', + 'expandos.h', + 'ignore.h', + 'iregex.h', + 'levels.h', + 'line-split.h', + 'log.h', + 'masks.h', + 'misc.h', + 'module.h', + 'modules-load.h', + 'modules.h', + 'net-disconnect.h', + 'net-nonblock.h', + 'net-sendbuffer.h', + 'network-openssl.h', + 'network.h', + 'nick-rec.h', + 'nicklist.h', + 'nickmatch-cache.h', + 'pidwait.h', + 'queries.h', + 'rawlog.h', + 'recode.h', + 'servers-reconnect.h', + 'servers-setup.h', + 'servers.h', + 'session.h', + 'settings.h', + 'signals.h', + 'special-vars.h', + 'tls.h', + 'utf8.h', + 'window-item-def.h', + 'write-buffer.h', + ), + subdir : incdir / 'src' / 'core') diff --git a/src/fe-common/core/meson.build b/src/fe-common/core/meson.build new file mode 100644 index 00000000..73cb156a --- /dev/null +++ b/src/fe-common/core/meson.build @@ -0,0 +1,99 @@ +# this file is part of irssi + +if have_capsicum + fe_common_core_capsicum_source = files('fe-capsicum.c') +else + fe_common_core_capsicum_source = [] +endif + +fe_common_core_sources = [ + files( + 'chat-completion.c', + 'command-history.c', + 'completion.c', + 'fe-channels.c', + 'fe-common-core.c', + 'fe-core-commands.c', + 'fe-exec.c', + 'fe-expandos.c', + 'fe-help.c', + 'fe-ignore-messages.c', + 'fe-ignore.c', + 'fe-log.c', + 'fe-messages.c', + 'fe-modules.c', + 'fe-queries.c', + 'fe-recode.c', + 'fe-server.c', + 'fe-settings.c', + 'fe-tls.c', + 'fe-windows.c', + 'formats.c', + 'hilight-text.c', + 'keyboard.c', + 'module-formats.c', + 'printtext.c', + 'themes.c', + 'window-activity.c', + 'window-commands.c', + 'window-items.c', + 'windows-layout.c', + ) + + fe_common_core_capsicum_source + + [ + default_theme_h, + irssi_version_h, + ] +] + +libfe_common_core_a = static_library('fe_common_core', + fe_common_core_sources, + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_themesdir, + ], + dependencies : dep) + +if want_fuzzer + libfuzzer_fe_common_core_a = static_library('fuzzer_fe_common_core', + fe_common_core_sources, + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_themesdir, + def_suppress_printf_fallback, + ], + dependencies : dep) +endif + +install_headers( + files( + 'chat-completion.h', + 'command-history.h', + 'completion.h', + 'fe-capsicum.h', + 'fe-channels.h', + 'fe-common-core.h', + 'fe-core-commands.h', + 'fe-exec.h', + 'fe-messages.h', + 'fe-queries.h', + 'fe-recode.h', + 'fe-settings.h', + 'fe-tls.h', + 'fe-windows.h', + 'formats.h', + 'hilight-text.h', + 'keyboard.h', + 'module-formats.h', + 'module.h', + 'printtext.h', + 'themes.h', + 'window-activity.h', + 'window-items.h', + 'windows-layout.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'core') diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 3e215d72..1826c754 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -447,7 +447,7 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text) if (dest->window == NULL) { str = strip_codes(text); #ifndef SUPPRESS_PRINTF_FALLBACK - printf("NO WINDOWS: %s\n", str); + printf("## NO WINDOWS: %s\n", str); #endif g_free(str); return; diff --git a/src/fe-common/irc/dcc/meson.build b/src/fe-common/irc/dcc/meson.build new file mode 100644 index 00000000..296b1d61 --- /dev/null +++ b/src/fe-common/irc/dcc/meson.build @@ -0,0 +1,27 @@ +# this file is part of irssi + +libfe_irc_dcc_a = static_library('fe_irc_dcc', + files( + 'fe-dcc-chat-messages.c', + 'fe-dcc-chat.c', + 'fe-dcc-get.c', + 'fe-dcc-send.c', + 'fe-dcc-server.c', + 'fe-dcc.c', + 'module-formats.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + 'fe-dcc.h', + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'dcc') diff --git a/src/fe-common/irc/irc-modules.c b/src/fe-common/irc/irc-modules.c new file mode 100644 index 00000000..3bf1f327 --- /dev/null +++ b/src/fe-common/irc/irc-modules.c @@ -0,0 +1,4 @@ +void fe_irc_dcc_init(void);void fe_irc_notifylist_init(void); +void fe_irc_notifylist_deinit(void);void fe_irc_dcc_deinit(void); +void fe_irc_modules_init(void) { fe_irc_dcc_init(); fe_irc_notifylist_init(); } +void fe_irc_modules_deinit(void) { fe_irc_notifylist_deinit(); fe_irc_dcc_deinit(); } diff --git a/src/fe-common/irc/meson.build b/src/fe-common/irc/meson.build new file mode 100644 index 00000000..1789133c --- /dev/null +++ b/src/fe-common/irc/meson.build @@ -0,0 +1,44 @@ +# this file is part of irssi + +libfe_common_irc_a = static_library('fe_common_irc', + files( + 'fe-cap.c', + 'fe-common-irc.c', + 'fe-ctcp.c', + 'fe-events-numeric.c', + 'fe-events.c', + 'fe-irc-channels.c', + 'fe-irc-commands.c', + 'fe-irc-messages.c', + 'fe-irc-queries.c', + 'fe-irc-server.c', + 'fe-ircnet.c', + 'fe-modes.c', + 'fe-netjoin.c', + 'fe-netsplit.c', + 'fe-sasl.c', + 'fe-whois.c', + 'irc-completion.c', + 'module-formats.c', + + 'irc-modules.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_themesdir, + ], + dependencies : dep) + +install_headers( + files( + 'fe-irc-channels.h', + 'fe-irc-server.h', + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc') + +subdir('dcc') +subdir('notifylist') diff --git a/src/fe-common/irc/notifylist/meson.build b/src/fe-common/irc/notifylist/meson.build new file mode 100644 index 00000000..2e66c786 --- /dev/null +++ b/src/fe-common/irc/notifylist/meson.build @@ -0,0 +1,21 @@ +# this file is part of irssi + +libfe_irc_notifylist_a = static_library('fe_irc_notifylist', + files( + 'fe-notifylist.c', + 'module-formats.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_helpdir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + 'module-formats.h', + 'module.h', + ), + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'notifylist') diff --git a/src/fe-common/meson.build b/src/fe-common/meson.build new file mode 100644 index 00000000..05ab38a1 --- /dev/null +++ b/src/fe-common/meson.build @@ -0,0 +1,6 @@ +# this file is part of irssi + +subdir('core') +foreach s : chat_modules + subdir(s) +endforeach diff --git a/src/fe-fuzz/fe-common/core/meson.build b/src/fe-fuzz/fe-common/core/meson.build new file mode 100644 index 00000000..679c19ce --- /dev/null +++ b/src/fe-fuzz/fe-common/core/meson.build @@ -0,0 +1,21 @@ +# this file is part of irssi +executable('theme-load-fuzz', + files( + 'theme-load.c', + '../../../fe-text/module-formats.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfuzzer_fe_common_core_a, + ], + link_args : [fuzzer_lib], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + dependencies : dep +) + +# noinst_headers = files( +# '../../../fe-text/module-formats.h', +# ) diff --git a/src/fe-fuzz/fe-common/core/theme-load.c b/src/fe-fuzz/fe-common/core/theme-load.c index 87429ac4..fbb35684 100644 --- a/src/fe-fuzz/fe-common/core/theme-load.c +++ b/src/fe-fuzz/fe-common/core/theme-load.c @@ -36,10 +36,10 @@ #include int LLVMFuzzerInitialize(int *argc, char ***argv) { - core_register_options(); - fe_common_core_register_options(); char *irssi_argv[] = {*argv[0], "--home", "/tmp/irssi", NULL}; int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1; + core_register_options(); + fe_common_core_register_options(); args_execute(irssi_argc, irssi_argv); core_preinit((*argv)[0]); core_init(); @@ -50,6 +50,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { } int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + THEME_REC *theme; gchar *copy = g_strndup((const gchar *)data, size); FILE *fp = fopen("/tmp/irssi/fuzz.theme", "wb"); @@ -58,7 +59,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { fclose(fp); } - THEME_REC *theme = theme_load("fuzz"); + theme = theme_load("fuzz"); theme_destroy(theme); g_free(copy); diff --git a/src/fe-fuzz/fe-common/meson.build b/src/fe-fuzz/fe-common/meson.build new file mode 100644 index 00000000..da02f2cf --- /dev/null +++ b/src/fe-fuzz/fe-common/meson.build @@ -0,0 +1,3 @@ +# this file is part of irssi + +subdir('core') diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index 36aeacf7..740602d1 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -48,17 +48,21 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { } int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - if (size < 1) { - return 0; - } uint8_t count = *data; - gchar *copy = g_strndup((const gchar *)data+1, size-1); + gchar *copy; char *output0; char *output1; char *output2; char *output3; char *params; + + if (size < 1) { + return 0; + } + + copy = g_strndup((const gchar *)data+1, size-1); + if (count % 8 == 0) { params = event_get_params(copy, 1 | PARAM_FLAG_GETREST, &output0); } else if (count % 8 == 1) { diff --git a/src/fe-fuzz/irc/core/meson.build b/src/fe-fuzz/irc/core/meson.build new file mode 100644 index 00000000..23d1271f --- /dev/null +++ b/src/fe-fuzz/irc/core/meson.build @@ -0,0 +1,23 @@ +# this file is part of irssi + +executable('event-get-params-fuzz', + files( + 'event-get-params.c', + '../../../fe-text/module-formats.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libirc_a, + libfuzzer_fe_common_core_a, + ], + link_args : [fuzzer_lib], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + dependencies : dep +) + +# noinst_headers = files( +# '../../../fe-text/module-formats.h', +# ) diff --git a/src/fe-fuzz/irc/meson.build b/src/fe-fuzz/irc/meson.build new file mode 100644 index 00000000..da02f2cf --- /dev/null +++ b/src/fe-fuzz/irc/meson.build @@ -0,0 +1,3 @@ +# this file is part of irssi + +subdir('core') diff --git a/src/fe-fuzz/meson.build b/src/fe-fuzz/meson.build new file mode 100644 index 00000000..5dccd38d --- /dev/null +++ b/src/fe-fuzz/meson.build @@ -0,0 +1,46 @@ +# this file is part of irssi + +subdir('irc') +subdir('fe-common') + +executable('irssi-fuzz', + files( + 'irssi.c', + '../fe-text/module-formats.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfuzzer_fe_common_core_a, + ], + link_args : [fuzzer_lib], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + dependencies : dep +) + +executable('server-fuzz', + files( + 'server.c', + '../fe-text/module-formats.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfuzzer_fe_common_core_a, + libirc_a, + libfe_common_irc_a, + libfe_irc_dcc_a, + libfe_irc_notifylist_a, + ], + link_args : [fuzzer_lib], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + dependencies : dep +) + +# noinst_headers = files( +# '../fe-text/module-formats.h', +# ) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 2e8cd3d2..cde03b89 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -150,13 +150,18 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { } int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + gboolean prefixedChoice = (gboolean)*data; + gchar *copy; + gchar **lines; + gchar **head; + if (size < 1) return 0; test_server(); - gboolean prefixedChoice = (gboolean)*data; - gchar *copy = g_strndup((const gchar *)data+1, size-1); - gchar **lines = g_strsplit(copy, "\r\n", -1); - gchar **head = lines; + + copy = g_strndup((const gchar *)data+1, size-1); + lines = g_strsplit(copy, "\r\n", -1); + head = lines; for (; *lines != NULL; lines++) { gchar *prefixedLine; diff --git a/src/fe-none/meson.build b/src/fe-none/meson.build new file mode 100644 index 00000000..58df15f6 --- /dev/null +++ b/src/fe-none/meson.build @@ -0,0 +1,21 @@ +# this file is part of irssi + +executable('botti', + files( + 'irssi.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + export_dynamic : true, + link_with : [ + libconfig_a, + libcore_a, + libirc_a, + ], + install : true, + dependencies : dep +) + +# noinst_headers = files( +# 'module.h', +# ) diff --git a/src/fe-text/meson.build b/src/fe-text/meson.build new file mode 100644 index 00000000..9070011e --- /dev/null +++ b/src/fe-text/meson.build @@ -0,0 +1,68 @@ +# this file is part of irssi + +executable('irssi', + files( + #### terminfo_sources #### + 'term-terminfo.c', + 'terminfo-core.c', + + #### irssi sources #### + 'gui-entry.c', + 'gui-expandos.c', + 'gui-printtext.c', + 'gui-readline.c', + 'gui-windows.c', + 'irssi.c', + 'lastlog.c', + 'mainwindow-activity.c', + 'mainwindows-layout.c', + 'mainwindows.c', + 'module-formats.c', + 'statusbar-config.c', + 'statusbar-items.c', + 'statusbar.c', + 'term.c', + 'textbuffer-commands.c', + 'textbuffer-view.c', + 'textbuffer.c', + ) + + [ irssi_version_h ], + include_directories : rootinc, + implicit_include_directories : false, + export_dynamic : true, + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + libirc_a, + libfe_common_irc_a, + libfe_irc_dcc_a, + libfe_irc_notifylist_a, + ], + install : true, + install_rpath : get_option('prefix') / get_option('libdir'), + dependencies : dep + + textui_dep +) + +install_headers( + files( + 'gui-printtext.h', + 'gui-windows.h', + 'mainwindows.h', + 'statusbar-item.h', + 'statusbar.h', + 'term.h', + 'textbuffer-view.h', + 'textbuffer.h', + ), + subdir : incdir / 'src' / 'fe-text') + +# noinst_headers = files( +# 'gui-entry.h', +# 'gui-readline.h', +# 'module-formats.h' +# 'module.h', +# 'statusbar-config.h', +# 'terminfo-core.h', +# ) diff --git a/src/irc/core/meson.build b/src/irc/core/meson.build new file mode 100644 index 00000000..e6cc89c7 --- /dev/null +++ b/src/irc/core/meson.build @@ -0,0 +1,66 @@ +# this file is part of irssi + +libirc_core_a = static_library('irc_core', + files( + 'bans.c', + 'channel-events.c', + 'channel-rejoin.c', + 'channels-query.c', + 'ctcp.c', + 'irc-cap.c', + 'irc-channels-setup.c', + 'irc-channels.c', + 'irc-chatnets.c', + 'irc-commands.c', + 'irc-core.c', + 'irc-expandos.c', + 'irc-masks.c', + 'irc-nicklist.c', + 'irc-queries.c', + 'irc-servers-reconnect.c', + 'irc-servers-setup.c', + 'irc-servers.c', + 'irc-session.c', + 'irc.c', + 'lag.c', + 'massjoin.c', + 'mode-lists.c', + 'modes.c', + 'netsplit.c', + 'sasl.c', + 'servers-idle.c', + 'servers-redirect.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + c_args : [ + def_moduledir, + def_sysconfdir, + ], + dependencies : dep) + +install_headers( + files( + 'bans.h', + 'channel-events.h', + 'channel-rejoin.h', + 'ctcp.h', + 'irc-cap.h', + 'irc-channels.h', + 'irc-chatnets.h', + 'irc-commands.h', + 'irc-masks.h', + 'irc-nicklist.h', + 'irc-queries.h', + 'irc-servers-setup.h', + 'irc-servers.h', + 'irc.h', + 'mode-lists.h', + 'modes.h', + 'module.h', + 'netsplit.h', + 'sasl.h', + 'servers-idle.h', + 'servers-redirect.h', + ), + subdir : incdir / 'src' / 'irc' / 'core') diff --git a/src/irc/dcc/meson.build b/src/irc/dcc/meson.build new file mode 100644 index 00000000..0c3d706a --- /dev/null +++ b/src/irc/dcc/meson.build @@ -0,0 +1,31 @@ +# this file is part of irssi + +libirc_dcc_a = static_library('irc_dcc', + files( + 'dcc-autoget.c', + 'dcc-chat.c', + 'dcc-get.c', + 'dcc-queue.c', + 'dcc-resume.c', + 'dcc-send.c', + 'dcc-server.c', + 'dcc.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep) + +install_headers( + files( + 'dcc-chat.h', + 'dcc-file-rec.h', + 'dcc-file.h', + 'dcc-get.h', + 'dcc-queue.h', + 'dcc-rec.h', + 'dcc-send.h', + 'dcc-server.h', + 'dcc.h', + 'module.h', + ), + subdir : incdir / 'src' / 'irc' / 'dcc') diff --git a/src/irc/flood/meson.build b/src/irc/flood/meson.build new file mode 100644 index 00000000..75107db1 --- /dev/null +++ b/src/irc/flood/meson.build @@ -0,0 +1,14 @@ +# this file is part of irssi + +libirc_flood_a = static_library('irc_flood', + files( + 'autoignore.c', + 'flood.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep) + +install_headers( + files('module.h'), + subdir : incdir / 'src' / 'irc' / 'flood') diff --git a/src/irc/irc.c b/src/irc/irc.c new file mode 100644 index 00000000..250a6fb4 --- /dev/null +++ b/src/irc/irc.c @@ -0,0 +1,5 @@ +void irc_core_init(void); void irc_core_deinit(void); +void irc_dcc_init(void);void irc_flood_init(void);void irc_notifylist_init(void); +void irc_notifylist_deinit(void);void irc_flood_deinit(void);void irc_dcc_deinit(void); +void irc_init(void) { irc_core_init(); irc_dcc_init(); irc_flood_init(); irc_notifylist_init(); } +void irc_deinit(void) { irc_notifylist_deinit(); irc_flood_deinit(); irc_dcc_deinit(); irc_core_deinit(); } diff --git a/src/irc/meson.build b/src/irc/meson.build new file mode 100644 index 00000000..72abc3ce --- /dev/null +++ b/src/irc/meson.build @@ -0,0 +1,24 @@ +# this file is part of irssi + +subdir('core') +subdir('dcc') +subdir('flood') +subdir('notifylist') + +libirc_a = static_library('irc', + files( + 'irc.c', + ), + link_with : [ + libirc_core_a, + libirc_dcc_a, + libirc_flood_a, + libirc_notifylist_a, + ], + include_directories : rootinc, + implicit_include_directories : false, +) + +if want_proxy + subdir('proxy') +endif diff --git a/src/irc/notifylist/meson.build b/src/irc/notifylist/meson.build new file mode 100644 index 00000000..f00ea321 --- /dev/null +++ b/src/irc/notifylist/meson.build @@ -0,0 +1,21 @@ +# this file is part of irssi + +libirc_notifylist_a = static_library('irc_notifylist', + files( + 'notify-commands.c', + 'notify-ison.c', + 'notify-setup.c', + 'notify-whois.c', + 'notifylist.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep) + +install_headers( + files( + 'module.h', + 'notify-setup.h', + 'notifylist.h', + ), + subdir : incdir / 'src' / 'irc' / 'notifylist') diff --git a/src/irc/proxy/meson.build b/src/irc/proxy/meson.build new file mode 100644 index 00000000..be91c7d5 --- /dev/null +++ b/src/irc/proxy/meson.build @@ -0,0 +1,20 @@ +# this file is part of irssi + +shared_module('irc_proxy', + files( + 'dump.c', + 'listen.c', + 'proxy.c', + ) + + [ irssi_version_h ], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + install_dir : moduledir, + dependencies : dep, +) + +# noinst_headers = files( +# 'module.h', +# 'proxy.h', +# ) diff --git a/src/lib-config/meson.build b/src/lib-config/meson.build new file mode 100644 index 00000000..2bc094dd --- /dev/null +++ b/src/lib-config/meson.build @@ -0,0 +1,19 @@ +# this file is part of irssi + +libconfig_a = static_library('irssi_config', + files( + 'get.c', + 'parse.c', + 'set.c', + 'write.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep) + +install_headers( + files( + 'iconfig.h', + 'module.h', + ), + subdir : incdir / 'src' / 'lib-config') diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..dee8dc3c --- /dev/null +++ b/src/meson.build @@ -0,0 +1,29 @@ +# this file is part of irssi + +subdir('lib-config') +subdir('core') +foreach s : chat_modules + subdir(s) +endforeach +subdir('fe-common') +if have_perl + subdir('perl') +endif +if have_otr + subdir('otr') +endif +if want_bot + subdir('fe-none') +endif +if want_textui + subdir('fe-text') +endif +if want_fuzzer + subdir('fe-fuzz') +endif + +install_headers( + files( + 'common.h' + ), + subdir : incdir / 'src') diff --git a/src/otr/meson.build b/src/otr/meson.build new file mode 100644 index 00000000..10b9fa55 --- /dev/null +++ b/src/otr/meson.build @@ -0,0 +1,26 @@ +# this file is part of irssi + +shared_module('otr_core', + files( + 'key.c', + 'otr-fe.c', + 'otr-formats.c', + 'otr-module.c', + 'otr-ops.c', + 'otr.c', + ), + include_directories : rootinc, + implicit_include_directories : false, + install : true, + install_dir : moduledir, + dependencies : dep, +) + +# noinst_headers = files( +# 'irssi-otr.h', +# 'key.h', +# 'module.h', +# 'otr-fe.h', +# 'otr-formats.h', +# 'otr.h', +# ) diff --git a/src/perl/common/meson.build b/src/perl/common/meson.build new file mode 100644 index 00000000..2cbf7f4c --- /dev/null +++ b/src/perl/common/meson.build @@ -0,0 +1,37 @@ +libperl_common_a = shared_module('Irssi', + [ xsubpp.process( + files( + 'Channel.xs', + 'Core.xs', + 'Expando.xs', + 'Ignore.xs', + 'Irssi.xs', + 'Log.xs', + 'Masks.xs', + 'Query.xs', + 'Rawlog.xs', + 'Server.xs', + 'Settings.xs', + ) + ) ] + + files( + 'module.h', + ) + + [ irssi_version_h ], + name_prefix : '', + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], +) + +install_headers( + files( + 'Irssi.pm', + ), + install_dir : perlmoddir, +) + +# 'Makefile.PL.in', +# 'typemap', diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index 806bcafa..275be157 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -6,7 +6,7 @@ print " * do not edit.\n"; print " */\n\n"; print "static PERL_SIGNAL_ARGS_REC perl_signal_args[] =\n{\n"; -while () { +while (<>) { chomp; next if (!/^ "([^"]*)"(<.*>)?(?:,\s*(.*))?/); diff --git a/src/perl/irc/meson.build b/src/perl/irc/meson.build new file mode 100644 index 00000000..7d77e0c1 --- /dev/null +++ b/src/perl/irc/meson.build @@ -0,0 +1,39 @@ +libperl_irc_a = shared_module('Irc', + [ xsubpp.process( + files( + 'Channel.xs', + 'Client.xs', + 'Ctcp.xs', + 'Dcc.xs', + 'Irc.xs', + 'Modes.xs', + 'Netsplit.xs', + 'Notifylist.xs', + 'Query.xs', + 'Server.xs', + ), + extra_args : [ + '-typemap', + '../common/typemap', + ], + ) ] + + files( + 'module.h', + ), + name_prefix : '', + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi' / 'Irc', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], +) + +install_headers( + files( + 'Irc.pm', + ), + install_dir : perlmoddir / 'Irssi', +) + +# 'Makefile.PL.in', +# 'typemap', diff --git a/src/perl/meson.build b/src/perl/meson.build new file mode 100644 index 00000000..e3935814 --- /dev/null +++ b/src/perl/meson.build @@ -0,0 +1,73 @@ + +perl_signals_list_h = custom_target('perl-signals-list.h', + input : files('../../docs/signals.txt'), + output : 'perl-signals-list.h', + capture : true, + depend_files : files('get-signals.pl'), + command : [perl, files('get-signals.pl'), '@INPUT@'], +) + +irssi_core_pl_h = custom_target('irssi-core.pl.h', + input : files('irssi-core.pl'), + output : 'irssi-core.pl.h', + capture : true, + command : [file2header, '@INPUT@', 'irssi_core_code'], +) + +shared_module('perl_core', + files( + 'perl-common.c', + 'perl-core.c', + 'perl-signals.c', + 'perl-sources.c', + ) + [ + irssi_core_pl_h, + perl_signals_list_h, + ], + c_args : [ + def_scriptdir, + '-D' + 'PERL_USE_LIB' + '="' + (set_perl_use_lib ? perl_use_lib : '') + '"', + '-D' + 'PERL_STATIC_LIBS' + '=' + 0.to_string(), + ], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + install_dir : moduledir, + install_rpath : perl_rpath, + build_rpath : perl_rpath, + dependencies : dep + [ perl_dep ], +) + +shared_module('fe_perl', + files( + 'module-formats.c', + 'perl-fe.c', + ), + c_args : [ + def_scriptdir, + ], + include_directories : rootinc, + implicit_include_directories : false, + install : true, + install_dir : moduledir, + dependencies : dep, +) + +subdir('common') +foreach s : chat_modules + subdir(s) +endforeach +subdir('ui') +if want_textui + subdir('textui') +endif + +# noinst_headers = files( +# 'module-fe.h', +# 'module-formats.h', +# 'module.h', +# 'perl-common.h', +# 'perl-core.h', +# 'perl-signals.h', +# 'perl-sources.h', +# ) diff --git a/src/perl/textui/meson.build b/src/perl/textui/meson.build new file mode 100644 index 00000000..61362d52 --- /dev/null +++ b/src/perl/textui/meson.build @@ -0,0 +1,35 @@ +libperl_textui_a = shared_module('TextUI', + [ xsubpp.process( + files( + 'Statusbar.xs', + 'TextBufferView.xs', + 'TextBuffer.xs', + 'TextUI.xs', + ), + extra_args : [ + '-typemap', + '../common/typemap', + '-typemap', + '../ui/typemap', + ], + ) ] + + files( + 'module.h', + ), + name_prefix : '', + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi' / 'TextUI', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], +) + +install_headers( + files( + 'TextUI.pm', + ), + install_dir : perlmoddir / 'Irssi', +) + +# 'Makefile.PL.in', +# 'typemap', diff --git a/src/perl/ui/meson.build b/src/perl/ui/meson.build new file mode 100644 index 00000000..eca864dd --- /dev/null +++ b/src/perl/ui/meson.build @@ -0,0 +1,33 @@ +libperl_ui_a = shared_module('UI', + [ xsubpp.process( + files( + 'Formats.xs', + 'Themes.xs', + 'UI.xs', + 'Window.xs', + ), + extra_args : [ + '-typemap', + '../common/typemap', + ], + ) ] + + files( + 'module.h', + ), + name_prefix : '', + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi' / 'UI', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], +) + +install_headers( + files( + 'UI.pm', + ), + install_dir : perlmoddir / 'Irssi', +) + +# 'Makefile.PL.in', +# 'typemap', diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap new file mode 100644 index 00000000..4def08b1 --- /dev/null +++ b/subprojects/glib.wrap @@ -0,0 +1,4 @@ +[wrap-git] +directory = glib +url = https://github.com/GNOME/glib +revision = glib-2-60 diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap new file mode 120000 index 00000000..4c62fa2c --- /dev/null +++ b/subprojects/libffi.wrap @@ -0,0 +1 @@ +glib/subprojects/libffi.wrap \ No newline at end of file diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap new file mode 120000 index 00000000..b74eca77 --- /dev/null +++ b/subprojects/proxy-libintl.wrap @@ -0,0 +1 @@ +glib/subprojects/proxy-libintl.wrap \ No newline at end of file diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap new file mode 120000 index 00000000..b944dda2 --- /dev/null +++ b/subprojects/zlib.wrap @@ -0,0 +1 @@ +glib/subprojects/zlib.wrap \ No newline at end of file diff --git a/tests/fe-common/core/meson.build b/tests/fe-common/core/meson.build new file mode 100644 index 00000000..44b11222 --- /dev/null +++ b/tests/fe-common/core/meson.build @@ -0,0 +1,19 @@ +test_test_formats = executable('test-formats', + files( + 'test-formats.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + ], + c_args : [ + '-D' + 'PACKAGE_STRING' + '="' + 'fe-common/core' + '"', + ], + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep +) +test('test-formats test', test_test_formats, + args : ['--tap'], + protocol : 'tap') diff --git a/tests/fe-common/meson.build b/tests/fe-common/meson.build new file mode 100644 index 00000000..dd52d8a4 --- /dev/null +++ b/tests/fe-common/meson.build @@ -0,0 +1 @@ +subdir('core') diff --git a/tests/fe-text/meson.build b/tests/fe-text/meson.build new file mode 100644 index 00000000..ea6ec620 --- /dev/null +++ b/tests/fe-text/meson.build @@ -0,0 +1,30 @@ +test_test_paste_join_multiline = executable('test-paste-join-multiline', + files( + '../../src/fe-text/gui-entry.c', + '../../src/fe-text/gui-printtext.c', + '../../src/fe-text/gui-windows.c', + '../../src/fe-text/mainwindows.c', + '../../src/fe-text/term-terminfo.c', + '../../src/fe-text/term.c', + '../../src/fe-text/terminfo-core.c', + '../../src/fe-text/textbuffer-view.c', + '../../src/fe-text/textbuffer.c', + 'mock-irssi.c', + 'test-paste-join-multiline.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + ], + c_args : [ + '-D' + 'PACKAGE_STRING' + '="' + 'fe-text' + '"', + ], + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep + textui_dep, +) +test('test-paste-join-multiline test', test_test_paste_join_multiline, + args : ['--tap'], + protocol : 'tap') + diff --git a/tests/irc/core/meson.build b/tests/irc/core/meson.build new file mode 100644 index 00000000..f63f4fa8 --- /dev/null +++ b/tests/irc/core/meson.build @@ -0,0 +1,45 @@ +test_test_irc = executable('test-irc', + files( + 'test-irc.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + libirc_core_a, + ], + c_args : [ + '-D' + 'PACKAGE_STRING' + '="' + 'irc/core' + '"', + ], + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep +) +test('test-irc test', test_test_irc, + args : [ + '--tap', + ], + protocol : 'tap') + +test_test_channel_events = executable('test-channel-events', + files( + 'test-channel-events.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + libirc_core_a, + ], + c_args : [ + '-D' + 'PACKAGE_STRING' + '="' + 'irc/core' + '"', + ], + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep +) +test('test-channel-events test', test_test_channel_events, + args : [ + '--tap', + ], + protocol : 'tap') diff --git a/tests/irc/flood/meson.build b/tests/irc/flood/meson.build new file mode 100644 index 00000000..e9d0a2bc --- /dev/null +++ b/tests/irc/flood/meson.build @@ -0,0 +1,25 @@ +test_test_796 = executable('test-796', + files( + 'test-796.c', + ), + link_with : [ + libconfig_a, + libcore_a, + libfe_common_core_a, + libirc_a, + libfe_common_irc_a, + libfe_irc_dcc_a, + libfe_irc_notifylist_a, + ], + c_args : [ + '-D' + 'PACKAGE_STRING' + '="' + 'irc/flood' + '"', + ], + include_directories : rootinc, + implicit_include_directories : false, + dependencies : dep +) +test('test-796 test', test_test_796, + args : [ + '--tap', + ], + protocol : 'tap') diff --git a/tests/irc/meson.build b/tests/irc/meson.build new file mode 100644 index 00000000..1a10ce0a --- /dev/null +++ b/tests/irc/meson.build @@ -0,0 +1,2 @@ +subdir('core') +subdir('flood') diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..6cfb3706 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,5 @@ +subdir('fe-common') +subdir('irc') +if want_textui + subdir('fe-text') +endif diff --git a/themes/meson.build b/themes/meson.build new file mode 100644 index 00000000..d58dddf4 --- /dev/null +++ b/themes/meson.build @@ -0,0 +1,6 @@ +install_data( + files( + 'default.theme', + 'colorless.theme', + ), + install_dir : themedir) diff --git a/utils/irssi-version.sh b/utils/irssi-version.sh index 6b3a46e4..466a29fd 100755 --- a/utils/irssi-version.sh +++ b/utils/irssi-version.sh @@ -1,14 +1,20 @@ #!/bin/sh -DATE=`GIT_DIR=$1/.git git log -1 --pretty=format:%ai HEAD` +DATE=`GIT_DIR=$1/.git git log -1 --pretty=format:%ai HEAD 2>/dev/null` VERSION_DATE=`echo $DATE | cut -f 1 -d ' ' | tr -d -` VERSION_TIME=`echo $DATE | cut -f 2 -d ' ' | awk -F: '{printf "%d", $1$2}'` if test -z "$VERSION_DATE"; then - exec>&2 - echo "**Error**: `basename "$0"` must be run in a git clone, cannot proceed." - exit 1 + DATE=`grep '^v' $1/NEWS | head -1` + VERSION_DATE=`echo "$DATE" | cut -f 2 -d ' ' | tr -d -` + case $VERSION_DATE in + *xx) + VERSION_DATE=`date +%Y%m%d` + ;; + esac + VERSION_TIME=`echo "$DATE" | cut -f 1 -d ' ' | tr -d v | tr .- ' '` + VERSION_TIME=`printf %d%d%02d $VERSION_TIME 2>/dev/null` fi echo "#define IRSSI_VERSION_DATE $VERSION_DATE" @@ -16,7 +22,7 @@ echo "#define IRSSI_VERSION_TIME $VERSION_TIME" if echo "${VERSION}" | grep -q -- -head; then # -head version, get extra details from git if we can - git_version=$(GIT_DIR=$1/.git git describe --dirty --long --always --tags) + git_version=$(GIT_DIR=$1/.git git describe --dirty --long --always --tags 2>/dev/null) if [ $? = 0 ]; then echo "#undef PACKAGE_VERSION" echo "#define PACKAGE_VERSION \"${git_version}\"" diff --git a/utils/syntax.pl b/utils/syntax.pl index 33bd12b4..42a4accb 100755 --- a/utils/syntax.pl +++ b/utils/syntax.pl @@ -39,6 +39,7 @@ foreach $file (@files) { } while () { next if (/Makefile/); + next if (/meson\.build/); open (FILE, "$_"); @data = ; From 9a93e714749eceeb7860a675b07349809883f22b Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 9 Jul 2019 13:41:11 +0200 Subject: [PATCH 0543/1198] try test travis --- .travis.yml | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 30f9cc35..a09b7271 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,9 @@ sudo: false -dist: trusty +dist: xenial language: perl perl: # ~stretch - "5.24-shrplib" - # ~xenial - # - "5.22-shrplib" - # ~jessie - # - "5.20-shrplib" - # ~trusty - # - "5.18-shrplib" - "system-perl" env: - CC=clang UNITTESTS=false @@ -28,22 +22,23 @@ addons: - libperl-dev - elinks - libgcrypt11-dev + - libotr5-dev before_install: - perl -V - - wget https://github.com/irssi-import/libotr/releases/download/4.1.1/travis-trusty-libotr-4.1.1.tar.gz - - tar zxf travis-trusty-libotr*.tar.gz -C $HOME - - ./autogen.sh --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-build/lib --with-libotr-inc-prefix=$HOME/otr-build/include - - make dist - - cd .. - - tar xaf */irssi-*.tar.* - - cd irssi-* + - pushd ~ + - curl -sSLf https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip | funzip > bin/ninja + - chmod +x bin/ninja + - curl -sSLf https://github.com/mesonbuild/meson/releases/download/0.51.1/meson-0.51.1.tar.gz | tar xz + - ( cd bin ; ln -s ../meson-*/meson.py meson ) + - curl -sSLf https://github.com/irssi-import/glib-travis-build/releases/download/2.58.3/travis-xenial-glib-2.58.3.tar.xz | tar xJ + - export PKG_CONFIG_PATH=$HOME/glib-build/lib/x86_64-linux-gnu/pkgconfig + - popd install: - - ./configure --with-proxy --with-bot --with-perl=module --with-otr=yes --with-libotr-prefix=$HOME/otr-build/lib --with-libotr-inc-prefix=$HOME/otr-build/include --prefix=$HOME/irssi-build - $( $UNITTESTS && echo --enable-always-build-tests ) - - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - - make install + - meson Build -Dwith-proxy=yes -Dwith-bot=yes -Dwith-perl=yes -Dwith-otr=yes --prefix=$HOME/irssi-build + - ninja -C Build + - ninja -C Build install before_script: - pushd ~ @@ -62,8 +57,8 @@ before_script: script: - irssi-build/bin/irssi --home irssi-test - popd - - if $UNITTESTS; then make -C tests -sk check; fi + - if $UNITTESTS; then ninja -C Build test; fi after_script: - cat ~/irc.log.* - - find -name test-suite.log -exec cat {} + + - find -name testlog.txt -exec sed -i -e '/Inherited environment:.* TRAVIS/d' {} + -exec cat {} + From 905bf86921d893d89d3ca453071c1b697174df20 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 10 Jul 2019 14:00:37 +0200 Subject: [PATCH 0544/1198] refactor glib install --- meson.build | 53 ++++++++++++++++++++++++++++++---- subprojects/glib.wrap | 10 ++++--- subprojects/libffi.wrap | 1 - subprojects/proxy-libintl.wrap | 1 - subprojects/zlib.wrap | 1 - 5 files changed, 54 insertions(+), 12 deletions(-) delete mode 120000 subprojects/libffi.wrap delete mode 120000 subprojects/proxy-libintl.wrap delete mode 120000 subprojects/zlib.wrap diff --git a/meson.build b/meson.build index 95a0f874..f1e23169 100644 --- a/meson.build +++ b/meson.build @@ -6,6 +6,7 @@ project('irssi', 'c', ############################ ############################ +glib_internal_version = 'glib-2.58.3' # keep this in sync with subprojects/glib.wrap cc = meson.get_compiler('c') rootinc = include_directories('.') dep = [] @@ -145,11 +146,53 @@ message('*** On Redhat: dnf install glib2-devel') glib_dep = dependency('glib-2.0', version : '>=2.58', required : not want_glib_internal) if not glib_dep.found() glib_internal = true - glib_proj = subproject('glib', default_options : [ - 'libmount=false', - ]) - glib_dep = glib_proj.get_variable('libglib_dep') - gmodule_dep = glib_proj.get_variable('libgmodule_dep') + meson_cmd = find_program('meson') + ninja = find_program('ninja') + glib_internal_download_t = custom_target('glib-internal-download', + command : [ meson_cmd, 'subprojects', 'download', 'glib', '--sourcedir', meson.current_source_dir() ], + console : true, + output : ['glib-internal-download'], + ) + glib_internal_configure_t = custom_target('glib-internal-configure', + command : [ meson_cmd, 'setup', '--prefix=/irssi-glib-internal', + '--buildtype=' + get_option('buildtype'), + '-Dlibmount=false', '-Dselinux=false', '-Ddefault_library=static', '-Dinternal_pcre=true', + (meson.current_build_dir() / 'build-subprojects' / 'glib'), + (meson.current_source_dir() / 'subprojects' / glib_internal_version) ], + console : true, + output : ['glib-internal-configure'], + depends : glib_internal_download_t,) + glib_internal_build_t = custom_target('glib-internal-build', + command : [ ninja, '-C', meson.current_build_dir() / 'build-subprojects' / 'glib', + 'glib' / 'libglib-2.0.a', + 'gmodule' / 'libgmodule-2.0.a'], + console : true, + output : ['glib-internal-build'], + depends : glib_internal_configure_t,) + glib_dep = declare_dependency( + dependencies : [ + dependency('threads'), + ], + sources : glib_internal_build_t, + compile_args : [ + '-I' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'glib'), + '-I' + (meson.current_source_dir() / 'subprojects' / glib_internal_version), + '-I' + (meson.current_build_dir() / 'build-subprojects' / 'glib' / 'glib'), + ], + link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'glib' / 'libglib-2.0.a' ], + ) + libdl_dep = [] + prov_lib = cc.find_library('dl', required : false) + if prov_lib.found() and cc.has_function('dlopen', dependencies : prov_lib) + libdl_dep += prov_lib + endif + gmodule_dep = declare_dependency(sources : glib_internal_build_t, + dependencies : libdl_dep, + compile_args : [ + '-I' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'gmodule'), + ], + link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gmodule' / 'libgmodule-2.0.a' ], + ) else gmodule_dep = dependency('gmodule-2.0') endif diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap index 4def08b1..5cb40b0e 100644 --- a/subprojects/glib.wrap +++ b/subprojects/glib.wrap @@ -1,4 +1,6 @@ -[wrap-git] -directory = glib -url = https://github.com/GNOME/glib -revision = glib-2-60 +[wrap-file] +# make sure to update the glib_internal_version in meson.build +directory = glib-2.58.3 +source_url = https://download.gnome.org/sources/glib/2.58/glib-2.58.3.tar.xz +source_filename = glib-2.58.3.tar.xz +source_hash = 8f43c31767e88a25da72b52a40f3301fefc49a665b56dc10ee7cc9565cbe7481 diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap deleted file mode 120000 index 4c62fa2c..00000000 --- a/subprojects/libffi.wrap +++ /dev/null @@ -1 +0,0 @@ -glib/subprojects/libffi.wrap \ No newline at end of file diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap deleted file mode 120000 index b74eca77..00000000 --- a/subprojects/proxy-libintl.wrap +++ /dev/null @@ -1 +0,0 @@ -glib/subprojects/proxy-libintl.wrap \ No newline at end of file diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap deleted file mode 120000 index b944dda2..00000000 --- a/subprojects/zlib.wrap +++ /dev/null @@ -1 +0,0 @@ -glib/subprojects/zlib.wrap \ No newline at end of file From 2599124bc8e581b5c9a48a6c0d1902b9de6230a6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 16 Jul 2019 14:23:12 +0000 Subject: [PATCH 0545/1198] Show meson commands in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3550b640..9ea92940 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ available. ``` git clone https://github.com/irssi/irssi cd irssi -./autogen.sh -make && sudo make install +meson Build +ninja -C Build && sudo ninja -C Build install ``` #### Release source installation From ddb9d5c15f428b23ab6af60188c5375415bc03cb Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 16 Jul 2019 17:25:12 +0200 Subject: [PATCH 0546/1198] update gitignore for meson stuff --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index f42839eb..79e4d4bb 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,7 @@ src/fe-fuzz/oom-* .deps .libs + +Build +subprojects/* +!subprojects/*.wrap From c3bd917cf2d93d95724e98aa5cfaaa5b5052c7be Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 17 Jul 2019 11:38:11 +0200 Subject: [PATCH 0547/1198] use correct libraries in travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a09b7271..896048d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ before_install: - ( cd bin ; ln -s ../meson-*/meson.py meson ) - curl -sSLf https://github.com/irssi-import/glib-travis-build/releases/download/2.58.3/travis-xenial-glib-2.58.3.tar.xz | tar xJ - export PKG_CONFIG_PATH=$HOME/glib-build/lib/x86_64-linux-gnu/pkgconfig + - export LD_LIBRARY_PATH=$HOME/glib-build/lib/x86_64-linux-gnu - popd install: From 00a7efc69f8cfc14fcfdf123421015e99ac07926 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 17 Jul 2019 13:37:19 +0200 Subject: [PATCH 0548/1198] modularise irc component --- src/core/modules.c | 12 +++++++++++- src/core/modules.h | 6 ++++++ src/fe-common/irc/dcc/fe-dcc.c | 2 ++ src/fe-common/irc/fe-common-irc.c | 4 +++- src/fe-common/irc/notifylist/fe-notifylist.c | 2 ++ src/irc/core/irc-core.c | 4 +++- src/irc/dcc/dcc.c | 1 + src/irc/flood/flood.c | 2 ++ src/irc/notifylist/notifylist.c | 2 ++ src/perl/perl-common.c | 3 +++ tests/irc/flood/test-796.c | 16 +++++++++++----- 11 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/core/modules.c b/src/core/modules.c index c625071a..119a8e67 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -247,14 +247,24 @@ MODULE_REC *module_find(const char *name) MODULE_FILE_REC *module_file_find(MODULE_REC *module, const char *name) { GSList *tmp; + char *tmpname, *p; + tmpname = g_strdup(name); + for (p = tmpname; *p != '\0'; p++) { + if (*p == '_') + *p = '-'; + } for (tmp = module->files; tmp != NULL; tmp = tmp->next) { MODULE_FILE_REC *rec = tmp->data; - if (g_strcmp0(rec->name, name) == 0) + if (g_strcmp0(rec->name, name) == 0 || + g_strcmp0(rec->name, tmpname) == 0) { + g_free(tmpname); return rec; + } } + g_free(tmpname); return NULL; } diff --git a/src/core/modules.h b/src/core/modules.h index e3deaee2..1e707c0c 100644 --- a/src/core/modules.h +++ b/src/core/modules.h @@ -24,6 +24,12 @@ # define MODULE_IS_STATIC(rec) TRUE #endif +#define MODULE_ABICHECK(fn_modulename) \ +void fn_modulename ## _abicheck(int *version) \ +{ \ + *version = IRSSI_ABI_VERSION; \ +} + enum { MODULE_ERROR_ALREADY_LOADED, MODULE_ERROR_LOAD, diff --git a/src/fe-common/irc/dcc/fe-dcc.c b/src/fe-common/irc/dcc/fe-dcc.c index 51fb5eea..f5fb3b22 100644 --- a/src/fe-common/irc/dcc/fe-dcc.c +++ b/src/fe-common/irc/dcc/fe-dcc.c @@ -191,3 +191,5 @@ void fe_irc_dcc_deinit(void) command_unbind("dcc", (SIGNAL_FUNC) cmd_dcc); command_unbind("dcc list", (SIGNAL_FUNC) cmd_dcc_list); } + +MODULE_ABICHECK(fe_irc_dcc) diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c index 0db2d98e..a36d3caa 100644 --- a/src/fe-common/irc/fe-common-irc.c +++ b/src/fe-common/irc/fe-common-irc.c @@ -102,7 +102,7 @@ void fe_common_irc_init(void) irc_completion_init(); settings_check(); - module_register("core", "fe-irc"); + module_register("irc", "fe-common"); fe_irc_modules_init(); } @@ -130,3 +130,5 @@ void fe_common_irc_deinit(void) theme_unregister(); } + +MODULE_ABICHECK(fe_common_irc) diff --git a/src/fe-common/irc/notifylist/fe-notifylist.c b/src/fe-common/irc/notifylist/fe-notifylist.c index 1f136a97..579b1824 100644 --- a/src/fe-common/irc/notifylist/fe-notifylist.c +++ b/src/fe-common/irc/notifylist/fe-notifylist.c @@ -246,3 +246,5 @@ void fe_irc_notifylist_deinit(void) signal_remove("notifylist left", (SIGNAL_FUNC) notifylist_left); signal_remove("notifylist away changed", (SIGNAL_FUNC) notifylist_away); } + +MODULE_ABICHECK(fe_irc_notifylist) diff --git a/src/irc/core/irc-core.c b/src/irc/core/irc-core.c index b5e80f2a..d1a0f72e 100644 --- a/src/irc/core/irc-core.c +++ b/src/irc/core/irc-core.c @@ -125,7 +125,7 @@ void irc_core_init(void) sasl_init(); settings_check(); - module_register("core", "irc"); + module_register("irc", "core"); } void irc_core_deinit(void) @@ -149,3 +149,5 @@ void irc_core_deinit(void) chat_protocol_unregister("IRC"); } + +MODULE_ABICHECK(irc_core) diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index 006a2b77..4c276ac6 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -597,3 +597,4 @@ void irc_dcc_deinit(void) g_source_remove(dcc_timeouttag); } +MODULE_ABICHECK(irc_dcc) diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c index 886a266c..a7425b90 100644 --- a/src/irc/flood/flood.c +++ b/src/irc/flood/flood.c @@ -346,3 +346,5 @@ void irc_flood_deinit(void) signal_remove("server connected", (SIGNAL_FUNC) flood_init_server); signal_remove("server destroyed", (SIGNAL_FUNC) flood_deinit_server); } + +MODULE_ABICHECK(irc_flood) diff --git a/src/irc/notifylist/notifylist.c b/src/irc/notifylist/notifylist.c index 475e92c8..158b4dea 100644 --- a/src/irc/notifylist/notifylist.c +++ b/src/irc/notifylist/notifylist.c @@ -358,3 +358,5 @@ void irc_notifylist_deinit(void) notifylist_destroy_all(); } + +MODULE_ABICHECK(irc_notifylist) diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index 6fd1705b..a2c7ffe4 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -584,6 +584,9 @@ static void perl_register_protocol(CHAT_PROTOCOL_REC *rec) chat_type = chat_protocol_lookup(rec->name); g_return_if_fail(chat_type >= 0); + if (rec->not_initialized) + return; + name = g_ascii_strdown(rec->name,-1); *name = *(rec->name); diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 6f0f3ac8..9e8aeee7 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -31,9 +31,13 @@ #include #include -/* irc.c */ -void irc_init(void); -void irc_deinit(void); +/* flood.c */ +void irc_flood_init(void); +void irc_flood_deinit(void); + +/* irc-core.c */ +void irc_core_init(void); +void irc_core_deinit(void); /* irc-session.c */ void irc_session_init(void); @@ -72,7 +76,8 @@ static void server_destroy_flood_set_up(ServerDestroyFloodData *fixture, const v { args_execute(0, NULL); core_init(); - irc_init(); + irc_core_init(); + irc_flood_init(); fe_common_core_init(); fe_common_irc_init(); signal_emit("irssi init finished", 0); @@ -90,7 +95,8 @@ static void server_destroy_flood_tear_down(ServerDestroyFloodData *fixture, cons command_unbind("echo", (SIGNAL_FUNC) cmd_echo); fe_common_irc_deinit(); fe_common_core_deinit(); - irc_deinit(); + irc_flood_deinit(); + irc_core_deinit(); core_deinit(); } From d55a74587c37942c7e4a0cf84e8a090e6adb5d01 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 17 Jul 2019 11:52:20 +0000 Subject: [PATCH 0549/1198] Add Meson ver requirement to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9ea92940..febe01b3 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ available. #### Development source installation +[Ninja](http://mesonbuild.com/) 1.5 and [Meson](http://mesonbuild.com/) 0.49 + ``` git clone https://github.com/irssi/irssi cd irssi From 73f6964d4f00a408f2e0caf1a68e61ecc61353ca Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 17 Jul 2019 12:09:39 +0000 Subject: [PATCH 0550/1198] Explain Meson in INSTALL --- INSTALL | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/INSTALL b/INSTALL index d2a0acc2..3476211f 100644 --- a/INSTALL +++ b/INSTALL @@ -4,14 +4,21 @@ To compile irssi you need: -- glib-2.6 or greater -- pkg-config +- meson-0.49 build system with ninja-1.5 or greater +- glib-2.28 or greater - openssl (for ssl support) - perl-5.6 or greater (for perl support) - terminfo or ncurses (for text frontend) For most people, this should work just fine: + meson Build + ninja -C Build + su + ninja -C Build install + +For the moment, autotools is also supported: + ./autogen.sh (for people who just cloned the repository) ./configure (if this script already exists, skip ./autogen.sh) make @@ -20,39 +27,45 @@ For most people, this should work just fine: configure options + These options can be given to meson or ./configure. + The first syntax is for meson, the 2nd for ./configure + + For a complete list of options, run + meson configure / ./configure --help + --prefix Specifies the path where irssi will be installed. YES, you can install irssi WITHOUT ROOT permissions by using --prefix=/home/dir - --with-proxy + -Dwith-proxy=yes / --with-proxy Build the irssi proxy (see startup-HOWTO). - --with-perl=[yes|no|module] + -Dwith-perl=[yes|no] / --with-perl=[yes|no|module] Enable Perl support yes enable builtin (default) no disable module enable as module - --with-perl-lib=[site|vendor|DIR] + -Dwith-perl-lib=[site|vendor|DIR] / --with-perl-lib=[site|vendor|DIR] Specify installation dir for Perl libraries site install in dir for site-specific modules (default) vendor install in dir for vendor-specific modules DIR install in DIR - --with-socks + [N/A] / --with-socks Build with socks library - --with-bot + -Dwith-bot=yes / --with-bot Build irssi-bot - --without-textui + -Dwithout-textui=yes / --without-textui Build without text frontend From 99b2c0b04a20cc1f374b0b7483b3113aa97e996d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 18 Jul 2019 10:29:30 +0200 Subject: [PATCH 0551/1198] fix small overflow --- src/fe-common/core/command-history.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 04922d2d..f4042640 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -10,7 +10,7 @@ typedef struct { int lines; int refcount; - int redo:1; + unsigned int redo:1; } HISTORY_REC; typedef struct { From 12c8cb1f37e1fc30ab3b45d7e11c7d45d08ae280 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 18 Jul 2019 11:37:11 +0200 Subject: [PATCH 0552/1198] carry rpath to working perl test --- meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index f1e23169..15725f6d 100644 --- a/meson.build +++ b/meson.build @@ -246,6 +246,7 @@ have_perl = false if want_perl perl_cflags = [] perl_ldflags = [] + perl_rpath_flags = [] perl_rpath = '' #### ccopts #### @@ -265,6 +266,7 @@ if want_perl if not fl.startswith('-A') and not skip_libs.contains(fl) if fl.startswith('-Wl,-rpath,') perl_rpath = fl.split(',')[2] + perl_rpath_flags += fl else perl_ldflags += fl endif @@ -283,7 +285,8 @@ int main() perl_alloc(); return 0; } -''', args : perl_cflags + perl_ldflags, name : 'working Perl support').compiled() +''', args : perl_cflags + perl_ldflags + perl_rpath_flags, + name : 'working Perl support').compiled() if require_perl error('error linking with perl libraries') else From 6277ccf67fb6cee50565318e458ebedbb75b4873 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 18 Jul 2019 18:04:42 +0200 Subject: [PATCH 0553/1198] manually maintain irc loader --- configure.ac | 31 ------------------------------- src/fe-common/irc/Makefile.am | 3 --- src/irc/Makefile.am | 3 --- 3 files changed, 37 deletions(-) diff --git a/configure.ac b/configure.ac index 7d35aefa..9198fd67 100644 --- a/configure.ac +++ b/configure.ac @@ -633,47 +633,16 @@ FE_COMMON_LIBS="" CHAT_LIBS="" for c in $CHAT_MODULES; do - module_inits="" - module_deinits="" - fe_module_inits="" - fe_module_deinits="" CHAT_LIBS="$CHAT_LIBS ../$c/lib$c.a ../$c/core/lib${c}_core.a" if test -f $srcdir/src/fe-common/$c/module.h; then FE_COMMON_LIBS="$FE_COMMON_LIBS../fe-common/$c/libfe_common_$c.a " fi for s in `eval echo \\$${c}_MODULES`; do CHAT_LIBS="$CHAT_LIBS ../$c/$s/lib${c}_$s.a" - module_inits="$module_inits ${c}_${s}_init();" - module_deinits="${c}_${s}_deinit(); $module_deinits" if test -f $srcdir/src/fe-common/$c/$s/module.h; then FE_COMMON_LIBS="$FE_COMMON_LIBS../fe-common/$c/$s/libfe_${c}_$s.a " - fe_module_inits="$fe_module_inits fe_${c}_${s}_init();" - fe_module_deinits="fe_${c}_${s}_deinit(); $fe_module_deinits" fi done - - mkdir -p src/$c - file="src/$c/$c.c" - echo "/* this file is automatically generated by configure - don't change */" > $file - echo "void ${c}_core_init(void); void ${c}_core_deinit(void);" >> $file - if test -n "$module_inits"; then - echo "$module_inits" | $sedpath -e 's/()/(void)/g' -e 's/ /void /g' >> $file - echo "$module_deinits" | $sedpath -e 's/ *$//' -e 's/()/(void)/g' -e 's/ /void /g' -e 's/^/void /' >> $file - fi - echo "void ${c}_init(void) { ${c}_core_init(); $module_inits }" >> $file - echo "void ${c}_deinit(void) { $module_deinits ${c}_core_deinit(); }" >> $file - - if test -f $srcdir/src/fe-common/$c/module.h; then - mkdir -p src/fe-common/$c - file="src/fe-common/$c/${c}-modules.c" - echo "/* this file is automatically generated by configure - don't change */" > $file - if test -n "$fe_module_inits"; then - echo "$fe_module_inits" | $sedpath -e 's/()/(void)/g' -e 's/ /void /g' >> $file - echo "$fe_module_deinits" | $sedpath -e 's/ *$//' -e 's/()/(void)/g' -e 's/ /void /g' -e 's/^/void /' >> $file - fi - echo "void fe_${c}_modules_init(void) { $fe_module_inits }" >> $file - echo "void fe_${c}_modules_deinit(void) { $fe_module_deinits }" >> $file - fi done FE_COMMON_LIBS="$FE_COMMON_LIBS../fe-common/core/libfe_common_core.a" diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index 704de297..f14d6942 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -39,6 +39,3 @@ pkginc_fe_common_irc_HEADERS = \ module-formats.h DISTFILES = $(DIST_COMMON) $(real_sources) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -distclean-generic: - rm -f irc-modules.c diff --git a/src/irc/Makefile.am b/src/irc/Makefile.am index f9d3eb40..9eda2a2f 100644 --- a/src/irc/Makefile.am +++ b/src/irc/Makefile.am @@ -9,6 +9,3 @@ noinst_LIBRARIES = libirc.a libirc_a_SOURCES = irc.c DISTFILES = $(DIST_COMMON) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -distclean-generic: - rm -f irc.c From 7f99bbfd001e3ede856a298d041e174b51de627c Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 20 Jul 2019 14:29:23 -0700 Subject: [PATCH 0554/1198] Link to Ninja site and use HTTPS for Meson site --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index febe01b3..f73b58a0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ available. #### Development source installation -[Ninja](http://mesonbuild.com/) 1.5 and [Meson](http://mesonbuild.com/) 0.49 +[Ninja](https://ninja-build.org/) 1.5 and [Meson](https://mesonbuild.com/) 0.49 ``` git clone https://github.com/irssi/irssi From 9a90213ba97a8419e56ef8d6af4a1d22e5dea8a9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 21 Jul 2019 00:05:07 +0200 Subject: [PATCH 0555/1198] do not use ?: to stay compatible with meson 0.49 --- meson.build | 21 ++++++++++++++++++--- src/perl/meson.build | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 15725f6d..4223cc08 100644 --- a/meson.build +++ b/meson.build @@ -112,7 +112,10 @@ default_theme_h = custom_target('default-theme.h', #### inet_addr #### inet_addr_found = false foreach inet_addr_provider : ['', 'nsl'] - prov_lib = inet_addr_provider != '' ? [cc.find_library(inet_addr_provider, required : false)] : [] + prov_lib = [] + if inet_addr_provider != '' + prov_lib += cc.find_library(inet_addr_provider, required : false) + endif if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('inet_addr', dependencies : prov_lib) dep += prov_lib inet_addr_found = true @@ -126,7 +129,10 @@ endif #### socket #### socket_found = false foreach socket_provider : ['', 'socket', 'network'] - prov_lib = socket_provider != '' ? [cc.find_library(socket_provider, required : false)] : [] + prov_lib = [] + if socket_provider != '' + prov_lib += cc.find_library(socket_provider, required : false) + endif if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('socket', dependencies : prov_lib) dep += prov_lib socket_found = true @@ -343,6 +349,11 @@ int main() perl_library_dir += ' - prepends to @INC with /set perl_use_lib' endif endif + def_perl_use_lib = '-D' + 'PERL_USE_LIB' + '="' + if set_perl_use_lib + def_perl_use_lib += perl_use_lib + endif + def_perl_use_lib += '"' have_perl = true endif @@ -446,7 +457,11 @@ endif ############## pc = import('pkgconfig') -pc.generate(filebase : 'irssi-1', name : 'Irssi', description : 'Irssi chat client', requires : glib_internal ? [] : glib_dep) +pc_requires = [] +if not glib_internal + pc_requires += glib_dep +endif +pc.generate(filebase : 'irssi-1', name : 'Irssi', description : 'Irssi chat client', requires : pc_requires) ########### # irssi.1 # diff --git a/src/perl/meson.build b/src/perl/meson.build index e3935814..dd8f2f8c 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -26,7 +26,7 @@ shared_module('perl_core', ], c_args : [ def_scriptdir, - '-D' + 'PERL_USE_LIB' + '="' + (set_perl_use_lib ? perl_use_lib : '') + '"', + def_perl_use_lib, '-D' + 'PERL_STATIC_LIBS' + '=' + 0.to_string(), ], include_directories : rootinc, From 6c7fa15417c90deeb319b2d67c9e3b58d55104d7 Mon Sep 17 00:00:00 2001 From: Zero King Date: Sat, 27 Jul 2019 18:23:51 +0000 Subject: [PATCH 0556/1198] Free g_strdup() allocated memory with g_free() Memory allocated with g_malloc() must be freed with g_free(). The allocators may use different memory pools. --- src/core/network-openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 92507e14..9956f217 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -226,7 +226,7 @@ static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname) } else { g_warning("No subjectAltNames and no valid common name in certificate"); } - free(cert_subject_cn); + g_free(cert_subject_cn); } return matched; From dde5fff4a533695f1d2559ef60f22caf66801e03 Mon Sep 17 00:00:00 2001 From: Zero King Date: Sat, 27 Jul 2019 18:34:03 +0000 Subject: [PATCH 0557/1198] Fix memory leaks --- src/core/settings.c | 1 + src/irc/dcc/dcc-resume.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/settings.c b/src/core/settings.c index 2bd6c06a..9b50f6f4 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -229,6 +229,7 @@ static void settings_add(const char *module, const char *section, if (rec->type != type) { g_warning("Trying to add already existing " "setting '%s' with different type.", key); + g_strfreev(choices_vec); return; } rec->refcount++; diff --git a/src/irc/dcc/dcc-resume.c b/src/irc/dcc/dcc-resume.c index b0438e79..dd62ff9d 100644 --- a/src/irc/dcc/dcc-resume.c +++ b/src/irc/dcc/dcc-resume.c @@ -92,8 +92,10 @@ static int dcc_ctcp_resume_parse(int type, const char *data, const char *nick, params = g_strsplit(data, " ", -1); paramcount = g_strv_length(params); - if (paramcount < 3) + if (paramcount < 3) { + g_strfreev(params); return 0; + } fileparams = get_file_params_count_resume(params, paramcount); From c92ff1701fc413b9f993bfe442894af60d61b5ad Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 28 Jul 2019 00:54:08 +0200 Subject: [PATCH 0558/1198] fix cut off text with theme-indent and /set indent_always off --- src/fe-text/textbuffer-view.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index ec518cbf..a031439d 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -281,6 +281,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) /* long word, remove the indentation from this line */ xpos -= sub->indent; sub->indent = 0; + sub->indent_func = NULL; } if (xpos + char_width > view->width) { @@ -434,7 +435,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, if (subline > 0) { /* continuing previous line - indent it */ indent_func = cache->lines[subline-1].indent_func; - if (indent_func == NULL) + if (indent_func == NULL || cache->lines[subline-1].continues) xpos = cache->lines[subline-1].indent; color = cache->lines[subline-1].color; #ifdef TERM_TRUECOLOR @@ -445,7 +446,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, indent_func = NULL; } - if (xpos == 0 && indent_func == NULL) + if (xpos == 0 && (indent_func == NULL || cache->lines[subline-1].continues)) need_clrtoeol = TRUE; else { /* line was indented - need to clear the From ec32e39ae7007a2b39bd022888ea95f5160841e3 Mon Sep 17 00:00:00 2001 From: Frost Date: Wed, 7 Aug 2019 20:51:59 +0000 Subject: [PATCH 0559/1198] hilight.in: fix typo the->to --- docs/help/in/hilight.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/hilight.in b/docs/help/in/hilight.in index 0726e5e7..49a73a7b 100644 --- a/docs/help/in/hilight.in +++ b/docs/help/in/hilight.in @@ -12,7 +12,7 @@ -full: The text must match the full word. -matchcase: The text must match case. -regexp: The text is a regular expression. - -color: The color the display the highlight in. + -color: The color to display the highlight in. -actcolor: The color to mark the highlight activity in the statusbar. -level: Matches only on the given message level. -network: Matches only on the given network. From 89686681c12419db16543a789f4b4ee0d296317f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 15:00:41 +0200 Subject: [PATCH 0560/1198] fix build system debug config to include -fno-omit-frame-pointer --- meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meson.build b/meson.build index 4223cc08..2dcae29d 100644 --- a/meson.build +++ b/meson.build @@ -443,6 +443,9 @@ add_project_arguments(cc.get_supported_arguments('-Werror=declaration-after-stat #### personality #### add_project_arguments(cc.get_supported_arguments('-fno-strict-aliasing'), language : 'c') +if get_option('buildtype').contains('debug') + add_project_arguments(cc.get_supported_arguments('-fno-omit-frame-pointer'), language : 'c') +endif if want_fuzzer if not cc.has_argument('-fsanitize=fuzzer-no-link') From 0495c67d9fe147254a954f38c57dec8882629430 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 11:36:56 +0200 Subject: [PATCH 0561/1198] fix glib version dependency --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 4223cc08..bcf9ad6e 100644 --- a/meson.build +++ b/meson.build @@ -149,7 +149,7 @@ message('*** to download and build it automatically') message('*** Or alternatively install your distribution\'s package') message('*** On Debian: sudo apt-get install libglib2.0-dev') message('*** On Redhat: dnf install glib2-devel') -glib_dep = dependency('glib-2.0', version : '>=2.58', required : not want_glib_internal) +glib_dep = dependency('glib-2.0', version : '>=2.28', required : not want_glib_internal) if not glib_dep.found() glib_internal = true meson_cmd = find_program('meson') From a865b07a673ea4e8ea13d00f436058861d3d9ff0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 19 Jul 2019 08:40:16 +0200 Subject: [PATCH 0562/1198] make the $Z time overridable --- src/core/expandos.c | 3 ++- src/core/expandos.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/expandos.c b/src/core/expandos.c index 96e2d9f3..9280b6f3 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -48,6 +48,7 @@ typedef struct { } EXPANDO_REC; const char *current_expando = NULL; +time_t current_time = (time_t)-1; static int timer_tag; @@ -441,7 +442,7 @@ static char *expando_time(SERVER_REC *server, void *item, int *free_ret) struct tm *tm; char str[256]; - now = time(NULL); + now = current_time != (time_t)-1 ? current_time : time(NULL); tm = localtime(&now); if (strftime(str, sizeof(str), timestamp_format, tm) == 0) diff --git a/src/core/expandos.h b/src/core/expandos.h index 05dfcf11..c03333a7 100644 --- a/src/core/expandos.h +++ b/src/core/expandos.h @@ -17,6 +17,7 @@ typedef char* (*EXPANDO_FUNC) (SERVER_REC *server, void *item, int *free_ret); extern const char *current_expando; +extern time_t current_time; /* Create expando - overrides any existing ones. ... = signal, type, ..., NULL - list of signals that might change the From e0ff13f6c17acd61a2123737688042703a2f7a42 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Aug 2019 17:07:17 +0200 Subject: [PATCH 0563/1198] enable irc cap ls 302 --- src/irc/core/irc-servers.c | 2 +- src/irc/core/irc-servers.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 7057c02a..8a7137eb 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -240,7 +240,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, "multi-prefix", TRUE); - irc_send_cmd_now(server, "CAP LS"); + irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); if (conn->password != NULL && *conn->password != '\0') { /* send password */ diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 57b65527..162d845f 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -5,6 +5,8 @@ #include #include +#define CAP_LS_VERSION "302" + /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ PROTO_CHECK_CAST(SERVER(server), IRC_SERVER_REC, chat_type, "IRC") From d512647b3f4b769305e3515d616833988d918943 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 17:36:20 +0200 Subject: [PATCH 0564/1198] use symbolic defines for capability strings --- src/irc/core/irc-servers.c | 4 ++-- src/irc/core/irc-servers.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 8a7137eb..118f7242 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -236,9 +236,9 @@ static void server_init(IRC_SERVER_REC *server) } if (conn->sasl_mechanism != SASL_MECHANISM_NONE) - irc_cap_toggle(server, "sasl", TRUE); + irc_cap_toggle(server, CAP_SASL, TRUE); - irc_cap_toggle(server, "multi-prefix", TRUE); + irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 162d845f..df0446cb 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -6,6 +6,8 @@ #include #define CAP_LS_VERSION "302" +#define CAP_SASL "sasl" +#define CAP_MULTI_PREFIX "multi-prefix" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ From 27546354ca029997500f81bb64d2df1b9cd226c6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 11 Aug 2019 20:41:57 +0200 Subject: [PATCH 0565/1198] increase disconnect buffer and get rid of some magic 510 values --- src/core/net-disconnect.c | 4 ++-- src/irc/core/irc-channels.c | 2 +- src/irc/core/irc-servers.c | 10 ++-------- src/irc/core/irc-servers.h | 9 +++++++++ src/irc/notifylist/notify-ison.c | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/core/net-disconnect.c b/src/core/net-disconnect.c index 889563c5..27540767 100644 --- a/src/core/net-disconnect.c +++ b/src/core/net-disconnect.c @@ -51,7 +51,7 @@ static void sig_disconnect(NET_DISCONNECT_REC *rec) char buf[512]; int count, ret; - /* check if there's any data waiting in socket. read max. 5kB so + /* check if there's any data waiting in socket. read max. 9kB so if server just keeps sending us stuff we won't get stuck */ count = 0; do { @@ -61,7 +61,7 @@ static void sig_disconnect(NET_DISCONNECT_REC *rec) net_disconnect_remove(rec); } count++; - } while (ret == sizeof(buf) && count < 10); + } while (ret == sizeof(buf) && count < 18); } static int sig_timeout_disconnect(void) diff --git a/src/irc/core/irc-channels.c b/src/irc/core/irc-channels.c index b2ee3772..27f8f4b2 100644 --- a/src/irc/core/irc-channels.c +++ b/src/irc/core/irc-channels.c @@ -142,7 +142,7 @@ static void irc_channels_join(IRC_SERVER_REC *server, const char *data, /* don't try to send too long lines make sure it's not longer than 510 so 510 - strlen("JOIN ") = 505 */ - if (cmdlen < 505) + if (cmdlen < MAX_IRC_MESSAGE_LEN - 5 /* strlen("JOIN ") */) continue; } if (outchans->len > 0) { diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 118f7242..5698b9a0 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -55,12 +55,6 @@ #define DEFAULT_CMDS_MAX_AT_ONCE 5 #define DEFAULT_MAX_QUERY_CHANS 1 /* more and more IRC networks are using stupid ircds.. */ -/* - * 63 is the maximum hostname length defined by the protocol. 10 is a common - * username limit on many networks. 1 is for the `@'. - */ -#define MAX_USERHOST_LEN (63 + 10 + 1) - void irc_servers_reconnect_init(void); void irc_servers_reconnect_deinit(void); @@ -208,7 +202,7 @@ static char **split_message(SERVER_REC *server, const char *target, /* length calculation shamelessly stolen from splitlong_safe.pl */ return split_line(SERVER(server), msg, target, - 510 - strlen(":! PRIVMSG :") - + MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :") - strlen(ircserver->nick) - MAX_USERHOST_LEN - strlen(target)); } @@ -498,7 +492,7 @@ char **irc_server_split_action(IRC_SERVER_REC *server, const char *target, g_return_val_if_fail(data != NULL, NULL); return split_line(SERVER(server), data, target, - 510 - strlen(":! PRIVMSG :\001ACTION \001") - + MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :\001ACTION \001") - strlen(server->nick) - MAX_USERHOST_LEN - strlen(target)); } diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index df0446cb..f1697c60 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -5,6 +5,15 @@ #include #include +/* + * 63 is the maximum hostname length defined by the protocol. 10 is a common + * username limit on many networks. 1 is for the `@'. + */ +#define MAX_USERHOST_LEN (63 + 10 + 1) +#define MAX_IRC_MESSAGE_LEN (512 - 2) /* (2 bytes for CR+LF) */ +#define MAX_IRC_TAGS_LEN (8191 - 2) /* (2 bytes for `@' and SPACE) */ +#define MAX_IRC_USER_TAGS_LEN 4094 + #define CAP_LS_VERSION "302" #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index 39292896..4fb9315a 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -131,7 +131,7 @@ static void notifylist_timeout_server(IRC_SERVER_REC *server) len = strlen(nick); - if (cmd->len+len+1 > 510) + if (cmd->len+len+1 > MAX_IRC_MESSAGE_LEN) ison_send(server, cmd); g_string_append_printf(cmd, "%s ", nick); From ed4297c41bf5b1ee00a945b5ea52360b357464c4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 19 Jul 2019 08:41:49 +0200 Subject: [PATCH 0566/1198] add a new "print noformat" signal to be emitted on printtext --- src/fe-common/core/printtext.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 1826c754..692a3bc2 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -38,6 +38,7 @@ static int signal_gui_print_text_finished; static int signal_print_starting; static int signal_print_text; static int signal_print_format; +static int signal_print_noformat; static int sending_print_starting; @@ -313,6 +314,8 @@ static void printtext_dest_args(TEXT_DEST_REC *dest, const char *text, va_list v } str = printtext_get_args(dest, text, va); + signal_emit_id(signal_print_noformat, 2, + dest, str); print_line(dest, str); g_free(str); } @@ -515,6 +518,7 @@ void printtext_init(void) signal_print_starting = signal_get_uniq_id("print starting"); signal_print_text = signal_get_uniq_id("print text"); signal_print_format = signal_get_uniq_id("print format"); + signal_print_noformat = signal_get_uniq_id("print noformat"); read_settings(); signal_add("print text", (SIGNAL_FUNC) sig_print_text); From 25270e046599b0aa2c84420bfb19660d255603c8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 02:16:22 +0200 Subject: [PATCH 0567/1198] use extended-join capability --- src/core/nick-rec.h | 1 + src/fe-common/core/fe-messages.c | 5 +++-- src/fe-common/core/module-formats.c | 2 +- src/fe-common/irc/fe-events.c | 8 ++++---- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + src/irc/core/massjoin.c | 15 +++++++++++++-- src/perl/perl-common.c | 1 + 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/core/nick-rec.h b/src/core/nick-rec.h index 1463f9f3..53bc7098 100644 --- a/src/core/nick-rec.h +++ b/src/core/nick-rec.h @@ -8,6 +8,7 @@ time_t last_check; /* last time gone was checked */ char *nick; char *host; char *realname; +char *account; int hops; /* status in server */ diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 5edac26d..4e1c2596 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -349,14 +349,15 @@ static void sig_message_own_private(SERVER_REC *server, const char *msg, } static void sig_message_join(SERVER_REC *server, const char *channel, - const char *nick, const char *address) + const char *nick, const char *address, + const char *account, const char *realname) { int level = MSGLEVEL_JOINS; ignore_check_plus(server, nick, address, channel, NULL, &level, FALSE); printformat(server, channel, level, - TXT_JOIN, nick, address, channel); + TXT_JOIN, nick, address, channel, account, realname); } static void sig_message_part(SERVER_REC *server, const char *channel, diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 0c41e68b..50d8d7cc 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -94,7 +94,7 @@ FORMAT_REC fecommon_core_formats[] = { /* ---- */ { NULL, "Channels", 0 }, - { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 3, { 0, 0, 0 } }, + { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, { "part", "{channick $0} {chanhost $1} has left {channel $2} {reason $3}", 4, { 0, 0, 0, 0 } }, { "kick", "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}", 5, { 0, 0, 0, 0, 0 } }, { "quit", "{channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index 30f00efc..8b3fe3ec 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -113,16 +113,16 @@ static void event_notice(IRC_SERVER_REC *server, const char *data, static void event_join(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { - char *params, *channel, *tmp; + char *params, *channel, *tmp, *account, *realname; g_return_if_fail(data != NULL); - params = event_get_params(data, 1, &channel); + params = event_get_params(data, 3, &channel, &account, &realname); tmp = strchr(channel, 7); /* ^G does something weird.. */ if (tmp != NULL) *tmp = '\0'; - signal_emit("message join", 4, server, - get_visible_target(server, channel), nick, addr); + signal_emit("message join", 6, server, + get_visible_target(server, channel), nick, addr, account, realname); g_free(params); } diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 118f7242..16bc9922 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -239,6 +239,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SASL, TRUE); irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); + irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index df0446cb..7539a1fa 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -8,6 +8,7 @@ #define CAP_LS_VERSION "302" #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" +#define CAP_EXTENDED_JOIN "extended-join" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index ec63a0b3..4a3f085d 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -35,7 +35,7 @@ static int massjoin_max_joins; static void event_join(IRC_SERVER_REC *server, const char *data, const char *nick, const char *address) { - char *params, *channel, *ptr; + char *params, *channel, *account, *realname, *ptr; IRC_CHANNEL_REC *chanrec; NICK_REC *nickrec; GSList *nicks, *tmp; @@ -47,7 +47,8 @@ static void event_join(IRC_SERVER_REC *server, const char *data, return; } - params = event_get_params(data, 1, &channel); + params = event_get_params(data, 3, &channel, &account, &realname); + ptr = strchr(channel, 7); /* ^G does something weird.. */ if (ptr != NULL) *ptr = '\0'; @@ -66,6 +67,11 @@ static void event_join(IRC_SERVER_REC *server, const char *data, /* add user to nicklist */ nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, TRUE, NULL); + if (*account != '\0' && g_strcmp0(nickrec->account, account) != 0) { + g_free(nickrec->account); + nickrec->account = g_strdup(account); + } + nicklist_set_host(CHANNEL(chanrec), nickrec, address); if (chanrec->massjoins == 0) { @@ -92,6 +98,11 @@ static void event_join(IRC_SERVER_REC *server, const char *data, g_slist_free(nicks); } + if (*realname != '\0' && g_strcmp0(nickrec->realname, realname) != 0) { + g_free(nickrec->realname); + nickrec->realname = g_strdup(realname); + } + chanrec->massjoins++; } diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index a2c7ffe4..31650cc4 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -426,6 +426,7 @@ void perl_nick_fill_hash(HV *hv, NICK_REC *nick) (void) hv_store(hv, "nick", 4, new_pv(nick->nick), 0); (void) hv_store(hv, "host", 4, new_pv(nick->host), 0); (void) hv_store(hv, "realname", 8, new_pv(nick->realname), 0); + (void) hv_store(hv, "account", 7, new_pv(nick->account), 0); (void) hv_store(hv, "hops", 4, newSViv(nick->hops), 0); (void) hv_store(hv, "gone", 4, newSViv(nick->gone), 0); From 4ae1dbbd0086c976599a22eb9083164839d9ad1c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 15:52:00 +0200 Subject: [PATCH 0568/1198] fix cap queue order --- src/irc/core/irc-cap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 21a27324..31b57094 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -184,6 +184,9 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add avail_caps = 0; + /* To process the queue in order, we need to reverse the stack once */ + server->cap_queue = g_slist_reverse(server->cap_queue); + /* Check whether the cap is supported by the server */ for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, NULL)) { From ad7ad063caee99a800b54ca16ee34dd32147df66 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 15:29:55 +0200 Subject: [PATCH 0569/1198] implement reference counted strings - on glib >=2.58, use the implementation provided by glib - otherwise, a hash table will contain the strings --- src/core/Makefile.am | 2 + src/core/core.c | 3 + src/core/meson.build | 2 + src/core/refstrings.c | 94 +++++++++++++++++++++++++++++++ src/core/refstrings.h | 24 ++++++++ src/fe-text/textbuffer-commands.c | 8 +++ 6 files changed, 133 insertions(+) create mode 100644 src/core/refstrings.c create mode 100644 src/core/refstrings.h diff --git a/src/core/Makefile.am b/src/core/Makefile.am index c01b8f10..7cf172ef 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -41,6 +41,7 @@ libcore_a_SOURCES = \ queries.c \ rawlog.c \ recode.c \ + refstrings.c \ servers.c \ servers-reconnect.c \ servers-setup.c \ @@ -102,6 +103,7 @@ pkginc_core_HEADERS = \ queries.h \ rawlog.h \ recode.h \ + refstrings.h \ servers.h \ servers-reconnect.h \ servers-setup.h \ diff --git a/src/core/core.c b/src/core/core.c index 8562836a..878d9eb6 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -261,6 +262,7 @@ void core_init(void) nicklist_init(); chat_commands_init(); + i_refstr_init(); wcwidth_wrapper_init(); settings_add_str("misc", "ignore_signals", ""); @@ -286,6 +288,7 @@ void core_deinit(void) signal_remove("irssi init finished", (SIGNAL_FUNC) sig_irssi_init_finished); wcwidth_wrapper_deinit(); + i_refstr_deinit(); chat_commands_deinit(); nicklist_deinit(); diff --git a/src/core/meson.build b/src/core/meson.build index dd5a4d49..b22a16de 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -43,6 +43,7 @@ libcore_a = static_library('core', 'queries.c', 'rawlog.c', 'recode.c', + 'refstrings.c', 'servers-reconnect.c', 'servers-setup.c', 'servers.c', @@ -114,6 +115,7 @@ install_headers( 'queries.h', 'rawlog.h', 'recode.h', + 'refstrings.h', 'servers-reconnect.h', 'servers-setup.h', 'servers.h', diff --git a/src/core/refstrings.c b/src/core/refstrings.c new file mode 100644 index 00000000..4b675fa5 --- /dev/null +++ b/src/core/refstrings.c @@ -0,0 +1,94 @@ +#include + +#include + +#if GLIB_CHECK_VERSION(2, 58, 0) +/* nothing */ +#else + +GHashTable *i_refstr_table; + +void i_refstr_init(void) +{ + i_refstr_table = g_hash_table_new(g_str_hash, g_str_equal); +} + +char *i_refstr_intern(const char *str) +{ + char *ret; + gpointer rc_p, ret_p; + size_t rc; + + if (str == NULL) + return NULL; + + if (g_hash_table_lookup_extended(i_refstr_table, str, &ret_p, &rc_p)) { + rc = GPOINTER_TO_SIZE(rc_p); + ret = ret_p; + } else { + rc = 0; + ret = g_strdup(str); + } + + if (rc + 1 <= G_MAXSIZE) { + g_hash_table_insert(i_refstr_table, ret, GSIZE_TO_POINTER(rc + 1)); + return ret; + } else { + return g_strdup(str); + } +} + +void i_refstr_release(char *str) +{ + char *ret; + gpointer rc_p, ret_p; + size_t rc; + + if (str == NULL) + return; + + if (g_hash_table_lookup_extended(i_refstr_table, str, &ret_p, &rc_p)) { + rc = GPOINTER_TO_SIZE(rc_p); + ret = ret_p; + } else { + rc = 0; + ret = NULL; + } + + if (ret == str) { + if (rc > 1) { + g_hash_table_insert(i_refstr_table, ret, GSIZE_TO_POINTER(rc - 1)); + } else { + g_hash_table_remove(i_refstr_table, ret); + g_free(ret); + } + } else { + g_free(str); + } +} + +void i_refstr_deinit(void) +{ + g_hash_table_foreach(i_refstr_table, (GHFunc) g_free, NULL); + g_hash_table_destroy(i_refstr_table); +} + +char *i_refstr_table_size_info(void) +{ + GHashTableIter iter; + void *k_p, *v_p; + size_t count, mem; + count = 0; + mem = 0; + g_hash_table_iter_init(&iter, i_refstr_table); + while (g_hash_table_iter_next(&iter, &k_p, &v_p)) { + char *key = k_p; + count++; + mem += sizeof(char) * (strlen(key) + 1) + 2 * sizeof(void *); + } + + return g_strdup_printf("Shared strings: %ld, %dkB of data", count, + (int) (mem / 1024)); +} + +#endif diff --git a/src/core/refstrings.h b/src/core/refstrings.h new file mode 100644 index 00000000..79036a20 --- /dev/null +++ b/src/core/refstrings.h @@ -0,0 +1,24 @@ +#ifndef IRSSI_CORE_REFSTRINGS_H +#define IRSSI_CORE_REFSTRINGS_H + +#include + +#if GLIB_CHECK_VERSION(2, 58, 0) + +#define i_refstr_init() /* nothing */ +#define i_refstr_release(str) ((str) == NULL ? NULL : g_ref_string_release(str)) +#define i_refstr_intern(str) ((str) == NULL ? NULL : g_ref_string_new_intern(str)) +#define i_refstr_deinit() /* nothing */ +#define i_refstr_table_size_info() NULL + +#else + +void i_refstr_init(void); +char *i_refstr_intern(const char *str); +void i_refstr_release(char *str); +void i_refstr_deinit(void); +char *i_refstr_table_size_info(void); + +#endif + +#endif diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c index 318ee077..11c0f123 100644 --- a/src/fe-text/textbuffer-commands.c +++ b/src/fe-text/textbuffer-commands.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -358,6 +359,13 @@ static void cmd_scrollback_status(void) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "Total: %d lines, %dkB of data", total_lines, (int)(total_mem / 1024)); + { + char *tmp = i_refstr_table_size_info(); + if (tmp != NULL) + printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, + "%s", tmp); + g_free(tmp); + } } static void sig_away_changed(SERVER_REC *server) From 76bcd01da065ce97acad6d5430218d5f04581e93 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Aug 2019 21:07:27 +0200 Subject: [PATCH 0570/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index d7eaac45..672e5e6c 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 21 +#define IRSSI_ABI_VERSION 22 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 47518b4b751fa1fc50798dc28a57bdf8e9e420e9 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 00:31:43 +0200 Subject: [PATCH 0571/1198] request the setname capability --- src/irc/core/irc-commands.c | 2 ++ src/irc/core/irc-nicklist.c | 23 +++++++++++++++++++++++ src/irc/core/irc-servers.c | 4 +++- src/irc/core/irc-servers.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 4062b1da..6737748f 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -1045,6 +1045,7 @@ void irc_commands_init(void) command_bind_irc("wallops", NULL, (SIGNAL_FUNC) command_1self); command_bind_irc("kickban", NULL, (SIGNAL_FUNC) cmd_kickban); command_bind_irc("knockout", NULL, (SIGNAL_FUNC) cmd_knockout); + command_bind_irc("setname", NULL, (SIGNAL_FUNC) command_1self); command_bind_irc("server purge", NULL, (SIGNAL_FUNC) cmd_server_purge); signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); @@ -1111,6 +1112,7 @@ void irc_commands_deinit(void) command_unbind("wait", (SIGNAL_FUNC) cmd_wait); command_unbind("wallops", (SIGNAL_FUNC) command_1self); command_unbind("kickban", (SIGNAL_FUNC) cmd_kickban); + command_unbind("setname", (SIGNAL_FUNC) command_1self); command_unbind("knockout", (SIGNAL_FUNC) cmd_knockout); command_unbind("server purge", (SIGNAL_FUNC) cmd_server_purge); diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 54a9bd3b..9073ddaa 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -446,6 +446,27 @@ static void event_userhost(SERVER_REC *server, const char *data) g_free(params); } +static void event_setname(SERVER_REC *server, const char *data, const char *nick, const char *address) +{ + GSList *nicks, *tmp; + NICK_REC *rec; + + if (!IS_IRC_SERVER(server)) + return; + + g_return_if_fail(data != NULL); + if (*data == ':') data++; + + nicks = nicklist_get_same(server, nick); + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + rec = tmp->next->data; + + g_free(rec->realname); + rec->realname = g_strdup(data); + } + g_slist_free(nicks); +} + static void sig_usermode(SERVER_REC *server) { g_return_if_fail(IS_SERVER(server)); @@ -487,6 +508,7 @@ void irc_nicklist_init(void) signal_add_first("event 437", (SIGNAL_FUNC) event_target_unavailable); signal_add_first("event 302", (SIGNAL_FUNC) event_userhost); signal_add("userhost event", (SIGNAL_FUNC) event_userhost); + signal_add("event setname", (SIGNAL_FUNC) event_setname); signal_add("user mode changed", (SIGNAL_FUNC) sig_usermode); signal_add("server connected", (SIGNAL_FUNC) sig_connected); } @@ -509,6 +531,7 @@ void irc_nicklist_deinit(void) signal_remove("event 437", (SIGNAL_FUNC) event_target_unavailable); signal_remove("event 302", (SIGNAL_FUNC) event_userhost); signal_remove("userhost event", (SIGNAL_FUNC) event_userhost); + signal_remove("event setname", (SIGNAL_FUNC) event_setname); signal_remove("user mode changed", (SIGNAL_FUNC) sig_usermode); signal_remove("server connected", (SIGNAL_FUNC) sig_connected); } diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index e2d96bdb..195ced02 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -229,11 +229,13 @@ static void server_init(IRC_SERVER_REC *server) g_free(cmd); } - if (conn->sasl_mechanism != SASL_MECHANISM_NONE) + if (conn->sasl_mechanism != SASL_MECHANISM_NONE) { irc_cap_toggle(server, CAP_SASL, TRUE); + } irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); + irc_cap_toggle(server, CAP_SETNAME, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index cd5a63ff..15ca7452 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -18,6 +18,7 @@ #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" #define CAP_EXTENDED_JOIN "extended-join" +#define CAP_SETNAME "draft/setname" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ From e62e55c0ab83cc643ee7c221dc0610ffecc18537 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 01:05:57 +0200 Subject: [PATCH 0572/1198] show invites of other users when provided --- src/fe-common/core/fe-ignore-messages.c | 10 ++++++++++ src/fe-common/core/fe-messages.c | 16 ++++++++++++++++ src/fe-common/core/module-formats.c | 1 + src/fe-common/core/module-formats.h | 1 + src/fe-common/irc/fe-events.c | 13 +++++++++---- src/irc/core/channel-events.c | 10 ++++++++-- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + 8 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/fe-ignore-messages.c b/src/fe-common/core/fe-ignore-messages.c index 73ebd01f..6bcfb6da 100644 --- a/src/fe-common/core/fe-ignore-messages.c +++ b/src/fe-common/core/fe-ignore-messages.c @@ -98,6 +98,14 @@ static void sig_message_invite(SERVER_REC *server, const char *channel, signal_stop(); } +static void sig_message_invite_other(SERVER_REC *server, const char *channel, + const char *invited, const char *nick, const char *address) +{ + if (ignore_check(server, nick, address, + channel, invited, MSGLEVEL_INVITES)) + signal_stop(); +} + static void sig_message_topic(SERVER_REC *server, const char *channel, const char *topic, const char *nick, const char *address) @@ -118,6 +126,7 @@ void fe_ignore_messages_init(void) signal_add_first("message nick", (SIGNAL_FUNC) sig_message_nick); signal_add_first("message own_nick", (SIGNAL_FUNC) sig_message_own_nick); signal_add_first("message invite", (SIGNAL_FUNC) sig_message_invite); + signal_add_first("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_add_first("message topic", (SIGNAL_FUNC) sig_message_topic); } @@ -132,5 +141,6 @@ void fe_ignore_messages_deinit(void) signal_remove("message nick", (SIGNAL_FUNC) sig_message_nick); signal_remove("message own_nick", (SIGNAL_FUNC) sig_message_own_nick); signal_remove("message invite", (SIGNAL_FUNC) sig_message_invite); + signal_remove("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_remove("message topic", (SIGNAL_FUNC) sig_message_topic); } diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 4e1c2596..37c0ef39 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -538,6 +538,20 @@ static void sig_message_invite(SERVER_REC *server, const char *channel, g_free(str); } +static void sig_message_invite_other(SERVER_REC *server, const char *channel, + const char *invited, const char *nick, const char *address) +{ + char *str; + int level = MSGLEVEL_INVITES; + + ignore_check_plus(server, nick, address, channel, invited, &level, FALSE); + + str = show_lowascii(channel); + printformat(server, channel, level, + TXT_INVITE_OTHER, invited, nick, str, address); + g_free(str); +} + static void sig_message_topic(SERVER_REC *server, const char *channel, const char *topic, const char *nick, const char *address) @@ -706,6 +720,7 @@ void fe_messages_init(void) signal_add_last("message nick", (SIGNAL_FUNC) sig_message_nick); signal_add_last("message own_nick", (SIGNAL_FUNC) sig_message_own_nick); signal_add_last("message invite", (SIGNAL_FUNC) sig_message_invite); + signal_add_last("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_add_last("message topic", (SIGNAL_FUNC) sig_message_topic); signal_add("nicklist new", (SIGNAL_FUNC) sig_nicklist_new); @@ -730,6 +745,7 @@ void fe_messages_deinit(void) signal_remove("message kick", (SIGNAL_FUNC) sig_message_kick); signal_remove("message nick", (SIGNAL_FUNC) sig_message_nick); signal_remove("message own_nick", (SIGNAL_FUNC) sig_message_own_nick); + signal_remove("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_remove("message invite", (SIGNAL_FUNC) sig_message_invite); signal_remove("message topic", (SIGNAL_FUNC) sig_message_topic); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 50d8d7cc..2532d82f 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -101,6 +101,7 @@ FORMAT_REC fecommon_core_formats[] = { { "quit_once", "{channel $3} {channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, { "invite", "{nick $0} invites you to {channel $1}", 3, { 0, 0, 0 } }, { "not_invited", "You have not been invited to a channel!", 0 }, + { "invite_other", "{nick $0} has been invited to {channel $2} by {channick_hilight $1}", 4, { 0, 0, 0, 0 } }, { "new_topic", "{nick $0} changed the topic of {channel $1} to: $2", 4, { 0, 0, 0, 0 } }, { "topic_unset", "Topic unset by {nick $0} on {channel $1}", 4, { 0, 0, 0, 0 } }, { "your_nick_changed", "You're now known as {nick $1}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index 181aa4c2..c5e2c4d1 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -77,6 +77,7 @@ enum { TXT_QUIT_ONCE, TXT_INVITE, TXT_NOT_INVITED, + TXT_INVITE_OTHER, TXT_NEW_TOPIC, TXT_TOPIC_UNSET, TXT_YOUR_NICK_CHANGED, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index 8b3fe3ec..c26f2e88 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -252,13 +252,18 @@ static void event_pong(IRC_SERVER_REC *server, const char *data, const char *nic static void event_invite(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { - char *params, *channel; + char *params, *invited, *channel; g_return_if_fail(data != NULL); - params = event_get_params(data, 2, NULL, &channel); - signal_emit("message invite", 4, - server, get_visible_target(server, channel), nick, addr); + params = event_get_params(data, 2, &invited, &channel); + if (server->nick_comp_func(invited, server->nick) == 0) { + signal_emit("message invite", 4, + server, get_visible_target(server, channel), nick, addr); + } else { + signal_emit("message invite_other", 5, + server, get_visible_target(server, channel), invited, nick, addr); + } g_free(params); } diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 7603a14f..3cdfe964 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -336,11 +336,17 @@ static void event_kick(IRC_SERVER_REC *server, const char *data) static void event_invite(IRC_SERVER_REC *server, const char *data) { - char *params, *channel, *shortchan; + char *params, *nick, *channel, *shortchan; g_return_if_fail(data != NULL); - params = event_get_params(data, 2, NULL, &channel); + params = event_get_params(data, 2, &nick, &channel); + + if (server->nick_comp_func(nick, server->nick) != 0) { + /* someone else was invited, no need to do anything */ + g_free(params); + return; + } if (irc_channel_find(server, channel) == NULL) { /* check if we're supposed to autojoin this channel */ diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 195ced02..5e98e724 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -236,6 +236,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE); + irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 15ca7452..5313c1d0 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -19,6 +19,7 @@ #define CAP_MULTI_PREFIX "multi-prefix" #define CAP_EXTENDED_JOIN "extended-join" #define CAP_SETNAME "draft/setname" +#define CAP_INVITE_NOTIFY "invite-notify" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ From 24154ced0db81d0f8db28c9f62ab7ae37bc4b419 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 11 Aug 2019 19:25:53 +0200 Subject: [PATCH 0573/1198] irc message tags support --- docs/signals.txt | 1 + src/irc/core/irc.c | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index 959387b2..358973db 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -144,6 +144,7 @@ sasl.c irc.c: "server event", SERVER_REC, char *data, char *sender_nick, char *sender_address + "server event tags", SERVER_REC, char *data, char *sender_nick, char *sender_address, char *tags "event ", SERVER_REC, char *args, char *sender_nick, char *sender_address "default event", SERVER_REC, char *data, char *sender_nick, char *sender_address "whois default event", SERVER_REC, char *args, char *sender_nick, char *sender_address diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 4940fcb4..4adbfcc9 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -32,6 +32,7 @@ char *current_server_event; static int signal_default_event; static int signal_server_event; +static int signal_server_event_tags; static int signal_server_incoming; #ifdef BLOCKING_SOCKETS @@ -158,6 +159,11 @@ static char *split_nicks(const char *cmd, char **pre, char **nicks, char **post, *pre = g_strdup(cmd); *post = *nicks = NULL; + + if (**pre == '@') { /* message-tags */ + arg++; + } + for (p = *pre; *p != '\0'; p++) { if (*p != ' ') continue; @@ -342,13 +348,31 @@ static void irc_server_event(IRC_SERVER_REC *server, const char *line, g_free(event); } -static char *irc_parse_prefix(char *line, char **nick, char **address) +static void irc_server_event_tags(IRC_SERVER_REC *server, const char *line, + const char *nick, const char *address, const char *tags) +{ + if (*line != '\0') + signal_emit_id(signal_server_event, 4, server, line, nick, address); +} + +static char *irc_parse_prefix(char *line, char **nick, char **address, char **tags) { char *p; - *nick = *address = NULL; + *nick = *address = *tags = NULL; - /* : [["!" ] "@" ] SPACE */ + /* ["@" SPACE] : [["!" ] "@" ] SPACE */ + + if (*line == '@') { + *tags = ++line; + while (*line != '\0' && *line != ' ') { + line++; + } + if (*line == ' ') { + *line++ = '\0'; + while (*line == ' ') line++; + } + } if (*line != ':') return line; @@ -382,14 +406,14 @@ static char *irc_parse_prefix(char *line, char **nick, char **address) /* Parse command line sent by server */ static void irc_parse_incoming_line(IRC_SERVER_REC *server, char *line) { - char *nick, *address; + char *nick, *address, *tags; g_return_if_fail(server != NULL); g_return_if_fail(line != NULL); - line = irc_parse_prefix(line, &nick, &address); - if (*line != '\0') - signal_emit_id(signal_server_event, 4, server, line, nick, address); + line = irc_parse_prefix(line, &nick, &address, &tags); + if (*line != '\0' || tags != NULL) + signal_emit_id(signal_server_event_tags, 5, server, line, nick, address, tags); } /* input function: handle incoming server messages */ @@ -441,12 +465,14 @@ static void irc_init_server(IRC_SERVER_REC *server) void irc_irc_init(void) { signal_add("server event", (SIGNAL_FUNC) irc_server_event); + signal_add("server event tags", (SIGNAL_FUNC) irc_server_event_tags); signal_add("server connected", (SIGNAL_FUNC) irc_init_server); signal_add("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line); current_server_event = NULL; signal_default_event = signal_get_uniq_id("default event"); signal_server_event = signal_get_uniq_id("server event"); + signal_server_event_tags = signal_get_uniq_id("server event tags"); signal_server_incoming = signal_get_uniq_id("server incoming"); } From eb3a44a71328fd600450782a042fd075434eec55 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 10:55:48 +0200 Subject: [PATCH 0574/1198] clarifying comment --- src/irc/core/irc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 4adbfcc9..3c7e30c0 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -160,7 +160,10 @@ static char *split_nicks(const char *cmd, char **pre, char **nicks, char **post, *pre = g_strdup(cmd); *post = *nicks = NULL; - if (**pre == '@') { /* message-tags */ + if (**pre == '@') { + /* the message-tags "add" one space separated argument + in front of the non message-tagged IRC commands. So + the nicks are now off-set by one to the right. */ arg++; } From 2576064982d2090f868e89e5315ee8ebfd8ed207 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 10:57:54 +0200 Subject: [PATCH 0575/1198] add missing signal_remove --- src/irc/core/irc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 3c7e30c0..2f520328 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -482,6 +482,7 @@ void irc_irc_init(void) void irc_irc_deinit(void) { signal_remove("server event", (SIGNAL_FUNC) irc_server_event); + signal_remove("server event tags", (SIGNAL_FUNC) irc_server_event_tags); signal_remove("server connected", (SIGNAL_FUNC) irc_init_server); signal_remove("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line); } From 0f361d26733b13bb57acc3817995abe5985e36c3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 15:37:20 +0200 Subject: [PATCH 0576/1198] refactor quit message into a separate function --- src/fe-common/core/fe-messages.c | 62 +++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 4e1c2596..85200419 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -372,50 +372,57 @@ static void sig_message_part(SERVER_REC *server, const char *channel, TXT_PART, nick, address, channel, reason); } -static void sig_message_quit(SERVER_REC *server, const char *nick, - const char *address, const char *reason) +static void spread_server_message_to_windows(SERVER_REC *server, gboolean once, + gboolean in_query, + int base_level, + int txt, int txt_once, + const char *nick, const char *address, + const char *data, + const char *ignore_data + ) { WINDOW_REC *window; GString *chans; GSList *tmp, *windows; char *print_channel; - int once, count, level = MSGLEVEL_QUITS; + int count, level = base_level; - if (ignore_check_plus(server, nick, address, NULL, reason, &level, TRUE)) + if (ignore_check_plus(server, nick, address, NULL, ignore_data, &level, TRUE)) return; print_channel = NULL; - once = settings_get_bool("show_quit_once"); count = 0; windows = NULL; chans = g_string_new(NULL); for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *rec; - level = MSGLEVEL_QUITS; + level = base_level; rec = tmp->data; - if (!nicklist_find(rec, nick)) + if (!nicklist_find(rec, nick)) { continue; + } if (ignore_check_plus(server, nick, address, rec->visible_name, - reason, &level, TRUE)) { + ignore_data, &level, TRUE)) { count++; continue; } if (print_channel == NULL || - active_win->active == (WI_ITEM_REC *) rec) + active_win->active == (WI_ITEM_REC *) rec) { print_channel = rec->visible_name; + } - if (once) + if (once) { g_string_append_printf(chans, "%s,", rec->visible_name); - else { + } else { window = window_item_window((WI_ITEM_REC *) rec); if (g_slist_find(windows, window) == NULL) { - windows = g_slist_append(windows, window); + windows = g_slist_prepend(windows, window); printformat(server, rec->visible_name, level, - TXT_QUIT, nick, address, reason, + txt, nick, address, data, rec->visible_name); } } @@ -423,26 +430,41 @@ static void sig_message_quit(SERVER_REC *server, const char *nick, } g_slist_free(windows); - if (!once) { + if (!once && in_query) { /* check if you had query with the nick and - display the quit there too */ + display the change there too */ QUERY_REC *query = query_find(server, nick); if (query != NULL) { printformat(server, nick, level, - TXT_QUIT, nick, address, reason, ""); + txt, nick, address, data, ""); } } if (once || count == 0) { - if (chans->len > 0) + if (chans->len > 0) { g_string_truncate(chans, chans->len-1); - printformat(server, print_channel, MSGLEVEL_QUITS, - count <= 1 ? TXT_QUIT : TXT_QUIT_ONCE, - nick, address, reason, chans->str); + } + printformat(server, print_channel, base_level, + count <= 1 ? txt : txt_once, + nick, address, data, chans->str); } g_string_free(chans, TRUE); } +static void sig_message_quit(SERVER_REC *server, const char *nick, + const char *address, const char *reason) +{ + spread_server_message_to_windows( + server, + settings_get_bool("show_quit_once"), + TRUE, + MSGLEVEL_QUITS, + TXT_QUIT, TXT_QUIT_ONCE, + nick, address, reason, + reason + ); +} + static void sig_message_kick(SERVER_REC *server, const char *channel, const char *nick, const char *kicker, const char *address, const char *reason) From da9adec47fc3a11f27f0221232c46f9f6b0d0b11 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 12 Aug 2019 23:41:18 +0200 Subject: [PATCH 0577/1198] sending of tag messages and customisable maximum irc message length --- src/irc/core/irc-channels.c | 2 +- src/irc/core/irc-servers.c | 17 +++++++-- src/irc/core/irc-servers.h | 4 +++ src/irc/core/irc.c | 60 ++++++++++++++++++++++++-------- src/irc/notifylist/notify-ison.c | 2 +- src/perl/irc/Irc.xs | 2 ++ 6 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/irc/core/irc-channels.c b/src/irc/core/irc-channels.c index 27f8f4b2..6d38c560 100644 --- a/src/irc/core/irc-channels.c +++ b/src/irc/core/irc-channels.c @@ -142,7 +142,7 @@ static void irc_channels_join(IRC_SERVER_REC *server, const char *data, /* don't try to send too long lines make sure it's not longer than 510 so 510 - strlen("JOIN ") = 505 */ - if (cmdlen < MAX_IRC_MESSAGE_LEN - 5 /* strlen("JOIN ") */) + if (cmdlen < server->max_message_len - 5 /* strlen("JOIN ") */) continue; } if (outchans->len > 0) { diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 5e98e724..38afb749 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -202,7 +202,7 @@ static char **split_message(SERVER_REC *server, const char *target, /* length calculation shamelessly stolen from splitlong_safe.pl */ return split_line(SERVER(server), msg, target, - MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :") - + ircserver->max_message_len - strlen(":! PRIVMSG :") - strlen(ircserver->nick) - MAX_USERHOST_LEN - strlen(target)); } @@ -233,6 +233,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SASL, TRUE); } + irc_cap_toggle(server, CAP_MAXLINE, TRUE); irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE); @@ -314,6 +315,8 @@ SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn) server->connrec->use_tls ? 6697 : 6667; } + server->max_message_len = MAX_IRC_MESSAGE_LEN; + server->cmd_queue_speed = ircconn->cmd_queue_speed > 0 ? ircconn->cmd_queue_speed : settings_get_time("cmd_queue_speed"); server->max_cmds_at_once = ircconn->max_cmds_at_once > 0 ? @@ -479,6 +482,14 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) g_free(recoded); } +static void cap_maxline(IRC_SERVER_REC *server) +{ + int maxline = atoi(g_hash_table_lookup(server->cap_supported, CAP_MAXLINE)); + if (maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { + server->max_message_len = maxline - 2; + } +} + void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data) { char *recoded; @@ -496,7 +507,7 @@ char **irc_server_split_action(IRC_SERVER_REC *server, const char *target, g_return_val_if_fail(data != NULL, NULL); return split_line(SERVER(server), data, target, - MAX_IRC_MESSAGE_LEN - strlen(":! PRIVMSG :\001ACTION \001") - + server->max_message_len - strlen(":! PRIVMSG :\001ACTION \001") - strlen(server->nick) - MAX_USERHOST_LEN - strlen(target)); } @@ -1033,6 +1044,7 @@ void irc_servers_init(void) signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit); + signal_add("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_add("event 001", (SIGNAL_FUNC) event_connected); signal_add("event 004", (SIGNAL_FUNC) event_server_info); signal_add("event 005", (SIGNAL_FUNC) event_isupport); @@ -1060,6 +1072,7 @@ void irc_servers_deinit(void) signal_remove("server connected", (SIGNAL_FUNC) sig_connected); signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed); signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit); + signal_remove("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_remove("event 001", (SIGNAL_FUNC) event_connected); signal_remove("event 004", (SIGNAL_FUNC) event_server_info); signal_remove("event 005", (SIGNAL_FUNC) event_isupport); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 5313c1d0..09936e91 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -15,6 +15,8 @@ #define MAX_IRC_USER_TAGS_LEN 4094 #define CAP_LS_VERSION "302" +#define CAP_MAXLINE "oragono.io/maxline-2" +#define CAP_MESSAGE_TAGS "message-tags" #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" #define CAP_EXTENDED_JOIN "extended-join" @@ -58,6 +60,8 @@ struct _IRC_SERVER_CONNECT_REC { struct _IRC_SERVER_REC { #include + int max_message_len; /* Maximum message length, default = 510 = 512 - 2 (for CR+LF) */ + /* For deciding if event should be redirected */ GSList *redirects; GSList *redirect_queue; /* should be updated from redirect_next each time cmdqueue is updated */ diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 2f520328..51770aaf 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -49,8 +49,9 @@ static void strip_params_colon(char *const); void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int send_now, int immediate, int raw) { - char str[513]; + GString *str; int len; + gboolean server_supports_tag; g_return_if_fail(server != NULL); g_return_if_fail(cmd != NULL); @@ -58,35 +59,66 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, if (server->connection_lost) return; - len = strlen(cmd); + str = g_string_sized_new(MAX_IRC_USER_TAGS_LEN + 2 /* `@'+SPACE */ + + server->max_message_len + 2 /* CR+LF */ + 1 /* `\0' */); + if (server->cmdcount == 0) irc_servers_start_cmd_timeout(); server->cmdcount++; if (!raw) { + const char *tmp = cmd; + + server_supports_tag = server->cap_supported != NULL && + g_hash_table_lookup_extended(server->cap_supported, CAP_MESSAGE_TAGS, NULL, NULL); + + if (*cmd == '@' && server_supports_tag) { + const char *end; + + while (*tmp != ' ' && *tmp != '\0') + tmp++; + + end = tmp; + + if (tmp - cmd > MAX_IRC_USER_TAGS_LEN) { + g_warning("irc_send_cmd_full(); tags too long(%ld)", tmp - cmd); + while (tmp - cmd > MAX_IRC_USER_TAGS_LEN && cmd != tmp - 1) tmp--; + while (*tmp != ',' && cmd != tmp - 1) tmp--; + } + if (cmd != tmp) + g_string_append_len(str, cmd, tmp - cmd); + + tmp = end; + while (*tmp == ' ') tmp++; + + if (*tmp != '\0' && str->len > 0) + g_string_append_c(str, ' '); + } + len = strlen(tmp); + /* check that we don't send any longer commands than 510 bytes (2 bytes for CR+LF) */ - strncpy(str, cmd, 510); - if (len > 510) len = 510; - str[len] = '\0'; - cmd = str; + g_string_append_len(str, tmp, len > server->max_message_len ? + server->max_message_len : len); + } else { + g_string_append(str, cmd); } if (send_now) { - rawlog_output(server->rawlog, cmd); - server_redirect_command(server, cmd, server->redirect_next); + rawlog_output(server->rawlog, str->str); + server_redirect_command(server, str->str, server->redirect_next); server->redirect_next = NULL; } if (!raw) { /* Add CR+LF to command */ - str[len++] = 13; - str[len++] = 10; - str[len] = '\0'; + g_string_append_c(str, 13); + g_string_append_c(str, 10); } if (send_now) { - irc_server_send_data(server, cmd, len); + irc_server_send_data(server, str->str, str->len); + g_string_free(str, TRUE); } else { /* add to queue */ @@ -94,10 +126,10 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, server->cmdqueue = g_slist_prepend(server->cmdqueue, server->redirect_next); server->cmdqueue = g_slist_prepend(server->cmdqueue, - g_strdup(cmd)); + g_string_free(str, FALSE)); } else { server->cmdqueue = g_slist_append(server->cmdqueue, - g_strdup(cmd)); + g_string_free(str, FALSE)); server->cmdqueue = g_slist_append(server->cmdqueue, server->redirect_next); } diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index 4fb9315a..910c0b73 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -131,7 +131,7 @@ static void notifylist_timeout_server(IRC_SERVER_REC *server) len = strlen(nick); - if (cmd->len+len+1 > MAX_IRC_MESSAGE_LEN) + if (cmd->len+len+1 > server->max_message_len) ison_send(server, cmd); g_string_append_printf(cmd, "%s ", nick); diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 3bf81f9a..f64d9728 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -24,6 +24,8 @@ static void perl_irc_server_fill_hash(HV *hv, IRC_SERVER_REC *server) (void) hv_store(hv, "usermode", 8, new_pv(server->usermode), 0); (void) hv_store(hv, "userhost", 8, new_pv(server->userhost), 0); + (void) hv_store(hv, "max_message_len", 15, newSViv(server->max_message_len), 0); + (void) hv_store(hv, "max_cmds_at_once", 16, newSViv(server->max_cmds_at_once), 0); (void) hv_store(hv, "cmd_queue_speed", 15, newSViv(server->cmd_queue_speed), 0); (void) hv_store(hv, "max_query_chans", 15, newSViv(server->max_query_chans), 0); From 200020da93830dc9cfd254b7984a84d25687e008 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Aug 2019 21:17:53 +0200 Subject: [PATCH 0578/1198] use better number parsing --- src/irc/core/irc-servers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 38afb749..044d676e 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -484,8 +484,10 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) static void cap_maxline(IRC_SERVER_REC *server) { - int maxline = atoi(g_hash_table_lookup(server->cap_supported, CAP_MAXLINE)); - if (maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { + unsigned int maxline = 0; + if (parse_uint(g_hash_table_lookup(server->cap_supported, CAP_MAXLINE), + NULL, 10, &maxline) && + maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { server->max_message_len = maxline - 2; } } From 6c370994078969225185bc38e1075b999b9f6bbc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 16:39:26 +0200 Subject: [PATCH 0579/1198] more variables --- src/irc/core/irc-servers.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 044d676e..2d26c271 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -485,8 +485,16 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) static void cap_maxline(IRC_SERVER_REC *server) { unsigned int maxline = 0; - if (parse_uint(g_hash_table_lookup(server->cap_supported, CAP_MAXLINE), - NULL, 10, &maxline) && + gboolean parse_successful = FALSE; + const char *maxline_str; + + maxline_str = g_hash_table_lookup(server->cap_supported, CAP_MAXLINE); + if (maxline_str != NULL) { + parse_successful = parse_uint(maxline_str, NULL, 10, &maxline); + + } + + if (parse_successful && maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { server->max_message_len = maxline - 2; } From 61d215acdd66379d8126bdd982bbfd64a7c71023 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Aug 2019 17:45:13 +0200 Subject: [PATCH 0580/1198] support cap away-notify --- src/fe-common/irc/fe-events.c | 17 ++++++++++++++ src/fe-common/irc/fe-irc-messages.c | 36 +++++++++++++++++++++++++++++ src/fe-common/irc/module-formats.c | 2 ++ src/fe-common/irc/module-formats.h | 2 ++ src/irc/core/irc-nicklist.c | 16 +++++++++++++ src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + 7 files changed, 75 insertions(+) diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index c26f2e88..aa8eaf81 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -237,6 +237,21 @@ static void event_mode(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_away_notify(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *awaymsg; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1 | PARAM_FLAG_GETREST, + &awaymsg); + + signal_emit("message irc away", 4, + server, nick, addr, awaymsg); + g_free(params); +} + static void event_pong(IRC_SERVER_REC *server, const char *data, const char *nick) { char *params, *host, *reply; @@ -458,6 +473,7 @@ void fe_events_init(void) signal_add("event error", (SIGNAL_FUNC) event_error); signal_add("event wallops", (SIGNAL_FUNC) event_wallops); signal_add("event silence", (SIGNAL_FUNC) event_silence); + signal_add("event away", (SIGNAL_FUNC) event_away_notify); signal_add("default event", (SIGNAL_FUNC) event_received); @@ -487,6 +503,7 @@ void fe_events_deinit(void) signal_remove("event error", (SIGNAL_FUNC) event_error); signal_remove("event wallops", (SIGNAL_FUNC) event_wallops); signal_remove("event silence", (SIGNAL_FUNC) event_silence); + signal_remove("event away", (SIGNAL_FUNC) event_away_notify); signal_remove("default event", (SIGNAL_FUNC) event_received); diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index ddd4311e..6218f6ac 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -295,9 +295,43 @@ static void sig_message_irc_ctcp(IRC_SERVER_REC *server, const char *cmd, IRCTXT_CTCP_REQUESTED, nick, addr, cmd, data, oldtarget); } +static void sig_message_irc_away(IRC_SERVER_REC *server, const char *nick, + const char *addr, const char *awaymsg) +{ + GSList *tmp, *windows; + + if (!settings_get_bool("away_notify_public")) + return; + + windows = NULL; + for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { + int level = MSGLEVEL_CRAP; + CHANNEL_REC *channel = tmp->data; + WINDOW_REC *window = + window_item_window((WI_ITEM_REC *) channel); + + if (nicklist_find(channel, nick) == NULL || + g_slist_find(windows, window) != NULL) + continue; + + if (ignore_check_plus(SERVER(server), nick, addr, + channel->visible_name, awaymsg, &level, TRUE)) + continue; + + windows = g_slist_prepend(windows, window); + + printformat(server, channel->visible_name, level, + *awaymsg == '\0' ? IRCTXT_NOTIFY_UNAWAY_CHANNEL : + IRCTXT_NOTIFY_AWAY_CHANNEL, + nick, addr, channel->visible_name, awaymsg); + } + g_slist_free(windows); +} + void fe_irc_messages_init(void) { settings_add_bool("misc", "notice_channel_context", TRUE); + settings_add_bool("lookandfeel", "away_notify_public", FALSE); signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); signal_add_last("message irc op_public", (SIGNAL_FUNC) sig_message_irc_op_public); @@ -308,6 +342,7 @@ void fe_irc_messages_init(void) signal_add_last("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); signal_add_last("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); signal_add_last("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); + signal_add_last("message irc away", (SIGNAL_FUNC) sig_message_irc_away); } void fe_irc_messages_deinit(void) @@ -321,4 +356,5 @@ void fe_irc_messages_deinit(void) signal_remove("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); signal_remove("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); signal_remove("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); + signal_remove("message irc away", (SIGNAL_FUNC) sig_message_irc_away); } diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index a0f6bd29..50f39d8e 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -95,6 +95,8 @@ FORMAT_REC fecommon_irc_formats[] = { { "away", "You have been marked as being away", 0 }, { "unaway", "You are no longer marked as being away", 0 }, { "nick_away", "{nick $0} is away: $1", 2, { 0, 0 } }, + { "notify_away_channel", "{channick $0} {chanhost $1} is now away: {reason $3}", 4, { 0, 0, 0, 0 } }, + { "notify_unaway_channel", "{channick_hilight $0} {chanhost $1} is no longer away", 3, { 0, 0, 0 } }, { "no_such_nick", "{nick $0}: No such nick/channel", 1, { 0 } }, { "nick_in_use", "Nick {nick $0} is already in use", 1, { 0 } }, { "nick_unavailable", "Nick {nick $0} is temporarily unavailable", 1, { 0 } }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 66a9804f..b9a89bc0 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -71,6 +71,8 @@ enum { IRCTXT_AWAY, IRCTXT_UNAWAY, IRCTXT_NICK_AWAY, + IRCTXT_NOTIFY_AWAY_CHANNEL, + IRCTXT_NOTIFY_UNAWAY_CHANNEL, IRCTXT_NO_SUCH_NICK, IRCTXT_NICK_IN_USE, IRCTXT_NICK_UNAVAILABLE, diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 9073ddaa..28ac6368 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -467,6 +467,20 @@ static void event_setname(SERVER_REC *server, const char *data, const char *nick g_slist_free(nicks); } +static void event_away_notify(IRC_SERVER_REC *server, const char *data, const char *nick, const char *add) +{ + char *params, *awaymsg; + + if (!IS_IRC_SERVER(server)) + return; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1 | PARAM_FLAG_GETREST, &awaymsg); + nicklist_update_flags(SERVER(server), nick, *awaymsg != '\0', -1); + g_free(params); +} + static void sig_usermode(SERVER_REC *server) { g_return_if_fail(IS_SERVER(server)); @@ -507,6 +521,7 @@ void irc_nicklist_init(void) signal_add_first("event 433", (SIGNAL_FUNC) event_nick_in_use); signal_add_first("event 437", (SIGNAL_FUNC) event_target_unavailable); signal_add_first("event 302", (SIGNAL_FUNC) event_userhost); + signal_add_first("event away", (SIGNAL_FUNC) event_away_notify); signal_add("userhost event", (SIGNAL_FUNC) event_userhost); signal_add("event setname", (SIGNAL_FUNC) event_setname); signal_add("user mode changed", (SIGNAL_FUNC) sig_usermode); @@ -530,6 +545,7 @@ void irc_nicklist_deinit(void) signal_remove("event 433", (SIGNAL_FUNC) event_nick_in_use); signal_remove("event 437", (SIGNAL_FUNC) event_target_unavailable); signal_remove("event 302", (SIGNAL_FUNC) event_userhost); + signal_remove("event away", (SIGNAL_FUNC) event_away_notify); signal_remove("userhost event", (SIGNAL_FUNC) event_userhost); signal_remove("event setname", (SIGNAL_FUNC) event_setname); signal_remove("user mode changed", (SIGNAL_FUNC) sig_usermode); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 5e98e724..16095ed3 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -237,6 +237,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE); irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); + irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 5313c1d0..3fccfe9e 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -20,6 +20,7 @@ #define CAP_EXTENDED_JOIN "extended-join" #define CAP_SETNAME "draft/setname" #define CAP_INVITE_NOTIFY "invite-notify" +#define CAP_AWAY_NOTIFY "away-notify" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ From 5f13614d47198dd7013502ef5c4ead0cffa87978 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Aug 2019 22:52:38 +0200 Subject: [PATCH 0581/1198] move away message to fe-common/core --- src/fe-common/core/fe-messages.c | 22 ++++++++++++++++++ src/fe-common/core/module-formats.c | 2 ++ src/fe-common/core/module-formats.h | 2 ++ src/fe-common/irc/fe-events.c | 2 +- src/fe-common/irc/fe-irc-messages.c | 36 ----------------------------- src/fe-common/irc/module-formats.c | 2 -- src/fe-common/irc/module-formats.h | 2 -- 7 files changed, 27 insertions(+), 41 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 308680d6..9545af73 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -587,6 +587,25 @@ static void sig_message_topic(SERVER_REC *server, const char *channel, nick, channel, topic, address); } +static void sig_message_away_notify(SERVER_REC *server, const char *nick, + const char *addr, const char *awaymsg) +{ + int txt = *awaymsg == '\0' ? TXT_NOTIFY_UNAWAY_CHANNEL : + TXT_NOTIFY_AWAY_CHANNEL; + + if (!settings_get_bool("away_notify_public")) + return; + + spread_server_message_to_windows(server, FALSE, + FALSE, + MSGLEVEL_CRAP, + txt, txt, + nick, addr, + awaymsg, + awaymsg + ); +} + static int printnick_exists(NICK_REC *first, NICK_REC *ignore, const char *nick) { @@ -730,6 +749,7 @@ void fe_messages_init(void) settings_add_bool("lookandfeel", "print_active_channel", FALSE); settings_add_bool("lookandfeel", "show_quit_once", FALSE); settings_add_bool("lookandfeel", "show_own_nickchange_once", FALSE); + settings_add_bool("lookandfeel", "away_notify_public", FALSE); signal_add_last("message public", (SIGNAL_FUNC) sig_message_public); signal_add_last("message private", (SIGNAL_FUNC) sig_message_private); @@ -744,6 +764,7 @@ void fe_messages_init(void) signal_add_last("message invite", (SIGNAL_FUNC) sig_message_invite); signal_add_last("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_add_last("message topic", (SIGNAL_FUNC) sig_message_topic); + signal_add_last("message away_notify", (SIGNAL_FUNC) sig_message_away_notify); signal_add("nicklist new", (SIGNAL_FUNC) sig_nicklist_new); signal_add("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove); @@ -770,6 +791,7 @@ void fe_messages_deinit(void) signal_remove("message invite_other", (SIGNAL_FUNC) sig_message_invite_other); signal_remove("message invite", (SIGNAL_FUNC) sig_message_invite); signal_remove("message topic", (SIGNAL_FUNC) sig_message_topic); + signal_remove("message away_notify", (SIGNAL_FUNC) sig_message_away_notify); signal_remove("nicklist new", (SIGNAL_FUNC) sig_nicklist_new); signal_remove("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 2532d82f..83eae589 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -106,6 +106,8 @@ FORMAT_REC fecommon_core_formats[] = { { "topic_unset", "Topic unset by {nick $0} on {channel $1}", 4, { 0, 0, 0, 0 } }, { "your_nick_changed", "You're now known as {nick $1}", 4, { 0, 0, 0, 0 } }, { "nick_changed", "{channick $0} is now known as {channick_hilight $1}", 4, { 0, 0, 0, 0 } }, + { "notify_away_channel", "{channick $0} {chanhost $1} is now away: {reason $2}", 4, { 0, 0, 0, 0 } }, + { "notify_unaway_channel", "{channick_hilight $0} {chanhost $1} is no longer away", 4, { 0, 0, 0, 0 } }, { "talking_in", "You are now talking in {channel $0}", 1, { 0 } }, { "not_in_channels", "You are not on any channels", 0 }, { "current_channel", "Current channel {channel $0}", 1, { 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index c5e2c4d1..74a4dfd9 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -82,6 +82,8 @@ enum { TXT_TOPIC_UNSET, TXT_YOUR_NICK_CHANGED, TXT_NICK_CHANGED, + TXT_NOTIFY_AWAY_CHANNEL, + TXT_NOTIFY_UNAWAY_CHANNEL, TXT_TALKING_IN, TXT_NOT_IN_CHANNELS, TXT_CURRENT_CHANNEL, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index aa8eaf81..4608b949 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -247,7 +247,7 @@ static void event_away_notify(IRC_SERVER_REC *server, const char *data, params = event_get_params(data, 1 | PARAM_FLAG_GETREST, &awaymsg); - signal_emit("message irc away", 4, + signal_emit("message away_notify", 4, server, nick, addr, awaymsg); g_free(params); } diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 6218f6ac..ddd4311e 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -295,43 +295,9 @@ static void sig_message_irc_ctcp(IRC_SERVER_REC *server, const char *cmd, IRCTXT_CTCP_REQUESTED, nick, addr, cmd, data, oldtarget); } -static void sig_message_irc_away(IRC_SERVER_REC *server, const char *nick, - const char *addr, const char *awaymsg) -{ - GSList *tmp, *windows; - - if (!settings_get_bool("away_notify_public")) - return; - - windows = NULL; - for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { - int level = MSGLEVEL_CRAP; - CHANNEL_REC *channel = tmp->data; - WINDOW_REC *window = - window_item_window((WI_ITEM_REC *) channel); - - if (nicklist_find(channel, nick) == NULL || - g_slist_find(windows, window) != NULL) - continue; - - if (ignore_check_plus(SERVER(server), nick, addr, - channel->visible_name, awaymsg, &level, TRUE)) - continue; - - windows = g_slist_prepend(windows, window); - - printformat(server, channel->visible_name, level, - *awaymsg == '\0' ? IRCTXT_NOTIFY_UNAWAY_CHANNEL : - IRCTXT_NOTIFY_AWAY_CHANNEL, - nick, addr, channel->visible_name, awaymsg); - } - g_slist_free(windows); -} - void fe_irc_messages_init(void) { settings_add_bool("misc", "notice_channel_context", TRUE); - settings_add_bool("lookandfeel", "away_notify_public", FALSE); signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); signal_add_last("message irc op_public", (SIGNAL_FUNC) sig_message_irc_op_public); @@ -342,7 +308,6 @@ void fe_irc_messages_init(void) signal_add_last("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); signal_add_last("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); signal_add_last("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); - signal_add_last("message irc away", (SIGNAL_FUNC) sig_message_irc_away); } void fe_irc_messages_deinit(void) @@ -356,5 +321,4 @@ void fe_irc_messages_deinit(void) signal_remove("message irc notice", (SIGNAL_FUNC) sig_message_irc_notice); signal_remove("message irc own_ctcp", (SIGNAL_FUNC) sig_message_own_ctcp); signal_remove("message irc ctcp", (SIGNAL_FUNC) sig_message_irc_ctcp); - signal_remove("message irc away", (SIGNAL_FUNC) sig_message_irc_away); } diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index 50f39d8e..a0f6bd29 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -95,8 +95,6 @@ FORMAT_REC fecommon_irc_formats[] = { { "away", "You have been marked as being away", 0 }, { "unaway", "You are no longer marked as being away", 0 }, { "nick_away", "{nick $0} is away: $1", 2, { 0, 0 } }, - { "notify_away_channel", "{channick $0} {chanhost $1} is now away: {reason $3}", 4, { 0, 0, 0, 0 } }, - { "notify_unaway_channel", "{channick_hilight $0} {chanhost $1} is no longer away", 3, { 0, 0, 0 } }, { "no_such_nick", "{nick $0}: No such nick/channel", 1, { 0 } }, { "nick_in_use", "Nick {nick $0} is already in use", 1, { 0 } }, { "nick_unavailable", "Nick {nick $0} is temporarily unavailable", 1, { 0 } }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index b9a89bc0..66a9804f 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -71,8 +71,6 @@ enum { IRCTXT_AWAY, IRCTXT_UNAWAY, IRCTXT_NICK_AWAY, - IRCTXT_NOTIFY_AWAY_CHANNEL, - IRCTXT_NOTIFY_UNAWAY_CHANNEL, IRCTXT_NO_SUCH_NICK, IRCTXT_NICK_IN_USE, IRCTXT_NICK_UNAVAILABLE, From 4dbbbf47a4b9e867fd63d8e4b5acc0e489a84bdc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 02:52:26 +0200 Subject: [PATCH 0582/1198] add chghost capability support --- src/fe-common/core/fe-ignore-messages.c | 9 +++++++++ src/fe-common/core/fe-messages.c | 16 +++++++++++++++ src/fe-common/core/module-formats.c | 1 + src/fe-common/core/module-formats.h | 1 + src/fe-common/irc/fe-events.c | 19 ++++++++++++++++++ src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + src/irc/core/massjoin.c | 26 +++++++++++++++++++++++++ 8 files changed, 74 insertions(+) diff --git a/src/fe-common/core/fe-ignore-messages.c b/src/fe-common/core/fe-ignore-messages.c index 6bcfb6da..4f625dec 100644 --- a/src/fe-common/core/fe-ignore-messages.c +++ b/src/fe-common/core/fe-ignore-messages.c @@ -46,6 +46,13 @@ static void sig_message_join(SERVER_REC *server, const char *channel, signal_stop(); } +static void sig_message_host_changed(SERVER_REC *server, const char *nick, + const char *address, const char *old_address) +{ + if (ignore_check(server, nick, address, NULL, NULL, MSGLEVEL_JOINS)) + signal_stop(); +} + static void sig_message_part(SERVER_REC *server, const char *channel, const char *nick, const char *address, const char *reason) @@ -120,6 +127,7 @@ void fe_ignore_messages_init(void) signal_add_first("message public", (SIGNAL_FUNC) sig_message_public); signal_add_first("message private", (SIGNAL_FUNC) sig_message_private); signal_add_first("message join", (SIGNAL_FUNC) sig_message_join); + signal_add_first("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); signal_add_first("message part", (SIGNAL_FUNC) sig_message_part); signal_add_first("message quit", (SIGNAL_FUNC) sig_message_quit); signal_add_first("message kick", (SIGNAL_FUNC) sig_message_kick); @@ -135,6 +143,7 @@ void fe_ignore_messages_deinit(void) signal_remove("message public", (SIGNAL_FUNC) sig_message_public); signal_remove("message private", (SIGNAL_FUNC) sig_message_private); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); + signal_remove("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); signal_remove("message part", (SIGNAL_FUNC) sig_message_part); signal_remove("message quit", (SIGNAL_FUNC) sig_message_quit); signal_remove("message kick", (SIGNAL_FUNC) sig_message_kick); diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 9545af73..17a81e56 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -451,6 +451,20 @@ static void spread_server_message_to_windows(SERVER_REC *server, gboolean once, g_string_free(chans, TRUE); } +static void sig_message_host_changed(SERVER_REC *server, const char *nick, + const char *address, const char *old_address) +{ + spread_server_message_to_windows( + server, + settings_get_bool("show_quit_once"), + TRUE, + MSGLEVEL_JOINS, + TXT_HOST_CHANGED, TXT_HOST_CHANGED, + nick, address, old_address, + NULL + ); +} + static void sig_message_quit(SERVER_REC *server, const char *nick, const char *address, const char *reason) { @@ -756,6 +770,7 @@ void fe_messages_init(void) signal_add_last("message own_public", (SIGNAL_FUNC) sig_message_own_public); signal_add_last("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_add_last("message join", (SIGNAL_FUNC) sig_message_join); + signal_add_last("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); signal_add_last("message part", (SIGNAL_FUNC) sig_message_part); signal_add_last("message quit", (SIGNAL_FUNC) sig_message_quit); signal_add_last("message kick", (SIGNAL_FUNC) sig_message_kick); @@ -783,6 +798,7 @@ void fe_messages_deinit(void) signal_remove("message own_public", (SIGNAL_FUNC) sig_message_own_public); signal_remove("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); + signal_remove("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); signal_remove("message part", (SIGNAL_FUNC) sig_message_part); signal_remove("message quit", (SIGNAL_FUNC) sig_message_quit); signal_remove("message kick", (SIGNAL_FUNC) sig_message_kick); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 83eae589..69507c21 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -95,6 +95,7 @@ FORMAT_REC fecommon_core_formats[] = { { NULL, "Channels", 0 }, { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, + { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} host changed", 4, { 0, 0, 0, 0 } }, { "part", "{channick $0} {chanhost $1} has left {channel $2} {reason $3}", 4, { 0, 0, 0, 0 } }, { "kick", "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}", 5, { 0, 0, 0, 0, 0 } }, { "quit", "{channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index 74a4dfd9..dc51e638 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -71,6 +71,7 @@ enum { TXT_FILL_3, TXT_JOIN, + TXT_HOST_CHANGED, TXT_PART, TXT_KICK, TXT_QUIT, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index 4608b949..a8aea027 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -126,6 +126,23 @@ static void event_join(IRC_SERVER_REC *server, const char *data, g_free(params); } + +static void event_chghost(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *user, *host, *new_addr; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &user, &host); + new_addr = g_strconcat(user, "@", host, NULL); + + signal_emit("message host_changed", 4, server, nick, new_addr, addr); + + g_free(new_addr); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -461,6 +478,7 @@ void fe_events_init(void) signal_add("ctcp action", (SIGNAL_FUNC) ctcp_action); signal_add("event notice", (SIGNAL_FUNC) event_notice); signal_add("event join", (SIGNAL_FUNC) event_join); + signal_add("event chghost", (SIGNAL_FUNC) event_chghost); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event quit", (SIGNAL_FUNC) event_quit); signal_add("event kick", (SIGNAL_FUNC) event_kick); @@ -491,6 +509,7 @@ void fe_events_deinit(void) signal_remove("ctcp action", (SIGNAL_FUNC) ctcp_action); signal_remove("event notice", (SIGNAL_FUNC) event_notice); signal_remove("event join", (SIGNAL_FUNC) event_join); + signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event quit", (SIGNAL_FUNC) event_quit); signal_remove("event kick", (SIGNAL_FUNC) event_kick); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 16095ed3..799b4441 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -238,6 +238,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SETNAME, TRUE); irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); + irc_cap_toggle(server, CAP_CHGHOST, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 3fccfe9e..b709edab 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -21,6 +21,7 @@ #define CAP_SETNAME "draft/setname" #define CAP_INVITE_NOTIFY "invite-notify" #define CAP_AWAY_NOTIFY "away-notify" +#define CAP_CHGHOST "chghost" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 4a3f085d..271ecddc 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -106,6 +106,30 @@ static void event_join(IRC_SERVER_REC *server, const char *data, chanrec->massjoins++; } +static void event_chghost(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *old_address) +{ + char *params, *user, *host, *address; + GSList *nicks, *tmp; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, &user, &host); + + /* check that the nick isn't already in nicklist. seems to happen + sometimes (server desyncs or something?) */ + nicks = nicklist_get_same(SERVER(server), nick); + address = nicks != NULL ? g_strconcat(user, "@", host, NULL) : NULL; + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + nicklist_set_host(CHANNEL(tmp->data), rec, address); + } + g_free(address); + g_slist_free(nicks); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -291,6 +315,7 @@ void massjoin_init(void) read_settings(); signal_add_first("event join", (SIGNAL_FUNC) event_join); + signal_add("event chghost", (SIGNAL_FUNC) event_chghost); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event kick", (SIGNAL_FUNC) event_kick); signal_add("event quit", (SIGNAL_FUNC) event_quit); @@ -302,6 +327,7 @@ void massjoin_deinit(void) g_source_remove(massjoin_tag); signal_remove("event join", (SIGNAL_FUNC) event_join); + signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event kick", (SIGNAL_FUNC) event_kick); signal_remove("event quit", (SIGNAL_FUNC) event_quit); From 8f65f58a4a7edb0016117d005b5a6c4b04b156e6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 14 Aug 2019 21:21:17 +0200 Subject: [PATCH 0583/1198] improve message wording --- src/fe-common/core/module-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 69507c21..094246a1 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -95,7 +95,7 @@ FORMAT_REC fecommon_core_formats[] = { { NULL, "Channels", 0 }, { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, - { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} host changed", 4, { 0, 0, 0, 0 } }, + { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} has changed host", 4, { 0, 0, 0, 0 } }, { "part", "{channick $0} {chanhost $1} has left {channel $2} {reason $3}", 4, { 0, 0, 0, 0 } }, { "kick", "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}", 5, { 0, 0, 0, 0, 0 } }, { "quit", "{channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, From 44d480ca991a7906fd8b09944dd3307c941522a8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 03:36:40 +0200 Subject: [PATCH 0584/1198] use account-notify capability --- src/core/nicklist.c | 8 ++++++++ src/core/nicklist.h | 1 + src/fe-common/core/fe-messages.c | 22 ++++++++++++++++++++++ src/fe-common/core/module-formats.c | 2 ++ src/fe-common/core/module-formats.h | 2 ++ src/fe-common/irc/fe-events.c | 17 ++++++++++++++++- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + src/irc/core/massjoin.c | 24 ++++++++++++++++++++++-- 9 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/core/nicklist.c b/src/core/nicklist.c index bf845c0d..528f2286 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -101,6 +101,14 @@ void nicklist_set_host(CHANNEL_REC *channel, NICK_REC *nick, const char *host) signal_emit("nicklist host changed", 2, channel, nick); } +void nicklist_set_account(CHANNEL_REC *channel, NICK_REC *nick, const char *account) +{ + g_free(nick->account); + nick->account = g_strdup(account); + + signal_emit("nicklist account changed", 2, channel, nick); +} + static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick) { signal_emit("nicklist remove", 2, channel, nick); diff --git a/src/core/nicklist.h b/src/core/nicklist.h index 62afa5ff..7999be0a 100644 --- a/src/core/nicklist.h +++ b/src/core/nicklist.h @@ -18,6 +18,7 @@ struct _NICK_REC { void nicklist_insert(CHANNEL_REC *channel, NICK_REC *nick); /* Set host address for nick */ void nicklist_set_host(CHANNEL_REC *channel, NICK_REC *nick, const char *host); +void nicklist_set_account(CHANNEL_REC *channel, NICK_REC *nick, const char *account); /* Remove nick from list */ void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick); /* Change nick */ diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 17a81e56..af724a1b 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -465,6 +465,26 @@ static void sig_message_host_changed(SERVER_REC *server, const char *nick, ); } +static void sig_message_account_changed(SERVER_REC *server, const char *nick, + const char *address, const char *account) +{ + gboolean logged_in; + int txt; + + logged_in = g_strcmp0("*", account) != 0; + txt = logged_in ? TXT_LOGGED_IN : TXT_LOGGED_OUT; + + spread_server_message_to_windows( + server, + settings_get_bool("show_quit_once"), + TRUE, + MSGLEVEL_MODES, + txt, txt, + nick, address, account, + "account" + ); +} + static void sig_message_quit(SERVER_REC *server, const char *nick, const char *address, const char *reason) { @@ -771,6 +791,7 @@ void fe_messages_init(void) signal_add_last("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_add_last("message join", (SIGNAL_FUNC) sig_message_join); signal_add_last("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); + signal_add_last("message account_changed", (SIGNAL_FUNC) sig_message_account_changed); signal_add_last("message part", (SIGNAL_FUNC) sig_message_part); signal_add_last("message quit", (SIGNAL_FUNC) sig_message_quit); signal_add_last("message kick", (SIGNAL_FUNC) sig_message_kick); @@ -799,6 +820,7 @@ void fe_messages_deinit(void) signal_remove("message own_private", (SIGNAL_FUNC) sig_message_own_private); signal_remove("message join", (SIGNAL_FUNC) sig_message_join); signal_remove("message host_changed", (SIGNAL_FUNC) sig_message_host_changed); + signal_remove("message account_changed", (SIGNAL_FUNC) sig_message_account_changed); signal_remove("message part", (SIGNAL_FUNC) sig_message_part); signal_remove("message quit", (SIGNAL_FUNC) sig_message_quit); signal_remove("message kick", (SIGNAL_FUNC) sig_message_kick); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index 094246a1..a5e99619 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -96,6 +96,8 @@ FORMAT_REC fecommon_core_formats[] = { { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} has changed host", 4, { 0, 0, 0, 0 } }, + { "logged_out", "{channick $0} {chanhost $1} has logged out of their account", 4, { 0, 0, 0, 0 } }, + { "logged_in", "{channick_hilight $0} {chanhost_hilight $1} has logged in to account {hilight $2}", 4, { 0, 0, 0, 0 } }, { "part", "{channick $0} {chanhost $1} has left {channel $2} {reason $3}", 4, { 0, 0, 0, 0 } }, { "kick", "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}", 5, { 0, 0, 0, 0, 0 } }, { "quit", "{channick $0} {chanhost $1} has quit {reason $2}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index dc51e638..b1cf1578 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -72,6 +72,8 @@ enum { TXT_JOIN, TXT_HOST_CHANGED, + TXT_LOGGED_OUT, + TXT_LOGGED_IN, TXT_PART, TXT_KICK, TXT_QUIT, diff --git a/src/fe-common/irc/fe-events.c b/src/fe-common/irc/fe-events.c index a8aea027..b6b3e75a 100644 --- a/src/fe-common/irc/fe-events.c +++ b/src/fe-common/irc/fe-events.c @@ -126,7 +126,6 @@ static void event_join(IRC_SERVER_REC *server, const char *data, g_free(params); } - static void event_chghost(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -143,6 +142,20 @@ static void event_chghost(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_account(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *addr) +{ + char *params, *account; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &account); + + signal_emit("message account_changed", 4, server, nick, addr, account); + + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -479,6 +492,7 @@ void fe_events_init(void) signal_add("event notice", (SIGNAL_FUNC) event_notice); signal_add("event join", (SIGNAL_FUNC) event_join); signal_add("event chghost", (SIGNAL_FUNC) event_chghost); + signal_add("event account", (SIGNAL_FUNC) event_account); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event quit", (SIGNAL_FUNC) event_quit); signal_add("event kick", (SIGNAL_FUNC) event_kick); @@ -510,6 +524,7 @@ void fe_events_deinit(void) signal_remove("event notice", (SIGNAL_FUNC) event_notice); signal_remove("event join", (SIGNAL_FUNC) event_join); signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); + signal_remove("event account", (SIGNAL_FUNC) event_account); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event quit", (SIGNAL_FUNC) event_quit); signal_remove("event kick", (SIGNAL_FUNC) event_kick); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 799b4441..a066113f 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -239,6 +239,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_INVITE_NOTIFY, TRUE); irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); irc_cap_toggle(server, CAP_CHGHOST, TRUE); + irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index b709edab..1a6f9595 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -22,6 +22,7 @@ #define CAP_INVITE_NOTIFY "invite-notify" #define CAP_AWAY_NOTIFY "away-notify" #define CAP_CHGHOST "chghost" +#define CAP_ACCOUNT_NOTIFY "account-notify" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 271ecddc..52b0e86a 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -68,8 +68,7 @@ static void event_join(IRC_SERVER_REC *server, const char *data, /* add user to nicklist */ nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, TRUE, NULL); if (*account != '\0' && g_strcmp0(nickrec->account, account) != 0) { - g_free(nickrec->account); - nickrec->account = g_strdup(account); + nicklist_set_account(CHANNEL(chanrec), nickrec, account); } nicklist_set_host(CHANNEL(chanrec), nickrec, address); @@ -130,6 +129,25 @@ static void event_chghost(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_account(IRC_SERVER_REC *server, const char *data, + const char *nick, const char *address) +{ + char *params, *account; + GSList *nicks, *tmp; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 1, &account); + nicks = nicklist_get_same(SERVER(server), nick); + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + nicklist_set_account(CHANNEL(tmp->data), rec, account); + } + g_slist_free(nicks); + g_free(params); +} + static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { @@ -316,6 +334,7 @@ void massjoin_init(void) read_settings(); signal_add_first("event join", (SIGNAL_FUNC) event_join); signal_add("event chghost", (SIGNAL_FUNC) event_chghost); + signal_add("event account", (SIGNAL_FUNC) event_account); signal_add("event part", (SIGNAL_FUNC) event_part); signal_add("event kick", (SIGNAL_FUNC) event_kick); signal_add("event quit", (SIGNAL_FUNC) event_quit); @@ -328,6 +347,7 @@ void massjoin_deinit(void) signal_remove("event join", (SIGNAL_FUNC) event_join); signal_remove("event chghost", (SIGNAL_FUNC) event_chghost); + signal_remove("event account", (SIGNAL_FUNC) event_account); signal_remove("event part", (SIGNAL_FUNC) event_part); signal_remove("event kick", (SIGNAL_FUNC) event_kick); signal_remove("event quit", (SIGNAL_FUNC) event_quit); From e20900a7cacafb05494f7179caf32868f7918c2e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 17:23:58 +0200 Subject: [PATCH 0585/1198] make a setting to disable account-notify --- src/fe-common/core/fe-messages.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index af724a1b..3d8651f9 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -471,6 +471,9 @@ static void sig_message_account_changed(SERVER_REC *server, const char *nick, gboolean logged_in; int txt; + if (!settings_get_bool("show_account_notify")) + return; + logged_in = g_strcmp0("*", account) != 0; txt = logged_in ? TXT_LOGGED_IN : TXT_LOGGED_OUT; @@ -784,6 +787,7 @@ void fe_messages_init(void) settings_add_bool("lookandfeel", "show_quit_once", FALSE); settings_add_bool("lookandfeel", "show_own_nickchange_once", FALSE); settings_add_bool("lookandfeel", "away_notify_public", FALSE); + settings_add_bool("lookandfeel", "show_account_notify", FALSE); signal_add_last("message public", (SIGNAL_FUNC) sig_message_public); signal_add_last("message private", (SIGNAL_FUNC) sig_message_private); From b6f1bf8fcddc67415fc6c74acad7f12faab1e3e5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 21:32:57 +0200 Subject: [PATCH 0586/1198] fix autotools build --- src/fe-common/irc/Makefile.am | 2 -- src/irc/Makefile.am | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index f14d6942..9efb71d3 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -37,5 +37,3 @@ pkginc_fe_common_irc_HEADERS = \ fe-irc-channels.h \ module.h \ module-formats.h - -DISTFILES = $(DIST_COMMON) $(real_sources) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) diff --git a/src/irc/Makefile.am b/src/irc/Makefile.am index 9eda2a2f..78a38643 100644 --- a/src/irc/Makefile.am +++ b/src/irc/Makefile.am @@ -7,5 +7,3 @@ SUBDIRS = core dcc flood notifylist $(PROXY) noinst_LIBRARIES = libirc.a libirc_a_SOURCES = irc.c - -DISTFILES = $(DIST_COMMON) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) From 587098199efc05a98b05ca2660a12ed16fc42cbb Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 15 Aug 2019 22:42:48 +0200 Subject: [PATCH 0587/1198] fix wrong version --- utils/irssi-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/irssi-version.sh b/utils/irssi-version.sh index 466a29fd..41970cb2 100755 --- a/utils/irssi-version.sh +++ b/utils/irssi-version.sh @@ -1,6 +1,6 @@ #!/bin/sh -DATE=`GIT_DIR=$1/.git git log -1 --pretty=format:%ai HEAD 2>/dev/null` +DATE=`GIT_DIR=$1/.git git log -1 --pretty=format:%ci HEAD 2>/dev/null` VERSION_DATE=`echo $DATE | cut -f 1 -d ' ' | tr -d -` VERSION_TIME=`echo $DATE | cut -f 2 -d ' ' | awk -F: '{printf "%d", $1$2}'` From 255d850c4df7d6c681c0f45443c19718ef55410c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Aug 2019 21:19:20 +0200 Subject: [PATCH 0588/1198] fix crash in setname --- src/irc/core/irc-nicklist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 28ac6368..2e210382 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -454,6 +454,7 @@ static void event_setname(SERVER_REC *server, const char *data, const char *nick if (!IS_IRC_SERVER(server)) return; + g_return_if_fail(nick != NULL); g_return_if_fail(data != NULL); if (*data == ':') data++; From d5329bc811d077eabe3e4bda397be17faba5ab0e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Aug 2019 21:37:53 +0200 Subject: [PATCH 0589/1198] fix crashes when nick is missing --- src/irc/core/irc-nicklist.c | 1 + src/irc/core/massjoin.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 2e210382..cc630a58 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -475,6 +475,7 @@ static void event_away_notify(IRC_SERVER_REC *server, const char *data, const ch if (!IS_IRC_SERVER(server)) return; + g_return_if_fail(nick != NULL); g_return_if_fail(data != NULL); params = event_get_params(data, 1 | PARAM_FLAG_GETREST, &awaymsg); diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 52b0e86a..be406d3d 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -111,6 +111,7 @@ static void event_chghost(IRC_SERVER_REC *server, const char *data, char *params, *user, *host, *address; GSList *nicks, *tmp; + g_return_if_fail(nick != NULL); g_return_if_fail(data != NULL); params = event_get_params(data, 2, &user, &host); @@ -135,6 +136,7 @@ static void event_account(IRC_SERVER_REC *server, const char *data, char *params, *account; GSList *nicks, *tmp; + g_return_if_fail(nick != NULL); g_return_if_fail(data != NULL); params = event_get_params(data, 1, &account); From 504d50c9a3aad5a45def3177d65946f637eae452 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Aug 2019 22:40:49 +0200 Subject: [PATCH 0590/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 672e5e6c..8a9713ce 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 22 +#define IRSSI_ABI_VERSION 23 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 38df7bfd29cb6aefa149bb7a48cb469782d9eab0 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 18 Aug 2019 11:24:48 +0200 Subject: [PATCH 0591/1198] make extended account info visible and formattable --- src/fe-common/core/fe-messages.c | 14 ++++++++++++-- src/fe-common/core/module-formats.c | 2 ++ src/fe-common/core/module-formats.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 3d8651f9..c1d87b2b 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -356,8 +356,17 @@ static void sig_message_join(SERVER_REC *server, const char *channel, ignore_check_plus(server, nick, address, channel, NULL, &level, FALSE); - printformat(server, channel, level, - TXT_JOIN, nick, address, channel, account, realname); + if (settings_get_bool("show_extended_join")) { + int txt; + if (*account == '\0') txt = TXT_JOIN; + else if (g_strcmp0("*", account) == 0) txt = TXT_JOIN_EXTENDED; + else txt = TXT_JOIN_EXTENDED_ACCOUNT; + printformat(server, channel, level, + txt, nick, address, channel, account, realname); + } else { + printformat(server, channel, level, + TXT_JOIN, nick, address, channel, account, realname); + } } static void sig_message_part(SERVER_REC *server, const char *channel, @@ -787,6 +796,7 @@ void fe_messages_init(void) settings_add_bool("lookandfeel", "show_quit_once", FALSE); settings_add_bool("lookandfeel", "show_own_nickchange_once", FALSE); settings_add_bool("lookandfeel", "away_notify_public", FALSE); + settings_add_bool("lookandfeel", "show_extended_join", FALSE); settings_add_bool("lookandfeel", "show_account_notify", FALSE); signal_add_last("message public", (SIGNAL_FUNC) sig_message_public); diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index a5e99619..0319ee11 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -95,6 +95,8 @@ FORMAT_REC fecommon_core_formats[] = { { NULL, "Channels", 0 }, { "join", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}", 5, { 0, 0, 0, 0, 0 } }, + { "join_extended", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2} {comment realname {reason $4}}", 5, { 0, 0, 0, 0, 0 } }, + { "join_extended_account", "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2} {reason account {hilight $3}} {comment realname {reason $4}}", 5, { 0, 0, 0, 0, 0 } }, { "host_changed", "{channick_hilight $0} {chanhost_hilight $1} has changed host", 4, { 0, 0, 0, 0 } }, { "logged_out", "{channick $0} {chanhost $1} has logged out of their account", 4, { 0, 0, 0, 0 } }, { "logged_in", "{channick_hilight $0} {chanhost_hilight $1} has logged in to account {hilight $2}", 4, { 0, 0, 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index b1cf1578..1b1927b1 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -71,6 +71,8 @@ enum { TXT_FILL_3, TXT_JOIN, + TXT_JOIN_EXTENDED, + TXT_JOIN_EXTENDED_ACCOUNT, TXT_HOST_CHANGED, TXT_LOGGED_OUT, TXT_LOGGED_IN, From e18708243bbb26c130ef7984103427604bd215c1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Aug 2019 15:29:29 +0000 Subject: [PATCH 0592/1198] Migrate push workflow to yaml --- .github/workflows/push.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/push.yml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..71b388a2 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,21 @@ +on: [push] +name: Check Irssi +jobs: + install: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: install + uses: irssi-import/actions-irssi/check-irssi@master + with: + args: before_install install + - name: unit_tests + uses: irssi-import/actions-irssi/check-irssi@master + with: + args: unit_tests after_unit_tests + - name: script + uses: irssi-import/actions-irssi/check-irssi@master + env: + TERM: xterm + with: + args: before_script script after_script From 7abec34668b8b34d0f0437e910cbae74abbf6da3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 16 Aug 2019 15:31:18 +0000 Subject: [PATCH 0593/1198] delete old workflow file --- .github/main.workflow | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 .github/main.workflow diff --git a/.github/main.workflow b/.github/main.workflow deleted file mode 100644 index 18a6088c..00000000 --- a/.github/main.workflow +++ /dev/null @@ -1,27 +0,0 @@ -# workflow "Check Irssi" { -# on = "push" -# resolves = [ -# "script", -# "unit_tests", -# ] -# } - -action "install" { - uses = "irssi-import/actions-irssi/check-irssi@master" - args = "before_install install" -} - -action "script" { - uses = "irssi-import/actions-irssi/check-irssi@master" - needs = ["install"] - args = "before_script script after_script" - env = { - TERM = "xterm" - } -} - -action "unit_tests" { - uses = "irssi-import/actions-irssi/check-irssi@master" - needs = ["install"] - args = "unit_tests after_unit_tests" -} From 3a654a9e01082c63faa6e51f0c15bbce413d139e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 22 Aug 2019 23:33:32 +0200 Subject: [PATCH 0594/1198] add various new message events to signals.txt --- docs/signals.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/signals.txt b/docs/signals.txt index 358973db..d7d42f5d 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -63,6 +63,7 @@ nicklist.c: "nicklist remove", CHANNEL_REC, NICK_REC "nicklist changed", CHANNEL_REC, NICK_REC, char *old_nick "nicklist host changed", CHANNEL_REC, NICK_REC + "nicklist account changed", CHANNEL_REC, NICK_REC, char *account "nicklist gone changed", CHANNEL_REC, NICK_REC "nicklist serverop changed", CHANNEL_REC, NICK_REC @@ -265,14 +266,18 @@ fe-messages.c: "message private", SERVER_REC, char *msg, char *nick, char *address, char *target "message own_public", SERVER_REC, char *msg, char *target "message own_private", SERVER_REC, char *msg, char *target, char *orig_target - "message join", SERVER_REC, char *channel, char *nick, char *address + "message join", SERVER_REC, char *channel, char *nick, char *address, char *account, char *realname "message part", SERVER_REC, char *channel, char *nick, char *address, char *reason "message quit", SERVER_REC, char *nick, char *address, char *reason "message kick", SERVER_REC, char *channel, char *nick, char *kicker, char *address, char *reason "message nick", SERVER_REC, char *newnick, char *oldnick, char *address "message own_nick", SERVER_REC, char *newnick, char *oldnick, char *address "message invite", SERVER_REC, char *channel, char *nick, char *address + "message invite_other", SERVER_REC, char *channel, char *invited, char *nick, char *address "message topic", SERVER_REC, char *channel, char *topic, char *nick, char *address + "message host_changed", SERVER_REC, char *nick, char *newaddress, char *oldaddress + "message account_changed", SERVER_REC, char *nick, char *address, char *account + "message away_notify", SERVER_REC, char *nick, char *address, char *awaymsg keyboard.c: "keyinfo created", KEYINFO_REC From 487d9434bd8b0403eaafe1963a96ad09abc32e8e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 23 Aug 2019 22:26:27 +0200 Subject: [PATCH 0595/1198] revert the change to perl-common that would stop it from creating ghost chatnets see 00a7efc69f8cfc14fcfdf123421015e99ac07926 --- src/perl/perl-common.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index 31650cc4..0c2b90e7 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -585,9 +585,6 @@ static void perl_register_protocol(CHAT_PROTOCOL_REC *rec) chat_type = chat_protocol_lookup(rec->name); g_return_if_fail(chat_type >= 0); - if (rec->not_initialized) - return; - name = g_ascii_strdown(rec->name,-1); *name = *(rec->name); From 44b060ce171111fe3433f13728663bac642a19d3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 27 Aug 2019 12:42:20 +0200 Subject: [PATCH 0596/1198] fix crash on startup when resizing before active_win --- src/fe-text/mainwindows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 051c63ae..711daf0a 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -829,7 +829,7 @@ void mainwindows_resize(int width, int height) } /* if we lost our active mainwin, get a new one */ - if (active_mainwin == NULL && !quitting) { + if (active_mainwin == NULL && active_win != NULL && !quitting) { active_mainwin = WINDOW_MAIN(active_win); window_set_active(active_mainwin->active); } From 5a4e7ab659aba2855895c9f43e9a7a131f4e89b3 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 27 Aug 2019 23:33:51 +0200 Subject: [PATCH 0597/1198] fix use after free receiving caps fixes GL#34 --- src/irc/core/irc-cap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 31b57094..639aace1 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -169,7 +169,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add * duplicated values, let's just warn the user */ g_warning("The server sent the %s capability twice", key); } - g_hash_table_insert(server->cap_supported, key, val); + g_hash_table_replace(server->cap_supported, key, val); } /* A multiline response is always terminated by a normal one, @@ -255,7 +255,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add continue; } - g_hash_table_insert(server->cap_supported, key, val); + g_hash_table_replace(server->cap_supported, key, val); cap_emit_signal(server, "new", key); } } From 991e24fb27233543e22430126e3da1eaedd16092 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 29 Aug 2019 17:26:35 +0200 Subject: [PATCH 0598/1198] Merge tag '1.2.2' into integrate/1.2.2 --- NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 2df16223..2e6e5025 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ v1.3-head 2019-xx-xx The Irssi team +v1.2.2 2019-08-29 The Irssi team + - Fix a use after free issue when receiving IRCv3 CAP + information from the server (GL#34) + - Fix a crash during startup when windows weren't fully + initialised yet (#1114, bdo#935813) + v1.2.1 2019-06-29 The Irssi team ! Contains all changes from 1.1.3 - Fix a test on big endian machines (#1014) From 3447904a5c4b11ea301ab7504ae768016fa45405 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 30 Aug 2019 20:29:03 +0200 Subject: [PATCH 0599/1198] fix warning in fe-fuzz/server-fuzz --- src/fe-fuzz/server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index cde03b89..6026cb4b 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -115,6 +115,7 @@ void test_server() { conn = server_create_conn(proto->id, "localhost", 0, "", "", "user"); server = proto->server_init_connect(conn); server->session_reconnect = TRUE; + g_free(server->tag); server->tag = g_strdup("testserver"); /* we skip some initialisations that would try to send data */ @@ -176,6 +177,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { g_strfreev(head); g_free(copy); - server_unref(server); + server_disconnect(server); return 0; } From 887950db0f728f1bec9d4a7aea03b7c0fce7b8ad Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 30 Aug 2019 20:30:02 +0200 Subject: [PATCH 0600/1198] limit special-vars alignment memory to not exhaust fuzzer --- src/core/special-vars.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/special-vars.c b/src/core/special-vars.c index d84912d2..ef56e2e1 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -33,7 +33,11 @@ #define isarg(c) \ (i_isdigit(c) || (c) == '*' || (c) == '~' || (c) == '-') +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* fuzzer should not exhaust memory here */ +#define ALIGN_MAX 512 +#else #define ALIGN_MAX 222488 +#endif static SPECIAL_HISTORY_FUNC history_func = NULL; From 7aa67b142b0f5b0062e9766eb8bf881023af5e8b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 30 Aug 2019 20:58:28 +0200 Subject: [PATCH 0601/1198] Add a new meson option : -Dstatic-dependency=yes to use static dependencies --- meson.build | 19 +++++++++++++------ meson_options.txt | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 3386737a..63f6c125 100644 --- a/meson.build +++ b/meson.build @@ -41,7 +41,10 @@ with_perl_lib = get_option('with-perl-lib') require_otr = get_option('with-otr') == 'yes' want_otr = get_option('with-otr') != 'no' -want_glib_internal = get_option('install-glib') == 'yes' +want_glib_internal = get_option('install-glib') != 'no' +require_glib_internal = get_option('install-glib') == 'force' + +want_static_dependency = get_option('static-dependency') == 'yes' chat_modules = ['irc'] @@ -149,7 +152,11 @@ message('*** to download and build it automatically') message('*** Or alternatively install your distribution\'s package') message('*** On Debian: sudo apt-get install libglib2.0-dev') message('*** On Redhat: dnf install glib2-devel') -glib_dep = dependency('glib-2.0', version : '>=2.28', required : not want_glib_internal) +if not require_glib_internal + glib_dep = dependency('glib-2.0', version : '>=2.28', required : not want_glib_internal, static : want_static_dependency) +else + glib_dep = dependency('', required : false) +endif if not glib_dep.found() glib_internal = true meson_cmd = find_program('meson') @@ -200,12 +207,12 @@ if not glib_dep.found() link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gmodule' / 'libgmodule-2.0.a' ], ) else - gmodule_dep = dependency('gmodule-2.0') + gmodule_dep = dependency('gmodule-2.0', static : want_static_dependency) endif dep += glib_dep dep += gmodule_dep -openssl_dep = dependency('openssl') +openssl_dep = dependency('openssl', static : want_static_dependency) dep += openssl_dep ############ @@ -365,8 +372,8 @@ endif have_otr = false if want_otr - libgcrypt = dependency('libgcrypt', version : '>=1.2.0', required : require_otr) - libotr = dependency('libotr', version : '>=4.1.0', required : require_otr) + libgcrypt = dependency('libgcrypt', version : '>=1.2.0', required : require_otr, static : want_static_dependency) + libotr = dependency('libotr', version : '>=4.1.0', required : require_otr, static : want_static_dependency) if libgcrypt.found() and libotr.found() dep += libgcrypt dep += libotr diff --git a/meson_options.txt b/meson_options.txt index 579b9cda..141e3fba 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,5 +10,6 @@ option('enable-true-color', type : 'combo', description : 'Build with true colo option('disable-gregex', type : 'combo', description : 'Build without GRegex (fall back to regex.h)', choices : ['no', 'yes']) option('disable-utf8proc', type : 'combo', description : 'Build without Julia\'s utf8proc', choices : ['auto', 'yes', 'no']) option('with-capsicum', type : 'combo', description : 'Build with Capsicum support', choices : ['auto', 'yes', 'no']) -option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes']) +option('static-dependency', type : 'combo', description : 'Request static dependencies', choices : ['no', 'yes']) +option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes', 'force']) option('docdir', type : 'string', description : 'Documentation directory') From c271609a494a9ac7f23b3a2fd8fefc109cd7e46f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 30 Aug 2019 22:11:27 +0200 Subject: [PATCH 0602/1198] add some dummy objects to server-fuzz --- src/fe-fuzz/server.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 6026cb4b..8e2b651c 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -98,6 +100,7 @@ void event_connected(IRC_SERVER_REC *server, const char *data, const char *from) } void irc_server_init_bare_minimum(IRC_SERVER_REC *server) { + server->rawlog = rawlog_create(); server->isupport = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); @@ -110,6 +113,9 @@ void test_server() { //SERVER_REC *server; /* = g_new0(IRC_SERVER_REC, 1); */ CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; + GIOChannel *handle = g_io_channel_unix_new(open("/dev/null", O_RDWR)); + g_io_channel_set_encoding(handle, NULL, NULL); + g_io_channel_set_close_on_unref(handle, TRUE); proto = chat_protocol_find("IRC"); conn = server_create_conn(proto->id, "localhost", 0, "", "", "user"); @@ -117,6 +123,7 @@ void test_server() { server->session_reconnect = TRUE; g_free(server->tag); server->tag = g_strdup("testserver"); + server->handle = net_sendbuffer_create(handle, 0); /* we skip some initialisations that would try to send data */ /* irc_servers_deinit(); */ @@ -147,6 +154,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { fe_common_irc_init(); signal_add("event 001", (SIGNAL_FUNC) event_connected); module_register("core", "fe-fuzz"); + rawlog_set_size(1); return 0; } From 948e7bb31787213e888b52df4968de4436dcd978 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 30 Aug 2019 22:14:26 +0200 Subject: [PATCH 0603/1198] free params --- src/irc/core/irc-cap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 639aace1..4dd9ceca 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -131,6 +131,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* Malformed request, terminate the negotiation */ else { irc_cap_finish_negotiation(server); + g_free(params); g_warn_if_reached(); return; } From 6d58052c4ab3cf6b72aa66e3212a48b3f493c577 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 4 Sep 2019 14:27:06 +0200 Subject: [PATCH 0604/1198] enable self-message support --- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 0fca78a0..8251c882 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -241,6 +241,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_AWAY_NOTIFY, TRUE); irc_cap_toggle(server, CAP_CHGHOST, TRUE); irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); + irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index f74b8210..2757db0d 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -25,6 +25,7 @@ #define CAP_AWAY_NOTIFY "away-notify" #define CAP_CHGHOST "chghost" #define CAP_ACCOUNT_NOTIFY "account-notify" +#define CAP_SELF_MESSAGE "znc.in/self-message" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ From f875d252d2637bb850f8c4d5d0153c1f29ede3aa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 4 Sep 2019 14:57:56 +0200 Subject: [PATCH 0605/1198] fix crash in join due to incorrect free --- src/irc/core/massjoin.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index be406d3d..2405f947 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -54,8 +54,10 @@ static void event_join(IRC_SERVER_REC *server, const char *data, /* find channel */ chanrec = irc_channel_find(server, channel); - g_free(params); - if (chanrec == NULL) return; + if (chanrec == NULL) { + g_free(params); + return; + } /* check that the nick isn't already in nicklist. seems to happen sometimes (server desyncs or something?) */ @@ -103,6 +105,7 @@ static void event_join(IRC_SERVER_REC *server, const char *data, } chanrec->massjoins++; + g_free(params); } static void event_chghost(IRC_SERVER_REC *server, const char *data, From 69dec1de33272bb94b7a81fe39b9c152aba3560f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 4 Sep 2019 22:48:03 +0200 Subject: [PATCH 0606/1198] add new meson build option -Dfuzzer-link-language=cpp for oss-fuzz --- meson.build | 6 +++++- meson_options.txt | 1 + src/fe-fuzz/fe-common/core/meson.build | 1 + src/fe-fuzz/irc/core/meson.build | 1 + src/fe-fuzz/meson.build | 2 ++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 63f6c125..d19e5735 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,7 @@ want_textui = get_option('without-textui') != 'yes' want_bot = get_option('with-bot') == 'yes' want_fuzzer = get_option('with-fuzzer') == 'yes' fuzzer_lib = get_option('with-fuzzer-lib') +fuzzer_link_language = get_option('fuzzer-link-language') want_proxy = get_option('with-proxy') == 'yes' want_truecolor = get_option('enable-true-color') == 'yes' want_gregex = get_option('disable-gregex') != 'yes' @@ -459,7 +460,10 @@ if want_fuzzer error('compiler does not support -fsanitize=fuzzer-no-link, try clang?') endif add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c') - add_project_link_arguments('-fsanitize=fuzzer-no-link', language : 'c') + if (fuzzer_link_language != 'c') + add_languages(fuzzer_link_language) + endif + add_project_link_arguments('-fsanitize=fuzzer-no-link', language : fuzzer_link_language) endif ############## diff --git a/meson_options.txt b/meson_options.txt index 141e3fba..c975db3a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,6 +2,7 @@ option('without-textui', type : 'combo', description : 'Build without text f option('with-bot', type : 'combo', description : 'Build irssi-bot', choices : ['no', 'yes']) option('with-fuzzer', type : 'combo', description : 'Build irssi-fuzzer', choices : ['no', 'yes']) option('with-fuzzer-lib', type : 'string', description : 'Specify path to fuzzer library', value : '-fsanitize=fuzzer') +option('fuzzer-link-language', type : 'string', description : 'The linker to use for the fuzz targets [c, cpp]', value : 'c') option('with-proxy', type : 'combo', description : 'Build irssi-proxy', choices : ['no', 'yes']) option('with-perl-lib', type : 'string', description : 'Specify where to install the Perl libraries for Irssi') option('with-perl', type : 'combo', description : 'Build with Perl support', choices : ['auto', 'yes', 'no']) diff --git a/src/fe-fuzz/fe-common/core/meson.build b/src/fe-fuzz/fe-common/core/meson.build index 679c19ce..8e321e8b 100644 --- a/src/fe-fuzz/fe-common/core/meson.build +++ b/src/fe-fuzz/fe-common/core/meson.build @@ -10,6 +10,7 @@ executable('theme-load-fuzz', libfuzzer_fe_common_core_a, ], link_args : [fuzzer_lib], + link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, diff --git a/src/fe-fuzz/irc/core/meson.build b/src/fe-fuzz/irc/core/meson.build index 23d1271f..1656523c 100644 --- a/src/fe-fuzz/irc/core/meson.build +++ b/src/fe-fuzz/irc/core/meson.build @@ -12,6 +12,7 @@ executable('event-get-params-fuzz', libfuzzer_fe_common_core_a, ], link_args : [fuzzer_lib], + link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, diff --git a/src/fe-fuzz/meson.build b/src/fe-fuzz/meson.build index 5dccd38d..1f6427db 100644 --- a/src/fe-fuzz/meson.build +++ b/src/fe-fuzz/meson.build @@ -14,6 +14,7 @@ executable('irssi-fuzz', libfuzzer_fe_common_core_a, ], link_args : [fuzzer_lib], + link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, @@ -35,6 +36,7 @@ executable('server-fuzz', libfe_irc_notifylist_a, ], link_args : [fuzzer_lib], + link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, From 9ff224d05d544a7fbd8f377d4f6f9eabc29e268f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 10 Sep 2019 13:08:35 +0200 Subject: [PATCH 0607/1198] silence glib log output during fuzzing on oss-fuzz --- src/fe-fuzz/Makefile.am | 3 +++ src/fe-fuzz/fe-common/core/Makefile.am | 1 + src/fe-fuzz/fe-common/core/meson.build | 1 + src/fe-fuzz/fe-common/core/theme-load.c | 4 ++++ src/fe-fuzz/irc/core/Makefile.am | 1 + src/fe-fuzz/irc/core/event-get-params.c | 4 ++++ src/fe-fuzz/irc/core/meson.build | 1 + src/fe-fuzz/irssi.c | 4 ++++ src/fe-fuzz/meson.build | 3 +++ src/fe-fuzz/null-logger.c | 16 ++++++++++++++++ src/fe-fuzz/null-logger.h | 6 ++++++ src/fe-fuzz/server.c | 4 ++++ 12 files changed, 48 insertions(+) create mode 100644 src/fe-fuzz/null-logger.c create mode 100644 src/fe-fuzz/null-logger.h diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index e72b8723..7ce2fcdd 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -17,6 +17,7 @@ irssi_fuzz_LDADD = \ irssi_fuzz_SOURCES = \ irssi.c \ + null-logger.c \ ../fe-text/module-formats.c server_fuzz_DEPENDENCIES = @COMMON_LIBS@ @@ -28,7 +29,9 @@ server_fuzz_LDADD = \ server_fuzz_SOURCES = \ server.c \ + null-logger.c \ ../fe-text/module-formats.c noinst_HEADERS = \ + null-logger.h \ ../fe-text/module-formats.h diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am index 692e95cf..da8731b9 100644 --- a/src/fe-fuzz/fe-common/core/Makefile.am +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -22,6 +22,7 @@ LDADD = \ $(FUZZER_LIBS) theme_load_fuzz_SOURCES = \ + ../../null-logger.c \ theme-load.c \ $(top_srcdir)/src/fe-text/module-formats.c diff --git a/src/fe-fuzz/fe-common/core/meson.build b/src/fe-fuzz/fe-common/core/meson.build index 8e321e8b..893f5937 100644 --- a/src/fe-fuzz/fe-common/core/meson.build +++ b/src/fe-fuzz/fe-common/core/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi executable('theme-load-fuzz', files( + '../../null-logger.c', 'theme-load.c', '../../../fe-text/module-formats.c', ), diff --git a/src/fe-fuzz/fe-common/core/theme-load.c b/src/fe-fuzz/fe-common/core/theme-load.c index fbb35684..faa063bb 100644 --- a/src/fe-fuzz/fe-common/core/theme-load.c +++ b/src/fe-fuzz/fe-common/core/theme-load.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,9 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { char *irssi_argv[] = {*argv[0], "--home", "/tmp/irssi", NULL}; int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_null_logger(); +#endif core_register_options(); fe_common_core_register_options(); args_execute(irssi_argc, irssi_argv); diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am index b2e1ea97..d66c2479 100644 --- a/src/fe-fuzz/irc/core/Makefile.am +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -22,6 +22,7 @@ LDADD = \ $(FUZZER_LIBS) event_get_params_fuzz_SOURCES = \ + ../../null-logger.c \ event-get-params.c \ $(top_srcdir)/src/fe-text/module-formats.c diff --git a/src/fe-fuzz/irc/core/event-get-params.c b/src/fe-fuzz/irc/core/event-get-params.c index 740602d1..3cdb789f 100644 --- a/src/fe-fuzz/irc/core/event-get-params.c +++ b/src/fe-fuzz/irc/core/event-get-params.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,9 @@ #include int LLVMFuzzerInitialize(int *argc, char ***argv) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_null_logger(); +#endif core_register_options(); fe_common_core_register_options(); /* no args */ diff --git a/src/fe-fuzz/irc/core/meson.build b/src/fe-fuzz/irc/core/meson.build index 1656523c..6a47e07d 100644 --- a/src/fe-fuzz/irc/core/meson.build +++ b/src/fe-fuzz/irc/core/meson.build @@ -2,6 +2,7 @@ executable('event-get-params-fuzz', files( + '../../null-logger.c', 'event-get-params.c', '../../../fe-text/module-formats.c', ), diff --git a/src/fe-fuzz/irssi.c b/src/fe-fuzz/irssi.c index 1c9f6c5f..6f79223a 100644 --- a/src/fe-fuzz/irssi.c +++ b/src/fe-fuzz/irssi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,9 @@ #include int LLVMFuzzerInitialize(int *argc, char ***argv) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_null_logger(); +#endif core_register_options(); fe_common_core_register_options(); /* no args */ diff --git a/src/fe-fuzz/meson.build b/src/fe-fuzz/meson.build index 1f6427db..7fac025d 100644 --- a/src/fe-fuzz/meson.build +++ b/src/fe-fuzz/meson.build @@ -5,6 +5,7 @@ subdir('fe-common') executable('irssi-fuzz', files( + 'null-logger.c', 'irssi.c', '../fe-text/module-formats.c', ), @@ -23,6 +24,7 @@ executable('irssi-fuzz', executable('server-fuzz', files( + 'null-logger.c', 'server.c', '../fe-text/module-formats.c', ), @@ -44,5 +46,6 @@ executable('server-fuzz', ) # noinst_headers = files( +# 'null-logger.h', # '../fe-text/module-formats.h', # ) diff --git a/src/fe-fuzz/null-logger.c b/src/fe-fuzz/null-logger.c new file mode 100644 index 00000000..dd88b84a --- /dev/null +++ b/src/fe-fuzz/null-logger.c @@ -0,0 +1,16 @@ +#include + +#include + +static void null_logger(const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + return; +} + +void g_log_set_null_logger(void) +{ + g_log_set_default_handler(null_logger, NULL); +} diff --git a/src/fe-fuzz/null-logger.h b/src/fe-fuzz/null-logger.h new file mode 100644 index 00000000..d27eeffa --- /dev/null +++ b/src/fe-fuzz/null-logger.h @@ -0,0 +1,6 @@ +#ifndef IRSSI_FE_FUZZ_NULL_LOGGER_H +#define IRSSI_FE_FUZZ_NULL_LOGGER_H + +void g_log_set_null_logger(void); + +#endif diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 8e2b651c..e8caafa0 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -41,6 +41,7 @@ #include #include #include +#include /* irc.c */ void irc_init(void); @@ -143,6 +144,9 @@ void test_server() { } int LLVMFuzzerInitialize(int *argc, char ***argv) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_null_logger(); +#endif core_register_options(); fe_common_core_register_options(); /* no args */ From 51190f69b284a393c74cd51475d710228ee89ded Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 10 Sep 2019 14:22:31 +0200 Subject: [PATCH 0608/1198] update fuzzer flags --- meson.build | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index d19e5735..2ea7bcc7 100644 --- a/meson.build +++ b/meson.build @@ -456,14 +456,15 @@ if get_option('buildtype').contains('debug') endif if want_fuzzer - if not cc.has_argument('-fsanitize=fuzzer-no-link') - error('compiler does not support -fsanitize=fuzzer-no-link, try clang?') + if fuzzer_lib.startswith('-fsanitize=fuzzer') + if not cc.has_argument('-fsanitize=fuzzer-no-link') + error('compiler does not support -fsanitize=fuzzer-no-link, try clang?') + endif + add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c') endif - add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c') - if (fuzzer_link_language != 'c') + if fuzzer_link_language != 'c' add_languages(fuzzer_link_language) endif - add_project_link_arguments('-fsanitize=fuzzer-no-link', language : fuzzer_link_language) endif ############## From f6cca3de4e7e2480b3e6a4845ff5211b9b24296d Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Tue, 24 Sep 2019 21:35:40 -0400 Subject: [PATCH 0609/1198] Properly free sasl_buffer GString --- src/irc/core/irc-servers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 8251c882..e3c856af 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -456,7 +456,9 @@ static void sig_destroyed(IRC_SERVER_REC *server) gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); server->cap_queue = NULL; - g_free_and_null(server->sasl_buffer); + /* was g_free_and_null, but can't use on a GString */ + g_string_free(server->sasl_buffer); + server->sasl_buffer = NULL; /* these are dynamically allocated only if isupport was sent */ g_hash_table_foreach(server->isupport, From ed65499d76daac352d76ae0f30e36f3feb623174 Mon Sep 17 00:00:00 2001 From: Joseph Bisch Date: Thu, 26 Sep 2019 21:51:36 -0400 Subject: [PATCH 0610/1198] Add missing g_string_free param --- src/irc/core/irc-servers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index e3c856af..fcd9346e 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -457,7 +457,7 @@ static void sig_destroyed(IRC_SERVER_REC *server) server->cap_queue = NULL; /* was g_free_and_null, but can't use on a GString */ - g_string_free(server->sasl_buffer); + g_string_free(server->sasl_buffer, TRUE); server->sasl_buffer = NULL; /* these are dynamically allocated only if isupport was sent */ From 7e694fd223c71dda83ae45f3923bff2d62997f40 Mon Sep 17 00:00:00 2001 From: Dan Collins Date: Sat, 28 Sep 2019 20:00:06 -0400 Subject: [PATCH 0611/1198] Fix hilight behavior for STATUSMSG This patch allows irc_op_public messages to properly trigger hilights when the message mentions the current nick or one of our hilights. This is done by copying the required code from sig_message_public. This is important because Freenode has begun using this message type for messages that can only be seen by ops due to the +z channel mode, and ops will want to be notified of watchwords even in that type of message. To test, make two connections to Freenode, join a new channel. The first client to join that channel will be an op. To establish a baseline, use the non-opped client to attempt to "ping" the opped client by addressing it by name and using terms in /hilight. Then, set channel mode to +mz and use the non-opped client to send the messages again. Without this patch, no message will "ping" the opped client with +mz set. With this patch, "pings" should operate normally, causing a bell, hilighting the window number, and so on. What I don't know is whether there is any other code from sig_message_public that should be copied over too. In particular, the lines related to "ignore_check_plus", "emphasis", and "printnick", I don't know if they are needed here. I also don't know if there are any other message types that these changes should be applied to. --- src/fe-common/irc/fe-irc-messages.c | 39 +++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index ddd4311e..7eb2fff1 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -71,8 +72,12 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { - char *nickmode, *optarget, *prefix; + CHANNEL_REC *chanrec; + char *nickmode, *optarget, *prefix, *color; const char *cleantarget; + int for_me, level; + HILIGHT_REC *hilight; + TEXT_DEST_REC dest; /* only skip here so the difference can be stored in prefix */ cleantarget = fe_channel_skip_prefix(IRC_SERVER(server), target); @@ -86,10 +91,34 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, optarget = g_strconcat(prefix, cleantarget, NULL); - printformat_module("fe-common/core", server, cleantarget, - MSGLEVEL_PUBLIC, - TXT_PUBMSG_CHANNEL, - nick, optarget, msg, nickmode); + chanrec = channel_find(server, target); + + /* Check for hilights */ + for_me = !settings_get_bool("hilight_nick_matches") ? FALSE : + !settings_get_bool("hilight_nick_matches_everywhere") ? + 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); + + level = MSGLEVEL_PUBLIC; + if (for_me) + level |= MSGLEVEL_HILIGHT; + + if (color != NULL) { + format_create_dest(&dest, server, cleantarget, level, NULL); + dest.address = address; + dest.nick = nick; + hilight_update_text_dest(&dest,hilight); + printformat_module_dest("fe-common/core", &dest, + TXT_PUBMSG_HILIGHT_CHANNEL, + color, nick, optarget, msg, nickmode); + } else { + printformat_module("fe-common/core", server, cleantarget, level, + for_me ? TXT_PUBMSG_ME_CHANNEL : TXT_PUBMSG_CHANNEL, + nick, optarget, msg, nickmode); + } g_free(nickmode); g_free(optarget); g_free(prefix); From 03eb8d032a1b7e09230ed3ff777fa99831172b17 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 1 Oct 2019 11:09:25 +0200 Subject: [PATCH 0612/1198] fix the fix --- src/irc/core/irc-servers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index fcd9346e..3ec0bba5 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -457,8 +457,10 @@ static void sig_destroyed(IRC_SERVER_REC *server) server->cap_queue = NULL; /* was g_free_and_null, but can't use on a GString */ - g_string_free(server->sasl_buffer, TRUE); - server->sasl_buffer = NULL; + if (server->sasl_buffer != NULL) { + g_string_free(server->sasl_buffer, TRUE); + server->sasl_buffer = NULL; + } /* these are dynamically allocated only if isupport was sent */ g_hash_table_foreach(server->isupport, From a68be4dccad651a69b8330bfc73f4f5dc548fea2 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 5 Oct 2019 23:30:25 +0200 Subject: [PATCH 0613/1198] missing free --- src/core/nicklist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/nicklist.c b/src/core/nicklist.c index 528f2286..f2aa1315 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -120,6 +120,7 @@ static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick) g_free(nick->nick); g_free_not_null(nick->realname); g_free_not_null(nick->host); + g_free(nick->account); g_free(nick); } From 2af7db2dfa9a685e9a93a99adb69f7bea4568907 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 14 Sep 2019 11:00:35 -0700 Subject: [PATCH 0614/1198] Remove unused function --- src/core/misc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index d612f587..c959ad91 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -270,11 +270,6 @@ char *gslist_to_string(GSList *list, const char *delimiter) return ret; } -void hash_save_key(char *key, void *value, GSList **list) -{ - *list = g_slist_append(*list, key); -} - /* remove all the options from the optlist hash table that are valid for the * command cmd */ GList *optlist_remove_known(const char *cmd, GHashTable *optlist) From e4d34380e50013b3b209720be14c0761d449bc4d Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 14 Sep 2019 11:03:36 -0700 Subject: [PATCH 0615/1198] Mark unused function deprecated --- src/core/misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/misc.h b/src/core/misc.h index 9e06c707..65534cdc 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -50,7 +50,7 @@ int match_wildcards(const char *mask, const char *data); /* octal <-> decimal conversions */ int octal2dec(int octal); -int dec2octal(int decimal); +int dec2octal(int decimal) G_GNUC_DEPRECATED; /* Get time in human readable form with localtime() + asctime() */ char *my_asctime(time_t t); From 145d1040ac255b3e16b6ba363bd7113d6291a3bb Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 11 Oct 2019 22:37:09 +0200 Subject: [PATCH 0616/1198] add ignore check, emphasis and fix a memory leak --- src/fe-common/irc/fe-irc-messages.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 7eb2fff1..d287bf1f 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -67,13 +67,14 @@ static void sig_message_own_public(SERVER_REC *server, const char *msg, } -/* received msg to all ops in channel */ +/* received msg to all ops in channel. + TODO: this code is a duplication of sig_message_public */ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, const char *nick, const char *address, const char *target) { CHANNEL_REC *chanrec; - char *nickmode, *optarget, *prefix, *color; + char *nickmode, *optarget, *prefix, *color, *freemsg = NULL; const char *cleantarget; int for_me, level; HILIGHT_REC *hilight; @@ -86,26 +87,33 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, /* and clean the rest here */ cleantarget = get_visible_target(IRC_SERVER(server), cleantarget); - nickmode = channel_get_nickmode(channel_find(server, cleantarget), - nick); + if (ignore_check_plus(server, nick, address, cleantarget, msg, &level, TRUE)) { + g_free(prefix); + return; + } + + chanrec = channel_find(server, cleantarget); + + nickmode = channel_get_nickmode(chanrec, nick); optarget = g_strconcat(prefix, cleantarget, NULL); - chanrec = channel_find(server, target); - /* Check for hilights */ for_me = !settings_get_bool("hilight_nick_matches") ? FALSE : !settings_get_bool("hilight_nick_matches_everywhere") ? 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); + hilight_match_nick(server, cleantarget, nick, address, MSGLEVEL_PUBLIC, msg); color = (hilight == NULL) ? NULL : hilight_get_color(hilight); level = MSGLEVEL_PUBLIC; if (for_me) level |= MSGLEVEL_HILIGHT; + if (settings_get_bool("emphasis")) + msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); + if (color != NULL) { format_create_dest(&dest, server, cleantarget, level, NULL); dest.address = address; @@ -119,7 +127,10 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, for_me ? TXT_PUBMSG_ME_CHANNEL : TXT_PUBMSG_CHANNEL, nick, optarget, msg, nickmode); } + g_free(nickmode); + g_free(freemsg); + g_free(color); g_free(optarget); g_free(prefix); } From 4476fbbad9e66421dbaf4fa9a1a47566d7b0bdc6 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 12 Oct 2019 15:37:49 -0700 Subject: [PATCH 0617/1198] Fix indentation --- src/core/servers-reconnect.c | 4 ++-- src/core/servers-setup.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 97175f78..dd949ead 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -181,7 +181,7 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) dest->tag = g_strdup(src->tag); if (connect_info) { - dest->family = src->family; + dest->family = src->family; dest->address = g_strdup(src->address); dest->port = src->port; dest->password = g_strdup(src->password); @@ -293,7 +293,7 @@ static void sig_reconnect(SERVER_REC *server) (!rec->last_connect || !rec->last_failed || rec->last_connect < now-FAILED_RECONNECT_WAIT)) { if (rec == sserver) - conn->port = server->connrec->port; + conn->port = server->connrec->port; sserver_connect(rec, conn); return; } diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index a505df5b..e1313791 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -159,11 +159,11 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn, sserver->last_connect = time(NULL); - if (sserver->no_proxy) + if (sserver->no_proxy) g_free_and_null(conn->proxy); if (sserver->family != 0 && conn->family == 0) - conn->family = sserver->family; + conn->family = sserver->family; if (sserver->port > 0 && conn->port <= 0) conn->port = sserver->port; From 163942521718328110152388203ca7494c3416df Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 12 Oct 2019 15:43:14 -0700 Subject: [PATCH 0618/1198] Do not copy TLS settings to reconnection record This was causing us to use the TLS settings from one server on another which is not always appropriate. Instead, we now treat it like other connection information and do not copy it. We get the TLS settings later as appropriate when connecting. Note there is still probably more that could be cleaned up here. For example, the unix socket might be better treated as connection info too. Fixes #1027. --- src/core/servers-reconnect.c | 20 +++++++++---------- src/core/servers-setup.c | 38 ++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index dd949ead..2098a6cc 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -185,6 +185,16 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) dest->address = g_strdup(src->address); dest->port = src->port; dest->password = g_strdup(src->password); + + dest->use_tls = src->use_tls; + dest->tls_cert = g_strdup(src->tls_cert); + dest->tls_pkey = g_strdup(src->tls_pkey); + dest->tls_verify = src->tls_verify; + dest->tls_cafile = g_strdup(src->tls_cafile); + dest->tls_capath = g_strdup(src->tls_capath); + dest->tls_ciphers = g_strdup(src->tls_ciphers); + dest->tls_pinned_cert = g_strdup(src->tls_pinned_cert); + dest->tls_pinned_pubkey = g_strdup(src->tls_pinned_pubkey); } dest->chatnet = g_strdup(src->chatnet); @@ -207,16 +217,6 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) dest->no_autosendcmd = src->no_autosendcmd; dest->unix_socket = src->unix_socket; - dest->use_tls = src->use_tls; - dest->tls_cert = g_strdup(src->tls_cert); - dest->tls_pkey = g_strdup(src->tls_pkey); - dest->tls_verify = src->tls_verify; - dest->tls_cafile = g_strdup(src->tls_cafile); - dest->tls_capath = g_strdup(src->tls_capath); - dest->tls_ciphers = g_strdup(src->tls_ciphers); - dest->tls_pinned_cert = g_strdup(src->tls_pinned_cert); - dest->tls_pinned_pubkey = g_strdup(src->tls_pinned_pubkey); - return dest; } diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index e1313791..fa68c049 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -108,6 +108,25 @@ void server_setup_fill_reconn(SERVER_CONNECT_REC *conn, if (sserver->password != NULL && conn->password == NULL) conn->password = g_strdup(sserver->password); + conn->use_tls = sserver->use_tls; + if (conn->tls_cert == NULL && sserver->tls_cert != NULL && sserver->tls_cert[0] != '\0') + conn->tls_cert = g_strdup(sserver->tls_cert); + if (conn->tls_pkey == NULL && sserver->tls_pkey != NULL && sserver->tls_pkey[0] != '\0') + conn->tls_pkey = g_strdup(sserver->tls_pkey); + if (conn->tls_pass == NULL && sserver->tls_pass != NULL && sserver->tls_pass[0] != '\0') + conn->tls_pass = g_strdup(sserver->tls_pass); + conn->tls_verify = sserver->tls_verify; + if (conn->tls_cafile == NULL && sserver->tls_cafile != NULL && sserver->tls_cafile[0] != '\0') + conn->tls_cafile = g_strdup(sserver->tls_cafile); + if (conn->tls_capath == NULL && sserver->tls_capath != NULL && sserver->tls_capath[0] != '\0') + conn->tls_capath = g_strdup(sserver->tls_capath); + if (conn->tls_ciphers == NULL && sserver->tls_ciphers != NULL && sserver->tls_ciphers[0] != '\0') + conn->tls_ciphers = g_strdup(sserver->tls_ciphers); + if (conn->tls_pinned_cert == NULL && sserver->tls_pinned_cert != NULL && sserver->tls_pinned_cert[0] != '\0') + conn->tls_pinned_cert = g_strdup(sserver->tls_pinned_cert); + if (conn->tls_pinned_pubkey == NULL && sserver->tls_pinned_pubkey != NULL && sserver->tls_pinned_pubkey[0] != '\0') + conn->tls_pinned_pubkey = g_strdup(sserver->tls_pinned_pubkey); + signal_emit("server setup fill reconn", 2, conn, sserver); } @@ -167,25 +186,6 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn, if (sserver->port > 0 && conn->port <= 0) conn->port = sserver->port; - conn->use_tls = sserver->use_tls; - if (conn->tls_cert == NULL && sserver->tls_cert != NULL && sserver->tls_cert[0] != '\0') - conn->tls_cert = g_strdup(sserver->tls_cert); - if (conn->tls_pkey == NULL && sserver->tls_pkey != NULL && sserver->tls_pkey[0] != '\0') - conn->tls_pkey = g_strdup(sserver->tls_pkey); - if (conn->tls_pass == NULL && sserver->tls_pass != NULL && sserver->tls_pass[0] != '\0') - conn->tls_pass = g_strdup(sserver->tls_pass); - conn->tls_verify = sserver->tls_verify; - if (conn->tls_cafile == NULL && sserver->tls_cafile != NULL && sserver->tls_cafile[0] != '\0') - conn->tls_cafile = g_strdup(sserver->tls_cafile); - if (conn->tls_capath == NULL && sserver->tls_capath != NULL && sserver->tls_capath[0] != '\0') - conn->tls_capath = g_strdup(sserver->tls_capath); - if (conn->tls_ciphers == NULL && sserver->tls_ciphers != NULL && sserver->tls_ciphers[0] != '\0') - conn->tls_ciphers = g_strdup(sserver->tls_ciphers); - if (conn->tls_pinned_cert == NULL && sserver->tls_pinned_cert != NULL && sserver->tls_pinned_cert[0] != '\0') - conn->tls_pinned_cert = g_strdup(sserver->tls_pinned_cert); - if (conn->tls_pinned_pubkey == NULL && sserver->tls_pinned_pubkey != NULL && sserver->tls_pinned_pubkey[0] != '\0') - conn->tls_pinned_pubkey = g_strdup(sserver->tls_pinned_pubkey); - server_setup_fill_reconn(conn, sserver); signal_emit("server setup fill server", 2, conn, sserver); From 34effcec01c01775db7c8575a88e1ae2adbd12de Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 12 Oct 2019 15:46:09 -0700 Subject: [PATCH 0619/1198] Fill more connection information in one spot --- src/core/servers-reconnect.c | 4 ---- src/core/servers-setup.c | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 2098a6cc..2cbe60b4 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -151,10 +151,6 @@ static int server_reconnect_timeout(void) static void sserver_connect(SERVER_SETUP_REC *rec, SERVER_CONNECT_REC *conn) { - conn->family = rec->family; - conn->address = g_strdup(rec->address); - if (conn->port == 0) conn->port = rec->port; - server_setup_fill_reconn(conn, rec); server_reconnect_add(conn, rec->last_connect+reconnect_time); server_connect_unref(conn); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index fa68c049..8662b30c 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -108,6 +108,16 @@ void server_setup_fill_reconn(SERVER_CONNECT_REC *conn, if (sserver->password != NULL && conn->password == NULL) conn->password = g_strdup(sserver->password); + if (sserver->no_proxy) + g_free_and_null(conn->proxy); + + if (sserver->family != 0 && conn->family == 0) + conn->family = sserver->family; + if (sserver->address && !conn->address) + conn->address = g_strdup(sserver->address); + if (sserver->port > 0 && conn->port <= 0) + conn->port = sserver->port; + conn->use_tls = sserver->use_tls; if (conn->tls_cert == NULL && sserver->tls_cert != NULL && sserver->tls_cert[0] != '\0') conn->tls_cert = g_strdup(sserver->tls_cert); @@ -178,14 +188,6 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn, sserver->last_connect = time(NULL); - if (sserver->no_proxy) - g_free_and_null(conn->proxy); - - if (sserver->family != 0 && conn->family == 0) - conn->family = sserver->family; - if (sserver->port > 0 && conn->port <= 0) - conn->port = sserver->port; - server_setup_fill_reconn(conn, sserver); signal_emit("server setup fill server", 2, conn, sserver); From f9db4019afee3bb5fcc894b2810a640e0f79fed1 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 12 Oct 2019 17:03:40 -0700 Subject: [PATCH 0620/1198] Remove else since prior condition returns --- src/core/settings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/settings.c b/src/core/settings.c index 9b50f6f4..18f44257 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -557,7 +557,8 @@ static int backwards_compatibility(const char *module, CONFIG_NODE *node, g_free(new_value); config_changed = TRUE; return new_key != NULL; - } else if (g_ascii_strcasecmp(node->key, "actlist_moves") == 0 && + } + if (g_ascii_strcasecmp(node->key, "actlist_moves") == 0 && node->value != NULL && g_ascii_strcasecmp(node->value, "yes") == 0) { config_node_set_str(mainconfig, parent, "actlist_sort", "recent"); config_node_set_str(mainconfig, parent, node->key, NULL); From 7e6d24420cc5c3e1fb5fcbec999de70e77178093 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Sat, 12 Oct 2019 17:09:13 -0700 Subject: [PATCH 0621/1198] Remove resolve_reverse_lookup setting This setting seems ill advised and breaks TLS verification. Fixes #1034. --- src/core/net-nonblock.c | 42 +---------------------------------------- src/core/net-nonblock.h | 4 +--- src/core/servers.c | 15 +-------------- src/core/settings.c | 6 ++++++ 4 files changed, 9 insertions(+), 58 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 31fbf985..90e4bdab 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -27,13 +27,11 @@ /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, - int reverse_lookup) +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe) { RESOLVED_IP_REC rec; const char *errorstr; int pid; - int len; g_return_val_if_fail(addr != NULL, FALSE); @@ -57,13 +55,6 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6); if (rec.error == 0) { errorstr = NULL; - if (reverse_lookup) { - /* reverse lookup the IP, ignore any error */ - if (rec.ip4.family != 0) - net_gethostbyaddr(&rec.ip4, &rec.host4); - if (rec.ip6.family != 0) - net_gethostbyaddr(&rec.ip6, &rec.host6); - } } else { errorstr = net_gethosterror(rec.error); rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; @@ -72,22 +63,6 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, g_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.errlen != 0) g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); - else { - if (rec.host4) { - len = strlen(rec.host4) + 1; - g_io_channel_write_block(pipe, (void *) &len, - sizeof(int)); - g_io_channel_write_block(pipe, (void *) rec.host4, - len); - } - if (rec.host6) { - len = strlen(rec.host6) + 1; - g_io_channel_write_block(pipe, (void *) &len, - sizeof(int)); - g_io_channel_write_block(pipe, (void *) rec.host6, - len); - } - } if (pid == 0) _exit(99); @@ -99,12 +74,8 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, /* get the resolved IP address */ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) { - int len; - rec->error = -1; rec->errorstr = NULL; - rec->host4 = NULL; - rec->host6 = NULL; fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); @@ -120,17 +91,6 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) reason, just ignore it. */ rec->errorstr = g_malloc0(rec->errlen+1); g_io_channel_read_block(pipe, rec->errorstr, rec->errlen); - } else { - if (rec->host4) { - g_io_channel_read_block(pipe, &len, sizeof(int)); - rec->host4 = g_malloc0(len); - g_io_channel_read_block(pipe, rec->host4, len); - } - if (rec->host6) { - g_io_channel_read_block(pipe, &len, sizeof(int)); - rec->host6 = g_malloc0(len); - g_io_channel_read_block(pipe, rec->host6, len); - } } return 0; diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 086c9dab..3d2f7354 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -9,12 +9,10 @@ typedef struct { int errlen; /* error text length */ char *errorstr; /* error string - dynamically allocated, you'll need to free() it yourself unless it's NULL */ - char *host4, *host6; /* dito */ } RESOLVED_IP_REC; /* nonblocking gethostbyname(), PID of the resolver child is returned. */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, - int reverse_lookup); +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe); /* get the resolved IP address. returns -1 if some error occurred with read() */ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec); diff --git a/src/core/servers.c b/src/core/servers.c index 20452f8c..50316c7d 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -261,7 +261,6 @@ static void server_connect_callback_readpipe(SERVER_REC *server) RESOLVED_IP_REC iprec; IPADDR *ip; const char *errormsg; - char *servername = NULL; g_source_remove(server->connect_tag); server->connect_tag = -1; @@ -283,11 +282,9 @@ static void server_connect_callback_readpipe(SERVER_REC *server) } else if (server->connrec->family == AF_INET) { /* force IPv4 connection */ ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4; - servername = iprec.host4; } else if (server->connrec->family == AF_INET6) { /* force IPv6 connection */ ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6; - servername = iprec.host6; } else { /* pick the one that was found, or if both do it like /SET resolve_prefer_ipv6 says. */ @@ -295,19 +292,13 @@ static void server_connect_callback_readpipe(SERVER_REC *server) (iprec.ip6.family != 0 && settings_get_bool("resolve_prefer_ipv6"))) { ip = &iprec.ip6; - servername = iprec.host6; } else { ip = &iprec.ip4; - servername = iprec.host4; } } if (ip != NULL) { /* host lookup ok */ - if (servername) { - g_free(server->connrec->address); - server->connrec->address = g_strdup(servername); - } server_real_connect(server, ip, NULL); errormsg = NULL; } else { @@ -333,8 +324,6 @@ static void server_connect_callback_readpipe(SERVER_REC *server) } g_free(iprec.errorstr); - g_free(iprec.host4); - g_free(iprec.host6); } SERVER_REC *server_connect(SERVER_CONNECT_REC *conn) @@ -418,8 +407,7 @@ int server_start_connect(SERVER_REC *server) server->connrec->proxy : server->connrec->address; server->connect_pid = net_gethostbyname_nonblock(connect_address, - server->connect_pipe[1], - settings_get_bool("resolve_reverse_lookup")); + server->connect_pipe[1]); server->connect_tag = g_input_add(server->connect_pipe[0], G_INPUT_READ, (GInputFunction) @@ -739,7 +727,6 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto) void servers_init(void) { settings_add_bool("server", "resolve_prefer_ipv6", FALSE); - settings_add_bool("server", "resolve_reverse_lookup", FALSE); lookup_servers = servers = NULL; signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit); diff --git a/src/core/settings.c b/src/core/settings.c index 18f44257..f8c0b9df 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -566,6 +566,12 @@ static int backwards_compatibility(const char *module, CONFIG_NODE *node, return TRUE; } } + if (g_strcmp0(module, "core") == 0 && + g_strcmp0(node->key, "resolve_reverse_lookup") == 0) { + config_node_set_str(mainconfig, parent, node->key, NULL); + config_changed = TRUE; + return TRUE; + } return new_key != NULL; } From 5776ca5e0bb36574974f39d52c4c8e19ff686bb1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 13 Oct 2019 21:35:30 +0200 Subject: [PATCH 0622/1198] bottom_startline lost? --- src/fe-text/textbuffer-view.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index a031439d..45035fa8 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -1205,14 +1205,14 @@ static void view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, LINE_REC *prevline; prevline = view->buffer->first_line == line ? NULL : - textbuffer_line_last(view->buffer); + textbuffer_line_last(view->buffer)->prev; view->cache->last_linecount = prevline == NULL ? 0 : view_get_linecount(view, prevline); } + /* first line in the buffer - this is the most commonly + removed line.. */ if (view->buffer->first_line == line) { - /* first line in the buffer - this is the most commonly - removed line.. */ if (view->bottom_startline == line) { /* very small scrollback.. */ view->bottom_startline = view->bottom_startline->next; @@ -1289,6 +1289,11 @@ void textbuffer_view_remove_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) } textbuffer_remove(view->buffer, line); + if (view->bottom_startline == NULL) { + /* We may have removed the bottom_startline, make sure + that scroll doesn't get stuck */ + textbuffer_view_init_bottom(view); + } } void textbuffer_view_remove_lines_by_level(TEXT_BUFFER_VIEW_REC *view, int level) From d84f285b91581e21312e44d53cfd8ed5a18e7252 Mon Sep 17 00:00:00 2001 From: Will Storey Date: Tue, 15 Oct 2019 19:07:48 -0700 Subject: [PATCH 0623/1198] Keep unused parameter for API compatibility --- src/core/net-nonblock.c | 4 +++- src/core/net-nonblock.h | 2 +- src/core/servers.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 90e4bdab..1ad5f42f 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -27,12 +27,14 @@ /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe) +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup) { RESOLVED_IP_REC rec; const char *errorstr; int pid; + (void) reverse_lookup; /* Kept for API backward compatibility */ + g_return_val_if_fail(addr != NULL, FALSE); pid = fork(); diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 3d2f7354..c93dd9e3 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -12,7 +12,7 @@ typedef struct { } RESOLVED_IP_REC; /* nonblocking gethostbyname(), PID of the resolver child is returned. */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe); +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup); /* get the resolved IP address. returns -1 if some error occurred with read() */ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec); diff --git a/src/core/servers.c b/src/core/servers.c index 50316c7d..5b850a28 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -407,7 +407,7 @@ int server_start_connect(SERVER_REC *server) server->connrec->proxy : server->connrec->address; server->connect_pid = net_gethostbyname_nonblock(connect_address, - server->connect_pipe[1]); + server->connect_pipe[1], 0); server->connect_tag = g_input_add(server->connect_pipe[0], G_INPUT_READ, (GInputFunction) From a827c691836658c9aa5473559a345120ebff4c9d Mon Sep 17 00:00:00 2001 From: Will Storey Date: Thu, 17 Oct 2019 19:43:29 -0700 Subject: [PATCH 0624/1198] Bump ABI --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 8a9713ce..355a9b14 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 23 +#define IRSSI_ABI_VERSION 24 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From b7f165a6094454b485767ec0dd98d93ded9172d7 Mon Sep 17 00:00:00 2001 From: Mike Quin Date: Sat, 19 Oct 2019 11:34:15 +0100 Subject: [PATCH 0625/1198] Improve clarity of nick in use message If irssi's preferred nick is in use irssi will issue a whois command and report some information on the current user of the nick. As the "is owned by" wording can be confusing to users of networks with nickname registration, propose rephrasing this to "is in use by". --- src/fe-common/irc/module-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index a0f6bd29..e36eed92 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -98,7 +98,7 @@ FORMAT_REC fecommon_irc_formats[] = { { "no_such_nick", "{nick $0}: No such nick/channel", 1, { 0 } }, { "nick_in_use", "Nick {nick $0} is already in use", 1, { 0 } }, { "nick_unavailable", "Nick {nick $0} is temporarily unavailable", 1, { 0 } }, - { "your_nick_owned", "Your nick is owned by {nick $3} {comment $1@$2}", 4, { 0, 0, 0, 0 } }, + { "your_nick_owned", "Your nick is in use by {nick $3} {comment $1@$2}", 4, { 0, 0, 0, 0 } }, /* ---- */ { NULL, "Who queries", 0 }, From bdf5d748f2ae93086ab9d047cf6573f999fdad4c Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 31 Oct 2019 21:02:26 +0100 Subject: [PATCH 0626/1198] meson.build: Remove unnecessary -Wall --- meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/meson.build b/meson.build index 2ea7bcc7..3ef1de9c 100644 --- a/meson.build +++ b/meson.build @@ -446,7 +446,6 @@ configure_file(output : 'irssi-config.h', ########## #### warnings #### -add_project_arguments('-Wall', language : 'c') add_project_arguments(cc.get_supported_arguments('-Werror=declaration-after-statement'), language : 'c') #### personality #### From 664c38afbaaa0bc4bbb8cb0952e475f11c68f0c0 Mon Sep 17 00:00:00 2001 From: dequis Date: Thu, 31 Oct 2019 23:49:40 +0100 Subject: [PATCH 0627/1198] Fix some glib deprecation warnings Most of these have been deprecated since forever (2.2), but they didn't raise warnings. Now they do, and the warnings are not the most verbose warnings you could ask for, but, they point in the right direction. This doesn't handle the GTimeVal deprecation warnings. Those seem trickier since they cover API, will look into those right after this. --- fuzz-support/fuzz.diff | 6 ++--- src/core/commands.c | 2 +- src/core/line-split.c | 2 +- src/core/net-sendbuffer.c | 2 +- src/fe-common/irc/fe-events-numeric.c | 2 +- src/fe-none/irssi.c | 6 ++--- src/fe-text/gui-entry.c | 32 +++++++++++++-------------- src/fe-text/irssi.c | 6 ++--- src/irc/core/bans.c | 2 +- src/irc/dcc/dcc-get.c | 4 ++-- src/irc/dcc/dcc-server.c | 2 +- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/fuzz-support/fuzz.diff b/fuzz-support/fuzz.diff index a3683493..5a3f2176 100644 --- a/fuzz-support/fuzz.diff +++ b/fuzz-support/fuzz.diff @@ -150,7 +150,7 @@ index ad79e0c..84d0c5c 100644 +++ b/src/fe-text/irssi.c @@ -314,20 +314,16 @@ int main(int argc, char **argv) textui_finish_init(); - main_loop = g_main_new(TRUE); + main_loop = g_main_loop_new(NULL, TRUE); +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); @@ -162,7 +162,7 @@ index ad79e0c..84d0c5c 100644 can call our dirty-checker after each iteration */ while (!quitting) { - term_refresh_freeze(); - g_main_iteration(TRUE); + g_main_context_iteration(NULL, TRUE); - term_refresh_thaw(); - - if (reload_config) { @@ -174,7 +174,7 @@ index ad79e0c..84d0c5c 100644 - dirty_check(); } - g_main_destroy(main_loop); + g_main_loop_unref(main_loop); diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index b2478c6..cebe260 100644 --- a/src/fe-text/term-terminfo.c diff --git a/src/core/commands.c b/src/core/commands.c index 4ba1ea1c..2805f8c0 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -501,7 +501,7 @@ char *cmd_get_quoted_param(char **data) while (**data != '\0' && (**data != quote || ((*data)[1] != ' ' && (*data)[1] != '\0'))) { if (**data == '\\' && (*data)[1] != '\0') - g_memmove(*data, (*data)+1, strlen(*data)); + memmove(*data, (*data)+1, strlen(*data)); (*data)++; } diff --git a/src/core/line-split.c b/src/core/line-split.c index da84a334..b1e67914 100644 --- a/src/core/line-split.c +++ b/src/core/line-split.c @@ -96,7 +96,7 @@ int line_split(const char *data, int len, char **output, LINEBUF_REC **buffer) if (rec->remove > 0) { rec->len -= rec->remove; - g_memmove(rec->str, rec->str+rec->remove, rec->len); + memmove(rec->str, rec->str+rec->remove, rec->len); rec->remove = 0; } diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c index 2272de1d..a085fac7 100644 --- a/src/core/net-sendbuffer.c +++ b/src/core/net-sendbuffer.c @@ -67,7 +67,7 @@ static int buffer_send(NET_SENDBUF_REC *rec) if (ret > 0) { rec->bufpos -= ret; - g_memmove(rec->buffer, rec->buffer+ret, rec->bufpos); + memmove(rec->buffer, rec->buffer+ret, rec->bufpos); } return FALSE; } diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index b4525db5..a6bbaa27 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -600,7 +600,7 @@ static void print_event_received(IRC_SERVER_REC *server, const char *data, args = g_strdup(ptr); ptr = strstr(args, " :"); if (ptr != NULL) - g_memmove(ptr+1, ptr+2, strlen(ptr+1)); + memmove(ptr+1, ptr+2, strlen(ptr+1)); } recoded = recode_in(SERVER(server), args, NULL); diff --git a/src/fe-none/irssi.c b/src/fe-none/irssi.c index c61d74f7..e7b4c427 100644 --- a/src/fe-none/irssi.c +++ b/src/fe-none/irssi.c @@ -103,9 +103,9 @@ int main(int argc, char **argv) do { reload = FALSE; module_load(autoload_module, NULL); - main_loop = g_main_new(TRUE); - g_main_run(main_loop); - g_main_destroy(main_loop); + main_loop = g_main_loop_new(NULL, TRUE); + g_main_loop_run(main_loop); + g_main_loop_unref(main_loop); } while (reload); noui_deinit(); diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 095c48a1..8ff7e485 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -611,13 +611,13 @@ void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str) entry_text_grow(entry, len); /* make space for the string */ - g_memmove(entry->text + entry->pos + len, entry->text + entry->pos, - (entry->text_len-entry->pos + 1) * sizeof(unichar)); + memmove(entry->text + entry->pos + len, entry->text + entry->pos, + (entry->text_len-entry->pos + 1) * sizeof(unichar)); /* make space for the color */ if (entry->uses_extents) { - g_memmove(entry->extents + entry->pos + len + 1, entry->extents + entry->pos + 1, - (entry->text_len-entry->pos) * sizeof(char *)); + memmove(entry->extents + entry->pos + len + 1, entry->extents + entry->pos + 1, + (entry->text_len-entry->pos) * sizeof(char *)); for (i = 0; i < len; i++) { entry->extents[entry->pos + i + 1] = NULL; } @@ -662,12 +662,12 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) entry_text_grow(entry, 1); /* make space for the string */ - g_memmove(entry->text + entry->pos + 1, entry->text + entry->pos, - (entry->text_len-entry->pos + 1) * sizeof(unichar)); + memmove(entry->text + entry->pos + 1, entry->text + entry->pos, + (entry->text_len-entry->pos + 1) * sizeof(unichar)); if (entry->uses_extents) { - g_memmove(entry->extents + entry->pos + 1 + 1, entry->extents + entry->pos + 1, - (entry->text_len-entry->pos) * sizeof(char *)); + memmove(entry->extents + entry->pos + 1 + 1, entry->extents + entry->pos + 1, + (entry->text_len-entry->pos) * sizeof(char *)); entry->extents[entry->pos + 1] = NULL; } @@ -838,8 +838,8 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ while (entry->pos-size-w > 0 && i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; - g_memmove(entry->text + entry->pos - size, entry->text + entry->pos, - (entry->text_len-entry->pos+1) * sizeof(unichar)); + memmove(entry->text + entry->pos - size, entry->text + entry->pos, + (entry->text_len-entry->pos+1) * sizeof(unichar)); if (entry->uses_extents) { for (i = entry->pos - size; i < entry->pos; i++) { @@ -847,8 +847,8 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ g_free(entry->extents[i+1]); } } - g_memmove(entry->extents + entry->pos - size + 1, entry->extents + entry->pos + 1, - (entry->text_len - entry->pos) * sizeof(void *)); /* no null terminator here */ + memmove(entry->extents + entry->pos - size + 1, entry->extents + entry->pos + 1, + (entry->text_len - entry->pos) * sizeof(void *)); /* no null terminator here */ for (i = 0; i < size; i++) { entry->extents[entry->text_len - i] = NULL; } @@ -876,16 +876,16 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry) while (entry->pos+size < entry->text_len && i_wcwidth(entry->text[entry->pos+size]) == 0) size++; - g_memmove(entry->text + entry->pos, entry->text + entry->pos + size, - (entry->text_len-entry->pos-size+1) * sizeof(unichar)); + memmove(entry->text + entry->pos, entry->text + entry->pos + size, + (entry->text_len-entry->pos-size+1) * sizeof(unichar)); if (entry->uses_extents) { int i; for (i = 0; i < size; i++) { g_free(entry->extents[entry->pos + i + 1]); } - g_memmove(entry->extents + entry->pos + 1, entry->extents + entry->pos + size + 1, - (entry->text_len-entry->pos-size) * sizeof(char *)); + memmove(entry->extents + entry->pos + 1, entry->extents + entry->pos + size + 1, + (entry->text_len-entry->pos-size) * sizeof(char *)); for (i = 0; i < size; i++) { entry->extents[entry->text_len - i] = NULL; } diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 8b466905..ca784bba 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -334,7 +334,7 @@ int main(int argc, char **argv) g_log_set_always_fatal(loglev); textui_finish_init(); - main_loop = g_main_new(TRUE); + main_loop = g_main_loop_new(NULL, TRUE); /* Does the same as g_main_run(main_loop), except we can call our dirty-checker after each iteration */ @@ -348,11 +348,11 @@ int main(int argc, char **argv) dirty_check(); term_refresh_freeze(); - g_main_iteration(TRUE); + g_main_context_iteration(NULL, TRUE); term_refresh_thaw(); } - g_main_destroy(main_loop); + g_main_loop_unref(main_loop); textui_deinit(); session_upgrade(); /* if we /UPGRADEd, start the new process */ diff --git a/src/irc/core/bans.c b/src/irc/core/bans.c index a61742f3..8a43d398 100644 --- a/src/irc/core/bans.c +++ b/src/irc/core/bans.c @@ -75,7 +75,7 @@ char *ban_get_mask(IRC_CHANNEL_REC *channel, const char *nick, int ban_type) size = (int) (host-user); if (size >= 10) { /* too long user mask */ - g_memmove(user+1, user+(size-9), strlen(user+(size-9))+1); + memmove(user+1, user+(size-9), strlen(user+(size-9))+1); } return str; } diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 0191c679..73a06590 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -477,8 +477,8 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data, if (len > 1 && *fname == '"' && fname[len-1] == '"') { /* "file name" - MIRC sends filenames with spaces like this */ fname[len-1] = '\0'; - g_memmove(fname, fname+1, len); - quoted = TRUE; + memmove(fname, fname+1, len); + quoted = TRUE; } if (passive && port != 0) { diff --git a/src/irc/dcc/dcc-server.c b/src/irc/dcc/dcc-server.c index 0a6c0acf..9c20e9bf 100644 --- a/src/irc/dcc/dcc-server.c +++ b/src/irc/dcc/dcc-server.c @@ -261,7 +261,7 @@ static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg) if (len > 1 && *fname == '"' && fname[len-1] == '"') { /* "file name" - MIRC sends filenames with spaces like this */ fname[len-1] = '\0'; - g_memmove(fname, fname+1, len); + memmove(fname, fname+1, len); quoted = TRUE; } From 1cdb4bc311ba0c568c68ae26348bbb1eee273580 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 6 Dec 2019 10:56:25 +0100 Subject: [PATCH 0628/1198] remove GTimeVal following glib 2.61.2 deprecation --- src/common.h | 2 +- src/core/misc.c | 6 ++++++ src/core/misc.h | 7 +++++-- src/core/server-rec.h | 2 +- src/fe-common/core/fe-core-commands.c | 8 ++++---- src/fe-common/core/fe-server.c | 2 +- src/fe-common/irc/fe-ctcp.c | 15 ++++++++------- src/fe-text/gui-readline.c | 14 +++++++------- src/fe-text/statusbar-items.c | 6 +++--- src/irc/core/irc-commands.c | 15 +++++---------- src/irc/core/irc-servers.c | 26 +++++++++++++------------- src/irc/core/irc-servers.h | 4 ++-- src/irc/core/irc.c | 12 ++++++------ src/irc/core/lag.c | 24 ++++++++++++------------ 14 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/common.h b/src/common.h index 355a9b14..d1f34870 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 24 +#define IRSSI_ABI_VERSION 25 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/misc.c b/src/core/misc.c index c959ad91..25e4f32b 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -94,8 +94,11 @@ int g_input_add_poll(int fd, int priority, int condition, return ret; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) { +#pragma GCC diagnostic pop if (tv1->tv_sec < tv2->tv_sec) return -1; if (tv1->tv_sec > tv2->tv_sec) @@ -105,8 +108,11 @@ int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) tv1->tv_usec > tv2->tv_usec ? 1 : 0; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) { +#pragma GCC diagnostic pop long secs, usecs; secs = tv1->tv_sec - tv2->tv_sec; diff --git a/src/core/misc.h b/src/core/misc.h index 65534cdc..cd5cf29c 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -11,11 +11,14 @@ int g_input_add_poll(int fd, int priority, int condition, typedef void* (*FOREACH_FIND_FUNC) (void *item, void *data); typedef int (*COLUMN_LEN_FUNC)(void *data); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /* Returns 1 if tv1 > tv2, -1 if tv2 > tv1 or 0 if they're equal. */ -int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2); +int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; /* Returns "tv1 - tv2", returns the result in milliseconds. Note that if the difference is too large, the result might be invalid. */ -long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2); +long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; +#pragma GCC diagnostic pop GSList *gslist_find_string(GSList *list, const char *key); GSList *gslist_find_icase_string(GSList *list, const char *key); diff --git a/src/core/server-rec.h b/src/core/server-rec.h index e2dcf5ce..c36c8abb 100644 --- a/src/core/server-rec.h +++ b/src/core/server-rec.h @@ -37,7 +37,7 @@ unsigned int usermode_away:1; unsigned int banned:1; /* not allowed to connect to this server */ unsigned int dns_error:1; /* DNS said the host doesn't exist */ -GTimeVal lag_sent; /* 0 or time when last lag query was sent to server */ +gint64 lag_sent; /* 0 or time when last lag query was sent to server */ time_t lag_last_check; /* last time we checked lag */ int lag; /* server lag in milliseconds */ diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 3da998bf..9a2c547f 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -65,7 +65,7 @@ int command_hide_output; the line had one or two command chars, and which one.. */ static const char *current_cmdline; -static GTimeVal time_command_last, time_command_now; +static gint64 time_command_last, time_command_now; static int last_command_cmd, command_cmd; /* SYNTAX: ECHO [-window ] [-level ] */ @@ -222,7 +222,7 @@ static void event_command(const char *data) time_command_last = time_command_now; last_command_cmd = command_cmd; - g_get_current_time(&time_command_now); + time_command_now = g_get_real_time(); command_cmd = *data != '\0' && strchr(settings_get_str("cmdchars"), *data) != NULL; @@ -271,7 +271,7 @@ static void event_default_command(const char *data, void *server, /* maybe we're copy+pasting text? check how long it was since the last line */ - diff = get_timeval_diff(&time_command_now, &time_command_last); + diff = time_command_now - time_command_last; if (item != NULL && !last_command_cmd && diff < PASTE_CHECK_SPEED) { signal_emit("send text", 3, current_cmdline, active_win->active_server, active_win->active); command_cmd = FALSE; @@ -334,7 +334,7 @@ void fe_core_commands_init(void) command_hide_output = 0; command_cmd = FALSE; - memset(&time_command_now, 0, sizeof(GTimeVal)); + time_command_now = 0; command_bind("echo", NULL, (SIGNAL_FUNC) cmd_echo); command_bind("version", NULL, (SIGNAL_FUNC) cmd_version); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index be5ea4ab..f5f96324 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -415,7 +415,7 @@ static void sig_server_lag_disconnected(SERVER_REC *server) printformat(server, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LAG_DISCONNECTED, server->connrec->address, - time(NULL)-server->lag_sent.tv_sec); + time(NULL)-(server->lag_sent / G_TIME_SPAN_SECOND)); } static void sig_server_reconnect_removed(RECONNECT_REC *reconnect) diff --git a/src/fe-common/irc/fe-ctcp.c b/src/fe-common/irc/fe-ctcp.c index 63d7ecd3..c73399be 100644 --- a/src/fe-common/irc/fe-ctcp.c +++ b/src/fe-common/irc/fe-ctcp.c @@ -123,22 +123,23 @@ static void ctcp_ping_reply(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target) { - GTimeVal tv, tv2; + gint64 tv, tv2; long usecs; g_return_if_fail(data != NULL); - if (sscanf(data, "%ld %ld", &tv2.tv_sec, &tv2.tv_usec) < 1) { - char *tmp = g_strconcat("PING ", data, NULL); + if (sscanf(data, "%ld %ld", &tv, &tv2) < 1) { + char *tmp = g_strconcat("PING ", data, NULL); ctcp_default_reply(server, tmp, nick, addr, target); g_free(tmp); return; } - g_get_current_time(&tv); - usecs = get_timeval_diff(&tv, &tv2); - printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, - IRCTXT_CTCP_PING_REPLY, nick, usecs/1000, usecs%1000); + tv2 += tv * G_TIME_SPAN_SECOND; + tv = g_get_real_time(); + usecs = tv - tv2; + printformat(server, server_ischannel(SERVER(server), target) ? target : nick, MSGLEVEL_CTCPS, + IRCTXT_CTCP_PING_REPLY, nick, usecs / G_TIME_SPAN_SECOND, usecs % G_TIME_SPAN_SECOND); } void fe_ctcp_init(void) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 8f5594cb..d56ebfb8 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -58,7 +58,7 @@ static int escape_next_key; static int readtag; static unichar prev_key; -static GTimeVal last_keypress; +static gint64 last_keypress; static int paste_detect_time, paste_verify_line_count; static char *paste_entry; @@ -395,8 +395,8 @@ static void insert_paste_prompt(void) static void sig_gui_key_pressed(gpointer keyp) { - GTimeVal now; - unichar key; + gint64 now; + unichar key; char str[20]; int ret; @@ -407,7 +407,7 @@ static void sig_gui_key_pressed(gpointer keyp) return; } - g_get_current_time(&now); + now = g_get_real_time(); if (key < 32) { /* control key */ @@ -875,7 +875,7 @@ static void key_paste_start(void) time_t get_idle_time(void) { - return last_keypress.tv_sec; + return last_keypress / G_TIME_SPAN_SECOND; } static void key_scroll_backward(void) @@ -1154,8 +1154,8 @@ void gui_readline_init(void) paste_old_prompt = NULL; paste_timeout_id = -1; paste_bracketed_mode = FALSE; - g_get_current_time(&last_keypress); - input_listen_init(STDIN_FILENO); + last_keypress = g_get_real_time(); + input_listen_init(STDIN_FILENO); settings_add_bool("lookandfeel", "term_appkey_mode", TRUE); settings_add_str("history", "scroll_page_count", "/2"); diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index c6770e32..4bca9403 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -333,15 +333,15 @@ static int get_lag(SERVER_REC *server, int *unknown) return 0; } - if (server->lag_sent.tv_sec == 0) { + if (server->lag_sent == 0) { /* no lag queries going on currently */ return server->lag; } - /* we're not sure about our current lag.. */ + /* we're not sure about our current lag.. */ *unknown = TRUE; - lag = (long) (time(NULL)-server->lag_sent.tv_sec); + lag = (long) (time(NULL) - (server->lag_sent / G_TIME_SPAN_SECOND)); if (server->lag/1000 > lag) { /* we've been waiting the lag reply less time than what last known lag was -> use the last known lag */ diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 6737748f..f6c25641 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -528,7 +528,7 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) /* SYNTAX: PING [ | | *] */ static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - GTimeVal tv; + gint64 tv; char *str; CMD_IRC_SERVER(server); @@ -539,9 +539,9 @@ static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item data = window_item_get_target(item); } - g_get_current_time(&tv); + tv = g_get_real_time(); - str = g_strdup_printf("%s PING %ld %ld", data, tv.tv_sec, tv.tv_usec); + str = g_strdup_printf("%s PING %ld %ld", data, tv / G_TIME_SPAN_SECOND, tv % G_TIME_SPAN_SECOND); signal_emit("command ctcp", 3, str, server, item); g_free(str); } @@ -616,13 +616,8 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) n = atoi(msecs); if (server != NULL && n > 0) { - g_get_current_time(&server->wait_cmd); - server->wait_cmd.tv_sec += n/1000; - server->wait_cmd.tv_usec += n%1000; - if (server->wait_cmd.tv_usec >= 1000) { - server->wait_cmd.tv_sec++; - server->wait_cmd.tv_usec -= 1000; - } + server->wait_cmd = g_get_real_time(); + server->wait_cmd += n * G_TIME_SPAN_MILLISECOND; } cmd_params_free(free_arg); } diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 3ec0bba5..9779ab58 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -294,8 +294,8 @@ static void server_init(IRC_SERVER_REC *server) /* prevent the queue from sending too early, we have a max cut off of 120 secs */ /* this will reset to 1 sec after we get the 001 event */ - g_get_current_time(&server->wait_cmd); - g_time_val_add(&server->wait_cmd, 120 * G_USEC_PER_SEC); + server->wait_cmd = g_get_real_time(); + server->wait_cmd += 120 * G_USEC_PER_SEC; } SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn) @@ -559,21 +559,21 @@ void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len) return; } - g_get_current_time(&server->last_cmd); + server->last_cmd = g_get_real_time(); /* A bit kludgy way to do the flood protection. In ircnet, there actually is 1sec / 100 bytes penalty, but we rather want to deal with the max. 1000 bytes input buffer problem. If we send more than that with the burst, we'll get excess flooded. */ if (len < 100 || server->cmd_queue_speed <= 10) - server->wait_cmd.tv_sec = 0; + server->wait_cmd = 0; else { - memcpy(&server->wait_cmd, &server->last_cmd, sizeof(GTimeVal)); - g_time_val_add(&server->wait_cmd, (2 + len/100) * G_USEC_PER_SEC); + server->wait_cmd = server->last_cmd; + server->wait_cmd += (2 + len / 100) * G_USEC_PER_SEC; } } -static int server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) +static int server_cmd_timeout(IRC_SERVER_REC *server, gint64 now) { REDIRECT_REC *redirect; GSList *link; @@ -587,10 +587,10 @@ static int server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) if (server->cmdcount == 0 && server->cmdqueue == NULL) return 0; - if (g_timeval_cmp(now, &server->wait_cmd) == -1) + if (now < server->wait_cmd) return 1; - usecs = get_timeval_diff(now, &server->last_cmd); + usecs = (now - server->last_cmd) / G_TIME_SPAN_MILLISECOND; if (usecs < server->cmd_queue_speed) return 1; @@ -626,13 +626,13 @@ static int server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) /* check every now and then if there's data to be sent in command buffer */ static int servers_cmd_timeout(void) { - GTimeVal now; + gint64 now; GSList *tmp; int keep = 0; - g_get_current_time(&now); + now = g_get_real_time(); for (tmp = servers; tmp != NULL; tmp = tmp->next) { - keep |= server_cmd_timeout(tmp->data, &now); + keep |= server_cmd_timeout(tmp->data, now); } if (keep) return 1; @@ -735,7 +735,7 @@ static void event_connected(IRC_SERVER_REC *server, const char *data, const char server->real_connect_time = time(NULL); /* let the queue send now that we are identified */ - g_get_current_time(&server->wait_cmd); + server->wait_cmd = g_get_real_time(); if (server->connrec->usermode != NULL) { /* Send the user mode, before the autosendcmd. diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 2757db0d..b7d31038 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -113,8 +113,8 @@ struct _IRC_SERVER_REC { how many messages can be sent before starting the flood control */ GSList *cmdqueue; /* command, redirection, ... */ - GTimeVal wait_cmd; /* don't send anything to server before this */ - GTimeVal last_cmd; /* last time command was sent to server */ + gint64 wait_cmd; /* don't send anything to server before this */ + gint64 last_cmd; /* last time command was sent to server */ int max_cmds_at_once; /* How many messages can be sent immediately before timeouting starts */ int cmd_queue_speed; /* Timeout between sending commands */ diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 51770aaf..ef7a3ad1 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -140,15 +140,15 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, /* Send command to IRC server */ void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd) { - GTimeVal now; + gint64 now; int send_now; - g_get_current_time(&now); - send_now = g_timeval_cmp(&now, &server->wait_cmd) >= 0 && - (server->cmdcount < server->max_cmds_at_once || - server->cmd_queue_speed <= 0); + now = g_get_real_time(); + send_now = now >= server->wait_cmd && + (server->cmdcount < server->max_cmds_at_once || + server->cmd_queue_speed <= 0); - irc_send_cmd_full(server, cmd, send_now, FALSE, FALSE); + irc_send_cmd_full(server, cmd, send_now, FALSE, FALSE); } /* Send command to IRC server */ diff --git a/src/irc/core/lag.c b/src/irc/core/lag.c index d3d6118d..66b0914a 100644 --- a/src/irc/core/lag.c +++ b/src/irc/core/lag.c @@ -30,7 +30,7 @@ static int timeout_tag; static void lag_get(IRC_SERVER_REC *server) { - g_get_current_time(&server->lag_sent); + server->lag_sent = g_get_real_time(); server->lag_last_check = time(NULL); server_redirect_event(server, "ping", 1, NULL, FALSE, @@ -48,18 +48,18 @@ static void lag_ping_error(IRC_SERVER_REC *server) static void lag_event_pong(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr) { - GTimeVal now; + gint64 now; g_return_if_fail(data != NULL); - if (server->lag_sent.tv_sec == 0) { + if (server->lag_sent == 0) { /* not expecting lag reply.. */ return; } - g_get_current_time(&now); - server->lag = (int) get_timeval_diff(&now, &server->lag_sent); - memset(&server->lag_sent, 0, sizeof(server->lag_sent)); + now = g_get_real_time(); + server->lag = now - server->lag_sent; + server->lag_sent = 0; signal_emit("server lag", 1, server); } @@ -76,8 +76,8 @@ static void sig_unknown_command(IRC_SERVER_REC *server, const char *data) trying alternative methods to detect lag with these servers. */ server->disable_lag = TRUE; - server->lag_sent.tv_sec = 0; - server->lag = 0; + server->lag_sent = 0; + server->lag = 0; } g_free(params); } @@ -102,16 +102,16 @@ static int sig_check_lag(void) if (!IS_IRC_SERVER(rec) || rec->disable_lag) continue; - if (rec->lag_sent.tv_sec != 0) { + if (rec->lag_sent != 0) { /* waiting for lag reply */ - if (max_lag > 1 && now-rec->lag_sent.tv_sec > max_lag) { + if (max_lag > 1 && now - rec->lag_sent > max_lag * G_TIME_SPAN_SECOND) { /* too much lag, disconnect */ signal_emit("server lag disconnect", 1, rec); rec->connection_lost = TRUE; server_disconnect((SERVER_REC *) rec); } - } else if (rec->lag_last_check+lag_check_time < now && - rec->cmdcount == 0 && rec->connected) { + } else if (rec->lag_last_check + lag_check_time < now && rec->cmdcount == 0 && + rec->connected) { /* no commands in buffer - get the lag */ lag_get(rec); } From 7d44964dcd37a32ef56fedae49d1631c4418b6ab Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 9 Dec 2019 22:47:59 -0500 Subject: [PATCH 0629/1198] fix #641 Track the address family of the last failed connection attempt (either immediately or during TLS handshake), then disprefer that address family during reconnection. --- src/core/server-connect-rec.h | 2 ++ src/core/servers-reconnect.c | 1 + src/core/servers.c | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h index fa348769..2f68bd04 100644 --- a/src/core/server-connect-rec.h +++ b/src/core/server-connect-rec.h @@ -11,6 +11,7 @@ int proxy_port; char *proxy_string, *proxy_string_after, *proxy_password; unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */ +unsigned short chosen_family; /* family actually chosen during name resolution */ char *tag; /* try to keep this tag when connected to server */ char *address; int port; @@ -43,5 +44,6 @@ unsigned int unix_socket:1; /* Connect using named unix socket */ unsigned int use_tls:1; /* this connection uses TLS */ unsigned int tls_verify:1; unsigned int no_connect:1; /* don't connect() at all, it's done by plugin */ +unsigned short last_failed_family; /* #641: if we failed to connect to ipv6, try ipv4 and vice versa */ char *channels; char *away_reason; diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 2cbe60b4..0cfac2ec 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -168,6 +168,7 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) server_connect_ref(dest); dest->type = module_get_uniq_id("SERVER CONNECT", 0); dest->reconnection = src->reconnection; + dest->last_failed_family = src->last_failed_family; dest->proxy = g_strdup(src->proxy); dest->proxy_port = src->proxy_port; dest->proxy_string = g_strdup(src->proxy_string); diff --git a/src/core/servers.c b/src/core/servers.c index 20452f8c..27f788bb 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -156,6 +156,7 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle) error = net_geterror(handle); if (error != 0) { server->connection_lost = TRUE; + server->connrec->last_failed_family = server->connrec->chosen_family; server_connect_failed(server, g_strerror(error)); return; } @@ -176,6 +177,7 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han error = irssi_ssl_handshake(handle); if (error == -1) { server->connection_lost = TRUE; + server->connrec->last_failed_family = server->connrec->chosen_family; server_connect_failed(server, NULL); return; } @@ -216,6 +218,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, return; if (ip != NULL) { + server->connrec->chosen_family = ip->family; own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4; port = server->connrec->proxy != NULL ? server->connrec->proxy_port : server->connrec->port; @@ -241,9 +244,11 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, server->no_reconnect = TRUE; server->connection_lost = TRUE; + server->connrec->last_failed_family = ip->family; server_connect_failed(server, errmsg2 ? errmsg2 : errmsg); g_free(errmsg2); } else { + server->connrec->last_failed_family = 0; server->handle = net_sendbuffer_create(handle, 0); if (server->connrec->use_tls) server_connect_callback_init_ssl(server, handle); @@ -289,11 +294,15 @@ static void server_connect_callback_readpipe(SERVER_REC *server) ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6; servername = iprec.host6; } else { - /* pick the one that was found, or if both do it like - /SET resolve_prefer_ipv6 says. */ + /* pick the one that was found. if both were found: + 1. disprefer the last one that failed + 2. prefer ipv4 over ipv6 unless resolve_prefer_ipv6 is set + */ if (iprec.ip4.family == 0 || (iprec.ip6.family != 0 && - settings_get_bool("resolve_prefer_ipv6"))) { + (server->connrec->last_failed_family == AF_INET || + (settings_get_bool("resolve_prefer_ipv6") && + server->connrec->last_failed_family != AF_INET6)))) { ip = &iprec.ip6; servername = iprec.host6; } else { From b8be2906401cd9071276b68a81516b4954e31676 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 8 Jan 2020 10:15:47 +0100 Subject: [PATCH 0630/1198] Update src/irc/core/lag.c Co-Authored-By: dx --- src/irc/core/lag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/lag.c b/src/irc/core/lag.c index 66b0914a..6af8524c 100644 --- a/src/irc/core/lag.c +++ b/src/irc/core/lag.c @@ -58,7 +58,7 @@ static void lag_event_pong(IRC_SERVER_REC *server, const char *data, } now = g_get_real_time(); - server->lag = now - server->lag_sent; + server->lag = (now - server->lag_sent) / G_TIME_SPAN_MILLISECOND; server->lag_sent = 0; signal_emit("server lag", 1, server); From e59c42bcc0a4c1a353d39e7e253adc293a152988 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 7 Feb 2020 16:33:53 +0100 Subject: [PATCH 0631/1198] refine zero width input test in empty line fixes #1153 --- 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 8ff7e485..d1cc8811 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -654,7 +654,7 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr) if (chr == 0 || chr == 13 || chr == 10) return; /* never insert NUL, CR or LF characters */ - if (entry->utf8 && entry->pos == 0 && i_wcwidth(chr) == 0) + if (entry->utf8 && entry->pos == 0 && unichar_isprint(chr) && i_wcwidth(chr) == 0) return; gui_entry_redraw_from(entry, entry->pos); From 5dba9fd0cc1839f13a0859420fcc9373f9b7a276 Mon Sep 17 00:00:00 2001 From: vague666 Date: Sun, 9 Feb 2020 12:40:09 +0100 Subject: [PATCH 0632/1198] Search for word anywhere, not only from the beginning of string --- src/fe-common/core/keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index 8f90b1ad..986ee7bd 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -772,7 +772,7 @@ static void cmd_show_keys(const char *searchkey, int full) if ((len == 0 || (full ? strncmp(rec->key, searchkey, len) == 0 : - g_ascii_strncasecmp(rec->key, searchkey, len) == 0)) && + g_strrstr(rec->key, searchkey) != NULL)) && (!full || rec->key[len] == '\0')) { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_LIST, rec->key, rec->info->id, rec->data == NULL ? "" : rec->data); From 03295b73b4d524b082b307a4ac3c437f92902c7b Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 17 Feb 2020 19:55:38 +0100 Subject: [PATCH 0633/1198] Improve server help --- docs/help/in/server.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 2e757260..593b144d 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -56,6 +56,8 @@ disconnected unless you prepend the server with the '+' character; the same method is applicable to the CONNECT parameter. + Specify '-' as password to remove a server password + %9Examples:%9 /SERVER From 43092a5bcc95e75576eb175a4cacddbbd8449a9e Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 19 Feb 2020 16:55:11 +0100 Subject: [PATCH 0634/1198] Improve server help --- docs/help/in/server.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 593b144d..d7640beb 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -56,7 +56,7 @@ disconnected unless you prepend the server with the '+' character; the same method is applicable to the CONNECT parameter. - Specify '-' as password to remove a server password + Specify '-' as password to remove a added server password %9Examples:%9 @@ -66,6 +66,7 @@ /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 /SERVER MODIFY -network Freenode -noauto orwell.freenode.net + /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE /SERVER PURGE orwell.freenode.net From ca04e0ba5de0f1fc6c93326373e33d0e1587df56 Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 9 Mar 2020 14:15:40 +0100 Subject: [PATCH 0635/1198] -time was missing in /ignore output and made it human-readable --- src/fe-common/core/fe-ignore.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 54ab6a55..e34055bc 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -19,6 +19,7 @@ */ #include "module.h" +#include #include #include #include @@ -48,6 +49,8 @@ static void ignore_print(int index, IGNORE_REC *rec) { GString *options; char *key, *levels; + struct tm ts; + char buf[20]; key = ignore_get_key(rec); levels = bits2level(rec->level); @@ -67,6 +70,11 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append_printf(options, "-network %s ", rec->servertag); if (rec->pattern != NULL) g_string_append_printf(options, "-pattern %s ", rec->pattern); + if (rec->unignore_time != NULL) { + ts = *localtime(&rec->unignore_time); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); + g_string_append_printf(options, "ignore ends: %s ", buf); + } if (options->len > 1) g_string_truncate(options, options->len-1); From 7e898fdcf4ab2d89977b2ef8db448986b8b68a37 Mon Sep 17 00:00:00 2001 From: vague666 Date: Thu, 12 Mar 2020 22:52:12 +0100 Subject: [PATCH 0636/1198] Make sure witem exists --- src/fe-common/core/fe-core-commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 9a2c547f..ea162e08 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -155,7 +155,9 @@ static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) return; } - target = g_hash_table_lookup(optlist, "window") != NULL ? item->name : NULL; + target = item != NULL && g_hash_table_lookup(optlist, "window") != NULL + ? item->name + : NULL; g_io_channel_set_encoding(handle, NULL, NULL); g_io_channel_seek_position(handle, fpos, G_SEEK_SET, NULL); From 1ad1083f84572e26467c27752545ddce5fd353a2 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 17 Mar 2020 00:54:23 +0000 Subject: [PATCH 0637/1198] improve wording --- docs/help/in/server.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/server.in b/docs/help/in/server.in index d7640beb..beb75114 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -56,7 +56,7 @@ disconnected unless you prepend the server with the '+' character; the same method is applicable to the CONNECT parameter. - Specify '-' as password to remove a added server password + Specify '-' as password to remove a server password %9Examples:%9 From 22851686f5b88ac83ca49e80e743ed50d18c57af Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 17 Mar 2020 00:58:48 +0000 Subject: [PATCH 0638/1198] simplify logic --- src/fe-common/core/fe-core-commands.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index ea162e08..c9ca93ce 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -117,7 +117,8 @@ static void cmd_version(char *data) /* SYNTAX: CAT [-window] [] */ static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { - char *fname, *fposstr, *target; + char *fname, *fposstr; + gboolean target; GHashTable *optlist; void *free_arg; int fpos; @@ -155,16 +156,14 @@ static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) return; } - target = item != NULL && g_hash_table_lookup(optlist, "window") != NULL - ? item->name - : NULL; + target = g_hash_table_lookup(optlist, "window") != NULL; g_io_channel_set_encoding(handle, NULL, NULL); g_io_channel_seek_position(handle, fpos, G_SEEK_SET, NULL); buf = g_string_sized_new(512); while (g_io_channel_read_line_string(handle, buf, &tpos, NULL) == G_IO_STATUS_NORMAL) { buf->str[tpos] = '\0'; - printtext(target != NULL ? server : NULL, target, MSGLEVEL_CLIENTCRAP | + printtext(target ? server : NULL, target && item != NULL ? item->name : NULL, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); } g_string_free(buf, TRUE); From d5a55f5e6ed4d2ba64fed2697c4e8a9477477364 Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 18 Mar 2020 17:27:18 +0100 Subject: [PATCH 0639/1198] unignore_time can not be NULL, check for 0 instead --- src/fe-common/core/fe-ignore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index e34055bc..890d2c19 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -70,7 +70,7 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append_printf(options, "-network %s ", rec->servertag); if (rec->pattern != NULL) g_string_append_printf(options, "-pattern %s ", rec->pattern); - if (rec->unignore_time != NULL) { + if (rec->unignore_time != 0) { ts = *localtime(&rec->unignore_time); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); g_string_append_printf(options, "ignore ends: %s ", buf); From 597afa404383a62d1a2e03600992db6e2e7c821c Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 18 Mar 2020 16:32:49 +0000 Subject: [PATCH 0640/1198] Use github actions to test PRs --- .github/workflows/{push.yml => check.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{push.yml => check.yml} (96%) diff --git a/.github/workflows/push.yml b/.github/workflows/check.yml similarity index 96% rename from .github/workflows/push.yml rename to .github/workflows/check.yml index 71b388a2..17da255d 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/check.yml @@ -1,4 +1,4 @@ -on: [push] +on: [pull_request] name: Check Irssi jobs: install: From be467111fa891697d92a8afde5dd0e66b8f32937 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 16 Mar 2020 21:39:33 +0100 Subject: [PATCH 0641/1198] update docs --- docs/design.html | 3 +-- docs/faq.html | 7 +++---- docs/faq.txt | 6 +++--- docs/startup-HOWTO.html | 9 ++++----- docs/startup-HOWTO.txt | 6 +++--- utils/syncdocs.sh | 2 +- 6 files changed, 15 insertions(+), 18 deletions(-) diff --git a/docs/design.html b/docs/design.html index 4be231ee..3865a7fb 100644 --- a/docs/design.html +++ b/docs/design.html @@ -1,7 +1,6 @@

Design

- -

Irssi’s hierarchy is something like this:

+

Irssi’s hierarchy is something like this:


         sub1 sub2
diff --git a/docs/faq.html b/docs/faq.html
index 70e90bb5..7c17f45d 100644
--- a/docs/faq.html
+++ b/docs/faq.html
@@ -1,7 +1,6 @@
 
 

Frequently Asked Questions

- -

Q: Why doesn’t irssi display colors even when ircii etc. displays them?

+

Q: Why doesn’t irssi display colors even when ircii etc. displays them?

A: They force ANSI colors even if terminal doesn’t support them. By default, irssi uses colors only if terminfo/termcap so says. The correct way to fix this would be to change your TERM environment to a value where colors work, like xterm-color or color_xterm (eg. TERM=xterm-color irssi). If this doesn’t help, then use the evil way of /SET term_force_colors ON.

@@ -55,7 +54,7 @@

Q: Will there be /DETACH-like feature?

-

A: tmux, screen and dtach can be used to do it just fine.

+

A: tmux, screen and dtach can be used to do it just fine.

Q: How do I run scripts automatically at startup?

@@ -71,7 +70,7 @@

Q: How can I have /WHOIS replies to active window?

-

A: You can disable the status window, or do /WINDOW LEVEL -CRAP in it which would also make several other messages show up in active window. You can also use a script.

+

A: You can disable the status window, or do /WINDOW LEVEL -CRAP in it which would also make several other messages show up in active window. You can also use a script.

Q: How do I add the active network to the statusbar

diff --git a/docs/faq.txt b/docs/faq.txt index 719fbb9a..0d0b5f46 100644 --- a/docs/faq.txt +++ b/docs/faq.txt @@ -117,8 +117,8 @@ A: Check [6]here References: [1] https://github.com/irssi-import/xirssi - [2] http://tmux.github.io/ - [3] http://www.gnu.org/software/screen/screen.html + [2] https://tmux.github.io/ + [3] https://www.gnu.org/software/screen/screen.html [4] http://dtach.sf.net/ - [5] http://dgl.cx/irssi/hack-whois-in-current-window.pl + [5] https://dgl.cx/irssi/hack-whois-in-current-window.pl [6] https://irssi.org/assets/irssi.wav diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 36d8edbf..48f6e6df 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -1,9 +1,8 @@

Startup How-To

+

To new Irssi users (not to new IRC users ..)

-

To new Irssi users (not to new IRC users ..)

- -

Copyright (c) 2000-2002 by Timo Sirainen, release under GNU FDL 1.1 license.

+

Copyright (c) 2000-2002 by Timo Sirainen, release under GNU FDL 1.1 license.

Index with some FAQ questions that are answered in the chapter:

@@ -161,7 +160,7 @@ Ctrl-P, Ctrl-N - Jump to previous / next window

Split windows and window items

-

Note: this guide might be a better introduction to window splits

+

Note: this guide might be a better introduction to window splits

Irssi also supports split windows, they’ve had some problems in past but I think they should work pretty well now :) Here’s some commands related to them:

@@ -516,7 +515,7 @@ Ctrl-X - set the next server in list active

SOCKS

-

Irssi can be compiled with socks support (\--with-socks option to configure), which requires “dante” and routes all connections through the proxy specified in the system-wide /etc/socks.conf. This method is known to have issues in Mac OS X.

+

Irssi can be compiled with socks support (--with-socks option to configure), which requires “dante” and routes all connections through the proxy specified in the system-wide /etc/socks.conf. This method is known to have issues in Mac OS X.

Note that /SET proxy settings don’t have anything to do with socks.

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index ecfe7ad8..61de27e3 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -578,7 +578,7 @@ Irssi proxy works fine with other IRC clients as well. SOCKS -Irssi can be compiled with socks support (\--with-socks option to configure), +Irssi can be compiled with socks support (--with-socks option to configure), which requires “dante” and routes all connections through the proxy specified in the system-wide /etc/socks.conf. This method is known to have issues in Mac OS X. @@ -792,8 +792,8 @@ ADD -before act mail. References: -[1] http://www.gnu.org/licenses/fdl.html +[1] https://www.gnu.org/licenses/fdl.html [2] https://www.iterm2.com/ -[3] http://quadpoint.org/articles/irssisplit/ +[3] https://quadpoint.org/articles/irssisplit/ [4] https://github.com/rofl0r/proxychains-ng [5] https://irssi.org/documentation/settings/ diff --git a/utils/syncdocs.sh b/utils/syncdocs.sh index bd92ffab..fb88393b 100755 --- a/utils/syncdocs.sh +++ b/utils/syncdocs.sh @@ -13,7 +13,7 @@ design=$site/documentation/design/ # FOOTER. May need to be adjusted as the source pages change pageclean_regex='s{.*(?=)?\s*(
\s*){0,3})}{\1\2}g;' +s{(<.*?)\sclass="(?:[^"]*\s+)*(?:highlighter-rouge|highlight)"(.*?>)}{\1\2}g;' srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. From 97670d1dc1b9f0fd2de2b0fe2f08bfdfcb7f0c12 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 30 Mar 2020 14:30:05 +0200 Subject: [PATCH 0642/1198] run syncscripts.sh sync scriptassist.pl to 2003020807 --- scripts/scriptassist.pl | 57 ++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/scripts/scriptassist.pl b/scripts/scriptassist.pl index 68708945..536ef33a 100644 --- a/scripts/scriptassist.pl +++ b/scripts/scriptassist.pl @@ -5,22 +5,22 @@ use strict; -our $VERSION = '2003020806'; +our $VERSION = '2003020807'; our %IRSSI = ( authors => 'Stefan \'tommie\' Tomanek', contact => 'stefan@pico.ruhr.de', name => 'scriptassist', description => 'keeps your scripts on the cutting edge', license => 'GPLv2', - url => 'http://irssi.org/scripts/', - modules => 'Data::Dumper LWP::UserAgent (GnuPG)', + url => 'https://scripts.irssi.org/', + modules => 'CPAN::Meta::YAML LWP::Protocol::https (GnuPG)', commands => "scriptassist" ); our ($forked, %remote_db, $have_gpg, @complist); use Irssi 20020324; -use Data::Dumper; +use CPAN::Meta::YAML; use LWP::UserAgent; use POSIX; @@ -170,14 +170,13 @@ sub bg_do { my $cmd = $items[1]; $result{data}{unknown}{$cmd} = get_unknown($cmd, $xml); } - my $dumper = Data::Dumper->new([\%result]); - $dumper->Purity(1)->Deepcopy(1)->Indent(0); - my $data = $dumper->Dump; + my $yaml = CPAN::Meta::YAML->new(\%result); + my $data = $yaml->write_string(); print($wh $data); }; if ($@) { - print($wh Data::Dumper->new([+{data=>+{error=>$@}}]) - ->Purity(1)->Deepcopy(1)->Indent(0)->Dump); + print($wh CPAN::Meta::YAML->new(+{data=>+{error=>$@}}) + ->write_string()); } close($wh); POSIX::_exit(1); @@ -313,7 +312,7 @@ sub get_new { my ($num) = @_; my $result; my $xml = get_scripts(); - foreach (sort {$xml->{$b}{last_modified} cmp $xml->{$a}{last_modified}} keys %$xml) { + foreach (sort {$xml->{$b}{modified} cmp $xml->{$a}{modified}} keys %$xml) { my %entry = %{ $xml->{$_} }; next if $entry{HIDDEN}; $result->{$_} = \%entry; @@ -427,8 +426,8 @@ sub pipe_input { print CLIENTCRAP "%R<<%n Something weird happend (no text)"; return(); } - local our $VAR1; - my $incoming = eval($text); + utf8::decode($text); + my $incoming = CPAN::Meta::YAML->read_string($text)->[0]; if ($incoming->{db} && $incoming->{timestamp}) { $remote_db{db} = $incoming->{db}; $remote_db{timestamp} = $incoming->{timestamp}; @@ -628,7 +627,7 @@ sub print_ratings { sub print_new { my ($list) = @_; my @table; - foreach (sort {$list->{$b}{last_modified} cmp $list->{$a}{last_modified}} keys %$list) { + foreach (sort {$list->{$b}{modified} cmp $list->{$a}{modified}} keys %$list) { my @line; my ($name) = get_names($_); if (get_local_version($name)) { @@ -637,7 +636,7 @@ sub print_new { push @line, "%yo%n"; } push @line, "%9".$name."%9"; - push @line, $list->{$_}{last_modified}; + push @line, $list->{$_}{modified}; push @table, \@line; } print CLIENTCRAP draw_box('ScriptAssist', array2table(@table), 'new scripts', 1) ; @@ -822,7 +821,7 @@ sub contact_author { sub get_scripts { my $ua = LWP::UserAgent->new(env_proxy=>1, keep_alive=>1, timeout=>30); - $ua->agent('ScriptAssist/'.2003020803); + $ua->agent('ScriptAssist/'.$VERSION); $ua->env_proxy(); my @mirrors = split(/ /, Irssi::settings_get_str('scriptassist_script_sources')); my %sites_db; @@ -852,22 +851,25 @@ sub get_scripts { $type = $2; } push @sources, $src; - #my @header = ('name', 'contact', 'authors', 'description', 'version', 'modules', 'last_modified'); + #my @header = ('name', 'contact', 'authors', 'description', 'version', 'modules', 'modified'); if ($type eq 'dmp') { - no strict 'vars'; - my $new_db = eval "$data"; - foreach (keys %$new_db) { - if (defined $sites_db{script}{$_}) { - my $old = $sites_db{$_}{version}; - my $new = $new_db->{$_}{version}; + die("Support for $type script database has been removed. Please /set scriptassist_script_sources and change $type -> yml.\n"); + } elsif ($type eq 'yml') { + utf8::decode($data); + my $new_db = CPAN::Meta::YAML->read_string($data); + foreach (@{$new_db->[0]}) { + my $K = $_->{filename}; + if (defined $sites_db{script}{$K}) { + my $old = $sites_db{$K}{version}; + my $new = $_->{version}; next if (compare_versions($old, $new) eq 'newer'); } #foreach my $key (@header) { - foreach my $key (keys %{ $new_db->{$_} }) { - next unless defined $new_db->{$_}{$key}; - $sites_db{$_}{$key} = $new_db->{$_}{$key}; + foreach my $key (keys %$_) { + next unless defined $_->{$key}; + $sites_db{$K}{$key} = $_->{$key}; } - $sites_db{$_}{source} = $src; + $sites_db{$K}{source} = $src; } } else { die("Unknown script database type ($type).\n"); @@ -1093,6 +1095,7 @@ sub missing_module { sub cmd_scripassist { my ($arg, $server, $witem) = @_; + utf8::decode($arg); my @args = split(/ /, $arg); if ($args[0] eq 'help' || $args[0] eq '-h') { show_help(); @@ -1176,7 +1179,7 @@ sub sig_complete { } -Irssi::settings_add_str($IRSSI{name}, 'scriptassist_script_sources', 'https://scripts.irssi.org/scripts.dmp'); +Irssi::settings_add_str($IRSSI{name}, 'scriptassist_script_sources', 'https://scripts.irssi.org/scripts.yml'); Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_cache_sources', 1); Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_update_verbose', 1); Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_check_verbose', 1); From 4594b0c4cf0ddc449f45b81ddea2180b837a10ac Mon Sep 17 00:00:00 2001 From: ailin Date: Thu, 2 Apr 2020 04:39:24 +0200 Subject: [PATCH 0643/1198] fix perl module build on openbsd unfortunately, some mangling is needed to create the correct linker and compiler invocations --- meson.build | 6 ++++++ src/perl/meson.build | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 2ea7bcc7..dc3a4fc2 100644 --- a/meson.build +++ b/meson.build @@ -406,6 +406,12 @@ if want_capsicum endif endif +# dependency helper sets +dep_cflagsonly = [] +foreach d : dep + dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true) +endforeach + ################## # irssi-config.h # ################## diff --git a/src/perl/meson.build b/src/perl/meson.build index dd8f2f8c..aa2b609f 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -35,7 +35,8 @@ shared_module('perl_core', install_dir : moduledir, install_rpath : perl_rpath, build_rpath : perl_rpath, - dependencies : dep + [ perl_dep ], + dependencies : dep_cflagsonly + [ perl_dep ], + override_options : ['b_asneeded=false'], ) shared_module('fe_perl', From ae89ba716441261333e340bea8e1b9851fe0f294 Mon Sep 17 00:00:00 2001 From: ailin Date: Thu, 2 Apr 2020 15:39:40 +0200 Subject: [PATCH 0644/1198] fix crash on /quit when unloading modules this fixes a crash on /quit when the module unloaded is trying to reference symbols from already-unloaded modules, by reversing the lists. --- src/core/modules.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/modules.c b/src/core/modules.c index 119a8e67..38c33dea 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -214,7 +214,7 @@ MODULE_FILE_REC *module_register_full(const char *name, const char *submodule, module = g_new0(MODULE_REC, 1); module->name = g_strdup(name); - modules = g_slist_append(modules, module); + modules = g_slist_prepend(modules, module); } file = module_file_find(module, submodule); @@ -226,8 +226,8 @@ MODULE_FILE_REC *module_register_full(const char *name, const char *submodule, file->name = g_strdup(submodule); file->defined_module_name = g_strdup(defined_module_name); - module->files = g_slist_append(module->files, file); - return file; + module->files = g_slist_prepend(module->files, file); + return file; } MODULE_REC *module_find(const char *name) From 8a446d24de9be3e35a638cd8f6856dea9ddd4b74 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 2 Apr 2020 15:47:15 +0200 Subject: [PATCH 0645/1198] fix /ignore ... MODES NO_ACT not working reported by letty --- src/fe-common/irc/fe-modes.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c index 61ea6c38..9ea2414d 100644 --- a/src/fe-common/irc/fe-modes.c +++ b/src/fe-common/irc/fe-modes.c @@ -36,6 +36,7 @@ typedef struct { IRC_CHANNEL_REC *channel; + int level; char *mode; GSList *nicks; time_t last_mode; @@ -84,9 +85,8 @@ static void print_mode(MODE_REC *rec) tmp = modes; modes = NULL; nicks = gslist_to_string(rec->nicks, ", "); - printformat(rec->channel->server, rec->channel->visible_name, - MSGLEVEL_MODES, IRCTXT_CHANMODE_CHANGE, - rec->channel->visible_name, rec->mode, nicks, ""); + printformat(rec->channel->server, rec->channel->visible_name, rec->level, + IRCTXT_CHANMODE_CHANGE, rec->channel->visible_name, rec->mode, nicks, ""); g_free(nicks); modes = tmp; @@ -126,8 +126,8 @@ static int sig_check_modes(void) return 1; } -static void msg_multi_mode(IRC_CHANNEL_REC *channel, const char *sender, - const char *addr, const char *mode) +static void msg_multi_mode(IRC_CHANNEL_REC *channel, int level, const char *sender, + const char *addr, const char *mode) { MODE_REC *rec; @@ -147,10 +147,13 @@ static void msg_multi_mode(IRC_CHANNEL_REC *channel, const char *sender, rec = g_new0(MODE_REC, 1); modes = g_slist_append(modes, rec); + rec->level = level; rec->channel = channel; rec->mode = g_strdup(mode); } - + /* the levels (everything below MSGLEVEL_ALL) are combined (|) + whereas the flags (anything above) must all match (&) */ + rec->level = ((rec->level | level) & MSGLEVEL_ALL) | (rec->level & level); rec->nicks = g_slist_append(rec->nicks, g_strdup(sender)); rec->last_mode = time(NULL); @@ -187,7 +190,7 @@ static void sig_message_mode(IRC_SERVER_REC *server, const char *channel, irc_channel_find(server, channel); if (chanrec != NULL && g_ascii_strcasecmp(nick, server->nick) != 0) - msg_multi_mode(chanrec, nick, addr, mode); + msg_multi_mode(chanrec, level, nick, addr, mode); else { printformat(server, channel, level, IRCTXT_CHANMODE_CHANGE, From 81dc94c406361564d833d33fadd9188f542fb46d Mon Sep 17 00:00:00 2001 From: Pinguin1234 <18099221+Pinguin1234@users.noreply.github.com> Date: Sat, 4 Apr 2020 00:55:27 +0200 Subject: [PATCH 0646/1198] Added option to quit in SIGHUP --- src/core/core.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 878d9eb6..08d9cb6e 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -88,6 +88,11 @@ static void sig_reload_config(int signo) reload_config = TRUE; } +static void sig_quit_on_hup(int signo) +{ + signal_emit("gui exit", 0); +} + static void read_settings(void) { static int signals[] = { @@ -102,14 +107,16 @@ static void read_settings(void) const char *ignores; struct sigaction act; int n; + int quit_on_hup; ignores = settings_get_str("ignore_signals"); sigemptyset (&act.sa_mask); act.sa_flags = 0; - /* reload config on SIGHUP */ - act.sa_handler = sig_reload_config; + quit_on_hup = settings_get_bool("quit_on_hup"); + + act.sa_handler = quit_on_hup ? sig_quit_on_hup : sig_reload_config; sigaction(SIGHUP, &act, NULL); for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) { @@ -267,6 +274,8 @@ void core_init(void) settings_add_str("misc", "ignore_signals", ""); settings_add_bool("misc", "override_coredump_limit", FALSE); + settings_add_bool("misc", "quit_on_hup", FALSE); + #ifdef HAVE_SYS_RESOURCE_H getrlimit(RLIMIT_CORE, &orig_core_rlimit); From cae37e37ca6b047411f86681255eca322cfd835a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 4 Apr 2020 01:12:03 +0200 Subject: [PATCH 0647/1198] run git-clang-format --- src/core/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 08d9cb6e..5bb7f23e 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -90,7 +90,7 @@ static void sig_reload_config(int signo) static void sig_quit_on_hup(int signo) { - signal_emit("gui exit", 0); + signal_emit("gui exit", 0); } static void read_settings(void) @@ -115,8 +115,8 @@ static void read_settings(void) act.sa_flags = 0; quit_on_hup = settings_get_bool("quit_on_hup"); - - act.sa_handler = quit_on_hup ? sig_quit_on_hup : sig_reload_config; + + act.sa_handler = quit_on_hup ? sig_quit_on_hup : sig_reload_config; sigaction(SIGHUP, &act, NULL); for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) { @@ -276,7 +276,6 @@ void core_init(void) settings_add_bool("misc", "override_coredump_limit", FALSE); settings_add_bool("misc", "quit_on_hup", FALSE); - #ifdef HAVE_SYS_RESOURCE_H getrlimit(RLIMIT_CORE, &orig_core_rlimit); #endif From f9595c03b1392aca8bd2aa2103f183ebedc8ec88 Mon Sep 17 00:00:00 2001 From: Dennis Pentmeier Date: Sat, 4 Apr 2020 17:59:46 +0200 Subject: [PATCH 0648/1198] Changed to async-signal safe method as suggested by dequis --- src/core/core.c | 16 ++++------------ src/core/core.h | 2 +- src/fe-text/irssi.c | 13 +++++++++---- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 5bb7f23e..0446052b 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -66,7 +66,7 @@ void wcwidth_wrapper_deinit(void); int irssi_gui; int irssi_init_finished; -int reload_config; +int sighup_received; time_t client_start_time; static char *irssi_dir, *irssi_config_file; @@ -83,14 +83,9 @@ const char *get_irssi_config(void) return irssi_config_file; } -static void sig_reload_config(int signo) +static void sig_hup(int signo) { - reload_config = TRUE; -} - -static void sig_quit_on_hup(int signo) -{ - signal_emit("gui exit", 0); + sighup_received = TRUE; } static void read_settings(void) @@ -107,16 +102,13 @@ static void read_settings(void) const char *ignores; struct sigaction act; int n; - int quit_on_hup; ignores = settings_get_str("ignore_signals"); sigemptyset (&act.sa_mask); act.sa_flags = 0; - quit_on_hup = settings_get_bool("quit_on_hup"); - - act.sa_handler = quit_on_hup ? sig_quit_on_hup : sig_reload_config; + act.sa_handler = sig_hup; sigaction(SIGHUP, &act, NULL); for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) { diff --git a/src/core/core.h b/src/core/core.h index 6c6c7b61..3c544753 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -13,7 +13,7 @@ extern int irssi_gui; extern int irssi_init_finished; /* TRUE after "irssi init finished" signal is sent */ -extern int reload_config; /* TRUE after received SIGHUP. */ +extern int sighup_received; /* TRUE after received SIGHUP. */ extern time_t client_start_time; void core_preinit(const char *path); diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index ca784bba..c3ded0b9 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -339,10 +339,15 @@ int main(int argc, char **argv) /* Does the same as g_main_run(main_loop), except we can call our dirty-checker after each iteration */ while (!quitting) { - if (reload_config) { - /* SIGHUP received, do /RELOAD */ - reload_config = FALSE; - signal_emit("command reload", 1, ""); + if (sighup_received) { + sighup_received = FALSE; + + if (settings_get_bool("quit_on_hup")) { + signal_emit("gui exit", 0); + } + else { + signal_emit("command reload", 1, ""); + } } dirty_check(); From 485ed2f52bafd9cc1d1c0a4ed87c87f2bde1de09 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 5 Apr 2020 21:22:19 +0200 Subject: [PATCH 0649/1198] hide the deprecated -ssl options from completion --- src/core/chat-commands.c | 7 +++++- src/core/commands.c | 39 +++++++++++++++++++++++---------- src/fe-common/core/completion.c | 6 ++++- src/fe-common/core/fe-server.c | 15 +++++++++++-- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 0b4b6591..ae44ef63 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -517,7 +517,12 @@ void chat_commands_init(void) signal_add("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg); - command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey +ssl_pass ssl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_pinned_cert +ssl_pinned_pubkey tls +tls_cert +tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); + command_set_options( + "connect", + "4 6 !! -network ~ssl ~+ssl_cert ~+ssl_pkey ~+ssl_pass ~ssl_verify ~+ssl_cafile " + "~+ssl_capath ~+ssl_ciphers ~+ssl_pinned_cert ~+ssl_pinned_pubkey tls +tls_cert " + "+tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert " + "+tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); command_set_options("msg", "channel nick"); } diff --git a/src/core/commands.c b/src/core/commands.c index 2805f8c0..198b1327 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -339,11 +339,28 @@ void command_runsub(const char *cmd, const char *data, g_free(orig); } +static char *optname(char *option) +{ + char *opt = option; + if (*opt == '~') + opt++; + if (iscmdtype(*opt)) + opt++; + return opt; +} + +static gboolean optflag(char *option, char *flag) +{ + if (*option == '~') + return optflag(option + 1, flag); + + return (strchr(flag, *option) != NULL) || (!iscmdtype(*option) && strchr(flag, ' ')); +} + static GSList *optlist_find(GSList *optlist, const char *option) { while (optlist != NULL) { - char *name = optlist->data; - if (iscmdtype(*name)) name++; + char *name = optname(optlist->data); if (g_ascii_strcasecmp(name, option) == 0) return optlist; @@ -369,7 +386,7 @@ int command_have_option(const char *cmd, const char *option) return FALSE; for (tmp = rec->options; *tmp != NULL; tmp++) { - char *name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp; + char *name = optname(*tmp); if (g_ascii_strcasecmp(name, option) == 0) return TRUE; @@ -399,7 +416,7 @@ static void command_calc_options(COMMAND_REC *rec, const char *options) /* merge the options */ for (tmp = optlist; *tmp != NULL; tmp++) { - name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp; + name = optname(*tmp); oldopt = optlist_find(list, name); if (oldopt != NULL) { @@ -529,7 +546,7 @@ static int option_find(char **array, const char *option) found = -1; index = 0; multiple = FALSE; for (tmp = array; *tmp != NULL; tmp++, index++) { - const char *text = *tmp + iscmdtype(**tmp); + const char *text = optname(*tmp); if (g_ascii_strncasecmp(text, option, len) == 0) { if (text[len] == '\0') { @@ -568,9 +585,9 @@ static int get_cmd_options(char **data, int ignore_unknown, option = NULL; pos = -1; for (;;) { if (**data == '\0' || **data == '-') { - if (option != NULL && *optlist[pos] == '+') { + if (option != NULL && optflag(optlist[pos], "+")) { /* required argument missing! */ - *data = optlist[pos] + 1; + *data = optname(optlist[pos]); return CMDERR_OPTION_ARG_MISSING; } } @@ -621,14 +638,12 @@ static int get_cmd_options(char **data, int ignore_unknown, if (pos >= 0) { /* if we used a shortcut of parameter, put the whole parameter name in options table */ - option = optlist[pos] + - iscmdtype(*optlist[pos]); + option = optname(optlist[pos]); } if (options != NULL && pos != -3) g_hash_table_insert(options, option, ""); - if (pos < 0 || !iscmdtype(*optlist[pos]) || - *optlist[pos] == '!') + if (pos < 0 || optflag(optlist[pos], " !")) option = NULL; while (**data == ' ') (*data)++; @@ -638,7 +653,7 @@ static int get_cmd_options(char **data, int ignore_unknown, if (option == NULL) break; - if (*optlist[pos] == '@' && !is_numeric(*data, ' ')) + if (optflag(optlist[pos], "@") && !is_numeric(*data, ' ')) break; /* expected a numeric argument */ /* save the argument */ diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 7778d8a4..0102bd2c 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -544,7 +544,11 @@ static GList *completion_get_options(const char *cmd, const char *option) list = NULL; len = strlen(option); for (tmp = rec->options; *tmp != NULL; tmp++) { - const char *optname = *tmp + iscmdtype(**tmp); + const char *optname; + if (**tmp == '~') + continue; /* deprecated or hidden option */ + + optname = *tmp + iscmdtype(**tmp); if (len == 0 || g_ascii_strncasecmp(optname, option, len) == 0) list = g_list_append(list, g_strconcat("-", optname, NULL)); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index f5f96324..5ed67170 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -453,8 +453,19 @@ void fe_server_init(void) command_bind_first("server", NULL, (SIGNAL_FUNC) server_command); command_bind_first("disconnect", NULL, (SIGNAL_FUNC) server_command); - command_set_options("server add", "4 6 !! ssl nossl +ssl_cert +ssl_pkey +ssl_pass ssl_verify nossl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls notls +tls_cert +tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); - command_set_options("server modify", "4 6 !! ssl nossl +ssl_cert +ssl_pkey +ssl_pass ssl_verify nossl_verify +ssl_cafile +ssl_capath +ssl_ciphers +ssl_fingerprint tls notls +tls_cert +tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); + command_set_options( + "server add", "4 6 !! ~ssl ~nossl ~+ssl_cert ~+ssl_pkey ~+ssl_pass ~ssl_verify " + "~nossl_verify ~+ssl_cafile ~+ssl_capath ~+ssl_ciphers ~+ssl_fingerprint " + "tls notls +tls_cert +tls_pkey +tls_pass tls_verify notls_verify " + "+tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert " + "+tls_pinned_pubkey auto noauto proxy noproxy -host -port noautosendcmd"); + command_set_options( + "server modify", + "4 6 !! ~ssl ~nossl ~+ssl_cert ~+ssl_pkey ~+ssl_pass ~ssl_verify ~nossl_verify " + "~+ssl_cafile ~+ssl_capath ~+ssl_ciphers ~+ssl_fingerprint tls notls +tls_cert " + "+tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers " + "+tls_pinned_cert +tls_pinned_pubkey auto noauto proxy noproxy -host -port " + "noautosendcmd"); signal_add("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting); From 1bfe27c66e5b51ba9eadcc1928b3b6134ec3bb29 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 6 Apr 2020 17:04:35 +0200 Subject: [PATCH 0650/1198] Used Tabs instead of spaces and increased ABI_VERSION --- src/common.h | 2 +- src/core/core.c | 4 ++-- src/fe-text/irssi.c | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/common.h b/src/common.h index d1f34870..e0da1080 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 25 +#define IRSSI_ABI_VERSION 26 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/core.c b/src/core/core.c index 0446052b..85f3a5d5 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -85,7 +85,7 @@ const char *get_irssi_config(void) static void sig_hup(int signo) { - sighup_received = TRUE; + sighup_received = TRUE; } static void read_settings(void) @@ -108,7 +108,7 @@ static void read_settings(void) sigemptyset (&act.sa_mask); act.sa_flags = 0; - act.sa_handler = sig_hup; + act.sa_handler = sig_hup; sigaction(SIGHUP, &act, NULL); for (n = 0; n < sizeof(signals)/sizeof(signals[0]); n++) { diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index c3ded0b9..c2013155 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -340,14 +340,14 @@ int main(int argc, char **argv) can call our dirty-checker after each iteration */ while (!quitting) { if (sighup_received) { - sighup_received = FALSE; + sighup_received = FALSE; - if (settings_get_bool("quit_on_hup")) { - signal_emit("gui exit", 0); - } - else { - signal_emit("command reload", 1, ""); - } + if (settings_get_bool("quit_on_hup")) { + signal_emit("gui exit", 0); + } + else { + signal_emit("command reload", 1, ""); + } } dirty_check(); From 6317db5ccbecc7fa8711867349531a89bb4c2861 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 12 Apr 2020 17:16:57 +0200 Subject: [PATCH 0651/1198] run clang-format as a pull request hook --- .github/workflows/clangformat.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/clangformat.yml diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml new file mode 100644 index 00000000..ff8a1cd5 --- /dev/null +++ b/.github/workflows/clangformat.yml @@ -0,0 +1,22 @@ +on: [pull_request] +name: clang-format +jobs: + check-clang-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: fetch target ref + run: + | + refs=($(git log -1 --format=%s)) + git fetch --depth=1 origin "${refs[3]}" + - name: run git-clang-format and Check if no changes are needed + run: + | + git-clang-format-9 --diff FETCH_HEAD HEAD | tee git-clang-format.diff + cmp -s <(echo no modified files to format) git-clang-format.diff + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: git-clang-format.diff + path: git-clang-format.diff \ No newline at end of file From 0548bb1a3cbd9a935504aa29dce26167fef8a85e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 14 Apr 2020 09:47:41 +0200 Subject: [PATCH 0652/1198] empty is also good --- .github/workflows/clangformat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index ff8a1cd5..b52dad8b 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -14,7 +14,7 @@ jobs: run: | git-clang-format-9 --diff FETCH_HEAD HEAD | tee git-clang-format.diff - cmp -s <(echo no modified files to format) git-clang-format.diff + cmp -s <(echo no modified files to format) git-clang-format.diff || cmp -s <(echo -n) git-clang-format.diff - uses: actions/upload-artifact@v1 if: failure() with: From 9ec9a9afc8a77c74be6853c080918f64090bc39e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 21 Apr 2020 18:58:30 +0200 Subject: [PATCH 0653/1198] try abipkgdiff --- .github/workflows/abicheck.yml | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/abicheck.yml diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml new file mode 100644 index 00000000..8ea6837f --- /dev/null +++ b/.github/workflows/abicheck.yml @@ -0,0 +1,71 @@ +on: [pull_request] +name: abicheck +jobs: + check-abi-diff: + runs-on: ubuntu-latest + env: + build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes + prefix: /usr/local + steps: + - name: set PATH + run: | + echo "::add-path::$HOME/.local/bin" + - name: prepare required software + run: | + sudo apt install abigail-tools ninja-build libutf8proc-dev libperl-dev libotr5-dev + pip3 install setuptools + pip3 install wheel + pip3 install meson + - name: checkout merge ref + uses: actions/checkout@master + with: + path: merge.src + - name: checkout base ref + uses: actions/checkout@master + with: + path: base.src + ref: ${{ github.base_ref }} + - name: build base ref + run: | + meson Build.base base.src $build_options + ninja -C Build.base + DESTDIR=$PWD/base ninja -C Build.base install + - name: build merge ref + run: | + meson Build.merge merge.src $build_options + ninja -C Build.merge + DESTDIR=$PWD/merge ninja -C Build.merge install + - run: | + # print versions and abi versions + getabidef() { awk '$1=="#define" && $2=="IRSSI_ABI_VERSION" { print $3 }' "$1"/include/irssi/src/common.h; } + base_abi=$(getabidef base$prefix) + echo base abi : $base_abi + ./base$prefix/bin/irssi --version + echo "::set-env name=base_abi::$base_abi" + merge_abi=$(getabidef merge$prefix) + echo merge abi : $merge_abi + ./merge$prefix/bin/irssi --version + echo "::set-env name=merge_abi::$merge_abi" + - run: | + # abipkgdiff + abipkgdiff -l base merge && diff_ret=0 || diff_ret=$? + echo "::set-env name=diff_ret::$diff_ret" + - run: | + # Check if no changes are needed + if [ "$diff_ret" -ne 0 ]; then + if [ "$base_abi" -lt "$merge_abi" ]; then + echo "::warning ::abigail found changes and ABI changed from $base_abi to $merge_abi" + exit 0 + else + echo "::error ::Looks like the ABI changed but the IRSSI_ABI_VERSION did not" + exit $diff_ret + fi + else + if [ "$base_abi" -ne "$merge_abi" ]; then + echo "::error ::abigail found no changes yet the IRSSI_ABI_VERSION changed. Is this correct?" + exit 1 + else + : "No changes detected and IRSSI_ABI_VERSION untouched" + exit 0 + fi + fi From 244ebaaa2e52a270eec2d797d72d193ae37c7482 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 23 Apr 2020 12:13:50 +0200 Subject: [PATCH 0654/1198] build fixes when using install-glib and on openbsd --- meson.build | 55 +++++++++++++++++++++++++++++++++++++++++--- src/perl/meson.build | 2 +- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 2af611cf..cf982146 100644 --- a/meson.build +++ b/meson.build @@ -147,6 +147,7 @@ if not socket_found error('socket not found') endif +built_src = [] glib_internal = false message('*** If you don\'t have GLib, you can run meson ... -Dinstall-glib=yes') message('*** to download and build it automatically') @@ -162,15 +163,64 @@ if not glib_dep.found() glib_internal = true meson_cmd = find_program('meson') ninja = find_program('ninja') + glib_internal_download_t = custom_target('glib-internal-download', command : [ meson_cmd, 'subprojects', 'download', 'glib', '--sourcedir', meson.current_source_dir() ], console : true, output : ['glib-internal-download'], ) + + glib_internal_dependencies = [ + dependency('threads'), + ] + glib_internal_configure_args = [] + + glib_internal_usr_local = false + if not cc.has_function('iconv_open') + prov_lib = cc.find_library('iconv', required : false) + if not prov_lib.found() + prov_lib = cc.find_library('iconv', dirs : '/usr/local/lib') + glib_internal_usr_local = true + endif + if cc.has_function('libiconv_open', dependencies : prov_lib) + glib_internal_configure_args += '-Diconv=gnu' + else + glib_internal_configure_args += '-Diconv=native' + endif + glib_internal_dependencies += prov_lib + endif + + if not cc.has_function('ngettext') + prov_lib = cc.find_library('intl', required : false) + if not prov_lib.found() + prov_lib = cc.find_library('intl', dirs : '/usr/local/lib') + glib_internal_usr_local = true + endif + glib_internal_dependencies += prov_lib + endif + + if glib_internal_usr_local + glib_internal_configure_args += ['-Dc_args=-I/usr/local/include', '-Dc_link_args=-L/usr/local/lib'] + endif + + if not cc.has_function('getxattr') or not cc.has_header('sys/xattr.h') + if cc.has_header_symbol('attr/xattr.h', 'getxattr') + prov_lib = cc.find_library('xattr', required : false) + else + prov_lib = dependency('', required : false) + endif + if prov_lib.found() + glib_internal_dependencies += prov_lib + else + glib_internal_configure_args += '-Dxattr=false' + endif + endif + glib_internal_configure_t = custom_target('glib-internal-configure', command : [ meson_cmd, 'setup', '--prefix=/irssi-glib-internal', '--buildtype=' + get_option('buildtype'), '-Dlibmount=false', '-Dselinux=false', '-Ddefault_library=static', '-Dinternal_pcre=true', + glib_internal_configure_args, (meson.current_build_dir() / 'build-subprojects' / 'glib'), (meson.current_source_dir() / 'subprojects' / glib_internal_version) ], console : true, @@ -184,9 +234,7 @@ if not glib_dep.found() output : ['glib-internal-build'], depends : glib_internal_configure_t,) glib_dep = declare_dependency( - dependencies : [ - dependency('threads'), - ], + dependencies : glib_internal_dependencies, sources : glib_internal_build_t, compile_args : [ '-I' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'glib'), @@ -195,6 +243,7 @@ if not glib_dep.found() ], link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'glib' / 'libglib-2.0.a' ], ) + built_src += glib_internal_build_t libdl_dep = [] prov_lib = cc.find_library('dl', required : false) if prov_lib.found() and cc.has_function('dlopen', dependencies : prov_lib) diff --git a/src/perl/meson.build b/src/perl/meson.build index aa2b609f..a9f1296a 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -23,7 +23,7 @@ shared_module('perl_core', ) + [ irssi_core_pl_h, perl_signals_list_h, - ], + ] + built_src, c_args : [ def_scriptdir, def_perl_use_lib, From 4b24d0a51d3fac05c9a9b254699b4e9047460b26 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 25 Apr 2020 11:59:04 +0200 Subject: [PATCH 0655/1198] remove some old compat code we already rely on c99 in other parts of the code --- src/fe-common/core/printtext.h | 75 +--------------------------------- 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/src/fe-common/core/printtext.h b/src/fe-common/core/printtext.h index 845bfc6c..c223a3ec 100644 --- a/src/fe-common/core/printtext.h +++ b/src/fe-common/core/printtext.h @@ -32,22 +32,7 @@ void printtext_deinit(void); /* printformat(...) = printformat_format(MODULE_NAME, ...) - Could this be any harder? :) With GNU C compiler and C99 compilers, - use #define. With others use either inline functions if they are - supported or static functions if they are not.. - */ -#if defined (__GNUC__) && !defined (__STRICT_ANSI__) -/* GCC */ -# define printformat(server, target, level, formatnum...) \ - printformat_module(MODULE_NAME, server, target, level, ##formatnum) -# define printformat_window(window, level, formatnum...) \ - printformat_module_window(MODULE_NAME, window, level, ##formatnum) -# define printformat_dest(dest, formatnum...) \ - printformat_module_dest(MODULE_NAME, dest, ##formatnum) -# define printformat_gui(formatnum...) \ - printformat_module_gui(MODULE_NAME, ##formatnum) -#elif __STDC_VERSION__ >= 199901L -/* C99 */ + Irssi requires a C99 pre-processor with __VA_ARGS__ support */ # define printformat(server, target, level, formatnum, ...) \ printformat_module(MODULE_NAME, server, target, level, formatnum, ##__VA_ARGS__) # define printformat_window(window, level, formatnum, ...) \ @@ -56,63 +41,5 @@ void printtext_deinit(void); printformat_module_dest(MODULE_NAME, dest, formatnum, ##__VA_ARGS__) # define printformat_gui(formatnum, ...) \ printformat_module_gui(MODULE_NAME, formatnum, ##__VA_ARGS__) -#else -/* inline/static */ -#ifdef G_CAN_INLINE -G_INLINE_FUNC -#else -static -#endif -void printformat(void *server, const char *target, int level, int formatnum, ...) -{ - va_list va; - - va_start(va, formatnum); - printformat_module_args(MODULE_NAME, server, target, level, formatnum, va); - va_end(va); -} - -#ifdef G_CAN_INLINE -G_INLINE_FUNC -#else -static -#endif -void printformat_window(WINDOW_REC *window, int level, int formatnum, ...) -{ - va_list va; - - va_start(va, formatnum); - printformat_module_window_args(MODULE_NAME, window, level, formatnum, va); - va_end(va); -} - -#ifdef G_CAN_INLINE -G_INLINE_FUNC -#else -static -#endif -void printformat_dest(TEXT_DEST_REC *dest, int formatnum, ...) -{ - va_list va; - - va_start(va, formatnum); - printformat_module_dest_args(MODULE_NAME, dest, formatnum, va); - va_end(va); -} - -#ifdef G_CAN_INLINE -G_INLINE_FUNC -#else -static -#endif -void printformat_gui(int formatnum, ...) -{ - va_list va; - - va_start(va, formatnum); - printformat_module_gui_args(MODULE_NAME, formatnum, va); - va_end(va); -} -#endif #endif From f95fc811302eac53d020ef438cd914c564657be5 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 14:59:30 +0200 Subject: [PATCH 0656/1198] make lines reformattable - completely removed the old textbuffer representation ( https://github.com/shabble/irssi-docs/wiki/Notes-256-Colour#textbuffer-encoding ) - textbuffer-formats is an extra module, so if we unhook the signals it should go back to the "old way" of storing pre-rendered tex - design uses cache, original formats and list of arguments --- src/core/levels.h | 7 +- src/fe-common/core/fe-core-commands.c | 2 + src/fe-common/core/formats.c | 97 ++++++- src/fe-common/core/formats.h | 8 +- src/fe-common/core/printtext.c | 94 ++++--- src/fe-text/Makefile.am | 4 +- src/fe-text/gui-printtext.c | 14 +- src/fe-text/gui-windows.c | 7 +- src/fe-text/irssi.c | 5 + src/fe-text/lastlog.c | 2 +- src/fe-text/meson.build | 2 + src/fe-text/textbuffer-commands.c | 45 ++- src/fe-text/textbuffer-formats.c | 258 +++++++++++++++++ src/fe-text/textbuffer-formats.h | 22 ++ src/fe-text/textbuffer-view.c | 384 +++++++++++++++----------- src/fe-text/textbuffer-view.h | 1 + src/fe-text/textbuffer.c | 382 +++---------------------- src/fe-text/textbuffer.h | 39 +-- src/perl/textui/TextBuffer.xs | 5 +- tests/fe-text/Makefile.am | 1 + tests/fe-text/meson.build | 1 + 21 files changed, 791 insertions(+), 589 deletions(-) create mode 100644 src/fe-text/textbuffer-formats.c create mode 100644 src/fe-text/textbuffer-formats.h diff --git a/src/core/levels.h b/src/core/levels.h index 385ecd0c..04893b34 100644 --- a/src/core/levels.h +++ b/src/core/levels.h @@ -6,6 +6,7 @@ difficult message leveling system (which might be done if really needed..). */ +/* clang-format off */ /* Message levels */ enum { MSGLEVEL_CRAP = 0x0000001, @@ -38,8 +39,12 @@ enum { MSGLEVEL_NEVER = 0x4000000, /* never ignore / never log */ MSGLEVEL_LASTLOG = 0x8000000, /* used for /lastlog */ - MSGLEVEL_HIDDEN = 0x10000000 /* Hidden from view */ + MSGLEVEL_HIDDEN = 0x10000000, /* Hidden from view */ + MSGLEVEL_RESERVED1 = 0x20000000, + MSGLEVEL_RESERVED2 = 0x40000000, + MSGLEVEL_FORMAT = 0x80000000 /* Format data */ }; +/* clang-format on */ int level_get(const char *level); int level2bits(const char *level, int *errorp); diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 9a2c547f..2c79334a 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -233,6 +233,7 @@ static void event_command(const char *data) (data[1] == *cmdchar && data[2] == '^')) && !command_hide_output++) { signal_add_first("print starting", (SIGNAL_FUNC) sig_stop); + signal_add_first("print noformat", (SIGNAL_FUNC) sig_stop); signal_add_first("print format", (SIGNAL_FUNC) sig_stop); signal_add_first("print text", (SIGNAL_FUNC) sig_stop); } @@ -242,6 +243,7 @@ static void event_command_last(const char *data) { if (command_hide_output && !--command_hide_output) { signal_remove("print starting", (SIGNAL_FUNC) sig_stop); + signal_remove("print noformat", (SIGNAL_FUNC) sig_stop); signal_remove("print format", (SIGNAL_FUNC) sig_stop); signal_remove("print text", (SIGNAL_FUNC) sig_stop); } diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 414c6582..a6fde7ea 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -850,14 +850,13 @@ char *format_get_line_start(THEME_REC *theme, TEXT_DEST_REC *dest, time_t t) return linestart; } -void format_newline(WINDOW_REC *window) +void format_newline(TEXT_DEST_REC *dest) { - g_return_if_fail(window != NULL); + g_return_if_fail(dest != NULL); + g_return_if_fail(dest->window != NULL); - signal_emit_id(signal_gui_print_text, 6, window, - GINT_TO_POINTER(-1), GINT_TO_POINTER(-1), - GINT_TO_POINTER(GUI_PRINT_FLAG_NEWLINE), - "", NULL); + signal_emit_id(signal_gui_print_text, 6, dest->window, GINT_TO_POINTER(-1), + GINT_TO_POINTER(-1), GINT_TO_POINTER(GUI_PRINT_FLAG_NEWLINE), "", dest); } #ifndef TERM_TRUECOLOR @@ -1269,7 +1268,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) } if (type == '\n') { - format_newline(dest->window); + format_newline(dest); fgcolor = theme->default_color; bgcolor = -1; flags &= GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_MONOSPACE; @@ -1415,6 +1414,90 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) g_free(dup); } +void format_gui_flags(GString *out, int *last_fg, int *last_bg, int *last_flags, int fg, int bg, + int flags) +{ + if (fg != *last_fg || + (flags & GUI_PRINT_FLAG_COLOR_24_FG) != (*last_flags & GUI_PRINT_FLAG_COLOR_24_FG)) { + *last_fg = fg; + +#ifdef TERM_TRUECOLOR + if (flags & GUI_PRINT_FLAG_COLOR_24_FG) { + *last_flags |= GUI_PRINT_FLAG_COLOR_24_FG; + format_24bit_color(out, 0, fg); + } else { + *last_flags &= ~GUI_PRINT_FLAG_COLOR_24_FG; +#endif + if (fg < 0) { + g_string_append_c(out, 4); + g_string_append_c(out, (char) -1); + g_string_append_c(out, FORMAT_COLOR_NOCHANGE); + } else { + format_ext_color(out, 0, fg); + } +#ifdef TERM_TRUECOLOR + } +#endif + } + if (bg != *last_bg || + (flags & GUI_PRINT_FLAG_COLOR_24_BG) != (*last_flags & GUI_PRINT_FLAG_COLOR_24_BG)) { + *last_bg = bg; +#ifdef TERM_TRUECOLOR + if (flags & GUI_PRINT_FLAG_COLOR_24_BG) { + *last_flags |= GUI_PRINT_FLAG_COLOR_24_BG; + format_24bit_color(out, 1, bg); + } else { + *last_flags &= ~GUI_PRINT_FLAG_COLOR_24_BG; +#endif + if (bg < 0) { + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_COLOR_NOCHANGE); + g_string_append_c(out, (char) -1); + } else { + format_ext_color(out, 1, bg); + } +#ifdef TERM_TRUECOLOR + } +#endif + } + + if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (*last_flags & GUI_PRINT_FLAG_UNDERLINE)) { + *last_flags ^= GUI_PRINT_FLAG_UNDERLINE; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_UNDERLINE); + } + if ((flags & GUI_PRINT_FLAG_REVERSE) != (*last_flags & GUI_PRINT_FLAG_REVERSE)) { + *last_flags ^= GUI_PRINT_FLAG_REVERSE; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_REVERSE); + } + if ((flags & GUI_PRINT_FLAG_BLINK) != (*last_flags & GUI_PRINT_FLAG_BLINK)) { + *last_flags ^= GUI_PRINT_FLAG_BLINK; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_BLINK); + } + if ((flags & GUI_PRINT_FLAG_BOLD) != (*last_flags & GUI_PRINT_FLAG_BOLD)) { + *last_flags ^= GUI_PRINT_FLAG_BOLD; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_BOLD); + } + if ((flags & GUI_PRINT_FLAG_ITALIC) != (*last_flags & GUI_PRINT_FLAG_ITALIC)) { + *last_flags ^= GUI_PRINT_FLAG_ITALIC; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_ITALIC); + } + if ((flags & GUI_PRINT_FLAG_MONOSPACE) != (*last_flags & GUI_PRINT_FLAG_MONOSPACE)) { + *last_flags ^= GUI_PRINT_FLAG_MONOSPACE; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_MONOSPACE); + } + if (flags & GUI_PRINT_FLAG_INDENT) { + *last_flags ^= GUI_PRINT_FLAG_INDENT; + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_INDENT); + } +} + static void read_settings(void) { timestamp_level = settings_get_bool("timestamps") ? MSGLEVEL_ALL : 0; diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 2e6133be..e30ac290 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -35,6 +35,7 @@ struct _FORMAT_REC { int paramtypes[MAX_FORMAT_PARAMS]; }; +/* clang-format off */ #define PRINT_FLAG_SET_LINE_START 0x0001 #define PRINT_FLAG_SET_LINE_START_IRSSI 0x0002 #define PRINT_FLAG_UNSET_LINE_START 0x0040 @@ -45,6 +46,9 @@ struct _FORMAT_REC { #define PRINT_FLAG_SET_SERVERTAG 0x0010 #define PRINT_FLAG_UNSET_SERVERTAG 0x0020 +#define PRINT_FLAG_FORMAT 0x0080 +/* clang-format on */ + typedef struct _HILIGHT_REC HILIGHT_REC; typedef struct _TEXT_DEST_REC { @@ -113,7 +117,7 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, const char *target, int level, WINDOW_REC *window); -void format_newline(WINDOW_REC *window); +void format_newline(TEXT_DEST_REC *dest); /* Return how many characters in `str' must be skipped before `len' characters of text is skipped. */ @@ -151,6 +155,8 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text); int format_expand_styles(GString *out, const char **format, int *flags); void format_ext_color(GString *out, int bg, int color); void format_24bit_color(GString *out, int bg, unsigned int color); +void format_gui_flags(GString *out, int *last_fg, int *last_bg, int *last_flags, int fg, int bg, + int flags); void formats_init(void); void formats_deinit(void); diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 692a3bc2..06c22a4c 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -42,7 +42,7 @@ static int signal_print_noformat; static int sending_print_starting; -static void print_line(TEXT_DEST_REC *dest, const char *text); +static void print_line(TEXT_DEST_REC *dest, const char *text, int formatted); void printformat_module_dest_args(const char *module, TEXT_DEST_REC *dest, int formatnum, va_list va) @@ -63,7 +63,6 @@ void printformat_module_dest_charargs(const char *module, TEXT_DEST_REC *dest, int formatnum, char **arglist) { THEME_REC *theme; - char *str; theme = window_get_theme(dest->window); @@ -75,11 +74,6 @@ void printformat_module_dest_charargs(const char *module, TEXT_DEST_REC *dest, signal_emit_id(signal_print_format, 5, theme, module, dest, GINT_TO_POINTER(formatnum), arglist); - - str = format_get_text_theme_charargs(theme, module, dest, - formatnum, arglist); - if (str != NULL && *str != '\0') print_line(dest, str); - g_free(str); } void printformat_module_dest(const char *module, TEXT_DEST_REC *dest, @@ -164,29 +158,6 @@ void printformat_module_gui(const char *module, int formatnum, ...) va_end(va); } -static void print_line(TEXT_DEST_REC *dest, const char *text) -{ - THEME_REC *theme; - char *str, *tmp, *stripped; - - g_return_if_fail(dest != NULL); - g_return_if_fail(text != NULL); - - theme = window_get_theme(dest->window); - tmp = format_get_level_tag(theme, dest); - str = !theme->info_eol ? format_add_linestart(text, tmp) : - format_add_lineend(text, tmp); - g_free_not_null(tmp); - - /* send both the formatted + stripped (for logging etc.) */ - stripped = strip_codes(str); - signal_emit_id(signal_print_text, 3, dest, str, stripped); - g_free_and_null(dest->hilight_color); - - g_free(str); - g_free(stripped); -} - /* append string to `out', expand newlines. */ static void printtext_append_str(TEXT_DEST_REC *dest, GString *out, const char *str) @@ -195,7 +166,7 @@ static void printtext_append_str(TEXT_DEST_REC *dest, GString *out, if (*str != '\n') g_string_append_c(out, *str); else { - print_line(dest, out->str); + print_line(dest, out->str, 0); g_string_truncate(out, 0); } str++; @@ -314,9 +285,7 @@ static void printtext_dest_args(TEXT_DEST_REC *dest, const char *text, va_list v } str = printtext_get_args(dest, text, va); - signal_emit_id(signal_print_noformat, 2, - dest, str); - print_line(dest, str); + print_line(dest, str, 0); g_free(str); } @@ -361,8 +330,8 @@ void printtext_string(void *server, const char *target, int level, const char *t } str = printtext_expand_formats(text, &dest.flags); - print_line(&dest, str); - g_free(str); + print_line(&dest, str, 0); + g_free(str); } /* Like printtext_window(), but don't handle %s etc. */ @@ -383,8 +352,8 @@ void printtext_string_window(WINDOW_REC *window, int level, const char *text) } str = printtext_expand_formats(text, &dest.flags); - print_line(&dest, str); - g_free(str); + print_line(&dest, str, 0); + g_free(str); } void printtext_window(WINDOW_REC *window, int level, const char *text, ...) @@ -476,6 +445,51 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text) signal_emit_id(signal_gui_print_text_finished, 1, dest->window); } +static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, + void *formatnump, char **arglist) +{ + int formatnum; + char *str; + + formatnum = GPOINTER_TO_INT(formatnump); + str = format_get_text_theme_charargs(theme, module, dest, formatnum, arglist); + if (str != NULL && *str != '\0') + print_line(dest, str, 1); + + g_free(str); +} + +static void sig_print_noformat(TEXT_DEST_REC *dest, const char *text) +{ + THEME_REC *theme; + char *str, *tmp, *stripped; + + theme = window_get_theme(dest->window); + tmp = format_get_level_tag(theme, dest); + str = !theme->info_eol ? format_add_linestart(text, tmp) : format_add_lineend(text, tmp); + g_free_not_null(tmp); + + /* send both the formatted + stripped (for logging etc.) */ + stripped = strip_codes(str); + signal_emit_id(signal_print_text, 3, dest, str, stripped); + + g_free_and_null(dest->hilight_color); + + g_free(str); + g_free(stripped); +} + +static void print_line(TEXT_DEST_REC *dest, const char *text, int formatted) +{ + g_return_if_fail(dest != NULL); + g_return_if_fail(text != NULL); + + if (!formatted) + signal_emit_id(signal_print_noformat, 2, dest, text); + else + sig_print_noformat(dest, text); +} + void printtext_multiline(void *server, const char *target, int level, const char *format, const char *text) { @@ -522,6 +536,8 @@ void printtext_init(void) read_settings(); signal_add("print text", (SIGNAL_FUNC) sig_print_text); + signal_add("print format", (SIGNAL_FUNC) sig_print_format); + signal_add("print noformat", (SIGNAL_FUNC) sig_print_noformat); signal_add("gui dialog", (SIGNAL_FUNC) sig_gui_dialog); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -529,6 +545,8 @@ void printtext_init(void) void printtext_deinit(void) { signal_remove("print text", (SIGNAL_FUNC) sig_print_text); + signal_remove("print format", (SIGNAL_FUNC) sig_print_format); + signal_remove("print noformat", (SIGNAL_FUNC) sig_print_noformat); signal_remove("gui dialog", (SIGNAL_FUNC) sig_gui_dialog); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); } diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index 94ce1a3c..8835f4b9 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -45,6 +45,7 @@ irssi_SOURCES = \ textbuffer.c \ textbuffer-commands.c \ textbuffer-view.c \ + textbuffer-formats.c \ irssi.c \ module-formats.c @@ -57,7 +58,8 @@ pkginc_fe_text_HEADERS = \ statusbar-item.h \ term.h \ textbuffer.h \ - textbuffer-view.h + textbuffer-view.h \ + textbuffer-formats.h noinst_HEADERS = \ gui-entry.h \ diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 24e91624..fe720264 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -19,8 +19,9 @@ */ #include "module.h" -#include +#include #include +#include #include #include @@ -329,7 +330,7 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, GUI_WINDOW_REC *gui; TEXT_BUFFER_VIEW_REC *view; LINE_REC *insert_after; - LINE_INFO_REC lineinfo; + LINE_INFO_REC lineinfo = { 0 }; int fg, bg, flags, attr; flags = GPOINTER_TO_INT(pflags); @@ -342,10 +343,16 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, return; } + if (dest != NULL && dest->flags & PRINT_FLAG_FORMAT) { + return; + } + lineinfo.level = dest == NULL ? 0 : dest->level; gui = WINDOW_GUI(window); lineinfo.time = (gui->use_insert_after && gui->insert_after_time) ? gui->insert_after_time : time(NULL); + lineinfo.format = + dest != NULL && dest->flags & PRINT_FLAG_FORMAT ? LINE_INFO_FORMAT_SET : NULL; view = gui->view; insert_after = gui->use_insert_after ? @@ -378,7 +385,8 @@ static void sig_gui_printtext_finished(WINDOW_REC *window) insert_after = WINDOW_GUI(window)->use_insert_after ? WINDOW_GUI(window)->insert_after : view->buffer->cur_line; - view_add_eol(view, &insert_after); + if (insert_after != NULL) + view_add_eol(view, &insert_after); remove_old_lines(view); } diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 9ca2dfdb..46be2396 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -43,10 +43,9 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, gui = g_new0(GUI_WINDOW_REC, 1); gui->parent = parent; - gui->view = textbuffer_view_create(textbuffer_create(), - window->width, window->height, - settings_get_bool("scroll"), - term_type == TERM_TYPE_UTF8); + gui->view = + textbuffer_view_create(textbuffer_create(window), window->width, window->height, + settings_get_bool("scroll"), term_type == TERM_TYPE_UTF8); textbuffer_view_set_default_indent(gui->view, settings_get_int("indent"), !settings_get_bool("indent_always"), diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index c2013155..1b891522 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -71,6 +71,9 @@ void gui_expandos_deinit(void); void textbuffer_commands_init(void); void textbuffer_commands_deinit(void); +void textbuffer_formats_init(void); +void textbuffer_formats_deinit(void); + void lastlog_init(void); void lastlog_deinit(void); @@ -168,6 +171,7 @@ static void textui_finish_init(void) textbuffer_init(); textbuffer_view_init(); textbuffer_commands_init(); + textbuffer_formats_init(); gui_expandos_init(); gui_printtext_init(); gui_readline_init(); @@ -256,6 +260,7 @@ static void textui_deinit(void) mainwindow_activity_deinit(); mainwindows_deinit(); gui_expandos_deinit(); + textbuffer_formats_deinit(); textbuffer_commands_deinit(); textbuffer_view_deinit(); textbuffer_deinit(); diff --git a/src/fe-text/lastlog.c b/src/fe-text/lastlog.c index d5aa298a..54321832 100644 --- a/src/fe-text/lastlog.c +++ b/src/fe-text/lastlog.c @@ -199,7 +199,7 @@ static void show_lastlog(const char *searchtext, GHashTable *optlist, } /* get the line text */ - textbuffer_line2text(rec, fhandle == NULL, line); + textbuffer_line2text(WINDOW_GUI(window)->view->buffer, rec, fhandle == NULL, line); if (!settings_get_bool("timestamps")) { struct tm *tm = localtime(&rec->info.time); char timestamp[10]; diff --git a/src/fe-text/meson.build b/src/fe-text/meson.build index 9070011e..4da98809 100644 --- a/src/fe-text/meson.build +++ b/src/fe-text/meson.build @@ -23,6 +23,7 @@ executable('irssi', 'statusbar.c', 'term.c', 'textbuffer-commands.c', + 'textbuffer-formats.c', 'textbuffer-view.c', 'textbuffer.c', ) @@ -53,6 +54,7 @@ install_headers( 'statusbar-item.h', 'statusbar.h', 'term.h', + 'textbuffer-formats.h', 'textbuffer-view.h', 'textbuffer.h', ), diff --git a/src/fe-text/textbuffer-commands.c b/src/fe-text/textbuffer-commands.c index 11c0f123..f30eab0e 100644 --- a/src/fe-text/textbuffer-commands.c +++ b/src/fe-text/textbuffer-commands.c @@ -19,14 +19,15 @@ */ #include "module.h" -#include -#include #include -#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include #include #include @@ -340,14 +341,29 @@ static void cmd_scrollback_status(void) total_lines = 0; total_mem = 0; for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *window = tmp->data; + int i; + LINE_REC *tmp; TEXT_BUFFER_VIEW_REC *view; view = WINDOW_GUI(window)->view; window_mem = sizeof(TEXT_BUFFER_REC); - window_mem += g_slist_length(view->buffer->text_chunks) * - sizeof(TEXT_CHUNK_REC); window_mem += view->buffer->lines_count * sizeof(LINE_REC); + for (tmp = view->buffer->cur_line; tmp != NULL; tmp = tmp->prev) { + if (tmp->info.text != NULL) { + window_mem += sizeof(char) * (strlen(tmp->info.text) + 1); + } + if (tmp->info.format != NULL) { + window_mem += sizeof(TEXT_BUFFER_FORMAT_REC); + for (i = 0; i < tmp->info.format->nargs; i++) { + if (tmp->info.format->args[i] != NULL) { + window_mem += + sizeof(char) * + (strlen(tmp->info.format->args[i]) + 1); + } + } + } + } total_lines += view->buffer->lines_count; total_mem += window_mem; printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, @@ -368,6 +384,19 @@ static void cmd_scrollback_status(void) } } +/* SYNTAX: SCROLLBACK REDRAW */ +static void cmd_scrollback_redraw(void) +{ + GUI_WINDOW_REC *gui; + + gui = WINDOW_GUI(active_win); + + term_refresh_freeze(); + textbuffer_view_reset_cache(gui->view); + gui_window_redraw(active_win); + term_refresh_thaw(); +} + static void sig_away_changed(SERVER_REC *server) { GSList *tmp; @@ -419,6 +448,7 @@ void textbuffer_commands_init(void) command_bind("scrollback home", NULL, (SIGNAL_FUNC) cmd_scrollback_home); command_bind("scrollback end", NULL, (SIGNAL_FUNC) cmd_scrollback_end); command_bind("scrollback status", NULL, (SIGNAL_FUNC) cmd_scrollback_status); + command_bind("scrollback redraw", NULL, (SIGNAL_FUNC) cmd_scrollback_redraw); command_set_options("clear", "all"); command_set_options("scrollback clear", "all"); @@ -442,6 +472,7 @@ void textbuffer_commands_deinit(void) command_unbind("scrollback home", (SIGNAL_FUNC) cmd_scrollback_home); command_unbind("scrollback end", (SIGNAL_FUNC) cmd_scrollback_end); command_unbind("scrollback status", (SIGNAL_FUNC) cmd_scrollback_status); + command_unbind("scrollback redraw", (SIGNAL_FUNC) cmd_scrollback_redraw); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); signal_remove("away mode changed", (SIGNAL_FUNC) sig_away_changed); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c new file mode 100644 index 00000000..599a85c6 --- /dev/null +++ b/src/fe-text/textbuffer-formats.c @@ -0,0 +1,258 @@ +#include "module.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TEXT_BUFFER_REC *color_buf; + +void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec) +{ + int n; + + if (rec == NULL) + return; + if (rec == LINE_INFO_FORMAT_SET) + return; + + i_refstr_release(rec->module); + i_refstr_release(rec->format); + i_refstr_release(rec->server_tag); + i_refstr_release(rec->target); + i_refstr_release(rec->nick); + if (rec->nargs >= 1) { + i_refstr_release(rec->args[0]); + } + for (n = 1; n < rec->nargs; n++) { + g_free(rec->args[n]); + } + rec->nargs = 0; + g_free(rec->args); + g_slice_free(TEXT_BUFFER_FORMAT_REC, rec); +} + +static TEXT_BUFFER_FORMAT_REC *format_rec_new(const char *module, const char *format_tag, + const char *server_tag, const char *target, + const char *nick, int nargs, const char **args) +{ + int n; + TEXT_BUFFER_FORMAT_REC *ret = g_slice_new0(TEXT_BUFFER_FORMAT_REC); + ret->module = i_refstr_intern(module); + ret->format = i_refstr_intern(format_tag); + ret->server_tag = i_refstr_intern(server_tag); + ret->target = i_refstr_intern(target); + ret->nick = i_refstr_intern(nick); + ret->nargs = nargs; + ret->args = g_new0(char *, nargs); + if (nargs >= 1) { + ret->args[0] = i_refstr_intern(args[0]); + } + for (n = 1; n < nargs; n++) { + ret->args[n] = g_strdup(args[n]); + } + return ret; +} + +static LINE_INFO_REC *store_lineinfo_tmp(TEXT_DEST_REC *dest) +{ + GUI_WINDOW_REC *gui; + TEXT_BUFFER_VIEW_REC *view; + TEXT_BUFFER_REC *buffer; + LINE_INFO_REC *lineinfo; + + gui = WINDOW_GUI(dest->window); + view = gui->view; + buffer = view->buffer; + + lineinfo = g_new0(LINE_INFO_REC, 1); + lineinfo->level = dest->level; + lineinfo->time = + (gui->use_insert_after && gui->insert_after_time) ? gui->insert_after_time : time(NULL); + + buffer->cur_info = g_slist_prepend(buffer->cur_info, lineinfo); + return lineinfo; +} + +static void free_lineinfo_tmp(WINDOW_REC *window) +{ + GUI_WINDOW_REC *gui; + TEXT_BUFFER_REC *buffer; + LINE_INFO_REC *info; + + gui = WINDOW_GUI(window); + buffer = gui->view->buffer; + + if (buffer->cur_info == NULL) + return; + + info = buffer->cur_info->data; + buffer->cur_info = g_slist_delete_link(buffer->cur_info, buffer->cur_info); + textbuffer_format_rec_free(info->format); + g_free(info); +} + +static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, + void *formatnump, const char **args) +{ + int formatnum; + FORMAT_REC *formats; + LINE_INFO_REC *info; + + info = store_lineinfo_tmp(dest); + + formatnum = GPOINTER_TO_INT(formatnump); + formats = g_hash_table_lookup(default_formats, module); + + info->format = format_rec_new(module, formats[formatnum].tag, dest->server_tag, + dest->target, dest->nick, formats[formatnum].params, args); + + info->format->flags = dest->flags; + dest->flags |= PRINT_FLAG_FORMAT; + + signal_continue(5, theme, module, dest, formatnump, args); + + free_lineinfo_tmp(dest->window); +} + +static void sig_print_noformat(TEXT_DEST_REC *dest, const char *text) +{ + LINE_INFO_REC *info; + + info = store_lineinfo_tmp(dest); + + info->format = format_rec_new(NULL, NULL, dest->server_tag, dest->target, dest->nick, 2, + (const char *[]){ NULL, text }); + + info->format->flags = dest->flags; + dest->flags |= PRINT_FLAG_FORMAT; + + signal_continue(2, dest, text); + + free_lineinfo_tmp(dest->window); +} + +static void sig_gui_print_text_finished(WINDOW_REC *window) +{ + GUI_WINDOW_REC *gui; + LINE_REC *insert_after; + LINE_INFO_REC *info; + TEXT_BUFFER_REC *buffer; + + gui = WINDOW_GUI(window); + buffer = gui->view->buffer; + insert_after = gui->use_insert_after ? gui->insert_after : buffer->cur_line; + + if (buffer->cur_info == NULL) + return; + + info = buffer->cur_info->data; + + if (info->format == NULL) + return; + + info->level |= MSGLEVEL_FORMAT; + + /* the line will be inserted into the view with textbuffer_view_insert_line by + gui-printtext.c:view_add_eol */ + insert_after = textbuffer_insert(buffer, insert_after, (const unsigned char[]){}, 0, info); + + /* the TEXT_BUFFER_FORMAT_REC pointer is now owned by the textbuffer */ + info->format = LINE_INFO_FORMAT_SET; + + if (gui->use_insert_after) + gui->insert_after = insert_after; +} + +char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) +{ + GUI_WINDOW_REC *gui; + LINE_REC *curr; + + g_return_val_if_fail(buffer != NULL, NULL); + g_return_val_if_fail(buffer->window != NULL, NULL); + + gui = WINDOW_GUI(buffer->window); + if (line == NULL || gui == NULL) + return NULL; + + if (line->info.level & MSGLEVEL_FORMAT) { + TEXT_DEST_REC dest; + THEME_REC *theme; + int formatnum; + TEXT_BUFFER_FORMAT_REC *format_rec; + char *text, *tmp, *str; + + curr = line; + line = NULL; + format_rec = curr->info.format; + + format_create_dest( + &dest, + format_rec->server_tag != NULL ? server_find_tag(format_rec->server_tag) : NULL, + format_rec->target, curr->info.level & ~MSGLEVEL_FORMAT, buffer->window); + + theme = window_get_theme(dest.window); + + if (format_rec->format != NULL) { + char *arglist[MAX_FORMAT_PARAMS] = { 0 }; + formatnum = format_find_tag(format_rec->module, format_rec->format); + memcpy(arglist, format_rec->args, format_rec->nargs * sizeof(char *)); + text = format_get_text_theme_charargs(theme, format_rec->module, &dest, + formatnum, arglist); + } else { + text = g_strdup(format_rec->args[1]); + } + + if (*text != '\0') { + current_time = curr->info.time; + + tmp = format_get_level_tag(theme, &dest); + str = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); + g_free_not_null(tmp); + g_free_not_null(text); + text = str; + tmp = format_get_line_start(theme, &dest, curr->info.time); + str = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); + g_free_not_null(tmp); + g_free_not_null(text); + text = str; + /* str = g_strconcat(text, "\n", NULL); */ + /* g_free(text); */ + + dest.flags |= PRINT_FLAG_FORMAT; + + current_time = (time_t) -1; + return str; + } else if (format_rec->format != NULL) { + g_free(text); + return NULL; + } else { + return text; + } + } else { + return g_strdup(line->info.text); + } +} + +void textbuffer_formats_init(void) +{ + signal_add("print format", (SIGNAL_FUNC) sig_print_format); + signal_add("print noformat", (SIGNAL_FUNC) sig_print_noformat); + signal_add_first("gui print text finished", (SIGNAL_FUNC) sig_gui_print_text_finished); +} + +void textbuffer_formats_deinit(void) +{ + signal_remove("print format", (SIGNAL_FUNC) sig_print_format); + signal_remove("print noformat", (SIGNAL_FUNC) sig_print_noformat); + signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_print_text_finished); +} diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h new file mode 100644 index 00000000..5a156fda --- /dev/null +++ b/src/fe-text/textbuffer-formats.h @@ -0,0 +1,22 @@ +#ifndef IRSSI_FE_TEXT_TEXTBUFFER_FORMATS_H +#define IRSSI_FE_TEXT_TEXTBUFFER_FORMATS_H + +#include + +typedef struct _TEXT_BUFFER_FORMAT_REC { + char *module; + char *format; + char *server_tag; + char *target; + char *nick; + char **args; + int nargs; + int flags; +} TEXT_BUFFER_FORMAT_REC; + +void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec); +char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line); +void textbuffer_formats_init(void); +void textbuffer_formats_deinit(void); + +#endif diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 45035fa8..0bbb3655 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -21,9 +21,12 @@ #define G_LOG_DOMAIN "TextBufferView" #include "module.h" -#include +#include #include #include +#include +#include +#include typedef struct { char *name; @@ -93,6 +96,7 @@ textbuffer_cache_get(GSList *views, int width) static int line_cache_destroy(void *key, LINE_CACHE_REC *cache) { + g_free(cache->line_text); g_free(cache); return TRUE; } @@ -114,52 +118,6 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache) #define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | FG_MASK | ATTR_FGCOLOR24) #define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | BG_MASK | ATTR_BGCOLOR24) -static void update_cmd_color(unsigned char cmd, int *color) -{ - if ((cmd & 0x80) == 0) { - if (cmd & LINE_COLOR_BG) { - /* set background color */ - *color &= FGATTR; - if ((cmd & LINE_COLOR_DEFAULT) == 0) - *color |= (cmd & 0x0f) << BG_SHIFT; - else { - *color = (*color & FGATTR) | ATTR_RESETBG; - } - } else { - /* set foreground color */ - *color &= BGATTR; - if ((cmd & LINE_COLOR_DEFAULT) == 0) - *color |= cmd & 0x0f; - else { - *color = (*color & BGATTR) | ATTR_RESETFG; - } - } - } else switch (cmd) { - case LINE_CMD_UNDERLINE: - *color ^= ATTR_UNDERLINE; - break; - case LINE_CMD_REVERSE: - *color ^= ATTR_REVERSE; - break; - case LINE_CMD_BLINK: - *color ^= ATTR_BLINK; - break; - case LINE_CMD_BOLD: - *color ^= ATTR_BOLD; - break; - case LINE_CMD_ITALIC: - *color ^= ATTR_ITALIC; - break; - case LINE_CMD_MONOSPACE: - /* ignored */ - break; - case LINE_CMD_COLOR0: - *color &= BGATTR; - *color &= ~ATTR_FGCOLOR24; - break; - } -} - #ifdef TERM_TRUECOLOR static void unformat_24bit_line_color(const unsigned char **ptr, int off, int *flags, unsigned int *fg, unsigned int *bg) { @@ -167,6 +125,8 @@ static void unformat_24bit_line_color(const unsigned char **ptr, int off, int *f unsigned char rgbx[4]; unsigned int i; for (i = 0; i < 4; ++i) { + if ((*ptr)[i + off] == '\0') + return; rgbx[i] = (*ptr)[i + off]; } rgbx[3] -= 0x20; @@ -202,6 +162,94 @@ static inline unichar read_unichar(const unsigned char *data, const unsigned cha return chr; } +static inline void unformat(const unsigned char **ptr, int *color, unsigned int *fg24, + unsigned int *bg24) +{ + switch (**ptr) { + case FORMAT_STYLE_BLINK: + *color ^= ATTR_BLINK; + break; + case FORMAT_STYLE_UNDERLINE: + *color ^= ATTR_UNDERLINE; + break; + case FORMAT_STYLE_BOLD: + *color ^= ATTR_BOLD; + break; + case FORMAT_STYLE_REVERSE: + *color ^= ATTR_REVERSE; + break; + case FORMAT_STYLE_ITALIC: + *color ^= ATTR_ITALIC; + break; + case FORMAT_STYLE_MONOSPACE: + /* *color ^= ATTR_MONOSPACE; */ + break; + case FORMAT_STYLE_DEFAULTS: + *color = ATTR_RESET; + break; + case FORMAT_STYLE_CLRTOEOL: + break; + case FORMAT_COLOR_EXT1: + *color &= ~ATTR_FGCOLOR24; + *color = (*color & BGATTR) | (0x10 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; + case FORMAT_COLOR_EXT1_BG: + *color &= ~ATTR_BGCOLOR24; + *color = (*color & FGATTR) | (0x10 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; + case FORMAT_COLOR_EXT2: + *color &= ~ATTR_FGCOLOR24; + *color = (*color & BGATTR) | (0x60 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; + case FORMAT_COLOR_EXT2_BG: + *color &= ~ATTR_BGCOLOR24; + *color = (*color & FGATTR) | (0x60 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; + case FORMAT_COLOR_EXT3: + *color &= ~ATTR_FGCOLOR24; + *color = (*color & BGATTR) | (0xb0 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; + case FORMAT_COLOR_EXT3_BG: + *color &= ~ATTR_BGCOLOR24; + *color = (*color & FGATTR) | (0xb0 + *++*ptr - FORMAT_COLOR_NOCHANGE); + break; +#ifdef TERM_TRUECOLOR + case FORMAT_COLOR_24: + unformat_24bit_line_color(ptr, 1, color, fg24, bg24); + break; +#endif + default: + if (**ptr != FORMAT_COLOR_NOCHANGE) { + if (**ptr == (unsigned char) 0xff) { + *color = (*color & BGATTR) | ATTR_RESETFG; + } else { + *color = (*color & BGATTR) | (((unsigned char) **ptr - '0') & 0xf); + } + } + if ((*ptr)[1] == '\0') + break; + + (*ptr)++; + if (**ptr != FORMAT_COLOR_NOCHANGE) { + if (**ptr == (unsigned char) 0xff) { + *color = (*color & FGATTR) | ATTR_RESETBG; + } else { + *color = (*color & FGATTR) | + ((((unsigned char) **ptr - '0') & 0xf) << BG_SHIFT); + } + } + } + if (**ptr == '\0') + return; + + (*ptr)++; +} + +#define NEXT_CHAR_OR_BREAK(p) \ + (p)++; \ + if (*(p) == '\0') \ + break + static LINE_CACHE_REC * view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) { @@ -209,14 +257,12 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) LINE_CACHE_REC *rec; LINE_CACHE_SUB_REC *sub; GSList *lines; - unsigned char cmd; + char *line_text; const unsigned char *ptr, *next_ptr, *last_space_ptr; int xpos, pos, indent_pos, last_space, last_color, color, linecount; unsigned int last_bg24, last_fg24, bg24, fg24; int char_width; - g_return_val_if_fail(line->text != NULL, NULL); - color = ATTR_RESETFG | ATTR_RESETBG; xpos = 0; indent_pos = view->default_indent; last_space = last_color = 0; last_space_ptr = NULL; sub = NULL; @@ -225,114 +271,132 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) indent_func = view->default_indent_func; linecount = 1; lines = NULL; - for (ptr = line->text;;) { - if (*ptr == '\0') { - /* command */ - ptr++; - cmd = *ptr; - ptr++; - if (cmd == LINE_CMD_EOL) + line_text = textbuffer_line_get_text(view->buffer, line); + if (line_text != NULL) { + for (ptr = (unsigned char *) line_text;;) { + if (*ptr == '\0') break; - if (cmd == LINE_CMD_CONTINUE) { - unsigned char *tmp; + if (*ptr == '\n') { + /* newline */ + xpos = 0; + last_space = 0; + + sub = g_new0(LINE_CACHE_SUB_REC, 1); + + sub->start = ++ptr; + sub->color = color; +#ifdef TERM_TRUECOLOR + sub->fg24 = fg24; + sub->bg24 = bg24; +#endif + + lines = g_slist_append(lines, sub); + linecount++; - memcpy(&tmp, ptr, sizeof(char *)); - ptr = tmp; continue; } - if (cmd == LINE_CMD_INDENT) { - /* set indentation position here - don't do - it if we're too close to right border */ - if (xpos < view->width-5) indent_pos = xpos; - } else if (cmd == LINE_COLOR_EXT) { - color &= ~ATTR_FGCOLOR24; - color = (color & BGATTR) | *ptr++; - } else if (cmd == LINE_COLOR_EXT_BG) { - color &= ~ATTR_BGCOLOR24; - color = (color & FGATTR) | (*ptr++ << BG_SHIFT); - } -#ifdef TERM_TRUECOLOR - else if (cmd == LINE_COLOR_24) - unformat_24bit_line_color(&ptr, 0, &color, &fg24, &bg24); -#endif - else - update_cmd_color(cmd, &color); - continue; - } + if (*ptr == 4) { + /* format */ + NEXT_CHAR_OR_BREAK(ptr); - if (!view->utf8) { - /* MH */ - if (term_type != TERM_TYPE_BIG5 || - ptr[1] == '\0' || !is_big5(ptr[0], ptr[1])) - char_width = 1; - else - char_width = 2; - next_ptr = ptr+char_width; - } else { - read_unichar(ptr, &next_ptr, &char_width); - } - - if (xpos + char_width > view->width && sub != NULL && - (last_space <= indent_pos || last_space <= 10) && - view->longword_noindent) { - /* long word, remove the indentation from this line */ - xpos -= sub->indent; - sub->indent = 0; - sub->indent_func = NULL; - } - - if (xpos + char_width > view->width) { - xpos = indent_func == NULL ? indent_pos : - indent_func(view, line, -1); - - sub = g_new0(LINE_CACHE_SUB_REC, 1); - if (last_space > indent_pos && last_space > 10) { - /* go back to last space */ - color = last_color; fg24 = last_fg24; bg24 = last_bg24; - ptr = last_space_ptr; - while (*ptr == ' ') ptr++; - } else if (view->longword_noindent) { - /* long word, no indentation in next line */ - xpos = 0; - sub->continues = TRUE; + if (*ptr == FORMAT_STYLE_INDENT) { + /* set indentation position here - don't do + it if we're too close to right border */ + if (xpos < view->width - 5) + indent_pos = xpos; + ptr++; + } else { + unformat(&ptr, &color, &fg24, &bg24); + } + continue; } - sub->start = ptr; - sub->indent = xpos; - sub->indent_func = indent_func; - sub->color = color; + if (!view->utf8) { + /* MH */ + if (term_type != TERM_TYPE_BIG5 || ptr[1] == '\0' || + !is_big5(ptr[0], ptr[1])) + char_width = 1; + else + char_width = 2; + next_ptr = ptr + char_width; + } else { + read_unichar(ptr, &next_ptr, &char_width); + } + + if (xpos + char_width > view->width && sub != NULL && + (last_space <= indent_pos || last_space <= 10) && + view->longword_noindent) { + /* long word, remove the indentation from this line */ + xpos -= sub->indent; + sub->indent = 0; + sub->indent_func = NULL; + } + + if (xpos + char_width > view->width) { + xpos = + indent_func == NULL ? indent_pos : indent_func(view, line, -1); + + sub = g_new0(LINE_CACHE_SUB_REC, 1); + if (last_space > indent_pos && last_space > 10) { + /* go back to last space */ + color = last_color; + fg24 = last_fg24; + bg24 = last_bg24; + ptr = last_space_ptr; + while (*ptr == ' ') + ptr++; + } else if (view->longword_noindent) { + /* long word, no indentation in next line */ + xpos = 0; + sub->continues = TRUE; + } + + sub->start = ptr; + sub->indent = xpos; + sub->indent_func = indent_func; + sub->color = color; #ifdef TERM_TRUECOLOR - sub->fg24 = fg24; sub->bg24 = bg24; + sub->fg24 = fg24; + sub->bg24 = bg24; #endif - lines = g_slist_append(lines, sub); - linecount++; + lines = g_slist_append(lines, sub); + linecount++; - last_space = 0; - continue; + last_space = 0; + continue; + } + + if (view->break_wide && char_width > 1) { + last_space = xpos; + last_space_ptr = next_ptr; + last_color = color; + last_fg24 = fg24; + last_bg24 = bg24; + } else if (*ptr == ' ') { + last_space = xpos; + last_space_ptr = ptr; + last_color = color; + last_fg24 = fg24; + last_bg24 = bg24; + } + + xpos += char_width; + ptr = next_ptr; } - - if (view->break_wide && char_width > 1) { - last_space = xpos; - last_space_ptr = next_ptr; - last_color = color; last_fg24 = fg24; last_bg24 = bg24; - } else if (*ptr == ' ') { - last_space = xpos; - last_space_ptr = ptr; - last_color = color; last_fg24 = fg24; last_bg24 = bg24; - } - - xpos += char_width; - ptr = next_ptr; } rec = g_malloc(sizeof(LINE_CACHE_REC)-sizeof(LINE_CACHE_SUB_REC) + sizeof(LINE_CACHE_SUB_REC) * (linecount-1)); rec->last_access = time(NULL); + if (line_text == NULL) { + linecount = 0; + } rec->count = linecount; + rec->line_text = line_text; if (rec->count > 1) { for (pos = 0; lines != NULL; pos++) { @@ -398,12 +462,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, INDENT_FUNC indent_func; LINE_CACHE_REC *cache; const unsigned char *text, *end, *text_newline; - unsigned char *tmp; unichar chr; int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width; -#ifdef TERM_TRUECOLOR unsigned int fg24, bg24; -#endif if (view->dirty) /* don't bother drawing anything - redraw is coming */ return 0; @@ -416,7 +477,8 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, need_move = TRUE; need_clrtoeol = FALSE; xpos = drawcount = 0; first = TRUE; text_newline = text = - subline == 0 ? line->text : cache->lines[subline-1].start; + subline == 0 ? (unsigned char *) cache->line_text : cache->lines[subline - 1].start; + for (;;) { if (text == text_newline) { if (need_clrtoeol && xpos < view->width + (view->width == term_width ? 0 : 1)) { @@ -484,31 +546,29 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, subline++; } - if (*text == '\0') { - /* command */ - text++; - if (*text == LINE_CMD_EOL) - break; + if (*text == '\n') { + /* newline */ + NEXT_CHAR_OR_BREAK(text); + continue; + } - if (*text == LINE_CMD_CONTINUE) { - /* jump to next block */ - memcpy(&tmp, text+1, sizeof(unsigned char *)); - text = tmp; - continue; + if (*text == 0) { + break; + } + + if (*text == 4) { + /* format */ + NEXT_CHAR_OR_BREAK(text); + + if (*text == FORMAT_STYLE_INDENT) { + /* ??? */ + NEXT_CHAR_OR_BREAK(text); } else { - if (*text == LINE_COLOR_EXT) - color = (color & BGATTR & ~ATTR_FGCOLOR24) | *++text; - else if (*text == LINE_COLOR_EXT_BG) - color = (color & FGATTR & ~ATTR_BGCOLOR24) | (*++text << BG_SHIFT); -#ifdef TERM_TRUECOLOR - else if (*text == LINE_COLOR_24) - unformat_24bit_line_color(&text, 1, &color, &fg24, &bg24); -#endif - else - update_cmd_color(*text, &color); + unformat(&text, &color, &fg24, &bg24); term_set_color2(view->window, color, fg24, bg24); + if (*text == 0) + break; } - text++; continue; } diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h index 607016ac..4e5ed82f 100644 --- a/src/fe-text/textbuffer-view.h +++ b/src/fe-text/textbuffer-view.h @@ -27,6 +27,7 @@ typedef struct { typedef struct { time_t last_access; + char *line_text; int count; /* number of real lines */ /* variable sized array, actually. starts from the second line, diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 470c0b00..b8fd2090 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -26,176 +26,59 @@ #include #include +#include #include #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) -TEXT_BUFFER_REC *textbuffer_create(void) +TEXT_BUFFER_REC *textbuffer_create(WINDOW_REC *window) { TEXT_BUFFER_REC *buffer; buffer = g_slice_new0(TEXT_BUFFER_REC); + buffer->window = window; buffer->last_eol = TRUE; buffer->last_fg = -1; buffer->last_bg = -1; - return buffer; + buffer->cur_text = g_string_sized_new(TEXT_CHUNK_USABLE_SIZE); + return buffer; } void textbuffer_destroy(TEXT_BUFFER_REC *buffer) { + GSList *tmp; + g_return_if_fail(buffer != NULL); textbuffer_remove_all_lines(buffer); - g_slice_free(TEXT_BUFFER_REC, buffer); -} - -static TEXT_CHUNK_REC *text_chunk_find(TEXT_BUFFER_REC *buffer, - const unsigned char *data) -{ - GSList *tmp; - - for (tmp = buffer->text_chunks; tmp != NULL; tmp = tmp->next) { - TEXT_CHUNK_REC *rec = tmp->data; - - if (data >= rec->buffer && - data < rec->buffer+sizeof(rec->buffer)) - return rec; + g_string_free(buffer->cur_text, TRUE); + for (tmp = buffer->cur_info; tmp != NULL; tmp = tmp->next) { + LINE_INFO_REC *info = buffer->cur_info->data; + textbuffer_format_rec_free(info->format); + g_free(info->text); + g_free(info); } + g_slist_free(buffer->cur_info); - return NULL; -} - -#define mark_temp_eol(chunk) G_STMT_START { \ - (chunk)->buffer[(chunk)->pos] = 0; \ - (chunk)->buffer[(chunk)->pos+1] = LINE_CMD_EOL; \ - } G_STMT_END - -static TEXT_CHUNK_REC *text_chunk_create(TEXT_BUFFER_REC *buffer) -{ - TEXT_CHUNK_REC *rec; - unsigned char *buf, *ptr, **pptr; - - rec = g_slice_new(TEXT_CHUNK_REC); - rec->pos = 0; - rec->refcount = 0; - - if (buffer->cur_line != NULL && buffer->cur_line->text != NULL) { - /* create a link to new block from the old block */ - buf = buffer->cur_text->buffer + buffer->cur_text->pos; - *buf++ = 0; *buf++ = (char) LINE_CMD_CONTINUE; - - /* we want to store pointer to beginning of the new text - block to char* buffer. this probably isn't ANSI-C - compatible, and trying this without the pptr variable - breaks at least NetBSD/Alpha, so don't go "optimize" - it :) */ - ptr = rec->buffer; pptr = &ptr; - memcpy(buf, pptr, sizeof(unsigned char *)); - } else { - /* just to be safe */ - mark_temp_eol(rec); - } - - buffer->cur_text = rec; - buffer->text_chunks = g_slist_append(buffer->text_chunks, rec); - return rec; -} - -static void text_chunk_destroy(TEXT_BUFFER_REC *buffer, TEXT_CHUNK_REC *chunk) -{ - buffer->text_chunks = g_slist_remove(buffer->text_chunks, chunk); - g_slice_free(TEXT_CHUNK_REC, chunk); -} - -static void text_chunk_line_free(TEXT_BUFFER_REC *buffer, LINE_REC *line) -{ - TEXT_CHUNK_REC *chunk; - const unsigned char *text; - unsigned char cmd, *tmp = NULL; - - for (text = line->text;; text++) { - if (*text != '\0') - continue; - - text++; - cmd = *text; - if (cmd == LINE_CMD_CONTINUE || cmd == LINE_CMD_EOL) { - if (cmd == LINE_CMD_CONTINUE) - memcpy(&tmp, text+1, sizeof(char *)); - - /* free the previous block */ - chunk = text_chunk_find(buffer, text); - if (--chunk->refcount == 0) { - if (buffer->cur_text == chunk) - chunk->pos = 0; - else - text_chunk_destroy(buffer, chunk); - } - - if (cmd == LINE_CMD_EOL) - break; - - text = tmp-1; - } - } + buffer->window = NULL; + g_slice_free(TEXT_BUFFER_REC, buffer); } static void text_chunk_append(TEXT_BUFFER_REC *buffer, const unsigned char *data, int len) { - TEXT_CHUNK_REC *chunk; - int left; - int i; - if (len == 0) return; - chunk = buffer->cur_text; - while (chunk->pos + len >= TEXT_CHUNK_USABLE_SIZE) { - left = TEXT_CHUNK_USABLE_SIZE - chunk->pos; - - /* don't split utf-8 character. (assume we can split non-utf8 anywhere.) */ - if (left < len && !is_utf8_leading(data[left])) { - int i; - for (i = 1; i < 4 && left >= i; i++) - if (is_utf8_leading(data[left - i])) { - left -= i; - break; - } - } - - for (i = 5; i > 0; --i) { - if (left >= i && data[left-i] == 0) { - left -= i; /* don't split the commands */ - break; - } - } - - memcpy(chunk->buffer + chunk->pos, data, left); - chunk->pos += left; - - chunk = text_chunk_create(buffer); - chunk->refcount++; - len -= left; data += left; - } - - memcpy(chunk->buffer + chunk->pos, data, len); - chunk->pos += len; - - mark_temp_eol(chunk); + /* g_string_append_len(buffer->cur_text, (const char *)data, len); */ + g_string_append(buffer->cur_text, (const char *) data); } static LINE_REC *textbuffer_line_create(TEXT_BUFFER_REC *buffer) { LINE_REC *rec; - if (buffer->cur_text == NULL) - text_chunk_create(buffer); - rec = g_slice_new0(LINE_REC); - rec->text = buffer->cur_text->buffer + buffer->cur_text->pos; - - buffer->cur_text->refcount++; return rec; } @@ -241,103 +124,18 @@ int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search) return FALSE; } -#ifdef TERM_TRUECOLOR -static void format_24bit_line_color(unsigned char *out, int *pos, int bg, unsigned int color) -{ - unsigned char rgb[] = { color >> 16, color >> 8, color }; - unsigned char x = bg ? 0x1 : 0; - unsigned int i; - out[(*pos)++] = LINE_COLOR_24; - for (i = 0; i < 3; ++i) { - if (rgb[i] > 0x20) - out[(*pos)++] = rgb[i]; - else { - out[(*pos)++] = 0x20 + rgb[i]; - x |= 0x10 << i; - } - } - out[(*pos)++] = 0x20 + x; -} -#endif - void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, int fg, int bg, int flags) { - unsigned char data[22]; - int pos; + GString *out = g_string_new(NULL); + format_gui_flags(out, &buffer->last_fg, &buffer->last_bg, &buffer->last_flags, fg, bg, + flags); - pos = 0; - if (fg != buffer->last_fg - || (flags & GUI_PRINT_FLAG_COLOR_24_FG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_FG)) { - buffer->last_fg = fg; - data[pos++] = 0; -#ifdef TERM_TRUECOLOR - if (flags & GUI_PRINT_FLAG_COLOR_24_FG) - format_24bit_line_color(data, &pos, 0, fg); - else -#endif - if (fg < 0) - data[pos++] = LINE_COLOR_DEFAULT; - else if (fg < 16) - data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg; - else if (fg < 256) { - data[pos++] = LINE_COLOR_EXT; - data[pos++] = fg; - } + if (*(out->str) != '\0') { + *line = + textbuffer_insert(buffer, *line, (unsigned char *) out->str, out->len, NULL); } - if (bg != buffer->last_bg - || (flags & GUI_PRINT_FLAG_COLOR_24_BG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_BG)) { - buffer->last_bg = bg; - data[pos++] = 0; -#ifdef TERM_TRUECOLOR - if (flags & GUI_PRINT_FLAG_COLOR_24_BG) - format_24bit_line_color(data, &pos, 1, bg); - else -#endif - if (bg < 0) - data[pos++] = LINE_COLOR_BG | LINE_COLOR_DEFAULT; - else if (bg < 16) - data[pos++] = LINE_COLOR_BG | bg; - else if (bg < 256) { - data[pos++] = LINE_COLOR_EXT_BG; - data[pos++] = bg; - } - } - - if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (buffer->last_flags & GUI_PRINT_FLAG_UNDERLINE)) { - data[pos++] = 0; - data[pos++] = LINE_CMD_UNDERLINE; - } - if ((flags & GUI_PRINT_FLAG_REVERSE) != (buffer->last_flags & GUI_PRINT_FLAG_REVERSE)) { - data[pos++] = 0; - data[pos++] = LINE_CMD_REVERSE; - } - if ((flags & GUI_PRINT_FLAG_BLINK) != (buffer->last_flags & GUI_PRINT_FLAG_BLINK)) { - data[pos++] = 0; - data[pos++] = LINE_CMD_BLINK; - } - if ((flags & GUI_PRINT_FLAG_BOLD) != (buffer->last_flags & GUI_PRINT_FLAG_BOLD)) { - data[pos++] = 0; - data[pos++] = LINE_CMD_BOLD; - } - if ((flags & GUI_PRINT_FLAG_ITALIC) != (buffer->last_flags & GUI_PRINT_FLAG_ITALIC)) { - 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; - } - - if (pos > 0) { - *line = textbuffer_insert(buffer, *line, data, pos, NULL); - } - - buffer->last_flags = flags; + g_string_free(out, TRUE); } LINE_REC *textbuffer_append(TEXT_BUFFER_REC *buffer, @@ -368,6 +166,11 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, data[len-2] == 0 && data[len-1] == LINE_CMD_EOL; if (buffer->last_eol) { + if (!line->info.format) { + line->info.text = g_strdup(buffer->cur_text->str); + g_string_truncate(buffer->cur_text, 0); + } + buffer->last_fg = -1; buffer->last_bg = -1; buffer->last_flags = 0; @@ -395,145 +198,50 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line) line->prev = line->next = NULL; buffer->lines_count--; - text_chunk_line_free(buffer, line); + g_free(line->info.text); + textbuffer_format_rec_free(line->info.format); g_slice_free(LINE_REC, line); } /* Removes all lines from buffer */ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer) { - GSList *tmp; LINE_REC *line; g_return_if_fail(buffer != NULL); - for (tmp = buffer->text_chunks; tmp != NULL; tmp = tmp->next) - g_slice_free(TEXT_CHUNK_REC, tmp->data); - g_slist_free(buffer->text_chunks); - buffer->text_chunks = NULL; - while (buffer->first_line != NULL) { line = buffer->first_line->next; + g_free(buffer->first_line->info.text); + textbuffer_format_rec_free(buffer->first_line->info.format); g_slice_free(LINE_REC, buffer->first_line); buffer->first_line = line; } buffer->lines_count = 0; buffer->cur_line = NULL; - buffer->cur_text = NULL; + g_string_truncate(buffer->cur_text, 0); buffer->last_eol = TRUE; } -static void set_color(GString *str, int cmd) +void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, GString *str) { - int color = -1; - - if (!(cmd & LINE_COLOR_DEFAULT)) - color = (cmd & 0x0f)+'0'; - - if ((cmd & LINE_COLOR_BG) == 0) { - /* change foreground color */ - g_string_append_printf(str, "\004%c%c", - color, FORMAT_COLOR_NOCHANGE); - } else { - /* change background color */ - g_string_append_printf(str, "\004%c%c", - FORMAT_COLOR_NOCHANGE, color); - } -} - -void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) -{ - unsigned char cmd, *ptr, *tmp; + char *ptr, *tmp; g_return_if_fail(line != NULL); g_return_if_fail(str != NULL); g_string_truncate(str, 0); - for (ptr = line->text;;) { - if (*ptr != 0) { - g_string_append_c(str, (char) *ptr); - ptr++; - continue; - } - - ptr++; - cmd = *ptr; - ptr++; - - if (cmd == LINE_CMD_EOL) { - /* end of line */ - break; - } - - if (cmd == LINE_CMD_CONTINUE) { - /* line continues in another address.. */ - memcpy(&tmp, ptr, sizeof(unsigned char *)); - ptr = tmp; - continue; - } - - if (!coloring) { - /* no colors, skip coloring commands */ - if (cmd == LINE_COLOR_EXT || cmd == LINE_COLOR_EXT_BG) - ptr++; -#ifdef TERM_TRUECOLOR - else if (cmd == LINE_COLOR_24) - ptr+=4; -#endif - - continue; - } - - if ((cmd & LINE_CMD_EOL) == 0) { - /* set color */ - set_color(str, cmd); - } else switch (cmd) { - case LINE_CMD_UNDERLINE: - g_string_append_c(str, 31); - break; - case LINE_CMD_REVERSE: - g_string_append_c(str, 22); - break; - case LINE_CMD_BLINK: - g_string_append_printf(str, "\004%c", - FORMAT_STYLE_BLINK); - break; - case LINE_CMD_BOLD: - g_string_append_printf(str, "\004%c", - FORMAT_STYLE_BOLD); - break; - case LINE_CMD_ITALIC: - 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); - break; - case LINE_CMD_INDENT: - g_string_append_printf(str, "\004%c", - FORMAT_STYLE_INDENT); - break; - case LINE_COLOR_EXT: - format_ext_color(str, 0, *ptr++); - break; - case LINE_COLOR_EXT_BG: - format_ext_color(str, 1, *ptr++); - break; -#ifdef TERM_TRUECOLOR - case LINE_COLOR_24: - g_string_append_printf(str, "\004%c", FORMAT_COLOR_24); - break; -#endif - } + ptr = textbuffer_line_get_text(buffer, line); + if (coloring == 0) { + tmp = ptr; + ptr = strip_codes(tmp); + g_free(tmp); } + g_string_append(str, ptr); + g_free(ptr); } GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, @@ -575,7 +283,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, (line->info.level & nolevel) == 0; if (*text != '\0') { - textbuffer_line2text(line, FALSE, str); + textbuffer_line2text(buffer, line, FALSE, str); if (line_matched) { line_matched = regexp ? diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index cbe4fbf0..5aaa817c 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -5,33 +5,23 @@ wastes a lot of memory. */ #define LINE_TEXT_CHUNK_SIZE (16384 - 16) -#define LINE_COLOR_BG 0x20 -#define LINE_COLOR_DEFAULT 0x10 +#define LINE_INFO_FORMAT_SET (void *) 0x1 enum { LINE_CMD_EOL=0x80, /* line ends here */ - LINE_CMD_CONTINUE, /* line continues in next block */ - LINE_CMD_COLOR0, /* change to black, would be same as \0\0 but it breaks things.. */ - LINE_CMD_UNDERLINE, /* enable/disable underlining */ - LINE_CMD_REVERSE, /* enable/disable reversed text */ - LINE_CMD_INDENT, /* if line is split, indent it at this position */ - 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 - LINE_COLOR_24, /* 24bit color */ -#endif }; +struct _TEXT_BUFFER_FORMAT_REC; + typedef struct { int level; time_t time; + char *text; + struct _TEXT_BUFFER_FORMAT_REC *format; } LINE_INFO_REC; typedef struct _LINE_REC { + struct _LINE_REC *prev, *next; /* Text in the line. \0 means that the next char will be a color or command. @@ -45,9 +35,6 @@ typedef struct _LINE_REC { DO NOT ADD BLACK WITH \0\0 - this will break things. Use LINE_CMD_COLOR0 instead. */ - struct _LINE_REC *prev, *next; - - unsigned char *text; LINE_INFO_REC info; } LINE_REC; @@ -58,12 +45,14 @@ typedef struct { } TEXT_CHUNK_REC; typedef struct { - GSList *text_chunks; - LINE_REC *first_line; - int lines_count; + WINDOW_REC *window; + + LINE_REC *first_line; + int lines_count; LINE_REC *cur_line; - TEXT_CHUNK_REC *cur_text; + GString *cur_text; + GSList *cur_info; int last_fg; int last_bg; @@ -72,7 +61,7 @@ typedef struct { } TEXT_BUFFER_REC; /* Create new buffer */ -TEXT_BUFFER_REC *textbuffer_create(void); +TEXT_BUFFER_REC *textbuffer_create(WINDOW_REC *window); /* Destroy the buffer */ void textbuffer_destroy(TEXT_BUFFER_REC *buffer); @@ -96,7 +85,7 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line); /* Removes all lines from buffer, ignoring reference counters */ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer); -void textbuffer_line2text(LINE_REC *line, int coloring, GString *str); +void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, GString *str); GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int level, int nolevel, const char *text, int before, int after, diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 14ef5950..40602272 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -25,7 +25,8 @@ OUTPUT: RETVAL void -textbuffer_line_get_text(line, coloring) +textbuffer_line_get_text(buffer, line, coloring) + Irssi::TextUI::TextBuffer buffer Irssi::TextUI::Line line int coloring PREINIT: @@ -33,7 +34,7 @@ PREINIT: SV *result; PPCODE: str = g_string_new(NULL); - textbuffer_line2text(line, coloring, str); + textbuffer_line2text(buffer, line, coloring, str); result = new_pv(str->str); XPUSHs(sv_2mortal(result)); g_string_free(str, TRUE); diff --git a/tests/fe-text/Makefile.am b/tests/fe-text/Makefile.am index b1762c7d..2a3450e9 100644 --- a/tests/fe-text/Makefile.am +++ b/tests/fe-text/Makefile.am @@ -26,6 +26,7 @@ test_paste_join_multiline_SOURCES = \ ../../src/fe-text/term-terminfo.c \ ../../src/fe-text/terminfo-core.c \ ../../src/fe-text/term.c \ + ../../src/fe-text/textbuffer-formats.c \ ../../src/fe-text/textbuffer-view.c \ ../../src/fe-text/textbuffer.c \ ../../src/fe-text/gui-windows.c \ diff --git a/tests/fe-text/meson.build b/tests/fe-text/meson.build index ea6ec620..397bd39f 100644 --- a/tests/fe-text/meson.build +++ b/tests/fe-text/meson.build @@ -7,6 +7,7 @@ test_test_paste_join_multiline = executable('test-paste-join-multiline', '../../src/fe-text/term-terminfo.c', '../../src/fe-text/term.c', '../../src/fe-text/terminfo-core.c', + '../../src/fe-text/textbuffer-formats.c', '../../src/fe-text/textbuffer-view.c', '../../src/fe-text/textbuffer.c', 'mock-irssi.c', From 6b93d6e3382b08b6e703b2c6dc71ff85b4c1fc9b Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 13 Aug 2019 15:15:15 +0200 Subject: [PATCH 0657/1198] implement expando cache - the expando values need to be stored now that the lines are reformattable, otherwise the old values are lost (and they depend on context only available at the time the line is initially printed) - the cache is collected from the special-vars evaluation code - the cache is controlled by the textbuffer-formats code, and stored in the text_buffer_format_rec --- src/core/core.c | 9 ++- src/core/special-vars.c | 119 ++++++++++++++++++++++++++----- src/core/special-vars.h | 9 +++ src/fe-text/textbuffer-formats.c | 39 +++++++++- src/fe-text/textbuffer-formats.h | 1 + 5 files changed, 155 insertions(+), 22 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 85f3a5d5..34649c81 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -34,16 +34,17 @@ #endif #include -#include #include #include #include -#include +#include #include #include -#include #include #include +#include +#include +#include #include #include @@ -262,6 +263,7 @@ void core_init(void) chat_commands_init(); i_refstr_init(); + special_vars_init(); wcwidth_wrapper_init(); settings_add_str("misc", "ignore_signals", ""); @@ -288,6 +290,7 @@ void core_deinit(void) signal_remove("irssi init finished", (SIGNAL_FUNC) sig_irssi_init_finished); wcwidth_wrapper_deinit(); + special_vars_deinit(); i_refstr_deinit(); chat_commands_deinit(); diff --git a/src/core/special-vars.c b/src/core/special-vars.c index ef56e2e1..802fcb36 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -19,12 +19,13 @@ */ #include "module.h" +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include #include #define isvarchar(c) \ @@ -40,6 +41,8 @@ #endif static SPECIAL_HISTORY_FUNC history_func = NULL; +static GSList *special_collector; +static GSList *special_cache; static char *get_argument(char **cmd, char **arglist) { @@ -121,8 +124,40 @@ static char *get_long_variable_value(const char *key, SERVER_REC *server, return NULL; } -static char *get_long_variable(char **cmd, SERVER_REC *server, - void *item, int *free_ret, int getname) +static gboolean cache_find(GSList **cache, const char *var, char **ret) +{ + GSList *tmp; + GSList *prev = NULL; + + if (cache == NULL) + return FALSE; + + for (tmp = *cache; tmp;) { + if (g_strcmp0(var, tmp->data) == 0) { + *ret = tmp->next->data; + if (prev != NULL) + prev->next->next = tmp->next->next; + else + *cache = tmp->next->next; + + g_slist_free_1(tmp->next); + g_slist_free_1(tmp); + return TRUE; + } + prev = tmp; + tmp = tmp->next->next; + } + return FALSE; +} + +static gboolean cache_find_char(GSList **cache, char var, char **ret) +{ + char varn[] = { var, '\0' }; + return cache_find(cache, varn, ret); +} + +static char *get_long_variable(char **cmd, SERVER_REC *server, void *item, int *free_ret, + int getname, GSList **collector, GSList **cache) { char *start, *var, *ret; @@ -135,16 +170,23 @@ static char *get_long_variable(char **cmd, SERVER_REC *server, *free_ret = TRUE; return var; } + if (cache_find(cache, var, &ret)) { + g_free(var); + return ret; + } ret = get_long_variable_value(var, server, item, free_ret); + if (collector != NULL) { + *collector = g_slist_prepend(*collector, g_strdup(ret)); + *collector = g_slist_prepend(*collector, i_refstr_intern(var)); + } g_free(var); return ret; } /* return the value of the variable found from `cmd'. if 'getname' is TRUE, return the name of the variable instead it's value */ -static char *get_variable(char **cmd, SERVER_REC *server, void *item, - char **arglist, int *free_ret, int *arg_used, - int getname) +static char *get_variable(char **cmd, SERVER_REC *server, void *item, char **arglist, int *free_ret, + int *arg_used, int getname, GSList **collector, GSList **cache) { EXPANDO_FUNC func; @@ -158,7 +200,7 @@ static char *get_variable(char **cmd, SERVER_REC *server, void *item, if (i_isalpha(**cmd) && isvarchar((*cmd)[1])) { /* long variable name.. */ - return get_long_variable(cmd, server, item, free_ret, getname); + return get_long_variable(cmd, server, item, free_ret, getname, collector, cache); } /* single character variable. */ @@ -167,15 +209,27 @@ static char *get_variable(char **cmd, SERVER_REC *server, void *item, return g_strdup_printf("%c", **cmd); } *free_ret = FALSE; + { + char *ret; + if (cache_find_char(cache, **cmd, &ret)) { + return ret; + } + } func = expando_find_char(**cmd); if (func == NULL) return NULL; else { char str[2]; + char *ret; str[0] = **cmd; str[1] = '\0'; current_expando = str; - return func(server, item, free_ret); + ret = func(server, item, free_ret); + if (**cmd != 'Z' && collector != NULL) { + *collector = g_slist_prepend(*collector, g_strdup(ret)); + *collector = g_slist_prepend(*collector, i_refstr_intern(str)); + } + return ret; } } @@ -199,9 +253,9 @@ static char *get_history(char **cmd, void *item, int *free_ret) return ret; } -static char *get_special_value(char **cmd, SERVER_REC *server, void *item, - char **arglist, int *free_ret, int *arg_used, - int flags) +static char *get_special_value(char **cmd, SERVER_REC *server, void *item, char **arglist, + int *free_ret, int *arg_used, int flags, GSList **collector, + GSList **cache) { char command, *value, *p; int len; @@ -236,8 +290,8 @@ static char *get_special_value(char **cmd, SERVER_REC *server, void *item, } } - value = get_variable(cmd, server, item, arglist, free_ret, - arg_used, flags & PARSE_FLAG_GETNAME); + value = get_variable(cmd, server, item, arglist, free_ret, arg_used, + flags & PARSE_FLAG_GETNAME, collector, cache); if (flags & PARSE_FLAG_GETNAME) return value; @@ -440,8 +494,9 @@ char *parse_special(char **cmd, SERVER_REC *server, void *item, brackets = TRUE; } - value = get_special_value(cmd, server, item, arglist, - free_ret, arg_used, flags); + value = get_special_value(cmd, server, item, arglist, free_ret, arg_used, flags, + special_collector != NULL ? special_collector->data : NULL, + &special_cache); if (**cmd == '\0') g_error("parse_special() : buffer overflow!"); @@ -635,6 +690,22 @@ void special_history_func_set(SPECIAL_HISTORY_FUNC func) history_func = func; } +void special_push_collector(GSList **list) +{ + special_collector = g_slist_prepend(special_collector, list); +} + +void special_pop_collector(void) +{ + special_collector = g_slist_delete_link(special_collector, special_collector); +} + +void special_fill_cache(GSList *list) +{ + g_slist_free(special_cache); + special_cache = g_slist_copy(list); +} + static void update_signals_hash(GHashTable **hash, int *signals) { void *signal_id; @@ -758,3 +829,15 @@ int *special_vars_get_signals(const char *text) { return special_vars_signals_task(text, 0, NULL, TASK_GET_SIGNALS); } + +void special_vars_init(void) +{ + special_cache = NULL; + special_collector = NULL; +} + +void special_vars_deinit(void) +{ + g_slist_free(special_cache); + g_slist_free(special_collector); +} diff --git a/src/core/special-vars.h b/src/core/special-vars.h index f4bd926d..87aba7d6 100644 --- a/src/core/special-vars.h +++ b/src/core/special-vars.h @@ -32,6 +32,11 @@ char *parse_special_string(const char *cmd, SERVER_REC *server, void *item, void eval_special_string(const char *cmd, const char *data, SERVER_REC *server, void *item); +void special_push_collector(GSList **list); +void special_pop_collector(void); + +void special_fill_cache(GSList *list); + void special_history_func_set(SPECIAL_HISTORY_FUNC func); void special_vars_add_signals(const char *text, @@ -41,4 +46,8 @@ void special_vars_remove_signals(const char *text, /* Returns [, EXPANDO_ARG_xxx, , ..., -1] */ int *special_vars_get_signals(const char *text); +void special_vars_init(void); + +void special_vars_deinit(void); + #endif diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 599a85c6..e0a5f193 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,18 @@ TEXT_BUFFER_REC *color_buf; +static void collector_free(GSList **collector) +{ + while (*collector) { + GSList *next = (*collector)->next->next; + i_refstr_release((*collector)->data); + g_free((*collector)->next->data); + g_slist_free_1((*collector)->next); + g_slist_free_1((*collector)); + *collector = next; + } +} + void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec) { int n; @@ -35,6 +48,7 @@ void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec) } rec->nargs = 0; g_free(rec->args); + collector_free(&rec->expando_cache); g_slice_free(TEXT_BUFFER_FORMAT_REC, rec); } @@ -112,12 +126,14 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC info->format = format_rec_new(module, formats[formatnum].tag, dest->server_tag, dest->target, dest->nick, formats[formatnum].params, args); + special_push_collector(&info->format->expando_cache); info->format->flags = dest->flags; dest->flags |= PRINT_FLAG_FORMAT; signal_continue(5, theme, module, dest, formatnump, args); + special_pop_collector(); free_lineinfo_tmp(dest->window); } @@ -125,19 +141,36 @@ static void sig_print_noformat(TEXT_DEST_REC *dest, const char *text) { LINE_INFO_REC *info; + special_push_collector(NULL); info = store_lineinfo_tmp(dest); info->format = format_rec_new(NULL, NULL, dest->server_tag, dest->target, dest->nick, 2, (const char *[]){ NULL, text }); + special_push_collector(&info->format->expando_cache); info->format->flags = dest->flags; dest->flags |= PRINT_FLAG_FORMAT; signal_continue(2, dest, text); + special_pop_collector(); free_lineinfo_tmp(dest->window); } +static GSList *reverse_collector(GSList *a1) +{ + GSList *b1, *c1; + c1 = NULL; + while (a1) { + b1 = a1->next->next; + a1->next->next = c1; + + c1 = a1; + a1 = b1; + } + return c1; +} + static void sig_gui_print_text_finished(WINDOW_REC *window) { GUI_WINDOW_REC *gui; @@ -157,6 +190,8 @@ static void sig_gui_print_text_finished(WINDOW_REC *window) if (info->format == NULL) return; + info->format->expando_cache = reverse_collector(info->format->expando_cache); + info->level |= MSGLEVEL_FORMAT; /* the line will be inserted into the view with textbuffer_view_insert_line by @@ -182,7 +217,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) if (line == NULL || gui == NULL) return NULL; - if (line->info.level & MSGLEVEL_FORMAT) { + if (line->info.level & MSGLEVEL_FORMAT && line->info.format != NULL) { TEXT_DEST_REC dest; THEME_REC *theme; int formatnum; @@ -200,6 +235,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) theme = window_get_theme(dest.window); + special_fill_cache(format_rec->expando_cache); if (format_rec->format != NULL) { char *arglist[MAX_FORMAT_PARAMS] = { 0 }; formatnum = format_find_tag(format_rec->module, format_rec->format); @@ -238,6 +274,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) } else { return text; } + special_fill_cache(NULL); } else { return g_strdup(line->info.text); } diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index 5a156fda..45e4ce1b 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -11,6 +11,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { char *nick; char **args; int nargs; + GSList *expando_cache; int flags; } TEXT_BUFFER_FORMAT_REC; From a0544571a80196e5b7705f56e6e2cbcdf7b4d80e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Apr 2020 21:45:15 +0200 Subject: [PATCH 0658/1198] manually handle NUL unicode in g_utf8_get_next_char_validated A change in GLib 2.63 broke some assumptions in Irssi that the null-byte NUL / U+0000 is a valid Unicode character. This would occur when the user types Ctrl+Space. As a result, the input loop never manages to process the NUL-byte (and any other user input that follows, ever). This patch adds a manual check that properly advances the input loop if GLib returns -2 (incomplete character) despite the length being positive and a NUL is in first position. Fixes #1180 https://gitlab.gnome.org/GNOME/glib/-/merge_requests/967 https://gitlab.gnome.org/GNOME/glib/-/issues/2093 --- src/fe-text/term-terminfo.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 5235f72d..78496a64 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -672,7 +672,11 @@ void term_stop(void) static int input_utf8(const unsigned char *buffer, int size, unichar *result) { - unichar c = g_utf8_get_char_validated((char *)buffer, size); + unichar c = g_utf8_get_char_validated((char *) buffer, size); + + /* GLib >= 2.63 do not accept Unicode NUL anymore */ + if (c == (unichar) -2 && *buffer == 0 && size > 0) + c = 0; switch (c) { case (unichar)-1: From 57fb173130cec6e82bccfbe6ead09731b591c5a6 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 8 Aug 2019 21:54:30 +0200 Subject: [PATCH 0659/1198] add perl code for textbuffer-formats - compatibility shim for new line - make format accessible from perl - fix perl line IDs being mixed up due to wrapper --- src/perl/Makefile.am | 1 + src/perl/textui/TextBuffer.xs | 39 ++++++++++-- src/perl/textui/TextBufferView.xs | 19 ++++++ src/perl/textui/TextUI.xs | 29 ++++++--- src/perl/textui/module.h | 2 +- src/perl/textui/typemap | 7 ++- src/perl/textui/wrapper_buffer_line.h | 90 +++++++++++++++++++++++++++ 7 files changed, 170 insertions(+), 17 deletions(-) create mode 100644 src/perl/textui/wrapper_buffer_line.h diff --git a/src/perl/Makefile.am b/src/perl/Makefile.am index 0e56d7a3..45ac1eea 100644 --- a/src/perl/Makefile.am +++ b/src/perl/Makefile.am @@ -108,6 +108,7 @@ textui_sources = \ textui/TextBufferView.xs \ textui/Statusbar.xs \ textui/Makefile.PL.in \ + textui/wrapper_buffer_line.h \ textui/typemap \ textui/module.h diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 40602272..ae3973c8 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -1,5 +1,7 @@ #define PERL_NO_GET_CONTEXT #include "module.h" +#include "wrapper_buffer_line.h" +#include MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi PROTOTYPES: ENABLE @@ -12,7 +14,7 @@ Irssi::TextUI::Line textbuffer_line_prev(line) Irssi::TextUI::Line line CODE: - RETVAL = line->prev; + RETVAL = perl_wrap_buffer_line(line->buffer, line->line->prev); OUTPUT: RETVAL @@ -20,13 +22,12 @@ Irssi::TextUI::Line textbuffer_line_next(line) Irssi::TextUI::Line line CODE: - RETVAL = line->next; + RETVAL = perl_wrap_buffer_line(line->buffer, line->line->next); OUTPUT: RETVAL void -textbuffer_line_get_text(buffer, line, coloring) - Irssi::TextUI::TextBuffer buffer +textbuffer_line_get_text(line, coloring) Irssi::TextUI::Line line int coloring PREINIT: @@ -34,8 +35,36 @@ PREINIT: SV *result; PPCODE: str = g_string_new(NULL); - textbuffer_line2text(buffer, line, coloring, str); + textbuffer_line2text(line->buffer, line->line, coloring, str); result = new_pv(str->str); XPUSHs(sv_2mortal(result)); g_string_free(str, TRUE); +void +textbuffer_line_get_format(line) + Irssi::TextUI::Line line +PREINIT: + HV *hv; + AV *av; + LINE_REC *l; + TEXT_BUFFER_FORMAT_REC *f; + int i; +PPCODE: + hv = newHV(); + l = line->line; + if (l->info.format != NULL) { + f = l->info.format; + (void) hv_store(hv, "module", 6, new_pv(f->module), 0); + (void) hv_store(hv, "format", 6, new_pv(f->format), 0); + (void) hv_store(hv, "server_tag", 10, new_pv(f->server_tag), 0); + (void) hv_store(hv, "target", 6, new_pv(f->target), 0); + (void) hv_store(hv, "nick", 4, new_pv(f->nick), 0); + av = newAV(); + for (i = 0; i < f->nargs; i++) { + av_push(av, new_pv(f->args[i])); + } + (void) hv_store(hv, "args", 4, newRV_noinc((SV *) av), 0); + } else { + (void) hv_store(hv, "text", 4, new_pv(l->info.text), 0); + } + XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs index c0dc762d..43aba4e6 100644 --- a/src/perl/textui/TextBufferView.xs +++ b/src/perl/textui/TextBufferView.xs @@ -1,5 +1,6 @@ #define PERL_NO_GET_CONTEXT #include "module.h" +#include "wrapper_buffer_line.h" MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBuffer PREFIX = textbuffer_ PROTOTYPES: ENABLE @@ -33,6 +34,10 @@ textbuffer_view_clear(view) Irssi::TextUI::Line textbuffer_view_get_lines(view) Irssi::TextUI::TextBufferView view +CODE: + RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_lines(view)); +OUTPUT: + RETVAL void textbuffer_view_scroll(view, lines) @@ -43,16 +48,24 @@ void textbuffer_view_scroll_line(view, line) Irssi::TextUI::TextBufferView view Irssi::TextUI::Line line +CODE: + textbuffer_view_scroll_line(view, line->line); Irssi::TextUI::LineCache textbuffer_view_get_line_cache(view, line) Irssi::TextUI::TextBufferView view Irssi::TextUI::Line line +CODE: + RETVAL = textbuffer_view_get_line_cache(view, line->line); +OUTPUT: + RETVAL void textbuffer_view_remove_line(view, line) Irssi::TextUI::TextBufferView view Irssi::TextUI::Line line +CODE: + textbuffer_view_remove_line(view, line->line); void textbuffer_view_remove_all_lines(view) @@ -68,6 +81,8 @@ textbuffer_view_set_bookmark(view, name, line) Irssi::TextUI::TextBufferView view char *name Irssi::TextUI::Line line +CODE: + textbuffer_view_set_bookmark(view, name, line->line); void textbuffer_view_set_bookmark_bottom(view, name) @@ -78,6 +93,10 @@ Irssi::TextUI::Line textbuffer_view_get_bookmark(view, name) Irssi::TextUI::TextBufferView view char *name +CODE: + RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_bookmark(view, name)); +OUTPUT: + RETVAL void textbuffer_view_redraw(view) diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index af978162..e87efb65 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -1,11 +1,17 @@ #define PERL_NO_GET_CONTEXT #include "module.h" +#include "wrapper_buffer_line.h" void perl_statusbar_init(void); void perl_statusbar_deinit(void); static int initialized = FALSE; +static SV *buffer_line_bless(TEXT_BUFFER_REC *buffer, LINE_REC *line) +{ + return perl_buffer_line_bless(perl_wrap_buffer_line(buffer, line)); +} + static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window) { (void) hv_store(hv, "active", 6, plain_bless(window->active, "Irssi::UI::Window"), 0); @@ -20,9 +26,9 @@ static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window) static void perl_text_buffer_fill_hash(HV *hv, TEXT_BUFFER_REC *buffer) { - (void) hv_store(hv, "first_line", 10, plain_bless(buffer->first_line, "Irssi::TextUI::Line"), 0); + (void) hv_store(hv, "first_line", 10, buffer_line_bless(buffer, buffer->first_line), 0); (void) hv_store(hv, "lines_count", 11, newSViv(buffer->lines_count), 0); - (void) hv_store(hv, "cur_line", 8, plain_bless(buffer->cur_line, "Irssi::TextUI::Line"), 0); + (void) hv_store(hv, "cur_line", 8, buffer_line_bless(buffer, buffer->cur_line), 0); (void) hv_store(hv, "last_eol", 8, newSViv(buffer->last_eol), 0); } @@ -38,20 +44,22 @@ static void perl_text_buffer_view_fill_hash(HV *hv, TEXT_BUFFER_VIEW_REC *view) (void) hv_store(hv, "ypos", 4, newSViv(view->ypos), 0); - (void) hv_store(hv, "startline", 9, plain_bless(view->startline, "Irssi::TextUI::Line"), 0); + (void) hv_store(hv, "startline", 9, buffer_line_bless(view->buffer, view->startline), 0); (void) hv_store(hv, "subline", 7, newSViv(view->subline), 0); (void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0); - (void) hv_store(hv, "bottom_startline", 16, plain_bless(view->bottom_startline, "Irssi::TextUI::Line"), 0); + (void) hv_store(hv, "bottom_startline", 16, + buffer_line_bless(view->buffer, view->bottom_startline), 0); (void) hv_store(hv, "bottom_subline", 14, newSViv(view->bottom_subline), 0); (void) hv_store(hv, "empty_linecount", 15, newSViv(view->empty_linecount), 0); (void) hv_store(hv, "bottom", 6, newSViv(view->bottom), 0); } -static void perl_line_fill_hash(HV *hv, LINE_REC *line) +static void perl_line_fill_hash(HV *hv, struct Buffer_Line_Wrapper *line) { - (void) hv_store(hv, "info", 4, plain_bless(&line->info, "Irssi::TextUI::LineInfo"), 0); + (void) hv_store(hv, "info", 4, plain_bless(&Line(line)->info, "Irssi::TextUI::LineInfo"), + 0); } static void perl_line_cache_fill_hash(HV *hv, LINE_CACHE_REC *cache) @@ -242,7 +250,7 @@ CODE: format_create_dest(&dest, NULL, NULL, level, window); text = format_string_expand(str, NULL); text2 = g_strconcat(text, "\n", NULL); - gui_printtext_after_time(&dest, prev, text2, time); + gui_printtext_after_time(&dest, Line(prev), text2, time); g_free(text); g_free(text2); @@ -257,13 +265,14 @@ PREINIT: TEXT_DEST_REC dest; CODE: format_create_dest(&dest, NULL, NULL, level, window); - gui_printtext_after_time(&dest, prev, str, time); + gui_printtext_after_time(&dest, Line(prev), str, time); Irssi::TextUI::Line last_line_insert(window) Irssi::UI::Window window CODE: - RETVAL = WINDOW_GUI(window)->insert_after; + RETVAL = perl_wrap_buffer_line(WINDOW_GUI(window)->view->buffer, + WINDOW_GUI(window)->insert_after); OUTPUT: RETVAL @@ -281,7 +290,7 @@ PREINIT: TEXT_DEST_REC dest; CODE: format_create_dest(&dest, server, target, level, NULL); - gui_printtext_after_time(&dest, prev, str, time); + gui_printtext_after_time(&dest, Line(prev), str, time); BOOT: irssi_boot(TextUI__Statusbar); diff --git a/src/perl/textui/module.h b/src/perl/textui/module.h index 394c2839..aba5bd77 100644 --- a/src/perl/textui/module.h +++ b/src/perl/textui/module.h @@ -11,7 +11,7 @@ typedef MAIN_WINDOW_REC *Irssi__TextUI__MainWindow; typedef TEXT_BUFFER_REC *Irssi__TextUI__TextBuffer; typedef TEXT_BUFFER_VIEW_REC *Irssi__TextUI__TextBufferView; -typedef LINE_REC *Irssi__TextUI__Line; +typedef struct Buffer_Line_Wrapper *Irssi__TextUI__Line; typedef LINE_CACHE_REC *Irssi__TextUI__LineCache; typedef LINE_INFO_REC *Irssi__TextUI__LineInfo; typedef SBAR_ITEM_REC *Irssi__TextUI__StatusbarItem; diff --git a/src/perl/textui/typemap b/src/perl/textui/typemap index 364cdf32..7710c2d2 100644 --- a/src/perl/textui/typemap +++ b/src/perl/textui/typemap @@ -2,7 +2,7 @@ TYPEMAP Irssi::TextUI::MainWindow T_PlainObj Irssi::TextUI::TextBuffer T_PlainObj Irssi::TextUI::TextBufferView T_PlainObj -Irssi::TextUI::Line T_PlainObj +Irssi::TextUI::Line T_BufferLineWrapper Irssi::TextUI::LineCache T_PlainObj Irssi::TextUI::LineInfo T_PlainObj Irssi::TextUI::StatusbarItem T_PlainObj @@ -12,8 +12,13 @@ INPUT T_PlainObj $var = irssi_ref_object($arg) +T_BufferLineWrapper + $var = irssi_ref_buffer_line_wrap($arg) + OUTPUT T_PlainObj $arg = plain_bless($var, \"$type\"); +T_BufferLineWrapper + $arg = perl_buffer_line_bless($var); diff --git a/src/perl/textui/wrapper_buffer_line.h b/src/perl/textui/wrapper_buffer_line.h new file mode 100644 index 00000000..34310655 --- /dev/null +++ b/src/perl/textui/wrapper_buffer_line.h @@ -0,0 +1,90 @@ +#ifndef IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H +#define IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H + +/* This Buffer_Line_Wrapper is a compatibility shim so that the Perl + * API does not change in Irssi ABI 24 even though the C API was + * changed. That way scripts can continue to work unchanged. */ + +struct Buffer_Line_Wrapper { + LINE_REC *line; + TEXT_BUFFER_REC *buffer; +}; + +#define Line(wrapper) ((wrapper) == NULL ? NULL : (wrapper)->line) + +static int magic_free_buffer_line(pTHX_ SV *sv, MAGIC *mg) +{ + struct Buffer_Line_Wrapper *wrap = (struct Buffer_Line_Wrapper *) mg->mg_ptr; + g_free(wrap); + mg->mg_ptr = NULL; + sv_setiv(sv, 0); + return 0; +} + +static MGVTBL vtbl_free_buffer_line = { NULL, NULL, NULL, NULL, magic_free_buffer_line }; + +static struct Buffer_Line_Wrapper *perl_wrap_buffer_line(TEXT_BUFFER_REC *buffer, LINE_REC *line) +{ + struct Buffer_Line_Wrapper *wrap; + + if (line == NULL) + return NULL; + + wrap = g_new0(struct Buffer_Line_Wrapper, 1); + wrap->buffer = buffer; + wrap->line = line; + + return wrap; +} + +/* This function is more or less a copy of plain_bless, but with a + special divertion to put the wrapper in _wrapper and the original + line pointer in _irssi, in order to stay compatible with signals + and scripts */ +static SV *perl_buffer_line_bless(struct Buffer_Line_Wrapper *object) +{ + SV *ret, **tmp; + HV *hv; + const char *stash = "Irssi::TextUI::Line"; + + if (object == NULL) + return &PL_sv_undef; + + ret = irssi_bless_plain(stash, object); + hv = hvref(ret); + + tmp = hv_fetch(hv, "_irssi", 6, 0); + + sv_magic(*tmp, NULL, '~', NULL, 0); + + SvMAGIC(*tmp)->mg_private = 0x1551; /* HF */ + SvMAGIC(*tmp)->mg_virtual = &vtbl_free_buffer_line; + SvMAGIC(*tmp)->mg_ptr = (char *) object; + + (void) hv_store(hv, "_wrapper", 8, *tmp, 0); + /* We have to put the Line Pointer in _irssi, not the + compatibility wrapper */ + *tmp = newSViv((IV) object->line); + return ret; +} + +/* This function is a copy of irssi_ref_object, but looking up the + wrapper object in _wrapper instead */ +static void *irssi_ref_buffer_line_wrap(SV *o) +{ + SV **sv; + HV *hv; + void *p; + + hv = hvref(o); + if (hv == NULL) + return NULL; + + sv = hv_fetch(hv, "_wrapper", 8, 0); + if (sv == NULL) + croak("variable is damaged"); + p = GINT_TO_POINTER(SvIV(*sv)); + return p; +} + +#endif From 8fd6dccaf19b08542d855beb468bbf2ba4af56aa Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 17 Mar 2020 00:26:25 +0100 Subject: [PATCH 0660/1198] enable mirc colour processing --- src/fe-common/core/formats.c | 38 ++++++++++++++++------ src/fe-common/core/formats.h | 11 ++++++- src/fe-text/gui-printtext.c | 4 +-- src/fe-text/gui-printtext.h | 1 + src/fe-text/textbuffer-formats.c | 54 +++++++++++++++++++++++++++----- 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index a6fde7ea..a4d3a023 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -1222,8 +1222,14 @@ char *strip_codes(const char *input) return str; } -/* send a fully parsed text string for GUI to print */ -void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) +/* parse text string into GUI_PRINT_FLAG_* separated pieces and emit them to handler + handler is a SIGNAL_FUNC with the following arguments: + + WINDOW_REC *window, void *fgcolor_int, void *bgcolor_int, + void *flags_int, const char *textpiece, TEXT_DEST_REC *dest + + */ +void format_send_as_gui_flags(TEXT_DEST_REC *dest, const char *text, SIGNAL_FUNC handler) { THEME_REC *theme; char *dup, *str, *ptr, type; @@ -1238,8 +1244,8 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) if (*str == '\0') { /* empty line, write line info only */ - signal_emit_id(signal_gui_print_text, 6, dest->window, GINT_TO_POINTER(fgcolor), - GINT_TO_POINTER(bgcolor), GINT_TO_POINTER(flags), str, dest); + handler(dest->window, GINT_TO_POINTER(fgcolor), GINT_TO_POINTER(bgcolor), + GINT_TO_POINTER(flags), str, dest); } while (*str != '\0') { @@ -1259,16 +1265,14 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) if (*str != '\0' || (flags & GUI_PRINT_FLAG_CLRTOEOL)) { /* send the text to gui handler */ - signal_emit_id(signal_gui_print_text, 6, dest->window, - GINT_TO_POINTER(fgcolor), - GINT_TO_POINTER(bgcolor), - GINT_TO_POINTER(flags), str, - dest); + handler(dest->window, GINT_TO_POINTER(fgcolor), GINT_TO_POINTER(bgcolor), + GINT_TO_POINTER(flags), str, dest); flags &= ~(GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_CLRTOEOL); } if (type == '\n') { - format_newline(dest); + handler(dest->window, GINT_TO_POINTER(-1), GINT_TO_POINTER(-1), + GINT_TO_POINTER(GUI_PRINT_FLAG_NEWLINE), "", dest); fgcolor = theme->default_color; bgcolor = -1; flags &= GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_MONOSPACE; @@ -1414,6 +1418,20 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) g_free(dup); } +inline static void gui_print_text_emitter(WINDOW_REC *window, void *fgcolor_int, void *bgcolor_int, + void *flags_int, const char *textpiece, + TEXT_DEST_REC *dest) +{ + signal_emit_id(signal_gui_print_text, 6, window, fgcolor_int, bgcolor_int, flags_int, + textpiece, dest); +} + +/* send a fully parsed text string for GUI to print */ +void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) +{ + format_send_as_gui_flags(dest, text, (SIGNAL_FUNC) gui_print_text_emitter); +} + void format_gui_flags(GString *out, int *last_fg, int *last_bg, int *last_flags, int fg, int bg, int flags) { diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index e30ac290..226348de 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -1,8 +1,9 @@ #ifndef IRSSI_FE_COMMON_CORE_FORMATS_H #define IRSSI_FE_COMMON_CORE_FORMATS_H -#include +#include #include +#include #define GUI_PRINT_FLAG_BOLD 0x0001 #define GUI_PRINT_FLAG_REVERSE 0x0002 @@ -130,6 +131,14 @@ char *strip_codes(const char *input); /* send a fully parsed text string for GUI to print */ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text); +/* parse text string into GUI_PRINT_FLAG_* separated pieces and emit them to handler + handler is a SIGNAL_FUNC with the following arguments: + + WINDOW_REC *window, void *fgcolor_int, void *bgcolor_int, + void *flags_int, const char *textpiece, TEXT_DEST_REC *dest + + */ +void format_send_as_gui_flags(TEXT_DEST_REC *dest, const char *text, SIGNAL_FUNC handler); #define FORMAT_COLOR_NOCHANGE ('0'-1) /* don't change this, at least hilighting depends this value */ #define FORMAT_COLOR_EXT1 ('0'-2) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index fe720264..872c73c4 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -238,7 +238,7 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) } } -static void get_colors(int *flags, int *fg, int *bg, int *attr) +void gui_printtext_get_colors(int *flags, int *fg, int *bg, int *attr) { *attr = 0; if (*flags & GUI_PRINT_FLAG_MIRC_COLOR) { @@ -336,7 +336,7 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, flags = GPOINTER_TO_INT(pflags); fg = GPOINTER_TO_INT(fgcolor); bg = GPOINTER_TO_INT(bgcolor); - get_colors(&flags, &fg, &bg, &attr); + gui_printtext_get_colors(&flags, &fg, &bg, &attr); if (window == NULL) { print_text_no_window(flags, fg, bg, attr, str); diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index ba5d6f8f..0acf4d31 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -21,5 +21,6 @@ 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); void gui_printtext_window_border(int xpos, int ypos); +void gui_printtext_get_colors(int *flags, int *fg, int *bg, int *attr); #endif diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index e0a5f193..46876e75 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -205,10 +205,47 @@ static void sig_gui_print_text_finished(WINDOW_REC *window) gui->insert_after = insert_after; } +static void parse_colors_collector(const WINDOW_REC *window, const void *fgcolor_int, + const void *bgcolor_int, const void *flags_int, + const char *textpiece, const TEXT_DEST_REC *dest) +{ + int fg, bg, flags, attr; + + flags = GPOINTER_TO_INT(flags_int); + fg = GPOINTER_TO_INT(fgcolor_int); + bg = GPOINTER_TO_INT(bgcolor_int); + gui_printtext_get_colors(&flags, &fg, &bg, &attr); + + if (flags & GUI_PRINT_FLAG_NEWLINE) { + g_string_append_c(color_buf->cur_text, '\n'); + } + format_gui_flags(color_buf->cur_text, &color_buf->last_fg, &color_buf->last_bg, + &color_buf->last_flags, fg, bg, flags); + + g_string_append(color_buf->cur_text, textpiece); +} + +static char *parse_colors(TEXT_DEST_REC *dest, const char *text) +{ + char *tmp; + + if (text == NULL) + return NULL; + + color_buf = textbuffer_create(NULL); + format_send_as_gui_flags(dest, text, (SIGNAL_FUNC) parse_colors_collector); + tmp = g_strdup(color_buf->cur_text->str); + textbuffer_destroy(color_buf); + color_buf = NULL; + + return tmp; +} + char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) { + TEXT_DEST_REC dest; GUI_WINDOW_REC *gui; - LINE_REC *curr; + char *tmp, *text = NULL; g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(buffer->window != NULL, NULL); @@ -218,11 +255,11 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) return NULL; if (line->info.level & MSGLEVEL_FORMAT && line->info.format != NULL) { - TEXT_DEST_REC dest; + LINE_REC *curr; THEME_REC *theme; int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; - char *text, *tmp, *str; + char *str; curr = line; line = NULL; @@ -267,17 +304,18 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) dest.flags |= PRINT_FLAG_FORMAT; current_time = (time_t) -1; - return str; } else if (format_rec->format != NULL) { g_free(text); - return NULL; - } else { - return text; + text = NULL; } special_fill_cache(NULL); } else { - return g_strdup(line->info.text); + format_create_dest(&dest, NULL, NULL, line->info.level, buffer->window); + text = g_strdup(line->info.text); } + tmp = parse_colors(&dest, text); + g_free(text); + return tmp; } void textbuffer_formats_init(void) From 449d86caf0ff9f5458443d3bb60e5bc7658c038a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 29 Mar 2020 19:10:30 +0200 Subject: [PATCH 0661/1198] add setting to disable reformat --- src/fe-text/textbuffer-formats.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 46876e75..05158b6f 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include TEXT_BUFFER_REC *color_buf; +int scrollback_format; static void collector_free(GSList **collector) { @@ -119,6 +121,9 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC FORMAT_REC *formats; LINE_INFO_REC *info; + if (!scrollback_format) + return; + info = store_lineinfo_tmp(dest); formatnum = GPOINTER_TO_INT(formatnump); @@ -141,6 +146,9 @@ static void sig_print_noformat(TEXT_DEST_REC *dest, const char *text) { LINE_INFO_REC *info; + if (!scrollback_format) + return; + special_push_collector(NULL); info = store_lineinfo_tmp(dest); @@ -318,15 +326,25 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) return tmp; } +static void read_settings(void) +{ + scrollback_format = settings_get_bool("scrollback_format"); +} + void textbuffer_formats_init(void) { + settings_add_bool("lookandfeel", "scrollback_format", TRUE); + + read_settings(); signal_add("print format", (SIGNAL_FUNC) sig_print_format); signal_add("print noformat", (SIGNAL_FUNC) sig_print_noformat); signal_add_first("gui print text finished", (SIGNAL_FUNC) sig_gui_print_text_finished); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); } void textbuffer_formats_deinit(void) { + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); signal_remove("print format", (SIGNAL_FUNC) sig_print_format); signal_remove("print noformat", (SIGNAL_FUNC) sig_print_noformat); signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_print_text_finished); From 675696aa84bd9a2aeb2edfa2ec4edd88cffe04c8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 20 Apr 2020 23:55:46 +0200 Subject: [PATCH 0662/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index e0da1080..5fcf5d19 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 26 +#define IRSSI_ABI_VERSION 27 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 66a7cc3c345b29e2413a7a5e4cc8f9e234f61619 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 28 Apr 2020 15:34:47 +0200 Subject: [PATCH 0663/1198] check xs format --- .github/workflows/clangformat.yml | 5 + .github/workflows/clangformat/clang-format-xs | 114 ++++++++++++++++++ .github/workflows/clangformat/format-xs-1.pl | 73 +++++++++++ .github/workflows/clangformat/format-xs-2.pl | 10 ++ .../workflows/clangformat/format-xs-xml.pl | 44 +++++++ 5 files changed, 246 insertions(+) create mode 100755 .github/workflows/clangformat/clang-format-xs create mode 100644 .github/workflows/clangformat/format-xs-1.pl create mode 100644 .github/workflows/clangformat/format-xs-2.pl create mode 100644 .github/workflows/clangformat/format-xs-xml.pl diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index b52dad8b..71f2ffed 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -10,6 +10,11 @@ jobs: | refs=($(git log -1 --format=%s)) git fetch --depth=1 origin "${refs[3]}" + - name: configure clang-format + run: + | + git config clangformat.binary $PWD/.github/workflows/clangformat/clang-format-xs + git config clangformat.extensions c,h,xs - name: run git-clang-format and Check if no changes are needed run: | diff --git a/.github/workflows/clangformat/clang-format-xs b/.github/workflows/clangformat/clang-format-xs new file mode 100755 index 00000000..c77b7305 --- /dev/null +++ b/.github/workflows/clangformat/clang-format-xs @@ -0,0 +1,114 @@ +#!/bin/bash + +set -eu + +srcdir=$(dirname "$(readlink -f "$0")") +test -z "$srcdir" && srcdir=. + +CLANG_FORMAT=${CLANG_FORMAT:-clang-format} +options=() +files=() +lines=() +no_options=0;inplace=0;xml=0;keep_offset=0;keep_length=0;keep=0; +filename=tmp.1.c +offsets= +karg= +off_opts=() +for arg in "$@"; do + if [[ $keep = 1 ]]; then + if [[ "$karg" = "-offset" ]]; then + offsets="$offsets${offsets:+ }$arg" + off_opts+=("$karg" "$arg") + elif [[ "$karg" = "-length" ]]; then + offsets="$offsets:$arg" + off_opts+=("$karg" "$arg") + elif [[ "$karg" = "-assume-filename" ]]; then + filename="$arg" + options+=("$karg" "$arg") + else + options+=("$karg" "$arg") + fi + keep=0 + elif [[ $no_options = 0 ]]; then + case "$arg" in + -assume-filename=*) + filename="${arg#-assume-filename=}" + ;; + -lines=*) + lines+=("${arg#-lines=}") + ;; + *) + ;; + esac + case "$arg" in + --) no_options=1 + ;; + -i) inplace=1 + ;; + -output-replacements-xml) + xml=1 + ;; + -offset|-length|-cursor|-assume-filename|-fallback-style|-style) + keep=1 + karg="$arg" + ;; + -*) options+=("$arg") + ;; + *) files+=("$arg") + ;; + esac + else + files+=("$arg") + fi +done + +export IN_LINES="${lines[*]}" +export OFFSETS="$offsets" + +options_o=("${options[@]}") +if [[ $inplace = 1 ]]; then + options_o=("-i" "${options[@]}") +fi +if [[ $xml = 1 ]]; then + options_o=("-output-replacements-xml" "${options[@]}") +fi +options_o+=("${off_opts[@]}") + +do_xs() { + perl "$srcdir"/format-xs-1.pl "$1" > "$1".1.c + $CLANG_FORMAT -i "${options[@]}" -- "$1".1.c + if [[ $xml = 1 ]]; then + perl "$srcdir"/format-xs-2.pl "$1".1.c > "$1".1.xs + perl "$srcdir"/format-xs-xml.pl <(diff -U0 <(od -An -tu1 -w1 -v "$1") <(od -An -tu1 -w1 -v "$1".1.xs)) + rm "$1".1.xs + elif [[ $inplace = 1 ]]; then + perl "$srcdir"/format-xs-2.pl "$1".1.c > "$1" + else + perl "$srcdir"/format-xs-2.pl "$1".1.c + fi + rm "$1".1.c +} + +if [[ ${#files[@]} -eq 0 ]]; then + case "$filename" in + *.xs) + cat > "$filename".1.xs + do_xs "$filename".1.xs + rm "$filename".1.xs + ;; + *) + $CLANG_FORMAT "${options_o[@]}" + ;; + esac +else + for file in "${files[@]}"; do + case "$file" in + *.xs) + do_xs "$file" + ;; + *) + $CLANG_FORMAT "${options_o[@]}" -- "$file" + ;; + esac + done +fi diff --git a/.github/workflows/clangformat/format-xs-1.pl b/.github/workflows/clangformat/format-xs-1.pl new file mode 100644 index 00000000..1d15316e --- /dev/null +++ b/.github/workflows/clangformat/format-xs-1.pl @@ -0,0 +1,73 @@ +use strict; +use warnings; + +my $in_code = 1; +my @lines = $ENV{IN_LINES} =~ /(\d+):(\d+)/g; +sub in_lines { + if (@lines) { + for (my $i = 0; $i < @lines; $i += 2) { + if ($_[0] >= $lines[$i] && $_[0] <= $lines[$i + 1]) { + return 1; + } + } + return ''; + } else { + return 1; + } +} +while (<>) { + chomp; + my $copy; + my $prot = 0; + my $code = $in_code; + if (/^#(define|undef|include|if)/) { + $copy = 1; + } + elsif (/^#[* ]/) { + $prot = 1; + } + elsif (/^[A-Z_]+\s*=/) { + $prot = 2; + $in_code = 0; + } + elsif (/^((PP)?CODE|PREINIT):/) { + $prot = 1; + $in_code = 3; + } + elsif (/^[A-Z_]*:/) { + $prot = 1; + $in_code = 0; + } + elsif (/^[\w:* ]+\s*$/) { + $in_code = 0; + } + + if ($prot || (!$copy && !$in_code)) { + if ($code == 2) { + print "}/* -xs- */"; + } + if ($prot == 2) { + print "/* clang-format off */"; + } + s/^\s+/\t/ if in_lines($.); + print "/* =xs= $_ */"; + if ($prot == 2) { + print "/* clang-format on */"; + } + if ($in_code == 3) { + print "{"; + $in_code = 2; + } + print "\n"; + } + elsif ($copy) { + print "$_\n"; + } + elsif ($in_code) { + print "$_\n"; + } + +} +if ($in_code) { + print "}/* -xs- */\n"; +} diff --git a/.github/workflows/clangformat/format-xs-2.pl b/.github/workflows/clangformat/format-xs-2.pl new file mode 100644 index 00000000..40242553 --- /dev/null +++ b/.github/workflows/clangformat/format-xs-2.pl @@ -0,0 +1,10 @@ +use strict; +use warnings; + +my $doc = do { local $/; <> }; + +$doc =~ s{\}[ \t]*/[*] -xs- [*]/\s*}{}g; +$doc =~ s{^[ \t]*?/[*] =xs= (.*?) [*]/(\s*\{$)?}{$1}gms; +$doc =~ s{^[ \t]*?/[*] clang-format off [*]//[*] =xs= (.*?) [*]/\s?/[*] clang-format on [*]/(\s*\{$)?}{$1}gms; + +print $doc; diff --git a/.github/workflows/clangformat/format-xs-xml.pl b/.github/workflows/clangformat/format-xs-xml.pl new file mode 100644 index 00000000..151649ca --- /dev/null +++ b/.github/workflows/clangformat/format-xs-xml.pl @@ -0,0 +1,44 @@ +use strict; +use warnings; + +my @diff = <>; +if (@diff && $diff[0] !~ /^---/) { + die "Not valid diff output"; +} +my @offs = $ENV{OFFSETS} =~ /(\d+):(\d+)/g; +sub in_off { + if (@offs) { + for (my $i = 0; $i < @offs; $i += 2) { + if ($_[0] + $_[1] >= $offs[$i] && $_[0] <= $offs[$i] + $offs[$i + 1]) { + return 1; + } + } + return ''; + } else { + return 1; + } +} + +print " +\n"; +my $open; +for (@diff) { + if (/^\@\@ -(\d+)(,(\d+))? /) { + if ($open) { + print "\n"; + } + if (in_off($1-($3//1?1:0), $3//1)) { + print ""; + $open = 1; + } else { + $open = 0; + } + } + elsif (/^[+] +(\d+)/ && $open) { + print "&#$1;"; + } +} +if ($open) { + print "\n"; +} +print "\n"; From 08ead5ef06532bb45c79d1687b814e2c9b12d34a Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 7 May 2020 01:11:15 +0200 Subject: [PATCH 0664/1198] fix npe on no text from format_get_text_theme_charargs --- src/fe-text/textbuffer-formats.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 05158b6f..f48773bc 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -249,6 +249,22 @@ static char *parse_colors(TEXT_DEST_REC *dest, const char *text) return tmp; } +static char *fallback_format(TEXT_BUFFER_FORMAT_REC *format_rec) +{ + int i; + GString *bs; + char *tmp; + bs = g_string_new(NULL); + g_string_printf(bs, "{%s#%s ", format_rec->module, format_rec->format); + for (i = 0; i < format_rec->nargs; i++) { + tmp = g_strescape(format_rec->args[i], ""); + g_string_append_printf(bs, "\"%s\"%s", tmp, i + 1 < format_rec->nargs ? " " : ""); + g_free(tmp); + } + g_string_append(bs, "}"); + return g_string_free(bs, FALSE); +} + char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) { TEXT_DEST_REC dest; @@ -287,11 +303,14 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) memcpy(arglist, format_rec->args, format_rec->nargs * sizeof(char *)); text = format_get_text_theme_charargs(theme, format_rec->module, &dest, formatnum, arglist); + if (text == NULL) { + text = fallback_format(format_rec); + } } else { text = g_strdup(format_rec->args[1]); } - if (*text != '\0') { + if (text != NULL && *text != '\0') { current_time = curr->info.time; tmp = format_get_level_tag(theme, &dest); From ba57684d73616af0c1678a54f4c8b13287cd8572 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 8 May 2020 15:34:49 +0200 Subject: [PATCH 0665/1198] fix NULL assertion in format args --- src/fe-text/textbuffer-formats.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index f48773bc..edd14dbc 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -255,10 +255,10 @@ static char *fallback_format(TEXT_BUFFER_FORMAT_REC *format_rec) GString *bs; char *tmp; bs = g_string_new(NULL); - g_string_printf(bs, "{%s#%s ", format_rec->module, format_rec->format); - for (i = 0; i < format_rec->nargs; i++) { + g_string_printf(bs, "{%s#%s", format_rec->module, format_rec->format); + for (i = 0; i < format_rec->nargs && format_rec->args[i] != NULL; i++) { tmp = g_strescape(format_rec->args[i], ""); - g_string_append_printf(bs, "\"%s\"%s", tmp, i + 1 < format_rec->nargs ? " " : ""); + g_string_append_printf(bs, " \"%s\"", tmp); g_free(tmp); } g_string_append(bs, "}"); From 4330dbec627d6bc1d2cd0c19fada7de4fd471bfc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 11 May 2020 17:46:45 +0200 Subject: [PATCH 0666/1198] add "print format" signal to perl fix syntax in signals.txt with regards to GLists simplify signal emit code --- docs/signals.txt | 4 +- src/fe-common/core/fe-log.c | 6 +- src/fe-common/core/formats.c | 3 + src/fe-text/textbuffer-formats.c | 3 + src/perl/common/Core.xs | 38 ++-- src/perl/get-signals.pl | 5 +- src/perl/perl-signals.c | 312 ++++++++++++++++++------------- src/perl/perl-signals.h | 4 +- 8 files changed, 214 insertions(+), 161 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index d7d42f5d..ff600cd3 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -251,7 +251,7 @@ FE common * Provides signals: completion.c: - "complete word", GList * of char*, WINDOW_REC, char *word, char *linestart, int *want_space + "complete word", GList * of char *s, WINDOW_REC, char *word, char *linestart, int *want_space fe-common-core.c: "irssi init read settings" @@ -285,6 +285,8 @@ keyboard.c: printtext.c: "print text", TEXT_DEST_REC *dest, char *text, char *stripped + "print format", THEME_REC *theme, char *module, TEXT_DEST_REC *dest, formatnum_args + "print noformat", TEXT_DEST_REC *dest, char *text themes.c: "theme created", THEME_REC diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 12b6b643..b5222059 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -570,10 +570,10 @@ static void sig_print_format(THEME_REC *theme, const char *module, str = format_get_text_theme_charargs(log_theme, module, dest, GPOINTER_TO_INT(formatnum), args); - skip_next_printtext = TRUE; + if (str != NULL && *str != '\0') { + skip_next_printtext = TRUE; - if (*str != '\0') { - /* add the line start format */ + /* add the line start format */ linestart = format_get_level_tag(log_theme, dest); tmp = str; str = format_add_linestart(tmp, linestart); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index a4d3a023..eb47646e 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -650,6 +650,9 @@ char *format_get_text_theme_charargs(THEME_REC *theme, const char *module, MODULE_THEME_REC *module_theme; char *text; + if (module == NULL) + return NULL; + module_theme = g_hash_table_lookup(theme->modules, module); if (module_theme == NULL) return NULL; diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index edd14dbc..47f1735a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -124,6 +124,9 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC if (!scrollback_format) return; + if (module == NULL) + return; + info = store_lineinfo_tmp(dest); formatnum = GPOINTER_TO_INT(formatnump); diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index 8e26f105..7ae18943 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -68,13 +68,15 @@ static void add_tuple(gpointer key_, gpointer value_, gpointer user_data) (void) hv_store(hash, key, strlen(key), new_pv(value), 0); } -static void wrap_signal_emit(void *signal, void **p) { - signal_emit(signal, 6, p[0], p[1], p[2], p[3], p[4], p[5]); +static void wrap_signal_emit(void *signal, int params, void **p) +{ + signal_emit(signal, params, p[0], p[1], p[2], p[3], p[4], p[5]); } -static void wrap_signal_continue(void *dummy, void **p) { +static void wrap_signal_continue(void *dummy, int params, void **p) +{ (void)dummy; - signal_continue(6, p[0], p[1], p[2], p[3], p[4], p[5]); + signal_continue(params, p[0], p[1], p[2], p[3], p[4], p[5]); } MODULE = Irssi::Core PACKAGE = Irssi @@ -85,33 +87,14 @@ signal_emit(signal, ...) char *signal CODE: int signal_id; - SV *args[SIGNAL_MAX_ARGUMENTS]; - int n, used; signal_id = signal_get_uniq_id(signal); - used = items - 1; - if (used > SIGNAL_MAX_ARGUMENTS) { - used = SIGNAL_MAX_ARGUMENTS; - } - for (n = 0; n < used; ++n) { - args[n] = ST(n + 1); - } - perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, args, used); + perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, &ST(1), items - 1); void signal_continue(...) CODE: - SV *args[SIGNAL_MAX_ARGUMENTS]; - int n, used; - - used = items; - if (used > SIGNAL_MAX_ARGUMENTS) { - used = SIGNAL_MAX_ARGUMENTS; - } - for (n = 0; n < used; ++n) { - args[n] = ST(n); - } - perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), args, used); + perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), &ST(0), items); void signal_add(...) @@ -162,7 +145,7 @@ PREINIT: HV *hv; HE *he; I32 len, pos; - const char *arr[7]; + const char *arr[SIGNAL_MAX_ARGUMENTS + 1]; CODE: if (items != 1 || !is_hvref(ST(0))) croak("Usage: Irssi::signal_register(hash)"); @@ -179,7 +162,8 @@ CODE: av = (AV *) SvRV(val); len = av_len(av)+1; - if (len > 6) len = 6; + if (len > SIGNAL_MAX_ARGUMENTS) + len = SIGNAL_MAX_ARGUMENTS; for (pos = 0; pos < len; pos++) { SV **val = av_fetch(av, pos, 0); arr[pos] = SvPV_nolen(*val); diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index 275be157..12aebdba 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -16,14 +16,15 @@ while (<>) { $signal = $1; $_ = $3; - s/GList \* of ([^,]*)/glistptr_\1/g; - s/GSList of (\w+)s/gslist_\1/g; + s/GList \* of ([^,]*)s/glistptr_\1/g; + s/GSList of ([^,]*)s/gslist_\1/g; s/char \*[^,]*/string/g; s/ulong \*[^,]*/ulongptr/g; s/int \*[^,]*/intptr/g; s/int [^,]*/int/g; + my %map = ( # core CHATNET_REC => 'iobject', diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 59289588..27522f5e 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -21,10 +21,11 @@ #define NEED_PERL_H #define PERL_NO_GET_CONTEXT #include "module.h" -#include -#include #include +#include #include +#include +#include #include #include @@ -39,7 +40,7 @@ typedef struct { typedef struct { char *signal; - char *args[7]; + char *args[SIGNAL_MAX_ARGUMENTS + 1]; int dynamic; } PERL_SIGNAL_ARGS_REC; @@ -71,9 +72,8 @@ static PERL_SIGNAL_ARGS_REC *perl_signal_args_find(int signal_id) return NULL; } -void perl_signal_args_to_c( - void (*callback)(void *, void **), void *cb_arg, - int signal_id, SV **args, size_t n_args) +void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id, + SV **args, size_t n_args) { union { int v_int; @@ -83,136 +83,162 @@ void perl_signal_args_to_c( } saved_args[SIGNAL_MAX_ARGUMENTS]; void *p[SIGNAL_MAX_ARGUMENTS]; PERL_SIGNAL_ARGS_REC *rec; - size_t n; + char *arglist[MAX_FORMAT_PARAMS]; + size_t n; - if (!(rec = perl_signal_args_find(signal_id))) { - const char *name = signal_get_id_str(signal_id); - if (!name) { - croak("%d is not a known signal id", signal_id); - } - croak("\"%s\" is not a registered signal", name); - } + if (!(rec = perl_signal_args_find(signal_id))) { + const char *name = signal_get_id_str(signal_id); + if (!name) { + croak("%d is not a known signal id", signal_id); + } + croak("\"%s\" is not a registered signal", name); + } - for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) { - void *c_arg; - SV *arg = args[n]; + for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) { + void *c_arg; + SV *arg = args[n]; - if (!SvOK(arg)) { - c_arg = NULL; - } else if (g_strcmp0(rec->args[n], "string") == 0) { - c_arg = SvPV_nolen(arg); - } else if (g_strcmp0(rec->args[n], "int") == 0) { - c_arg = (void *)SvIV(arg); - } else if (g_strcmp0(rec->args[n], "ulongptr") == 0) { - saved_args[n].v_ulong = SvUV(arg); - c_arg = &saved_args[n].v_ulong; - } else if (g_strcmp0(rec->args[n], "intptr") == 0) { - saved_args[n].v_int = SvIV(SvRV(arg)); - c_arg = &saved_args[n].v_int; - } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { - GList *gl; - int is_str; - AV *av; - SV *t; - int count; + if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { + const FORMAT_REC *formats; + const char *module; + int num; + int formatnum; - t = SvRV(arg); - if (SvTYPE(t) != SVt_PVAV) { - croak("Not an ARRAY reference"); - } - av = (AV *)t; + module = SvPV_nolen(args[n - 2]); + formatnum = format_find_tag(module, SvPV_nolen(arg)); + if (formatnum < 0) { /* format out of bounds */ + p[n - 2] = NULL; + break; + } - is_str = g_strcmp0(rec->args[n]+9, "char*") == 0; + formats = g_hash_table_lookup(default_formats, module); + arglist[formats[formatnum].params] = NULL; - gl = NULL; - count = av_len(av) + 1; - while (count-- > 0) { - SV **px = av_fetch(av, count, 0); - SV *x = px ? *px : NULL; - gl = g_list_prepend( - gl, - x == NULL ? NULL : - is_str ? g_strdup(SvPV_nolen(x)) : - irssi_ref_object(x) - ); - } - saved_args[n].v_glist = gl; - c_arg = &saved_args[n].v_glist; - } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { - GSList *gsl; - AV *av; - SV *t; - int count; + p[n++] = GINT_TO_POINTER(formatnum); - t = SvRV(arg); - if (SvTYPE(t) != SVt_PVAV) { - croak("Not an ARRAY reference"); - } - av = (AV *)t; + for (num = 0; num < formats[formatnum].params; num++) { + if (n + num < n_args) + arglist[num] = SvPV_nolen(args[n + num]); + else + arglist[num] = ""; + } - gsl = NULL; - count = av_len(av) + 1; - while (count-- > 0) { - SV **x = av_fetch(av, count, 0); - gsl = g_slist_prepend( - gsl, - x == NULL ? NULL : - irssi_ref_object(*x) - ); - } - c_arg = saved_args[n].v_gslist = gsl; - } else { - c_arg = irssi_ref_object(arg); - } + p[n++] = arglist; + n_args = n; - p[n] = c_arg; - } + break; + } else if (!SvOK(arg)) { + c_arg = NULL; + } else if (g_strcmp0(rec->args[n], "string") == 0) { + c_arg = SvPV_nolen(arg); + } else if (g_strcmp0(rec->args[n], "int") == 0) { + c_arg = (void *) SvIV(arg); + } else if (g_strcmp0(rec->args[n], "ulongptr") == 0) { + saved_args[n].v_ulong = SvUV(arg); + c_arg = &saved_args[n].v_ulong; + } else if (g_strcmp0(rec->args[n], "intptr") == 0) { + saved_args[n].v_int = SvIV(SvRV(arg)); + c_arg = &saved_args[n].v_int; + } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { + GList *gl; + int is_str; + AV *av; + SV *t; + int count; - for (; n < SIGNAL_MAX_ARGUMENTS; ++n) { - p[n] = NULL; - } + t = SvRV(arg); + if (SvTYPE(t) != SVt_PVAV) { + croak("Not an ARRAY reference"); + } + av = (AV *) t; - callback(cb_arg, p); + is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 || + g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */ - for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) { - SV *arg = args[n]; + gl = NULL; + count = av_len(av) + 1; + while (count-- > 0) { + SV **px = av_fetch(av, count, 0); + SV *x = px ? *px : NULL; + gl = g_list_prepend(gl, x == NULL ? + NULL : + is_str ? g_strdup(SvPV_nolen(x)) : + irssi_ref_object(x)); + } + saved_args[n].v_glist = gl; + c_arg = &saved_args[n].v_glist; + } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { + GSList *gsl; + AV *av; + SV *t; + int count; - if (!SvOK(arg)) { - continue; - } + t = SvRV(arg); + if (SvTYPE(t) != SVt_PVAV) { + croak("Not an ARRAY reference"); + } + av = (AV *) t; - if (g_strcmp0(rec->args[n], "intptr") == 0) { - SV *t = SvRV(arg); - SvIOK_only(t); - SvIV_set(t, saved_args[n].v_int); - } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { - g_slist_free(saved_args[n].v_gslist); - } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { - int is_iobject, is_str; - AV *av; - GList *gl, *tmp; + gsl = NULL; + count = av_len(av) + 1; + while (count-- > 0) { + SV **x = av_fetch(av, count, 0); + gsl = g_slist_prepend(gsl, x == NULL ? NULL : irssi_ref_object(*x)); + } + c_arg = saved_args[n].v_gslist = gsl; + } else { + c_arg = irssi_ref_object(arg); + } - is_iobject = g_strcmp0(rec->args[n]+9, "iobject") == 0; - is_str = g_strcmp0(rec->args[n]+9, "char*") == 0; + p[n] = c_arg; + } - av = (AV *)SvRV(arg); - av_clear(av); + for (; n < SIGNAL_MAX_ARGUMENTS; ++n) { + p[n] = NULL; + } - gl = saved_args[n].v_glist; - for (tmp = gl; tmp != NULL; tmp = tmp->next) { - av_push(av, - is_iobject ? iobject_bless((SERVER_REC *)tmp->data) : - is_str ? new_pv(tmp->data) : - irssi_bless_plain(rec->args[n]+9, tmp->data) - ); - } + callback(cb_arg, n_args, p); - if (is_str) { - g_list_foreach(gl, (GFunc)g_free, NULL); - } - g_list_free(gl); - } - } + for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) { + SV *arg = args[n]; + + if (!SvOK(arg)) { + continue; + } + + if (g_strcmp0(rec->args[n], "intptr") == 0) { + SV *t = SvRV(arg); + SvIOK_only(t); + SvIV_set(t, saved_args[n].v_int); + } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { + g_slist_free(saved_args[n].v_gslist); + } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { + int is_iobject, is_str; + AV *av; + GList *gl, *tmp; + + is_iobject = g_strcmp0(rec->args[n] + 9, "iobject") == 0; + is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 || + g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */ + + av = (AV *) SvRV(arg); + av_clear(av); + + gl = saved_args[n].v_glist; + for (tmp = gl; tmp != NULL; tmp = tmp->next) { + av_push(av, is_iobject ? + iobject_bless((SERVER_REC *) tmp->data) : + is_str ? + new_pv(tmp->data) : + irssi_bless_plain(rec->args[n] + 9, tmp->data)); + } + + if (is_str) { + g_list_foreach(gl, (GFunc) g_free, NULL); + } + g_list_free(gl); + } + } } static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, @@ -246,7 +272,8 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, int is_iobject, is_str; is_iobject = g_strcmp0(rec->args[n]+9, "iobject") == 0; - is_str = g_strcmp0(rec->args[n]+9, "char*") == 0; + is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 || + g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */ av = newAV(); ptr = arg; @@ -267,8 +294,37 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, else if (g_strcmp0(rec->args[n], "ulongptr") == 0) perlarg = newSViv(*(unsigned long *) arg); else if (g_strcmp0(rec->args[n], "intptr") == 0) - saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg)); - else if (strncmp(rec->args[n], "gslist_", 7) == 0) { + saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg)); + else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { + const THEME_REC *theme; + const MODULE_THEME_REC *rec; + const FORMAT_REC *formats; + char *const *tmp; + int formatnum; + + theme = args[n - 3]; + if (theme == NULL) /* no theme */ + continue; + + rec = g_hash_table_lookup(theme->modules, args[n - 2]); + if (rec == NULL) /* no module in theme */ + continue; + + formats = g_hash_table_lookup(default_formats, args[n - 2]); + if (formats == NULL) /* no module in default_formats */ + continue; + + formatnum = GPOINTER_TO_INT(arg); + if (formatnum >= rec->count) /* format out of bounds */ + continue; + + XPUSHs(sv_2mortal(new_pv(formats[formatnum].tag))); + for (tmp = args[n + 1]; *tmp != NULL; tmp++) { + XPUSHs(sv_2mortal(new_pv(*tmp))); + } + + continue; + } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { /* linked list - push as AV */ GSList *tmp; int is_iobject; @@ -338,8 +394,9 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, out = g_list_append(out, val); } - if (g_strcmp0(rec->args[n]+9, "char*") == 0) - g_list_foreach(*ret, (GFunc) g_free, NULL); + if (g_strcmp0(rec->args[n] + 9, "string") == 0 || + g_strcmp0(rec->args[n] + 9, "char*") == 0) /* deprecated form */ + g_list_foreach(*ret, (GFunc) g_free, NULL); g_list_free(*ret); *ret = out; } @@ -349,12 +406,15 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, LEAVE; } +#if SIGNAL_MAX_ARGUMENTS != 6 +#error SIGNAL_MAX_ARGUMENTS changed - update code +#endif static void sig_func(const void *p1, const void *p2, const void *p3, const void *p4, const void *p5, const void *p6) { PERL_SIGNAL_REC *rec; - const void *args[6]; + const void *args[SIGNAL_MAX_ARGUMENTS]; args[0] = p1; args[1] = p2; args[2] = p3; args[3] = p4; args[4] = p5; args[5] = p6; @@ -553,7 +613,7 @@ void perl_signal_register(const char *signal, const char **args) return; rec = g_new0(PERL_SIGNAL_ARGS_REC, 1); - for (i = 0; i < 6 && args[i] != NULL; i++) + for (i = 0; i < SIGNAL_MAX_ARGUMENTS && args[i] != NULL; i++) rec->args[i] = g_strdup(args[i]); rec->dynamic = TRUE; rec->signal = g_strdup(signal); @@ -579,7 +639,7 @@ static void signal_args_free(PERL_SIGNAL_ARGS_REC *rec) if (!rec->dynamic) return; - for (i = 0; i < 6 && rec->args[i] != NULL; i++) + for (i = 0; i < SIGNAL_MAX_ARGUMENTS && rec->args[i] != NULL; i++) g_free(rec->args[i]); g_free(rec->signal); g_free(rec); diff --git a/src/perl/perl-signals.h b/src/perl/perl-signals.h index 8191a917..cb636d3c 100644 --- a/src/perl/perl-signals.h +++ b/src/perl/perl-signals.h @@ -1,8 +1,8 @@ #ifndef IRSSI_PERL_PERL_SIGNALS_H #define IRSSI_PERL_PERL_SIGNALS_H -void perl_signal_args_to_c(void (*callback)(void *, void **), void *cb_arg, - int signal_id, SV **args, size_t n_args); +void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id, + SV **args, size_t n_args); void perl_signal_add_full(const char *signal, SV *func, int priority); From 3ea854816d378dd370575a4a557fbd2b80a55347 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 13 May 2020 00:03:36 +0200 Subject: [PATCH 0667/1198] Correct a wrong package for format_create_dest --- src/perl/ui/Formats.xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs index c10f0b4e..8e34b7b9 100644 --- a/src/perl/ui/Formats.xs +++ b/src/perl/ui/Formats.xs @@ -104,7 +104,7 @@ PPCODE: g_free_not_null(ret); #******************************* -MODULE = Irssi::UI::Formats PACKAGE = Irssi::Window +MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::Window #******************************* void From b0cd72aadd62d6f018b36289635e7133f6988afc Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 13 May 2020 00:23:12 +0200 Subject: [PATCH 0668/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 5fcf5d19..f2c50cde 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 27 +#define IRSSI_ABI_VERSION 28 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 3cb662797351506041f89c23deadeff498c8da44 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Fri, 15 May 2020 11:18:43 +0200 Subject: [PATCH 0669/1198] also check XS abi --- .github/workflows/abicheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index 8ea6837f..48f39b25 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -4,7 +4,7 @@ jobs: check-abi-diff: runs-on: ubuntu-latest env: - build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes + build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes -Dc_args=-DPERL_EUPXS_ALWAYS_EXPORT prefix: /usr/local steps: - name: set PATH From ae6c8a1bd51b698c577c23a7be4862f8ab6cf470 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Fri, 15 May 2020 20:25:41 +0200 Subject: [PATCH 0670/1198] Add better support for numeric 489 ERR_SECUREONLYCHAN along with a print format modified: src/fe-common/irc/fe-events-numeric.c modified: src/fe-common/irc/module-formats.c modified: src/fe-common/irc/module-formats.h --- src/fe-common/irc/fe-events-numeric.c | 29 +++++++++++++++++++++++++-- src/fe-common/irc/module-formats.c | 1 + src/fe-common/irc/module-formats.h | 1 + 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index a6bbaa27..eb356945 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -531,6 +531,31 @@ static void event_477(IRC_SERVER_REC *server, const char *data, g_free(params); } +static void event_489(IRC_SERVER_REC *server, const char *data, + const char *nick) +{ + /* Numeric 489 can mean one of two things things: + * cannot join to channel (secure only), or not chanop or voice. + * If we tried to join this channel, display the joinerror. + * Otherwise depending on the channel being joined or not + * display the error in the channel or status window. + */ + IRC_CHANNEL_REC *chanrec; + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + + chanrec = irc_channel_find(server, channel); + if (chanrec != NULL && !chanrec->joined) { + cannot_join(server, data, IRCTXT_JOINERROR_SECURE_ONLY); + } else { + print_event_received(server, data, nick, chanrec == NULL || chanrec->joined); + } + g_free(params); +} + static void event_target_too_fast(IRC_SERVER_REC *server, const char *data, const char *nick) { @@ -683,6 +708,7 @@ void fe_events_numeric_init(void) signal_add("event 475", (SIGNAL_FUNC) event_bad_channel_key); signal_add("event 476", (SIGNAL_FUNC) event_bad_channel_mask); signal_add("event 477", (SIGNAL_FUNC) event_477); + signal_add("event 489", (SIGNAL_FUNC) event_489); /* cannot join to channel (secure only), or not chanop or voice. */ signal_add("event 375", (SIGNAL_FUNC) event_motd); signal_add("event 376", (SIGNAL_FUNC) event_motd); signal_add("event 372", (SIGNAL_FUNC) event_motd); @@ -726,7 +752,6 @@ void fe_events_numeric_init(void) signal_add("event 478", (SIGNAL_FUNC) event_target_received); /* ban list is full */ signal_add("event 482", (SIGNAL_FUNC) event_target_received); /* not chanop */ signal_add("event 486", (SIGNAL_FUNC) event_target_received); /* cannot /msg (+R) */ - signal_add("event 489", (SIGNAL_FUNC) event_target_received); /* not chanop or voice */ signal_add("event 494", (SIGNAL_FUNC) event_target_received); /* cannot /msg (own +R) */ signal_add("event 506", (SIGNAL_FUNC) event_target_received); /* cannot send (+R) */ signal_add("event 716", (SIGNAL_FUNC) event_target_received); /* cannot /msg (+g) */ @@ -776,6 +801,7 @@ void fe_events_numeric_deinit(void) signal_remove("event 475", (SIGNAL_FUNC) event_bad_channel_key); signal_remove("event 476", (SIGNAL_FUNC) event_bad_channel_mask); signal_remove("event 477", (SIGNAL_FUNC) event_477); + signal_remove("event 489", (SIGNAL_FUNC) event_489); signal_remove("event 375", (SIGNAL_FUNC) event_motd); signal_remove("event 376", (SIGNAL_FUNC) event_motd); signal_remove("event 372", (SIGNAL_FUNC) event_motd); @@ -815,7 +841,6 @@ void fe_events_numeric_deinit(void) signal_remove("event 478", (SIGNAL_FUNC) event_target_received); signal_remove("event 482", (SIGNAL_FUNC) event_target_received); signal_remove("event 486", (SIGNAL_FUNC) event_target_received); - signal_remove("event 489", (SIGNAL_FUNC) event_target_received); signal_remove("event 494", (SIGNAL_FUNC) event_target_received); signal_remove("event 506", (SIGNAL_FUNC) event_target_received); signal_remove("event 716", (SIGNAL_FUNC) event_target_received); diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index e36eed92..6cca76d2 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -63,6 +63,7 @@ FORMAT_REC fecommon_irc_formats[] = { { "joinerror_banned", "Cannot join to channel {channel $0} (You are banned)", 1, { 0 } }, { "joinerror_bad_key", "Cannot join to channel {channel $0} (Bad channel key)", 1, { 0 } }, { "joinerror_bad_mask", "Cannot join to channel {channel $0} (Bad channel mask)", 1, { 0 } }, + { "joinerror_secure_only", "Cannot join to channel {channel $0} (Secure clients only)", 1, { 0 } }, { "joinerror_unavail", "Cannot join to channel {channel $0} (Channel is temporarily unavailable)", 1, { 0 } }, { "joinerror_duplicate", "Channel {channel $0} already exists - cannot create it", 1, { 0 } }, { "channel_rejoin", "Channel {channel $0} is temporarily unavailable, this is normally because of netsplits. Irssi will now automatically try to rejoin back to this channel until the join is successful. Use /RMREJOINS command if you wish to abort this.", 1, { 0 } }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 66a9804f..02247c4d 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -40,6 +40,7 @@ enum { IRCTXT_JOINERROR_BANNED, IRCTXT_JOINERROR_BAD_KEY, IRCTXT_JOINERROR_BAD_MASK, + IRCTXT_JOINERROR_SECURE_ONLY, IRCTXT_JOINERROR_UNAVAIL, IRCTXT_JOINERROR_DUPLICATE, IRCTXT_CHANNEL_REJOIN, From 28768e40a35488f6431ac924bfc1802fd1343f5b Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 16 May 2020 00:48:58 +0200 Subject: [PATCH 0671/1198] Increased IRSSI_ABI_VERSION to 29 modified: src/common.h --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index f2c50cde..c9c4e545 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 28 +#define IRSSI_ABI_VERSION 29 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 1fef8f82a5d12ceb8525595f3b65c4de448b8019 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 16 May 2020 01:00:17 +0200 Subject: [PATCH 0672/1198] make git-clang-format check happy modified: src/fe-common/irc/fe-events-numeric.c --- src/fe-common/irc/fe-events-numeric.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index eb356945..8d672931 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -511,8 +511,7 @@ static void event_bad_channel_mask(IRC_SERVER_REC *server, const char *data) cannot_join(server, data, IRCTXT_JOINERROR_BAD_MASK); } -static void event_477(IRC_SERVER_REC *server, const char *data, - const char *nick) +static void event_477(IRC_SERVER_REC *server, const char *data, const char *nick) { /* Numeric 477 can mean many things: * modeless channel, cannot join/send to channel (+r/+R/+M). From 451e3692b24b9146788e35b4b7b950c1b5c18c52 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 16 May 2020 01:20:22 +0200 Subject: [PATCH 0673/1198] disable clang-format check for a few sections of code from before format strictnes got tightened modified: src/fe-common/irc/fe-events-numeric.c modified: src/fe-common/irc/module-formats.c modified: src/fe-common/irc/module-formats.h --- src/fe-common/irc/fe-events-numeric.c | 2 ++ src/fe-common/irc/module-formats.c | 2 ++ src/fe-common/irc/module-formats.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index 8d672931..08c97866 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -671,6 +671,7 @@ void fe_events_numeric_init(void) last_away_nick = NULL; last_away_msg = NULL; + /* clang-format off */ signal_add("event 221", (SIGNAL_FUNC) event_user_mode); signal_add("event 303", (SIGNAL_FUNC) event_ison); signal_add("event 353", (SIGNAL_FUNC) event_names_list); @@ -757,6 +758,7 @@ void fe_events_numeric_init(void) signal_add("event 717", (SIGNAL_FUNC) event_target_received); /* +g notified */ signal_add("event 728", (SIGNAL_FUNC) event_target_received); /* quiet (or other) list */ signal_add("event 729", (SIGNAL_FUNC) event_target_received); /* end of quiet (or other) list */ + /* clang-format on */ } void fe_events_numeric_deinit(void) diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index 6cca76d2..d4c00f25 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -21,6 +21,7 @@ #include "module.h" #include +/* clang-format off */ FORMAT_REC fecommon_irc_formats[] = { { MODULE_NAME, "IRC", 0 }, @@ -176,3 +177,4 @@ FORMAT_REC fecommon_irc_formats[] = { { NULL, NULL, 0 } }; +/* clang-format on */ diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 02247c4d..892b77c8 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -1,5 +1,6 @@ #include +/* clang-format off */ enum { IRCTXT_MODULE_NAME, @@ -144,5 +145,6 @@ enum { IRCTXT_ASK_OPER_PASS, IRCTXT_ACCEPT_LIST }; +/* clang-format on */ extern FORMAT_REC fecommon_irc_formats[]; From 214c7ad7da283d37fa47ff663edbb4035c7aa0ac Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 16 May 2020 01:26:00 +0200 Subject: [PATCH 0674/1198] make clang-format happy about the code i added, instead of the code above it. modified: src/fe-common/irc/fe-events-numeric.c --- src/fe-common/irc/fe-events-numeric.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index 08c97866..37fdf30a 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -530,8 +530,7 @@ static void event_477(IRC_SERVER_REC *server, const char *data, const char *nick g_free(params); } -static void event_489(IRC_SERVER_REC *server, const char *data, - const char *nick) +static void event_489(IRC_SERVER_REC *server, const char *data, const char *nick) { /* Numeric 489 can mean one of two things things: * cannot join to channel (secure only), or not chanop or voice. From 7c1237de981bbb67d57869790427929e75f925d1 Mon Sep 17 00:00:00 2001 From: Lauri Tirkkonen Date: Thu, 21 May 2020 11:14:16 +0300 Subject: [PATCH 0675/1198] use visible channel name in layout save --- irssi.conf | 2 +- src/fe-common/core/windows-layout.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/irssi.conf b/irssi.conf index 828b5997..174d0552 100644 --- a/irssi.conf +++ b/irssi.conf @@ -107,7 +107,7 @@ channels = ( aliases = { ATAG = "WINDOW SERVER"; - ADDALLCHANS = "SCRIPT EXEC foreach my \\$channel (Irssi::channels()) { Irssi::command(\"CHANNEL ADD -auto \\$channel->{name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}"; + ADDALLCHANS = "SCRIPT EXEC foreach my \\$channel (Irssi::channels()) { Irssi::command(\"CHANNEL ADD -auto \\$channel->{visible_name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}"; B = "BAN"; BACK = "AWAY"; BANS = "BAN"; diff --git a/src/fe-common/core/windows-layout.c b/src/fe-common/core/windows-layout.c index 745453d5..fa209f48 100644 --- a/src/fe-common/core/windows-layout.c +++ b/src/fe-common/core/windows-layout.c @@ -169,12 +169,12 @@ static void sig_layout_save_item(WINDOW_REC *window, WI_ITEM_REC *item, chat_protocol_find_id(item->chat_type); if (proto != NULL) iconfig_node_set_str(subnode, "chat_type", proto->name); - iconfig_node_set_str(subnode, "name", item->name); + iconfig_node_set_str(subnode, "name", item->visible_name); if (item->server != NULL) { iconfig_node_set_str(subnode, "tag", item->server->tag); if (IS_CHANNEL(item)) { - rec = window_bind_add(window, item->server->tag, item->name); + rec = window_bind_add(window, item->server->tag, item->visible_name); if (rec != NULL) rec->sticky = TRUE; } From d5017cfc7c4e6155cbfe08b2af881ff44d930cf8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 24 May 2020 18:43:46 +0200 Subject: [PATCH 0676/1198] make actlist_sort a choice type now that we have it --- src/fe-text/statusbar-items.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 4bca9403..47b31103 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -451,28 +451,16 @@ static void item_input(SBAR_ITEM_REC *item, int get_size_only) static void read_settings(void) { - const char *str; - if (active_entry != NULL) gui_entry_set_utf8(active_entry, term_type == TERM_TYPE_UTF8); - str = settings_get_str("actlist_sort"); - if (g_ascii_strcasecmp(str, "recent") == 0) - actlist_sort = 1; - else if (g_ascii_strcasecmp(str, "level") == 0) - actlist_sort = 2; - else if (g_ascii_strcasecmp(str, "level,recent") == 0) - actlist_sort = 3; - else { - settings_set_str("actlist_sort", "refnum"); - actlist_sort = 0; - } + actlist_sort = settings_get_choice("actlist_sort"); } void statusbar_items_init(void) { settings_add_time("misc", "lag_min_show", "1sec"); - settings_add_str("lookandfeel", "actlist_sort", "refnum"); + settings_add_choice("lookandfeel", "actlist_sort", 0, "refnum;recent;level;level,recent"); settings_add_bool("lookandfeel", "actlist_names", FALSE); settings_add_bool("lookandfeel", "actlist_prefer_window_name", FALSE); From 4b2c710ebe440bc90d2ec38733d83a15c124b0ff Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 2 Jun 2020 09:53:18 +0200 Subject: [PATCH 0677/1198] disable setuid/setgid on android --- src/fe-common/core/fe-exec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index 0da4ac89..58471345 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -316,11 +316,13 @@ static void process_exec(PROCESS_REC *rec, const char *cmd) /* child process, try to clean up everything */ setsid(); +#ifndef __ANDROID__ if (setuid(getuid()) != 0) _exit(EXIT_FAILURE); if (setgid(getgid()) != 0) _exit(EXIT_FAILURE); +#endif signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_DFL); From 01ecb879a63941fbbe78c8f3d8683539d1f87d2e Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 27 May 2020 22:28:07 +0200 Subject: [PATCH 0678/1198] Add support for building in Termux-Android in meson - introduce cross perl - workaround for the android linker --- INSTALL | 32 +++++++-- configure.ac | 1 + docs/example-cross-android-aarch64.txt | 47 ++++++++++++ meson.build | 95 ++++++++++++++++++------- meson_options.txt | 1 + src/fe-common/core/fe-exec.c | 6 +- src/fe-fuzz/fe-common/core/theme-load.c | 4 +- src/perl/common/meson.build | 4 +- src/perl/irc/meson.build | 3 +- src/perl/meson.build | 14 ++-- src/perl/textui/meson.build | 3 +- src/perl/ui/meson.build | 3 +- 12 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 docs/example-cross-android-aarch64.txt diff --git a/INSTALL b/INSTALL index 3476211f..712678e4 100644 --- a/INSTALL +++ b/INSTALL @@ -2,12 +2,12 @@ Irssi installation instructions ------------------------------- -To compile irssi you need: +To compile Irssi you need: - meson-0.49 build system with ninja-1.5 or greater - glib-2.28 or greater - openssl (for ssl support) -- perl-5.6 or greater (for perl support) +- perl-5.6 or greater (for Perl support) - terminfo or ncurses (for text frontend) For most people, this should work just fine: @@ -35,13 +35,13 @@ configure options --prefix - Specifies the path where irssi will be installed. - YES, you can install irssi WITHOUT ROOT permissions + Specifies the path where Irssi will be installed. + YES, you can install Irssi WITHOUT ROOT permissions by using --prefix=/home/dir -Dwith-proxy=yes / --with-proxy - Build the irssi proxy (see startup-HOWTO). + Build the Irssi proxy (see startup-HOWTO). -Dwith-perl=[yes|no] / --with-perl=[yes|no|module] @@ -70,9 +70,9 @@ configure options Build without text frontend If anything is in non-standard path, you can just give the paths in -CPPFLAGS and LIBS environment variable, eg.: +the -Dc_args and -Dc_link_args options variable, eg.: - CPPFLAGS=-I/opt/openssl/include LDFLAGS=-L/opt/openssl/lib ./configure + meson Build -Dc_args='-I/opt/openssl/include' -Dc_link_args='-L/opt/openssl/lib' @@ -112,6 +112,24 @@ perl static core fe System specific notes --------------------- + Android + +When cross compiling Irssi for Android, you can specify the path of +the cross-perl in the cross file. + +You may not have a cross-perl available. In that case, you will have +to manually supply the required Perl arguments in the cross file. See +the commented properties in the example cross file. + +An example cross file can be found in the docs folder. To use it, you +would call: + + meson Build --cross-file cross-android-aarch64.txt \ + --prefix /data/data/com.termux/files/usr \ + --libdir lib \ + -Dfhs-prefix=/data/data/com.termux/files/usr \ + + Cygwin Getting perl scripting to work needs a few things: diff --git a/configure.ac b/configure.ac index 9198fd67..14a79fb5 100644 --- a/configure.ac +++ b/configure.ac @@ -665,6 +665,7 @@ else want_gregex=no fi +AC_DEFINE([FHS_PREFIX], [""], [Alternate filesystem prefix for Termux]) AH_TEMPLATE(HAVE_GMODULE) AH_TEMPLATE(HAVE_SOCKS_H, [misc..]) AH_TEMPLATE(HAVE_STATIC_PERL) diff --git a/docs/example-cross-android-aarch64.txt b/docs/example-cross-android-aarch64.txt new file mode 100644 index 00000000..caae0383 --- /dev/null +++ b/docs/example-cross-android-aarch64.txt @@ -0,0 +1,47 @@ +[binaries] +ar = 'aarch64-linux-android-ar' +c = 'aarch64-linux-android-clang' +cpp = 'aarch64-linux-android-clang++' +ld = 'aarch64-linux-android-ld' +pkgconfig = '/home/builder/.termux-build/_cache/android-r20-api-24-v3/bin/aarch64-linux-android-pkg-config' +strip = 'aarch64-linux-android-strip' + +;; you have to substitute 5.30.2 with the Perl version, that can be +;; obtained by running ` miniperl -e 'print substr $^V, 1' ` + +perl = ['/home/builder/.termux-build/perl/src/miniperl', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2'] + +[properties] +needs_exe_wrapper = true +c_args = ['-fstack-protector-strong', '-Oz', '-I/data/data/com.termux/files/usr/include'] +cpp_args = ['-fstack-protector-strong', '-Oz', '-I/data/data/com.termux/files/usr/include'] +c_link_args = ['-L/data/data/com.termux/files/usr/lib', '-Wl,-rpath=/data/data/com.termux/files/usr/lib', '-Wl,--enable-new-dtags', '-Wl,--as-needed', '-Wl,-z,relro,-z,now', '-landroid-glob'] +cpp_link_args = ['-L/data/data/com.termux/files/usr/lib', '-Wl,-rpath=/data/data/com.termux/files/usr/lib', '-Wl,--enable-new-dtags', '-Wl,--as-needed', '-Wl,-z,relro,-z,now', '-landroid-glob'] + +;; if you do not have a cross-perl like miniperl available, you have +;; to specify the required options by uncommenting the following +;; properties + +;; you can get the proper values by running the commands on your +;; Android device: + +;; ` perl -V::version: ` +; perl_version = '5.30.2' +;; ` perl -MExtUtils::Embed -o ccopts ` +; perl_ccopts = ['-I/data/data/com.termux/files/usr/include', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android/CORE'] +;; ` perl -MExtUtils::Embed -o ldopts ` +; perl_ldopts = ['-Wl,-E', '-I/data/data/com.termux/files/usr/include', '-L/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android/CORE', '-lperl', '-lm', '-ldl'] +;; ` perl -V::archname: ` +; perl_archname = 'aarch64-android' +;; ` perl -V::installsitearch: ` +; perl_installsitearch = '/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2/aarch64-android' +;; ` perl -V::installvendorarch: ` +; perl_installvendorarch = '' +;; ` perl -E 'say for @INC' ` +; perl_inc = ['/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2/aarch64-android', '/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2', '/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android', '/data/data/com.termux/files/usr/lib/perl5/5.30.2'] + +[host_machine] +cpu_family = 'arm' +cpu = 'aarch64' +endian = 'little' +system = 'android' diff --git a/meson.build b/meson.build index cf982146..22ed9ec7 100644 --- a/meson.build +++ b/meson.build @@ -11,6 +11,12 @@ cc = meson.get_compiler('c') rootinc = include_directories('.') dep = [] textui_dep = [] +need_dl_cross_link = false +# The Android environment requires that all modules are linked to each other. +# See https://github.com/android/ndk/issues/201 +if host_machine.system() == 'android' + need_dl_cross_link = true +endif includedir = get_option('includedir') incdir = 'irssi' @@ -66,8 +72,13 @@ def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK' # Help files # ############## -perl = find_program('perl') -run_command(perl, files('utils/syntax.pl')) +build_perl = find_program('perl', native : true) +if meson.is_cross_build() + cross_perl = find_program('perl') +else + cross_perl = build_perl +endif +run_command(build_perl, files('utils/syntax.pl')) ################### # irssi-version.h # @@ -313,34 +324,46 @@ if want_perl perl_rpath = '' #### ccopts #### - res = run_command(perl, '-MExtUtils::Embed', '-e', 'ccopts') - foreach fl : res.stdout().strip().split() - if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m') - perl_cflags += fl - endif + perl_ccopts = meson.get_cross_property('perl_ccopts', false) + if perl_ccopts == false + res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ccopts') + perl_ccopts = res.stdout().strip().split() + endif + foreach fl : perl_ccopts + if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m') + perl_cflags += fl + endif endforeach perl_cflags += cc.get_supported_arguments('-fPIC') #### ldopts #### - res = run_command(perl, '-MExtUtils::Embed', '-e', 'ldopts') + perl_ldopts = meson.get_cross_property('perl_ldopts', false) + if perl_ldopts == false + res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ldopts') + perl_ldopts = res.stdout().strip().split() + endif skip_libs = ['-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic'] - foreach fl : res.stdout().strip().split() - if not fl.startswith('-A') and not skip_libs.contains(fl) - if fl.startswith('-Wl,-rpath,') - perl_rpath = fl.split(',')[2] - perl_rpath_flags += fl - else - perl_ldflags += fl - endif - endif + foreach fl : perl_ldopts + if not fl.startswith('-A') and not skip_libs.contains(fl) + if fl.startswith('-Wl,-rpath,') + perl_rpath = fl.split(',')[2] + perl_rpath_flags += fl + else + perl_ldflags += fl + endif + endif endforeach + perl_version = meson.get_cross_property('perl_version', false) + if perl_version == false + perl_version = run_command(cross_perl, '-V::version:').stdout().split('\'')[1] + endif perl_dep = declare_dependency(compile_args : perl_cflags, link_args : perl_ldflags, - version : run_command(perl, '-V::version:').stdout().split('\'')[1]) + version : perl_version) #### - if not cc.run(''' + if not cc.compiles(''' #include #include int main() @@ -349,15 +372,18 @@ int main() return 0; } ''', args : perl_cflags + perl_ldflags + perl_rpath_flags, - name : 'working Perl support').compiled() + name : 'working Perl support') if require_perl error('error linking with perl libraries') else warning('error linking with perl libraries') endif else - xsubpp_file_c = run_command(perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout() - xsubpp = generator(perl, + xsubpp_file_c = meson.get_cross_property('perl_xsubpp', false) + if xsubpp_file_c == false + xsubpp_file_c = run_command(build_perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout() + endif + xsubpp = generator(build_perl, output : '@BASENAME@.c', capture : true, arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ], @@ -365,7 +391,7 @@ int main() xsubpp_file = files(xsubpp_file_c) if with_perl_lib == 'module' - perl_install_base = run_command(perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}').stdout() + perl_install_base = run_command(build_perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}').stdout() if perl_install_base == '' with_perl_lib = '' endif @@ -381,9 +407,16 @@ int main() set_perl_use_lib = false perl_library_dir = with_perl_lib + ' default' if with_perl_lib in ['site', 'vendor'] - perlmoddir = run_command(perl, '-V::install' + with_perl_lib + 'arch:').stdout().split('\'')[1] + perlmoddir = meson.get_cross_property('perl_install' + with_perl_lib + 'arch', false) + if perlmoddir == false + perlmoddir = run_command(cross_perl, '-V::install' + with_perl_lib + 'arch:').stdout().split('\'')[1] + endif elif with_perl_lib == 'module' - perlmoddir = perl_install_base / 'lib' / 'perl5' / run_command(perl, '-V::archname:').stdout().split('\'')[1] + perl_archname = meson.get_cross_property('perl_archname', false) + if perl_archname == false + perl_archname = run_command(cross_perl, '-V::archname:').stdout().split('\'')[1] + endif + perlmoddir = perl_install_base / 'lib' / 'perl5' / perl_archname endif elif with_perl_lib == '' set_perl_use_lib = true @@ -399,7 +432,12 @@ int main() perl_use_lib = get_option('prefix') / perlmoddir if set_perl_use_lib - set_perl_use_lib = run_command(perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib).returncode() != 0 + perl_inc = meson.get_cross_property('perl_inc', false) + if perl_inc == false + set_perl_use_lib = run_command(cross_perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib).returncode() != 0 + else + set_perl_use_lib = not perl_inc.contains(perl_use_lib) + endif if not set_perl_use_lib perl_library_dir += ' - other path in @INC' else @@ -460,6 +498,10 @@ dep_cflagsonly = [] foreach d : dep dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true) endforeach +dl_cross_dep = [] +if need_dl_cross_link + dl_cross_dep = dep +endif ################## # irssi-config.h # @@ -473,6 +515,7 @@ conf.set('HAVE_SOCKS', false, description : 'Build with socks support') conf.set('TERM_TRUECOLOR', want_truecolor, description : 'true color support in terminal') conf.set('USE_GREGEX', want_gregex, description : 'use GRegex for regular expressions') conf.set10('_DARWIN_USE_64_BIT_INODE', true, description : 'Enable large inode numbers on Mac OS X 10.5.') +conf.set_quoted('FHS_PREFIX', get_option('fhs-prefix')) headers = [ 'sys/ioctl.h', diff --git a/meson_options.txt b/meson_options.txt index c975db3a..5dc9c514 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,3 +14,4 @@ option('with-capsicum', type : 'combo', description : 'Build with Capsicum option('static-dependency', type : 'combo', description : 'Request static dependencies', choices : ['no', 'yes']) option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes', 'force']) option('docdir', type : 'string', description : 'Documentation directory') +option('fhs-prefix', type : 'string', description : 'System prefix for Termux') diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index 58471345..dcd4ecb5 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -281,8 +281,8 @@ static void exec_show_list(void) static void process_exec(PROCESS_REC *rec, const char *cmd) { - const char *shell_args[4] = { "/bin/sh", "-c", NULL, NULL }; - char **args; + const char *shell_args[4] = { FHS_PREFIX "/bin/sh", "-c", NULL, NULL }; + char **args; int in[2], out[2]; int n; @@ -341,7 +341,7 @@ static void process_exec(PROCESS_REC *rec, const char *cmd) if (rec->shell) { execvp(shell_args[0], (char **) shell_args); - fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno)); + fprintf(stderr, "Exec: " FHS_PREFIX "/bin/sh: %s\n", g_strerror(errno)); } else { args = g_strsplit(cmd, " ", -1); execvp(args[0], args); diff --git a/src/fe-fuzz/fe-common/core/theme-load.c b/src/fe-fuzz/fe-common/core/theme-load.c index faa063bb..f6db8f5f 100644 --- a/src/fe-fuzz/fe-common/core/theme-load.c +++ b/src/fe-fuzz/fe-common/core/theme-load.c @@ -37,7 +37,7 @@ #include int LLVMFuzzerInitialize(int *argc, char ***argv) { - char *irssi_argv[] = {*argv[0], "--home", "/tmp/irssi", NULL}; + char *irssi_argv[] = { *argv[0], "--home", FHS_PREFIX "/tmp/irssi", NULL }; int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1; #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION g_log_set_null_logger(); @@ -57,7 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { THEME_REC *theme; gchar *copy = g_strndup((const gchar *)data, size); - FILE *fp = fopen("/tmp/irssi/fuzz.theme", "wb"); + FILE *fp = fopen(FHS_PREFIX "/tmp/irssi/fuzz.theme", "wb"); if (fp) { fwrite(copy, strlen(copy), 1, fp); fclose(fp); diff --git a/src/perl/common/meson.build b/src/perl/common/meson.build index 2cbf7f4c..f2a69bc9 100644 --- a/src/perl/common/meson.build +++ b/src/perl/common/meson.build @@ -1,4 +1,5 @@ -libperl_common_a = shared_module('Irssi', + +libperl_Irssi_a = shared_module('Irssi', [ xsubpp.process( files( 'Channel.xs', @@ -24,6 +25,7 @@ libperl_common_a = shared_module('Irssi', include_directories : rootinc, implicit_include_directories : true, dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core, ) install_headers( diff --git a/src/perl/irc/meson.build b/src/perl/irc/meson.build index 7d77e0c1..0a8fd9f9 100644 --- a/src/perl/irc/meson.build +++ b/src/perl/irc/meson.build @@ -1,4 +1,4 @@ -libperl_irc_a = shared_module('Irc', +libperl_Irssi_Irc_a = shared_module('Irc', [ xsubpp.process( files( 'Channel.xs', @@ -26,6 +26,7 @@ libperl_irc_a = shared_module('Irc', include_directories : rootinc, implicit_include_directories : true, dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core, ) install_headers( diff --git a/src/perl/meson.build b/src/perl/meson.build index a9f1296a..6a2aaa85 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -4,7 +4,7 @@ perl_signals_list_h = custom_target('perl-signals-list.h', output : 'perl-signals-list.h', capture : true, depend_files : files('get-signals.pl'), - command : [perl, files('get-signals.pl'), '@INPUT@'], + command : [build_perl, files('get-signals.pl'), '@INPUT@'], ) irssi_core_pl_h = custom_target('irssi-core.pl.h', @@ -14,7 +14,7 @@ irssi_core_pl_h = custom_target('irssi-core.pl.h', command : [file2header, '@INPUT@', 'irssi_core_code'], ) -shared_module('perl_core', +libperl_core_a = shared_module('perl_core', files( 'perl-common.c', 'perl-core.c', @@ -35,11 +35,16 @@ shared_module('perl_core', install_dir : moduledir, install_rpath : perl_rpath, build_rpath : perl_rpath, - dependencies : dep_cflagsonly + [ perl_dep ], + dependencies : dep_cflagsonly + [ perl_dep ] + dl_cross_dep, override_options : ['b_asneeded=false'], ) -shared_module('fe_perl', +dl_cross_perl_core = [] +if need_dl_cross_link + dl_cross_perl_core += libperl_core_a +endif + +libfe_perl_a = shared_module('fe_perl', files( 'module-formats.c', 'perl-fe.c', @@ -52,6 +57,7 @@ shared_module('fe_perl', install : true, install_dir : moduledir, dependencies : dep, + link_with : dl_cross_perl_core, ) subdir('common') diff --git a/src/perl/textui/meson.build b/src/perl/textui/meson.build index 61362d52..1705fa36 100644 --- a/src/perl/textui/meson.build +++ b/src/perl/textui/meson.build @@ -1,4 +1,4 @@ -libperl_textui_a = shared_module('TextUI', +libperl_Irssi_TextUI_a = shared_module('TextUI', [ xsubpp.process( files( 'Statusbar.xs', @@ -22,6 +22,7 @@ libperl_textui_a = shared_module('TextUI', include_directories : rootinc, implicit_include_directories : true, dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core, ) install_headers( diff --git a/src/perl/ui/meson.build b/src/perl/ui/meson.build index eca864dd..14bc7699 100644 --- a/src/perl/ui/meson.build +++ b/src/perl/ui/meson.build @@ -1,4 +1,4 @@ -libperl_ui_a = shared_module('UI', +libperl_Irssi_UI_a = shared_module('UI', [ xsubpp.process( files( 'Formats.xs', @@ -20,6 +20,7 @@ libperl_ui_a = shared_module('UI', include_directories : rootinc, implicit_include_directories : true, dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core, ) install_headers( From fe9a44338087b186deeb11d57c520d2be44c383b Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 29 Jun 2020 16:11:45 +0200 Subject: [PATCH 0679/1198] change to strstr --- src/fe-common/core/keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index 986ee7bd..fa8ca076 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -772,7 +772,7 @@ static void cmd_show_keys(const char *searchkey, int full) if ((len == 0 || (full ? strncmp(rec->key, searchkey, len) == 0 : - g_strrstr(rec->key, searchkey) != NULL)) && + strstr(rec->key, searchkey) != NULL)) && (!full || rec->key[len] == '\0')) { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_LIST, rec->key, rec->info->id, rec->data == NULL ? "" : rec->data); From 0d2997b36f76798472d717ffb1fdee95b3561507 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 30 Jun 2020 09:29:50 +0200 Subject: [PATCH 0680/1198] make clang-format happy in keyboard.c --- src/fe-common/core/keyboard.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/keyboard.c b/src/fe-common/core/keyboard.c index fa8ca076..e0e061dd 100644 --- a/src/fe-common/core/keyboard.c +++ b/src/fe-common/core/keyboard.c @@ -770,9 +770,8 @@ 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 || - (full ? strncmp(rec->key, searchkey, len) == 0 : - strstr(rec->key, searchkey) != NULL)) && + if ((len == 0 || (full ? strncmp(rec->key, searchkey, len) == 0 : + strstr(rec->key, searchkey) != NULL)) && (!full || rec->key[len] == '\0')) { printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_BIND_LIST, rec->key, rec->info->id, rec->data == NULL ? "" : rec->data); From 108f57ac7bc31bf0139dbdbbc0125c554d852bb7 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 4 Jul 2020 12:15:25 +0200 Subject: [PATCH 0681/1198] fix extended bg colours --- src/fe-text/textbuffer-view.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 0bbb3655..bc7cc5a8 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -189,30 +189,32 @@ static inline void unformat(const unsigned char **ptr, int *color, unsigned int break; case FORMAT_STYLE_CLRTOEOL: break; +#define SET_COLOR_EXT_FG_BITS(base, pc) \ + *color &= ~ATTR_FGCOLOR24; \ + *color = (*color & BGATTR) | (base + *pc - FORMAT_COLOR_NOCHANGE) +#define SET_COLOR_EXT_BG_BITS(base, pc) \ + *color &= ~ATTR_BGCOLOR24; \ + *color = (*color & FGATTR) | ((base + *pc - FORMAT_COLOR_NOCHANGE) << BG_SHIFT) case FORMAT_COLOR_EXT1: - *color &= ~ATTR_FGCOLOR24; - *color = (*color & BGATTR) | (0x10 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_FG_BITS(0x10, ++*ptr); break; case FORMAT_COLOR_EXT1_BG: - *color &= ~ATTR_BGCOLOR24; - *color = (*color & FGATTR) | (0x10 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_BG_BITS(0x10, ++*ptr); break; case FORMAT_COLOR_EXT2: - *color &= ~ATTR_FGCOLOR24; - *color = (*color & BGATTR) | (0x60 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_FG_BITS(0x60, ++*ptr); break; case FORMAT_COLOR_EXT2_BG: - *color &= ~ATTR_BGCOLOR24; - *color = (*color & FGATTR) | (0x60 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_BG_BITS(0x60, ++*ptr); break; case FORMAT_COLOR_EXT3: - *color &= ~ATTR_FGCOLOR24; - *color = (*color & BGATTR) | (0xb0 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_FG_BITS(0xb0, ++*ptr); break; case FORMAT_COLOR_EXT3_BG: - *color &= ~ATTR_BGCOLOR24; - *color = (*color & FGATTR) | (0xb0 + *++*ptr - FORMAT_COLOR_NOCHANGE); + SET_COLOR_EXT_BG_BITS(0xb0, ++*ptr); break; +#undef SET_COLOR_EXT_BG_BITS +#undef SET_COLOR_EXT_FG_BITS #ifdef TERM_TRUECOLOR case FORMAT_COLOR_24: unformat_24bit_line_color(ptr, 1, color, fg24, bg24); From 0cc1e4b7cd4eb8881f58d03a5ab5d321f4ae12e8 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 4 Jul 2020 18:19:37 +0200 Subject: [PATCH 0682/1198] properly restore the saved text dest --- docs/signals.txt | 4 +-- src/common.h | 2 +- src/fe-common/core/printtext.c | 2 +- src/fe-text/gui-printtext.c | 5 ++-- src/fe-text/textbuffer-formats.c | 44 ++++++++++++++++++++------------ src/fe-text/textbuffer-formats.h | 1 + 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index ff600cd3..1eefc7e0 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -246,7 +246,7 @@ FE common "gui print text", WINDOW_REC, int fg, int bg, int flags, char *text, TEXT_DEST_REC (Can be used to determine when all "gui print text"s are sent (not required)) - "gui print text finished", WINDOW_REC + "gui print text finished", WINDOW_REC, TEXT_DEST_REC * Provides signals: @@ -353,7 +353,7 @@ gui-readline.c: gui-printtext.c: "beep" - "gui print text after finished", WINDOW_REC, LINE_REC *line, LINE_REC *prev_line + "gui print text after finished", WINDOW_REC, LINE_REC *line, LINE_REC *prev_line, TEXT_DEST_REC textbuffer-view.c "gui textbuffer line removed", TEXTBUFFER_VIEW_REC *view, LINE_REC *line, LINE_REC *prev_line diff --git a/src/common.h b/src/common.h index c9c4e545..73de4b78 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 29 +#define IRSSI_ABI_VERSION 30 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 06c22a4c..6869fba3 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -442,7 +442,7 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text) format_send_to_gui(dest, str); g_free(str); - signal_emit_id(signal_gui_print_text_finished, 1, dest->window); + signal_emit_id(signal_gui_print_text_finished, 2, dest->window, dest); } static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC *dest, diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 872c73c4..a92c6f3b 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -158,7 +158,8 @@ void gui_printtext_after_time(TEXT_DEST_REC *dest, LINE_REC *prev, const char *s gui->insert_after_time = time; format_send_to_gui(dest, str); gui->use_insert_after = FALSE; - signal_emit("gui print text after finished", 3, dest->window, gui->insert_after, prev); + signal_emit("gui print text after finished", 4, dest->window, gui->insert_after, prev, + dest); } void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str) @@ -376,7 +377,7 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, gui->insert_after = insert_after; } -static void sig_gui_printtext_finished(WINDOW_REC *window) +static void sig_gui_printtext_finished(WINDOW_REC *window, TEXT_DEST_REC *dest) { TEXT_BUFFER_VIEW_REC *view; LINE_REC *insert_after; diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 47f1735a..84aaebb9 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -42,6 +42,7 @@ void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec) i_refstr_release(rec->server_tag); i_refstr_release(rec->target); i_refstr_release(rec->nick); + i_refstr_release(rec->address); if (rec->nargs >= 1) { i_refstr_release(rec->args[0]); } @@ -54,17 +55,13 @@ void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec) g_slice_free(TEXT_BUFFER_FORMAT_REC, rec); } -static TEXT_BUFFER_FORMAT_REC *format_rec_new(const char *module, const char *format_tag, - const char *server_tag, const char *target, - const char *nick, int nargs, const char **args) +static TEXT_BUFFER_FORMAT_REC *format_rec_new(const char *module, const char *format_tag, int nargs, + const char **args) { int n; TEXT_BUFFER_FORMAT_REC *ret = g_slice_new0(TEXT_BUFFER_FORMAT_REC); ret->module = i_refstr_intern(module); ret->format = i_refstr_intern(format_tag); - ret->server_tag = i_refstr_intern(server_tag); - ret->target = i_refstr_intern(target); - ret->nick = i_refstr_intern(nick); ret->nargs = nargs; ret->args = g_new0(char *, nargs); if (nargs >= 1) { @@ -76,6 +73,19 @@ static TEXT_BUFFER_FORMAT_REC *format_rec_new(const char *module, const char *fo return ret; } +static void format_rec_set_dest(TEXT_BUFFER_FORMAT_REC *rec, const TEXT_DEST_REC *dest) +{ + i_refstr_release(rec->server_tag); + i_refstr_release(rec->target); + i_refstr_release(rec->nick); + i_refstr_release(rec->address); + rec->server_tag = i_refstr_intern(dest->server_tag); + rec->target = i_refstr_intern(dest->target); + rec->nick = i_refstr_intern(dest->nick); + rec->address = i_refstr_intern(dest->address); + rec->flags = dest->flags & ~PRINT_FLAG_FORMAT; +} + static LINE_INFO_REC *store_lineinfo_tmp(TEXT_DEST_REC *dest) { GUI_WINDOW_REC *gui; @@ -132,11 +142,10 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC formatnum = GPOINTER_TO_INT(formatnump); formats = g_hash_table_lookup(default_formats, module); - info->format = format_rec_new(module, formats[formatnum].tag, dest->server_tag, - dest->target, dest->nick, formats[formatnum].params, args); + info->format = + format_rec_new(module, formats[formatnum].tag, formats[formatnum].params, args); special_push_collector(&info->format->expando_cache); - info->format->flags = dest->flags; dest->flags |= PRINT_FLAG_FORMAT; signal_continue(5, theme, module, dest, formatnump, args); @@ -155,11 +164,9 @@ static void sig_print_noformat(TEXT_DEST_REC *dest, const char *text) special_push_collector(NULL); info = store_lineinfo_tmp(dest); - info->format = format_rec_new(NULL, NULL, dest->server_tag, dest->target, dest->nick, 2, - (const char *[]){ NULL, text }); + info->format = format_rec_new(NULL, NULL, 2, (const char *[]){ NULL, text }); special_push_collector(&info->format->expando_cache); - info->format->flags = dest->flags; dest->flags |= PRINT_FLAG_FORMAT; signal_continue(2, dest, text); @@ -182,7 +189,7 @@ static GSList *reverse_collector(GSList *a1) return c1; } -static void sig_gui_print_text_finished(WINDOW_REC *window) +static void sig_gui_print_text_finished(WINDOW_REC *window, TEXT_DEST_REC *dest) { GUI_WINDOW_REC *gui; LINE_REC *insert_after; @@ -202,6 +209,7 @@ static void sig_gui_print_text_finished(WINDOW_REC *window) return; info->format->expando_cache = reverse_collector(info->format->expando_cache); + format_rec_set_dest(info->format, dest); info->level |= MSGLEVEL_FORMAT; @@ -290,12 +298,16 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) curr = line; line = NULL; - format_rec = curr->info.format; - format_create_dest( + format_rec = curr->info.format; + format_create_dest_tag( &dest, format_rec->server_tag != NULL ? server_find_tag(format_rec->server_tag) : NULL, - format_rec->target, curr->info.level & ~MSGLEVEL_FORMAT, buffer->window); + format_rec->server_tag, format_rec->target, curr->info.level & ~MSGLEVEL_FORMAT, + buffer->window); + dest.nick = format_rec->nick; + dest.address = format_rec->address; + dest.flags = format_rec->flags; theme = window_get_theme(dest.window); diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index 45e4ce1b..b57f61c9 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -9,6 +9,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { char *server_tag; char *target; char *nick; + char *address; char **args; int nargs; GSList *expando_cache; From 6012ec9e56a8b3c41193652c58285699733cbf59 Mon Sep 17 00:00:00 2001 From: aquanight Date: Sun, 5 Jul 2020 15:31:07 -0600 Subject: [PATCH 0683/1198] Prevent double calls of perl_script_unload --- src/perl/perl-core.c | 28 ++++++++++++++++++++++++---- src/perl/perl-core.h | 7 +++++++ src/perl/perl-fe.c | 2 +- src/perl/perl-signals.c | 4 ++++ src/perl/perl-sources.c | 5 +++++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 866b86e8..295715d3 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -67,9 +67,6 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script) { perl_scripts = g_slist_remove(perl_scripts, script); - perl_signal_remove_script(script); - perl_source_remove_script(script); - signal_emit("script destroyed", 1, script); g_free(script->name); @@ -314,7 +311,30 @@ void perl_script_unload(PERL_SCRIPT_REC *script) g_return_if_fail(script != NULL); perl_script_destroy_package(script); - perl_script_destroy(script); + + perl_signal_remove_script(script); + perl_source_remove_script(script); + + script->unloaded = 1; + if (!script->active_signals) + perl_script_destroy(script); +} + +/* Enter a perl script (signal or input source) */ +void perl_script_enter(PERL_SCRIPT_REC *script) +{ + g_return_if_fail(script != NULL); + + script->active_signals++; +} + +void perl_script_exit(PERL_SCRIPT_REC *script) +{ + g_return_if_fail(script != NULL); + + script->active_signals--; + if (script->unloaded) + perl_script_destroy(script); } /* Find loaded script by name */ diff --git a/src/perl/perl-core.h b/src/perl/perl-core.h index 0d3a1a2f..5b2de9ac 100644 --- a/src/perl/perl-core.h +++ b/src/perl/perl-core.h @@ -8,6 +8,8 @@ typedef struct { /* Script can be loaded from a file, or from some data in memory */ char *path; /* FILE: full path for file */ char *data; /* DATA: data used for the script */ + int unloaded; /* Indicates unloading has been done, so it should be destroyed once all signals exit */ + int active_signals; /* active signal calls into this script - prevents full teardown when nonzero */ } PERL_SCRIPT_REC; extern GSList *perl_scripts; @@ -26,6 +28,11 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data); /* Unload perl script */ void perl_script_unload(PERL_SCRIPT_REC *script); +/* Mark a script as entered */ +void perl_script_enter(PERL_SCRIPT_REC *script); +/* Mark a script as exited */ +void perl_script_exit(PERL_SCRIPT_REC *script); + /* Find loaded script by name */ PERL_SCRIPT_REC *perl_script_find(const char *name); /* Find loaded script by package */ diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c index ac84d67a..ba6dccce 100644 --- a/src/perl/perl-fe.c +++ b/src/perl/perl-fe.c @@ -106,7 +106,7 @@ static void cmd_script_unload(const char *data) script_fix_name(name); script = perl_script_find(name); - if (script == NULL) { + if (script == NULL || script->unloaded) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SCRIPT_NOT_LOADED, name); } else { diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 27522f5e..5ea40d73 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -420,7 +420,10 @@ static void sig_func(const void *p1, const void *p2, args[3] = p4; args[4] = p5; args[5] = p6; rec = signal_get_user_data(); + if (rec->script->unloaded) return; /* Drop signal calls into unloaded scripts. */ + perl_script_enter(rec->script); perl_call_signal(rec->script, rec->func, signal_get_emitted_id(), args); + perl_script_exit(rec->script); } static void perl_signal_add_full_int(const char *signal, SV *func, @@ -437,6 +440,7 @@ static void perl_signal_add_full_int(const char *signal, SV *func, script = perl_script_find_package(perl_get_package()); g_return_if_fail(script != NULL); + g_return_if_fail(script->unloaded); rec = g_new(PERL_SIGNAL_REC, 1); rec->script = script; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 3c72be22..57fb579d 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -78,6 +78,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) PUTBACK; perl_source_ref(rec); + perl_script_enter(rec->script); perl_call_sv(rec->func, G_EVAL|G_DISCARD); if (SvTRUE(ERRSV)) { @@ -86,6 +87,8 @@ static int perl_source_event(PERL_SOURCE_REC *rec) g_free(error); } + perl_script_exit(rec->script); + if (perl_source_unref(rec) && rec->once) perl_source_destroy(rec); @@ -104,6 +107,7 @@ int perl_timeout_add(int msecs, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); + g_return_val_if_fail(script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); @@ -127,6 +131,7 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); + g_return_val_if_fail(script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); From 7daeaa25b68b542326bc1226aa937e235c75c102 Mon Sep 17 00:00:00 2001 From: aquanight Date: Sun, 5 Jul 2020 15:46:34 -0600 Subject: [PATCH 0684/1198] Fix wrong way on unloaded checks --- src/perl/perl-signals.c | 2 +- src/perl/perl-sources.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 5ea40d73..792b1746 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -440,7 +440,7 @@ static void perl_signal_add_full_int(const char *signal, SV *func, script = perl_script_find_package(perl_get_package()); g_return_if_fail(script != NULL); - g_return_if_fail(script->unloaded); + g_return_if_fail(!script->unloaded); rec = g_new(PERL_SIGNAL_REC, 1); rec->script = script; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 57fb579d..16260007 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -107,7 +107,7 @@ int perl_timeout_add(int msecs, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(script->unloaded, -1); + g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); @@ -131,7 +131,7 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(script->unloaded, -1); + g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); From 2d59df8162cd33220c7241528e66f511d1f9385c Mon Sep 17 00:00:00 2001 From: aquanight Date: Sun, 5 Jul 2020 16:09:19 -0600 Subject: [PATCH 0685/1198] Don't try to use the PERL_SIGNAL_REC after it could be freed --- src/perl/perl-signals.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 792b1746..43c992fe 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -414,16 +414,18 @@ static void sig_func(const void *p1, const void *p2, const void *p5, const void *p6) { PERL_SIGNAL_REC *rec; + PERL_SCRIPT_REC *script; const void *args[SIGNAL_MAX_ARGUMENTS]; args[0] = p1; args[1] = p2; args[2] = p3; args[3] = p4; args[4] = p5; args[5] = p6; rec = signal_get_user_data(); + script = rec->script; if (rec->script->unloaded) return; /* Drop signal calls into unloaded scripts. */ - perl_script_enter(rec->script); - perl_call_signal(rec->script, rec->func, signal_get_emitted_id(), args); - perl_script_exit(rec->script); + perl_script_enter(script); + perl_call_signal(script, rec->func, signal_get_emitted_id(), args); + perl_script_exit(script); } static void perl_signal_add_full_int(const char *signal, SV *func, From 26f3049a86288ab37f1adcce2e25fc44a64d666b Mon Sep 17 00:00:00 2001 From: aquanight Date: Sun, 5 Jul 2020 17:20:08 -0600 Subject: [PATCH 0686/1198] Refactor to pure refcount for PERL_SCRIPT_REC --- src/perl/perl-core.c | 25 ++++++++++++++++--------- src/perl/perl-core.h | 7 +++---- src/perl/perl-fe.c | 2 +- src/perl/perl-signals.c | 6 ++---- src/perl/perl-sources.c | 6 ++---- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 295715d3..6fd73322 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -65,7 +65,6 @@ static void perl_script_destroy_package(PERL_SCRIPT_REC *script) static void perl_script_destroy(PERL_SCRIPT_REC *script) { - perl_scripts = g_slist_remove(perl_scripts, script); signal_emit("script destroyed", 1, script); @@ -274,6 +273,7 @@ static PERL_SCRIPT_REC *script_load(char *name, const char *path, script->package = g_strdup_printf("Irssi::Script::%s", name); script->path = g_strdup(path); script->data = g_strdup(data); + script->refcount = 1; perl_scripts = g_slist_append(perl_scripts, script); signal_emit("script created", 1, script); @@ -308,6 +308,7 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data) /* Unload perl script */ void perl_script_unload(PERL_SCRIPT_REC *script) { + GSList* link; g_return_if_fail(script != NULL); perl_script_destroy_package(script); @@ -315,25 +316,31 @@ void perl_script_unload(PERL_SCRIPT_REC *script) perl_signal_remove_script(script); perl_source_remove_script(script); - script->unloaded = 1; - if (!script->active_signals) - perl_script_destroy(script); + link = g_slist_find(perl_scripts, script); + if (link != NULL) { + perl_scripts = g_slist_remove_link(perl_scripts, link); + g_slist_free(link); + perl_script_unref(script); + } + +/* perl_scripts = g_slist_remove(perl_scripts, script); + perl_script_unref(script);*/ } /* Enter a perl script (signal or input source) */ -void perl_script_enter(PERL_SCRIPT_REC *script) +void perl_script_ref(PERL_SCRIPT_REC *script) { g_return_if_fail(script != NULL); - script->active_signals++; + script->refcount++; } -void perl_script_exit(PERL_SCRIPT_REC *script) +void perl_script_unref(PERL_SCRIPT_REC *script) { g_return_if_fail(script != NULL); - script->active_signals--; - if (script->unloaded) + script->refcount--; + if (!script->refcount) perl_script_destroy(script); } diff --git a/src/perl/perl-core.h b/src/perl/perl-core.h index 5b2de9ac..6ea637ae 100644 --- a/src/perl/perl-core.h +++ b/src/perl/perl-core.h @@ -8,8 +8,7 @@ typedef struct { /* Script can be loaded from a file, or from some data in memory */ char *path; /* FILE: full path for file */ char *data; /* DATA: data used for the script */ - int unloaded; /* Indicates unloading has been done, so it should be destroyed once all signals exit */ - int active_signals; /* active signal calls into this script - prevents full teardown when nonzero */ + int refcount; /* 0 = destroy */ } PERL_SCRIPT_REC; extern GSList *perl_scripts; @@ -29,9 +28,9 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data); void perl_script_unload(PERL_SCRIPT_REC *script); /* Mark a script as entered */ -void perl_script_enter(PERL_SCRIPT_REC *script); +void perl_script_ref(PERL_SCRIPT_REC *script); /* Mark a script as exited */ -void perl_script_exit(PERL_SCRIPT_REC *script); +void perl_script_unref(PERL_SCRIPT_REC *script); /* Find loaded script by name */ PERL_SCRIPT_REC *perl_script_find(const char *name); diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c index ba6dccce..ac84d67a 100644 --- a/src/perl/perl-fe.c +++ b/src/perl/perl-fe.c @@ -106,7 +106,7 @@ static void cmd_script_unload(const char *data) script_fix_name(name); script = perl_script_find(name); - if (script == NULL || script->unloaded) { + if (script == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SCRIPT_NOT_LOADED, name); } else { diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 43c992fe..f5f9d6e2 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -422,10 +422,9 @@ static void sig_func(const void *p1, const void *p2, rec = signal_get_user_data(); script = rec->script; - if (rec->script->unloaded) return; /* Drop signal calls into unloaded scripts. */ - perl_script_enter(script); + perl_script_ref(script); perl_call_signal(script, rec->func, signal_get_emitted_id(), args); - perl_script_exit(script); + perl_script_unref(script); } static void perl_signal_add_full_int(const char *signal, SV *func, @@ -442,7 +441,6 @@ static void perl_signal_add_full_int(const char *signal, SV *func, script = perl_script_find_package(perl_get_package()); g_return_if_fail(script != NULL); - g_return_if_fail(!script->unloaded); rec = g_new(PERL_SIGNAL_REC, 1); rec->script = script; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 16260007..69d86f1f 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -78,7 +78,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) PUTBACK; perl_source_ref(rec); - perl_script_enter(rec->script); + perl_script_ref(rec->script); perl_call_sv(rec->func, G_EVAL|G_DISCARD); if (SvTRUE(ERRSV)) { @@ -87,7 +87,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) g_free(error); } - perl_script_exit(rec->script); + perl_script_unref(rec->script); if (perl_source_unref(rec) && rec->once) perl_source_destroy(rec); @@ -107,7 +107,6 @@ int perl_timeout_add(int msecs, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); @@ -131,7 +130,6 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); From 9593be14f5fb93be937a5c67426402757b528909 Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 6 Jul 2020 12:22:16 +0200 Subject: [PATCH 0687/1198] print to active window when -window is specified --- src/fe-common/core/fe-core-commands.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index c9ca93ce..78c136dc 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -163,8 +163,10 @@ static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) buf = g_string_sized_new(512); while (g_io_channel_read_line_string(handle, buf, &tpos, NULL) == G_IO_STATUS_NORMAL) { buf->str[tpos] = '\0'; - printtext(target ? server : NULL, target && item != NULL ? item->name : NULL, MSGLEVEL_CLIENTCRAP | - MSGLEVEL_NEVER, "%s", buf->str); + if (target) + printtext_window(active_win, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); + else + printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); } g_string_free(buf, TRUE); cmd_params_free(free_arg); From 357beb91f547051f1c3161df9081f632fcb2acd4 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 7 Jul 2020 09:28:41 +0200 Subject: [PATCH 0688/1198] make clang-format happy --- src/fe-common/core/fe-core-commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c index 78c136dc..c314c405 100644 --- a/src/fe-common/core/fe-core-commands.c +++ b/src/fe-common/core/fe-core-commands.c @@ -164,7 +164,8 @@ static void cmd_cat(const char *data, SERVER_REC *server, WI_ITEM_REC *item) while (g_io_channel_read_line_string(handle, buf, &tpos, NULL) == G_IO_STATUS_NORMAL) { buf->str[tpos] = '\0'; if (target) - printtext_window(active_win, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); + printtext_window(active_win, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", + buf->str); else printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER, "%s", buf->str); } From cc759e11790cdedf8b27646fcb140a7db6327a10 Mon Sep 17 00:00:00 2001 From: aquanight Date: Fri, 10 Jul 2020 18:27:54 -0600 Subject: [PATCH 0689/1198] Clean up commented out stuff and fix merge issues --- src/common.h | 2 +- src/perl/perl-core.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/common.h b/src/common.h index c9c4e545..73de4b78 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 29 +#define IRSSI_ABI_VERSION 30 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 6fd73322..24f0218c 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -308,8 +308,8 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data) /* Unload perl script */ void perl_script_unload(PERL_SCRIPT_REC *script) { - GSList* link; - g_return_if_fail(script != NULL); + GSList *link; + g_return_if_fail(script != NULL); perl_script_destroy_package(script); @@ -322,9 +322,6 @@ void perl_script_unload(PERL_SCRIPT_REC *script) g_slist_free(link); perl_script_unref(script); } - -/* perl_scripts = g_slist_remove(perl_scripts, script); - perl_script_unref(script);*/ } /* Enter a perl script (signal or input source) */ From af5987827c7c2b17f44122c46bf8718b805bf1b4 Mon Sep 17 00:00:00 2001 From: aquanight Date: Fri, 10 Jul 2020 18:31:47 -0600 Subject: [PATCH 0690/1198] ABI version again --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 73de4b78..0b429d45 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 30 +#define IRSSI_ABI_VERSION 31 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From ad30d568d6b1342f08b24aac1b3236958e402441 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 13 Jul 2020 13:25:18 +0200 Subject: [PATCH 0691/1198] do not use localtime result after other functions --- src/fe-common/core/fe-windows.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 88fc0711..d575813d 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -679,10 +679,11 @@ static void sig_server_disconnected(SERVER_REC *server) } } -static void window_print_daychange(WINDOW_REC *window, struct tm *tm) +static void window_print_daychange(WINDOW_REC *window, time_t t) { THEME_REC *theme; TEXT_DEST_REC dest; + struct tm *tm; char *format, str[256]; int ret; @@ -690,6 +691,7 @@ static void window_print_daychange(WINDOW_REC *window, struct tm *tm) format_create_dest(&dest, NULL, NULL, MSGLEVEL_NEVER, window); format = format_get_text_theme(theme, MODULE_NAME, &dest, TXT_DAYCHANGE); + tm = localtime(&t); ret = strftime(str, sizeof(str), format, tm); g_free(format); if (ret <= 0) return; @@ -770,7 +772,7 @@ static void sig_print_text(void) /* day changed, print notice about it to every window */ for (tmp = windows; tmp != NULL; tmp = tmp->next) - window_print_daychange(tmp->data, tm); + window_print_daychange(tmp->data, t); } static int sig_check_daychange(void) From 4e9dab4aeb5435368627f644beddf5e9d25e1082 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 23 Jul 2020 00:42:54 +0200 Subject: [PATCH 0692/1198] fix crash when server got disconnected/reconnected before it was properly connected --- src/fe-common/core/chat-completion.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 144ed0f4..fb052f7f 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1195,6 +1195,9 @@ static void sig_server_disconnected(SERVER_REC *server) g_return_if_fail(server != NULL); mserver = MODULE_DATA(server); + if (mserver == NULL) + return; + while (mserver->lastmsgs) last_msg_destroy(&mserver->lastmsgs, mserver->lastmsgs->data); } From 468d8b0c78b371466c092c54308013cdda3bf8f5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 23 Jul 2020 00:18:22 +0200 Subject: [PATCH 0693/1198] fix missing wrapping of line in signals --- src/perl/perl-common.h | 2 ++ src/perl/perl-signals.c | 47 +++++++++++++++++++++++++++++++++++---- src/perl/perl-signals.h | 2 ++ src/perl/textui/TextUI.xs | 14 +++++++++++- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/perl/perl-common.h b/src/perl/perl-common.h index 88adaa7e..1b802c6d 100644 --- a/src/perl/perl-common.h +++ b/src/perl/perl-common.h @@ -13,6 +13,8 @@ typedef void (*PERL_OBJECT_FUNC) (HV *hv, void *object); +typedef SV *(*PERL_BLESS_FUNC)(void *object, void *arg1, void *arg2, void *arg3); + typedef struct { char *name; PERL_OBJECT_FUNC fill_func; diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index f5f9d6e2..9dd73cdb 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -46,10 +46,16 @@ typedef struct { #include "perl-signals-list.h" -static GHashTable *signals; +static GHashTable *signals, *signal_stashes; static GHashTable *perl_signal_args_hash; static GSList *perl_signal_args_partial; +void irssi_add_signal_arg_conv(const char *stash, PERL_BLESS_FUNC func) +{ + if (g_hash_table_lookup(signal_stashes, stash) == NULL) + g_hash_table_insert(signal_stashes, g_strdup(stash), func); +} + static PERL_SIGNAL_ARGS_REC *perl_signal_args_find(int signal_id) { PERL_SIGNAL_ARGS_REC *rec; @@ -348,8 +354,36 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, int type; as it's first variable (dcc) */ perlarg = simple_iobject_bless((SERVER_REC *) arg); } else { - /* blessed object */ - perlarg = plain_bless(arg, rec->args[n]); + PERL_BLESS_FUNC bless_func; + + bless_func = g_hash_table_lookup(signal_stashes, rec->args[n]); + if (bless_func != NULL) { + void *a1 = NULL; + void *a2 = NULL; + void *a3 = NULL; + if (g_strcmp0(rec->args[n], "Irssi::TextUI::Line") == 0) { + /* need to find the corresponding buffer */ + int j; + + for (j = n - 1; j >= 0; j--) { + if (g_strcmp0(rec->args[j], + "Irssi::TextUI::TextBufferView") == + 0) { + a1 = (void *) args[j]; + break; + } else if (g_strcmp0(rec->args[j], + "Irssi::UI::Window") == 0) { + a2 = (void *) args[j]; + break; + } + } + } + + perlarg = bless_func(rec->args[n], a1, a2, a3); + } else { + /* blessed object */ + perlarg = plain_bless(arg, rec->args[n]); + } } XPUSHs(sv_2mortal(perlarg)); } @@ -628,6 +662,7 @@ void perl_signals_init(void) { int n; + signal_stashes = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); perl_signal_args_hash = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal); perl_signal_args_partial = NULL; @@ -662,5 +697,9 @@ void perl_signals_deinit(void) g_hash_table_foreach(perl_signal_args_hash, (GHFunc) signal_args_hash_free, NULL); - g_hash_table_destroy(perl_signal_args_hash); + g_hash_table_destroy(perl_signal_args_hash); + + g_hash_table_foreach(signal_stashes, (GHFunc) g_free, NULL); + g_hash_table_destroy(signal_stashes); + signal_stashes = NULL; } diff --git a/src/perl/perl-signals.h b/src/perl/perl-signals.h index cb636d3c..0110b5ae 100644 --- a/src/perl/perl-signals.h +++ b/src/perl/perl-signals.h @@ -24,6 +24,8 @@ void perl_command_unbind(const char *cmd, SV *func); void perl_command_runsub(const char *cmd, const char *data, SERVER_REC *server, WI_ITEM_REC *item); +void irssi_add_signal_arg_conv(const char *stash, PERL_BLESS_FUNC func); + void perl_signal_register(const char *signal, const char **args); void perl_signals_start(void); diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs index e87efb65..0ebcc7a6 100644 --- a/src/perl/textui/TextUI.xs +++ b/src/perl/textui/TextUI.xs @@ -85,6 +85,16 @@ static void perl_statusbar_item_fill_hash(HV *hv, SBAR_ITEM_REC *item) (void) hv_store(hv, "window", 6, plain_bless(item->bar->parent_window->active, "Irssi::UI::Window"), 0); } +static SV *perl_line_signal_arg_conv(LINE_REC *line, TEXT_BUFFER_VIEW_REC *view, WINDOW_REC *window) +{ + if (view != NULL) + return buffer_line_bless(view->buffer, line); + else if (window != NULL) + return buffer_line_bless(WINDOW_GUI(window)->view->buffer, line); + else + return &PL_sv_undef; +} + static PLAIN_OBJECT_INIT_REC textui_plains[] = { { "Irssi::TextUI::MainWindow", (PERL_OBJECT_FUNC) perl_main_window_fill_hash }, { "Irssi::TextUI::TextBuffer", (PERL_OBJECT_FUNC) perl_text_buffer_fill_hash }, @@ -109,7 +119,9 @@ CODE: initialized = TRUE; irssi_add_plains(textui_plains); - perl_statusbar_init(); + irssi_add_signal_arg_conv("Irssi::TextUI::Line", + (PERL_BLESS_FUNC) perl_line_signal_arg_conv); + perl_statusbar_init(); void deinit() From ffe0c715542f58705ae35cd5589c03a741590f3c Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 23 Jul 2020 00:53:24 +0200 Subject: [PATCH 0694/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 0b429d45..3036397b 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 31 +#define IRSSI_ABI_VERSION 32 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From f4f2350d3c804b3c8cefcadd80066a529273bfc1 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Thu, 23 Jul 2020 12:05:19 +0200 Subject: [PATCH 0695/1198] update github actions/checkout to new branch --- .github/workflows/abicheck.yml | 4 ++-- .github/workflows/check.yml | 2 +- .github/workflows/clangformat.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index 48f39b25..992f2811 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -17,11 +17,11 @@ jobs: pip3 install wheel pip3 install meson - name: checkout merge ref - uses: actions/checkout@master + uses: actions/checkout@main with: path: merge.src - name: checkout base ref - uses: actions/checkout@master + uses: actions/checkout@main with: path: base.src ref: ${{ github.base_ref }} diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 17da255d..4558a244 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -4,7 +4,7 @@ jobs: install: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@main - name: install uses: irssi-import/actions-irssi/check-irssi@master with: diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index 71f2ffed..070227bf 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -4,7 +4,7 @@ jobs: check-clang-format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@main - name: fetch target ref run: | From fcf2919348d61cac1df282e827fbd9c562fadb78 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Mon, 27 Jul 2020 16:14:44 +0200 Subject: [PATCH 0696/1198] Update help with HIDDEN level --- docs/help/in/levels.in | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/help/in/levels.in b/docs/help/in/levels.in index 429dd7c0..99f3070a 100644 --- a/docs/help/in/levels.in +++ b/docs/help/in/levels.in @@ -32,6 +32,7 @@ HILIGHT The text is highlighted. NEVER Never ignores or logs the message. + HIDDEN Hides the message when window HIDELEVEL includes HIDDEN. NO_ACT Doesn't trigger any activity in the statusbar. NOHILIGHT The text is not highlighted. From 556cb2523905e1537fc5197221d4d6e880450f32 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Mon, 27 Jul 2020 17:37:01 +0200 Subject: [PATCH 0697/1198] Update ignore.in --- docs/help/in/ignore.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/help/in/ignore.in b/docs/help/in/ignore.in index b0a547c1..00d64963 100644 --- a/docs/help/in/ignore.in +++ b/docs/help/in/ignore.in @@ -25,6 +25,8 @@ The special level 'NO_ACT' can be used to ignore activity in the statusbar without actually ignoring the message; this behavior is somewhat special because it is allowed in addition to other ignores for the same target. + The special level 'HIDDEN' can be used to hide matching activity without + actually ignoring the message. %9Examples:%9 @@ -40,6 +42,7 @@ /IGNORE *away* NICKS /IGNORE #irssi NO_ACT JOINS PARTS QUITS /IGNORE mike NO_ACT -MSGS + /IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS /IGNORE -regexp -pattern %9See also:%9 ACCEPT, SILENCE, UNIGNORE From ec2f269e98115a1852ecffcfe83103f8adbf8cb3 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Tue, 28 Jul 2020 23:48:52 +0200 Subject: [PATCH 0698/1198] Update ignore.in --- docs/help/in/ignore.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/help/in/ignore.in b/docs/help/in/ignore.in index 00d64963..cb2393d2 100644 --- a/docs/help/in/ignore.in +++ b/docs/help/in/ignore.in @@ -25,8 +25,8 @@ The special level 'NO_ACT' can be used to ignore activity in the statusbar without actually ignoring the message; this behavior is somewhat special because it is allowed in addition to other ignores for the same target. - The special level 'HIDDEN' can be used to hide matching activity without - actually ignoring the message. + The special level 'HIDDEN' can be used to hide matching messages that can + later be revealed using /WINDOW HIDELEVEL -HIDDEN %9Examples:%9 From a88806640b6672635983ba143b0c161ec03922d4 Mon Sep 17 00:00:00 2001 From: Nutchanon Wetchasit Date: Tue, 8 Sep 2020 17:59:24 +0700 Subject: [PATCH 0699/1198] Make colorless.theme de-color vertical window borders Fixes #1220. --- themes/colorless.theme | 1 + 1 file changed, 1 insertion(+) diff --git a/themes/colorless.theme b/themes/colorless.theme index 1b26f628..e87e12f1 100644 --- a/themes/colorless.theme +++ b/themes/colorless.theme @@ -251,6 +251,7 @@ abstracts = { # default background for all statusbars. You can also give # the default foreground color for statusbar items. sb_background = "%8"; + window_border = "%8"; # default backround for "default" statusbar group #sb_default_bg = "%8"; From 447e56530944bd3f914a77476ef38b365f3617da Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sat, 26 Sep 2020 16:40:18 +0200 Subject: [PATCH 0700/1198] Fix meson capsicum Fixes #1223 --- meson.build | 2 +- src/core/meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 22ed9ec7..cb3c3c0c 100644 --- a/meson.build +++ b/meson.build @@ -477,7 +477,7 @@ have_capsicum = false if want_capsicum if cc.has_function('cap_enter', dependencies : cc.find_library('c')) libnv = cc.find_library('nv', required : require_capsicum) - nvlist_create_found = libnv.found() and cc.has_function('nvlist_create_found', dependencies : libnv) + nvlist_create_found = libnv.found() and cc.has_function('nvlist_create', dependencies : libnv) if nvlist_create_found dep += libnv have_capsicum = true diff --git a/src/core/meson.build b/src/core/meson.build index b22a16de..c0e9b90e 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -7,7 +7,7 @@ else endif if have_capsicum - core_capsicum_source = files('fe-capsicum.c') + core_capsicum_source = files('capsicum.c') else core_capsicum_source = [] endif From eb4174ee1eabbee37622e8eb827719a16007f11f Mon Sep 17 00:00:00 2001 From: vague666 Date: Fri, 23 Oct 2020 21:49:09 +0200 Subject: [PATCH 0701/1198] Make hilight priority work --- src/fe-common/core/hilight-text.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 2fe6068b..22e46ffa 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -244,6 +244,8 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, GSList *tmp; CHANNEL_REC *chanrec; NICK_REC *nickrec; + HILIGHT_REC *tmprec; + int priority = -1; g_return_val_if_fail(str != NULL, NULL); @@ -274,11 +276,14 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, hilight_match_channel(rec, channel) && (rec->servertag == NULL || (server != NULL && g_ascii_strcasecmp(rec->servertag, server->tag) == 0)) && - hilight_match_text(rec, str, match_beg, match_end)) - return rec; + hilight_match_text(rec, str, match_beg, match_end) && + rec->priority > priority) { + tmprec = rec; + priority = rec->priority; + } } - return NULL; + return tmprec; } static char *hilight_get_act_color(HILIGHT_REC *rec) From 4fb10322d1a4ba8617dd6f53eda5f5002158d659 Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 26 Oct 2020 10:57:05 +0100 Subject: [PATCH 0702/1198] Optimize execution --- src/fe-common/core/hilight-text.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 22e46ffa..fc213533 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -272,12 +272,11 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; - if (!rec->nickmask && hilight_match_level(rec, level) && - hilight_match_channel(rec, channel) && + if (rec->priority > priority && !rec->nickmask && + hilight_match_level(rec, level) && hilight_match_channel(rec, channel) && (rec->servertag == NULL || (server != NULL && g_ascii_strcasecmp(rec->servertag, server->tag) == 0)) && - hilight_match_text(rec, str, match_beg, match_end) && - rec->priority > priority) { + hilight_match_text(rec, str, match_beg, match_end)) { tmprec = rec; priority = rec->priority; } From 8f4f0be6d48b169f20389d73f3d7cd3259d6f5a9 Mon Sep 17 00:00:00 2001 From: vague666 Date: Mon, 26 Oct 2020 11:01:03 +0100 Subject: [PATCH 0703/1198] Add prio check to hilight_nick_cache also --- src/fe-common/core/hilight-text.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index fc213533..4e971d75 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -674,6 +674,7 @@ static void hilight_nick_cache(GHashTable *list, CHANNEL_REC *channel, HILIGHT_REC *match; char *nickmask; int len, best_match; + int priority = -1; if (nick->host == NULL) return; /* don't check until host is known */ @@ -684,11 +685,12 @@ static void hilight_nick_cache(GHashTable *list, CHANNEL_REC *channel, for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; - if (rec->nickmask && + if (rec->priority > priority && rec->nickmask && hilight_match_channel(rec, channel->name) && match_wildcards(rec->text, nickmask)) { len = strlen(rec->text); if (best_match < len) { + priority = rec->priority; best_match = len; match = rec; } From 11b9cbdf3571b1db608fdc6ac83fe3669c3fcebe Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 26 Oct 2020 17:00:58 +0100 Subject: [PATCH 0704/1198] fix clang-format-xs option parser by using getopt --- .github/workflows/clangformat/clang-format-xs | 98 ++++++++++--------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/.github/workflows/clangformat/clang-format-xs b/.github/workflows/clangformat/clang-format-xs index c77b7305..dd93592e 100755 --- a/.github/workflows/clangformat/clang-format-xs +++ b/.github/workflows/clangformat/clang-format-xs @@ -9,58 +9,60 @@ CLANG_FORMAT=${CLANG_FORMAT:-clang-format} options=() files=() lines=() -no_options=0;inplace=0;xml=0;keep_offset=0;keep_length=0;keep=0; +inplace=0;xml=0; filename=tmp.1.c offsets= -karg= off_opts=() -for arg in "$@"; do - if [[ $keep = 1 ]]; then - if [[ "$karg" = "-offset" ]]; then - offsets="$offsets${offsets:+ }$arg" - off_opts+=("$karg" "$arg") - elif [[ "$karg" = "-length" ]]; then - offsets="$offsets:$arg" - off_opts+=("$karg" "$arg") - elif [[ "$karg" = "-assume-filename" ]]; then - filename="$arg" - options+=("$karg" "$arg") - else - options+=("$karg" "$arg") - fi - keep=0 - elif [[ $no_options = 0 ]]; then - case "$arg" in - -assume-filename=*) - filename="${arg#-assume-filename=}" - ;; - -lines=*) - lines+=("${arg#-lines=}") - ;; - *) - ;; - esac - case "$arg" in - --) no_options=1 - ;; - -i) inplace=1 - ;; - -output-replacements-xml) - xml=1 - ;; - -offset|-length|-cursor|-assume-filename|-fallback-style|-style) - keep=1 - karg="$arg" - ;; - -*) options+=("$arg") - ;; - *) files+=("$arg") - ;; - esac - else - files+=("$arg") - fi +opts=$(getopt -n clang-format-xs -s bash -a -o in -l Werror,assume-filename:,cursor:,dry-run,dump-config,fallback-style:,ferror-limit:,help,length:,lines:,offset:,output-replacement-xmls,sort-includes,style:,verbose,version -- "$@") +if [ $? -ne 0 ]; then exit 1; fi +eval set -- "$opts"; unset opts +while :; do + case "$1" in + --offset) + offsets="$offsets${offsets:+ }$2" + off_opts+=("$1" "$2") + shift 2 + continue + ;; + --length) + offsets="$offsets:$2" + off_opts+=("$1" "$2") + shift 2 + continue + ;; + --assume-filename) + filename="$2" + options+=("$1" "$2") + shift 2 + continue + ;; + --lines) + lines+=("$2") + shift 2 + continue + ;; + --output-replacements-xml) + xml=1 + shift + continue + ;; + -i) + inplace=1 + shift + continue + ;; + --) + shift + break + ;; + *) + options+=("$1") + shift + continue + ;; + esac done +files=("$@") export IN_LINES="${lines[*]}" export OFFSETS="$offsets" From 5c0d798ef4e77dface1541d4677eec1b6cae212e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 26 Oct 2020 23:24:30 +0100 Subject: [PATCH 0705/1198] keep up with github-actions changes --- .github/workflows/abicheck.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index 992f2811..86b065cd 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -9,7 +9,7 @@ jobs: steps: - name: set PATH run: | - echo "::add-path::$HOME/.local/bin" + echo "$HOME/.local/bin" >> $GITHUB_PATH - name: prepare required software run: | sudo apt install abigail-tools ninja-build libutf8proc-dev libperl-dev libotr5-dev @@ -41,15 +41,15 @@ jobs: base_abi=$(getabidef base$prefix) echo base abi : $base_abi ./base$prefix/bin/irssi --version - echo "::set-env name=base_abi::$base_abi" + echo "base_abi=$base_abi" >> $GITHUB_ENV merge_abi=$(getabidef merge$prefix) echo merge abi : $merge_abi ./merge$prefix/bin/irssi --version - echo "::set-env name=merge_abi::$merge_abi" + echo "merge_abi=$merge_abi" >> $GITHUB_ENV - run: | # abipkgdiff abipkgdiff -l base merge && diff_ret=0 || diff_ret=$? - echo "::set-env name=diff_ret::$diff_ret" + echo "diff_ret=$diff_ret" >> $GITHUB_ENV - run: | # Check if no changes are needed if [ "$diff_ret" -ne 0 ]; then From 323b60f339bd9b139bbcb9a5cd07747bc10a9b84 Mon Sep 17 00:00:00 2001 From: vague666 Date: Tue, 27 Oct 2020 09:49:54 +0100 Subject: [PATCH 0706/1198] Initialize tmprec --- src/fe-common/core/hilight-text.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 4e971d75..b3247efc 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -248,6 +248,7 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, int priority = -1; g_return_val_if_fail(str != NULL, NULL); + tmprec = NULL; if ((never_hilight_level & level) == level) return NULL; From 5f7d274ec5762cbdfc56379c66e20807bd93d2ec Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 11 Nov 2020 23:08:28 +0100 Subject: [PATCH 0707/1198] fix clang-format-xs formatting whole file regression of #1230 --- .github/workflows/clangformat/clang-format-xs | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/clangformat/clang-format-xs b/.github/workflows/clangformat/clang-format-xs index dd93592e..a48eafe9 100755 --- a/.github/workflows/clangformat/clang-format-xs +++ b/.github/workflows/clangformat/clang-format-xs @@ -38,6 +38,7 @@ while :; do ;; --lines) lines+=("$2") + off_opts+=("$1" "$2") shift 2 continue ;; From c9ccf9867f322138c8468f8f7a5691b742dd976a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 11 Nov 2020 23:06:59 +0100 Subject: [PATCH 0708/1198] Make a copy of the signal arguments so we don't have to worry about the stack plug some mem leaks later copy --- src/perl/perl-signals.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 9dd73cdb..9f49fba8 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -87,8 +87,9 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, GSList *v_gslist; GList *v_glist; } saved_args[SIGNAL_MAX_ARGUMENTS]; - void *p[SIGNAL_MAX_ARGUMENTS]; - PERL_SIGNAL_ARGS_REC *rec; + AV *aargs; + void *p[SIGNAL_MAX_ARGUMENTS]; + PERL_SIGNAL_ARGS_REC *rec; char *arglist[MAX_FORMAT_PARAMS]; size_t n; @@ -203,10 +204,13 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, p[n] = NULL; } + /* make a copy of the stack now, since the callback might change it */ + aargs = av_make(n_args, args); + callback(cb_arg, n_args, p); for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) { - SV *arg = args[n]; + SV *arg = *av_fetch(aargs, n, 0); if (!SvOK(arg)) { continue; @@ -245,6 +249,7 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, g_list_free(gl); } } + av_undef(aargs); } static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, From 69396482be83b51af1817c308eead76e1ca57f31 Mon Sep 17 00:00:00 2001 From: vague666 Date: Wed, 2 Dec 2020 14:33:23 +0100 Subject: [PATCH 0709/1198] style format change --- src/fe-common/core/hilight-text.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index b3247efc..153a7a15 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -273,14 +273,14 @@ HILIGHT_REC *hilight_match(SERVER_REC *server, const char *channel, for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; - if (rec->priority > priority && !rec->nickmask && - hilight_match_level(rec, level) && hilight_match_channel(rec, channel) && - (rec->servertag == NULL || - (server != NULL && g_ascii_strcasecmp(rec->servertag, server->tag) == 0)) && - hilight_match_text(rec, str, match_beg, match_end)) { - tmprec = rec; - priority = rec->priority; - } + if (rec->priority > priority && !rec->nickmask && hilight_match_level(rec, level) && + hilight_match_channel(rec, channel) && + (rec->servertag == NULL || + (server != NULL && g_ascii_strcasecmp(rec->servertag, server->tag) == 0)) && + hilight_match_text(rec, str, match_beg, match_end)) { + tmprec = rec; + priority = rec->priority; + } } return tmprec; @@ -687,8 +687,8 @@ static void hilight_nick_cache(GHashTable *list, CHANNEL_REC *channel, HILIGHT_REC *rec = tmp->data; if (rec->priority > priority && rec->nickmask && - hilight_match_channel(rec, channel->name) && - match_wildcards(rec->text, nickmask)) { + hilight_match_channel(rec, channel->name) && + match_wildcards(rec->text, nickmask)) { len = strlen(rec->text); if (best_match < len) { priority = rec->priority; From ae5e2fe5e5c472a54fe3a1526a7ae443ec18d035 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 31 Dec 2020 17:50:40 +0100 Subject: [PATCH 0710/1198] properly ignore empty lines and comments in servers and channels config fixes #1242 --- src/core/channels-setup.c | 4 ++++ src/core/servers-setup.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index 55b4533e..cd323a84 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -34,6 +34,10 @@ static int compare_channel_setup (CONFIG_NODE *node, CHANNEL_SETUP_REC *channel) { char *name, *chatnet; + /* skip comment nodes */ + if (node->type == NODE_TYPE_COMMENT) + return -1; + name = config_node_get_str(node, "name", NULL); chatnet = config_node_get_str(node, "chatnet", NULL); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 8662b30c..6e4e238a 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -472,6 +472,10 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) char *address, *chatnet; int port; + /* skip comment nodes */ + if (node->type == NODE_TYPE_COMMENT) + return -1; + address = config_node_get_str(node, "address", NULL); chatnet = config_node_get_str(node, "chatnet", NULL); port = config_node_get_int(node, "port", 0); From 06396e9c8fa10b98d4e369152982b35863d3d96c Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 3 Jan 2021 23:07:27 +0100 Subject: [PATCH 0711/1198] error out on empty perlmodlib, for example non-existant vendor reported by Xogium --- meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index cb3c3c0c..b7143fbf 100644 --- a/meson.build +++ b/meson.build @@ -403,6 +403,7 @@ int main() with_perl_lib = 'vendor' endif endif + perlmoddir = '' if with_perl_lib in ['site', 'vendor', 'module'] set_perl_use_lib = false perl_library_dir = with_perl_lib + ' default' @@ -426,7 +427,8 @@ int main() set_perl_use_lib = true perl_library_dir = 'custom' perlmoddir = with_perl_lib - else + endif + if perlmoddir == '' error('Unrecognised with-perl-lib value: ' + with_perl_lib) endif From 0706ad14fcaa24cd97852851f8580f20416f3c76 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 08:37:56 +0100 Subject: [PATCH 0712/1198] use cc.links in meson.build to fix regression of meson 0.56 fixes #1235 reported by dcbaker --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index cb3c3c0c..026028f9 100644 --- a/meson.build +++ b/meson.build @@ -363,7 +363,7 @@ if want_perl version : perl_version) #### - if not cc.compiles(''' + if not cc.links(''' #include #include int main() From e08aca6c8569dd30ad34503cc9d2610b1a47678a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 12:14:42 +0100 Subject: [PATCH 0713/1198] fix clang-format-xs formatting whole file incomplete fix in #1234 --- .github/workflows/clangformat/clang-format-xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clangformat/clang-format-xs b/.github/workflows/clangformat/clang-format-xs index a48eafe9..3216210b 100755 --- a/.github/workflows/clangformat/clang-format-xs +++ b/.github/workflows/clangformat/clang-format-xs @@ -38,7 +38,7 @@ while :; do ;; --lines) lines+=("$2") - off_opts+=("$1" "$2") + options+=("$1" "$2") shift 2 continue ;; From 18a1a0ba7c7f1471e6376b0bc9bcc5ed5a987fd0 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 5 Jan 2021 21:22:49 +0100 Subject: [PATCH 0714/1198] fix multiple identical active caps --- src/irc/core/irc-cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 4dd9ceca..bcf5b5df 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -224,7 +224,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add if (disable) server->cap_active = gslist_delete_string(server->cap_active, caps[i] + 1, g_free); - else + else if (!gslist_find_string(server->cap_active, caps[i])) server->cap_active = g_slist_prepend(server->cap_active, g_strdup(caps[i])); if (!strcmp(caps[i], "sasl")) From 1e7af8bf611df1c8dc1834dfa1860223fdee7ffc Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 6 Jan 2021 21:52:32 +0100 Subject: [PATCH 0715/1198] fix autotools build --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 14a79fb5..453fcd33 100644 --- a/configure.ac +++ b/configure.ac @@ -735,7 +735,7 @@ if test "x$old_dir" != "x$whole_dir"; then 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 - subdirfiles=`echo $subdirfiles $i/typemap $i/module.h $i/*.pm $i/*.xs` + subdirfiles=`echo $subdirfiles $i/typemap $i/*.h $i/*.pm $i/*.xs` done for file in $whole_dir/src/perl/module.h $subdirfiles; do link=`echo $file|$sedpath "s?$whole_dir/??"` From 1f05f8616765fbbe901d208f697653d5ed42157f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 6 Jan 2021 20:58:08 +0100 Subject: [PATCH 0716/1198] package the meson.build files --- Makefile.am | 4 +++- docs/Makefile.am | 3 ++- docs/help/Makefile.am.gen | 3 ++- scripts/Makefile.am | 3 ++- src/Makefile.am | 2 ++ src/core/Makefile.am | 2 ++ src/fe-common/Makefile.am | 2 ++ src/fe-common/core/Makefile.am | 2 ++ src/fe-common/irc/Makefile.am | 2 ++ src/fe-common/irc/dcc/Makefile.am | 2 ++ src/fe-common/irc/notifylist/Makefile.am | 2 ++ src/fe-fuzz/Makefile.am | 2 ++ src/fe-fuzz/fe-common/Makefile.am | 2 ++ src/fe-fuzz/fe-common/core/Makefile.am | 2 ++ src/fe-fuzz/irc/Makefile.am | 2 ++ src/fe-fuzz/irc/core/Makefile.am | 2 ++ src/fe-none/Makefile.am | 2 ++ src/fe-text/Makefile.am | 3 ++- src/irc/Makefile.am | 2 ++ src/irc/core/Makefile.am | 2 ++ src/irc/dcc/Makefile.am | 2 ++ src/irc/flood/Makefile.am | 2 ++ src/irc/notifylist/Makefile.am | 2 ++ src/irc/proxy/Makefile.am | 2 ++ src/lib-config/Makefile.am | 2 ++ src/otr/Makefile.am | 2 ++ src/perl/Makefile.am | 7 ++++++- tests/Makefile.am | 2 ++ tests/fe-common/Makefile.am | 2 ++ tests/fe-common/core/Makefile.am | 2 ++ tests/fe-text/Makefile.am | 2 ++ tests/irc/Makefile.am | 2 ++ tests/irc/core/Makefile.am | 2 ++ tests/irc/flood/Makefile.am | 2 ++ themes/Makefile.am | 3 ++- 35 files changed, 75 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8bfa362e..74f81303 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,4 +30,6 @@ EXTRA_DIST = \ autogen.sh \ README.md \ $(conf_DATA) \ - irssi-icon.png + irssi-icon.png \ + meson.build \ + meson_options.txt diff --git a/docs/Makefile.am b/docs/Makefile.am index 23d61648..05ebb319 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -15,6 +15,7 @@ doc_DATA = \ startup-HOWTO.html \ startup-HOWTO.txt -EXTRA_DIST = $(doc_DATA) $(man_MANS) +EXTRA_DIST = $(doc_DATA) $(man_MANS) \ + meson.build SUBDIRS = help diff --git a/docs/help/Makefile.am.gen b/docs/help/Makefile.am.gen index abf824b4..917abe64 100644 --- a/docs/help/Makefile.am.gen +++ b/docs/help/Makefile.am.gen @@ -7,6 +7,7 @@ help_DATA = \ EXTRA_DIST = \ Makefile.am.gen \ - $(help_DATA) + $(help_DATA) \ + meson.build SUBDIRS = in diff --git a/scripts/Makefile.am b/scripts/Makefile.am index cd795153..42b3ea7b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -14,4 +14,5 @@ script_DATA = \ scriptassist.pl \ usercount.pl -EXTRA_DIST = $(script_DATA) +EXTRA_DIST = $(script_DATA) \ + meson.build diff --git a/src/Makefile.am b/src/Makefile.am index 48cdc3eb..83fb562f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,3 +23,5 @@ pkginc_src_HEADERS = \ common.h SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(OTRDIR) $(TEXTUI) $(BOTUI) $(FUZZERUI) + +EXTRA_DIST = meson.build diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 7cf172ef..b49dad18 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -117,3 +117,5 @@ pkginc_core_HEADERS = \ tls.h \ write-buffer.h \ $(structure_headers) + +EXTRA_DIST = meson.build diff --git a/src/fe-common/Makefile.am b/src/fe-common/Makefile.am index d5f92eec..f4b78b34 100644 --- a/src/fe-common/Makefile.am +++ b/src/fe-common/Makefile.am @@ -1 +1,3 @@ SUBDIRS = core irc + +EXTRA_DIST = meson.build diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 4e8fdcb2..7e76d3a0 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -68,3 +68,5 @@ pkginc_fe_common_core_HEADERS = \ window-items.h \ windows-layout.h \ fe-windows.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index 9efb71d3..401720f6 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -37,3 +37,5 @@ pkginc_fe_common_irc_HEADERS = \ fe-irc-channels.h \ module.h \ module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/dcc/Makefile.am b/src/fe-common/irc/dcc/Makefile.am index c6a5d79d..0be3cffa 100644 --- a/src/fe-common/irc/dcc/Makefile.am +++ b/src/fe-common/irc/dcc/Makefile.am @@ -19,3 +19,5 @@ pkginc_fe_common_irc_dcc_HEADERS = \ module.h \ module-formats.h \ fe-dcc.h + +EXTRA_DIST = meson.build diff --git a/src/fe-common/irc/notifylist/Makefile.am b/src/fe-common/irc/notifylist/Makefile.am index b0f35fdf..6fca7676 100644 --- a/src/fe-common/irc/notifylist/Makefile.am +++ b/src/fe-common/irc/notifylist/Makefile.am @@ -13,3 +13,5 @@ pkginc_fe_common_irc_notifylistdir=$(pkgincludedir)/src/fe-common/irc/notifylist pkginc_fe_common_irc_notifylist_HEADERS = \ module.h \ module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index 7ce2fcdd..d54c3291 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -35,3 +35,5 @@ server_fuzz_SOURCES = \ noinst_HEADERS = \ null-logger.h \ ../fe-text/module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-fuzz/fe-common/Makefile.am b/src/fe-fuzz/fe-common/Makefile.am index 52770885..74f13119 100644 --- a/src/fe-fuzz/fe-common/Makefile.am +++ b/src/fe-fuzz/fe-common/Makefile.am @@ -1 +1,3 @@ SUBDIRS = core + +EXTRA_DIST = meson.build diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am index da8731b9..8fcd59b3 100644 --- a/src/fe-fuzz/fe-common/core/Makefile.am +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -28,3 +28,5 @@ theme_load_fuzz_SOURCES = \ noinst_HEADERS = \ $(top_srcdir)/src/fe-text/module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-fuzz/irc/Makefile.am b/src/fe-fuzz/irc/Makefile.am index 52770885..74f13119 100644 --- a/src/fe-fuzz/irc/Makefile.am +++ b/src/fe-fuzz/irc/Makefile.am @@ -1 +1,3 @@ SUBDIRS = core + +EXTRA_DIST = meson.build diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am index d66c2479..33f7664d 100644 --- a/src/fe-fuzz/irc/core/Makefile.am +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -28,3 +28,5 @@ event_get_params_fuzz_SOURCES = \ noinst_HEADERS = \ $(top_srcdir)/src/fe-text/module-formats.h + +EXTRA_DIST = meson.build diff --git a/src/fe-none/Makefile.am b/src/fe-none/Makefile.am index 570d6261..44c23d6e 100644 --- a/src/fe-none/Makefile.am +++ b/src/fe-none/Makefile.am @@ -16,3 +16,5 @@ botti_SOURCES = \ noinst_HEADERS = \ module.h + +EXTRA_DIST = meson.build diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index 8835f4b9..c7044ba9 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -70,4 +70,5 @@ noinst_HEADERS = \ module-formats.h EXTRA_DIST = \ - $(terminfo_sources) + $(terminfo_sources) \ + meson.build diff --git a/src/irc/Makefile.am b/src/irc/Makefile.am index 78a38643..a271a891 100644 --- a/src/irc/Makefile.am +++ b/src/irc/Makefile.am @@ -7,3 +7,5 @@ SUBDIRS = core dcc flood notifylist $(PROXY) noinst_LIBRARIES = libirc.a libirc_a_SOURCES = irc.c + +EXTRA_DIST = meson.build diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am index 63b41113..858d7fcb 100644 --- a/src/irc/core/Makefile.am +++ b/src/irc/core/Makefile.am @@ -57,3 +57,5 @@ pkginc_irc_core_HEADERS = \ netsplit.h \ servers-idle.h \ servers-redirect.h + +EXTRA_DIST = meson.build diff --git a/src/irc/dcc/Makefile.am b/src/irc/dcc/Makefile.am index a81bf84d..887a65d2 100644 --- a/src/irc/dcc/Makefile.am +++ b/src/irc/dcc/Makefile.am @@ -25,3 +25,5 @@ pkginc_irc_dcc_HEADERS = \ dcc-queue.h \ module.h \ dcc-server.h + +EXTRA_DIST = meson.build diff --git a/src/irc/flood/Makefile.am b/src/irc/flood/Makefile.am index b582ffe4..7a49001d 100644 --- a/src/irc/flood/Makefile.am +++ b/src/irc/flood/Makefile.am @@ -10,3 +10,5 @@ libirc_flood_a_SOURCES = \ pkginc_irc_flooddir=$(pkgincludedir)/src/irc/flood pkginc_irc_flood_HEADERS = \ module.h + +EXTRA_DIST = meson.build diff --git a/src/irc/notifylist/Makefile.am b/src/irc/notifylist/Makefile.am index 421bc7d4..9bc0fd8b 100644 --- a/src/irc/notifylist/Makefile.am +++ b/src/irc/notifylist/Makefile.am @@ -15,3 +15,5 @@ pkginc_irc_notifylist_HEADERS = \ notifylist.h \ notify-setup.h \ module.h + +EXTRA_DIST = meson.build diff --git a/src/irc/proxy/Makefile.am b/src/irc/proxy/Makefile.am index 6411f49d..2e7259ad 100644 --- a/src/irc/proxy/Makefile.am +++ b/src/irc/proxy/Makefile.am @@ -23,3 +23,5 @@ noinst_HEADERS = \ clean-generic: rm -f libirc_proxy.a + +EXTRA_DIST = meson.build diff --git a/src/lib-config/Makefile.am b/src/lib-config/Makefile.am index d644eae5..4912aa9b 100644 --- a/src/lib-config/Makefile.am +++ b/src/lib-config/Makefile.am @@ -13,3 +13,5 @@ pkginc_lib_configdir=$(pkgincludedir)/src/lib-config pkginc_lib_config_HEADERS = \ iconfig.h \ module.h + +EXTRA_DIST = meson.build diff --git a/src/otr/Makefile.am b/src/otr/Makefile.am index ac40cbac..149b952d 100644 --- a/src/otr/Makefile.am +++ b/src/otr/Makefile.am @@ -35,3 +35,5 @@ noinst_HEADERS = \ otr-formats.h \ otr-fe.h \ otr.h + +EXTRA_DIST = meson.build diff --git a/src/perl/Makefile.am b/src/perl/Makefile.am index 45ac1eea..ad937457 100644 --- a/src/perl/Makefile.am +++ b/src/perl/Makefile.am @@ -119,7 +119,12 @@ EXTRA_DIST = \ $(common_sources) \ $(irc_sources) \ $(ui_sources) \ - $(textui_sources) + $(textui_sources) \ + meson.build \ + common/meson.build \ + irc/meson.build \ + ui/meson.build \ + textui/meson.build am_v_pl__show_gen = $(am__v_pl__show_gen_$(V)) am_v_pl__hide_gen = $(am__v_pl__hide_gen_$(V)) diff --git a/tests/Makefile.am b/tests/Makefile.am index 8713b38f..0799ee3f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,3 +3,5 @@ TEXTUI=fe-text endif SUBDIRS = fe-common irc $(TEXTUI) + +EXTRA_DIST = meson.build diff --git a/tests/fe-common/Makefile.am b/tests/fe-common/Makefile.am index 52770885..74f13119 100644 --- a/tests/fe-common/Makefile.am +++ b/tests/fe-common/Makefile.am @@ -1 +1,3 @@ SUBDIRS = core + +EXTRA_DIST = meson.build diff --git a/tests/fe-common/core/Makefile.am b/tests/fe-common/core/Makefile.am index ddd619a0..eb7e2c7f 100644 --- a/tests/fe-common/core/Makefile.am +++ b/tests/fe-common/core/Makefile.am @@ -22,3 +22,5 @@ test_formats_LDADD = \ test_formats_SOURCES = \ test-formats.c + +EXTRA_DIST += meson.build diff --git a/tests/fe-text/Makefile.am b/tests/fe-text/Makefile.am index 2a3450e9..8f44dded 100644 --- a/tests/fe-text/Makefile.am +++ b/tests/fe-text/Makefile.am @@ -33,3 +33,5 @@ test_paste_join_multiline_SOURCES = \ ../../src/fe-text/gui-printtext.c \ mock-irssi.c \ test-paste-join-multiline.c + +EXTRA_DIST += meson.build diff --git a/tests/irc/Makefile.am b/tests/irc/Makefile.am index d42cfc87..88adb5b9 100644 --- a/tests/irc/Makefile.am +++ b/tests/irc/Makefile.am @@ -1,3 +1,5 @@ SUBDIRS = \ core \ flood + +EXTRA_DIST = meson.build diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index 23c1ef2c..fbf001da 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -26,3 +26,5 @@ test_channel_events_SOURCES = \ test_irc_SOURCES = \ test-irc.c + +EXTRA_DIST += meson.build diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am index 17885d53..f815504d 100644 --- a/tests/irc/flood/Makefile.am +++ b/tests/irc/flood/Makefile.am @@ -32,3 +32,5 @@ test_796_LDADD = \ test_796_SOURCES = \ test-796.c + +EXTRA_DIST += meson.build diff --git a/themes/Makefile.am b/themes/Makefile.am index ad0707c2..c8814532 100644 --- a/themes/Makefile.am +++ b/themes/Makefile.am @@ -2,4 +2,5 @@ themedir = $(datadir)/irssi/themes theme_DATA = default.theme colorless.theme EXTRA_DIST = \ - $(theme_DATA) + $(theme_DATA) \ + meson.build From 8f6e67b9b3858f3f4dd06909fa5013a6029634b8 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 6 Jan 2021 17:10:59 +0100 Subject: [PATCH 0717/1198] Check Irssi compilation using github actions --- .github/actions.yml | 43 ------------ .github/workflows/abicheck.yml | 96 +++++++++++++++++++++------ .github/workflows/check.yml | 118 ++++++++++++++++++++++++++++----- 3 files changed, 178 insertions(+), 79 deletions(-) delete mode 100644 .github/actions.yml diff --git a/.github/actions.yml b/.github/actions.yml deleted file mode 100644 index ae47fbde..00000000 --- a/.github/actions.yml +++ /dev/null @@ -1,43 +0,0 @@ -before_install: - - ./autogen.sh --with-proxy=module --with-bot --with-perl=module --with-otr=module - - make dist - - CO_DIR=$(pwd) - - mkdir -p $HOME/src - - cd $HOME/src - - tar xaf $CO_DIR/irssi-*.tar.* - -install: - - cd $HOME/src/irssi-* - - ./configure --with-proxy=module --with-bot --with-perl=module --with-otr=module --prefix=$HOME/irssi-build --enable-always-build-tests - - make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" - - make install - -unit_tests: - - cd $HOME/src/irssi-* - - make -C tests -sk check - -after_unit_tests: - - cd $HOME/src/irssi-* - - find -name test-suite.log -exec cat {} + - -before_script: - - cd $HOME - - mkdir irssi-test - - | - echo 'echo automated irssi launch test - ^set settings_autosave off - ^set -clear log_close_string - ^set -clear log_day_changed - ^set -clear log_open_string - ^set log_timestamp * - ^window log on' > irssi-test/startup - - echo load perl >> irssi-test/startup - - echo load proxy >> irssi-test/startup - - echo ^quit >> irssi-test/startup - -script: - - cd $HOME - - irssi-build/bin/irssi --home irssi-test | /tools/render.pl - -after_script: - - cat $HOME/irc.log.* diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index 86b065cd..eceaa32e 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -1,25 +1,24 @@ on: [pull_request] name: abicheck +env: + build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes -Dc_args=-DPERL_EUPXS_ALWAYS_EXPORT + prefix: /usr/local + apt_build_deps: ninja-build libutf8proc-dev libperl-dev libotr5-dev + get_pip_build_deps: pip3 install setuptools; pip3 install wheel; pip3 install meson + getabidef_def: getabidef() { awk '$1=="#define" && $2=="IRSSI_ABI_VERSION" { print $3 }' "$1"/include/irssi/src/common.h; } jobs: - check-abi-diff: + build-base-ref: runs-on: ubuntu-latest - env: - build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes -Dc_args=-DPERL_EUPXS_ALWAYS_EXPORT - prefix: /usr/local + outputs: + base_abi: ${{ steps.out.outputs.base_abi }} steps: - name: set PATH run: | echo "$HOME/.local/bin" >> $GITHUB_PATH - name: prepare required software run: | - sudo apt install abigail-tools ninja-build libutf8proc-dev libperl-dev libotr5-dev - pip3 install setuptools - pip3 install wheel - pip3 install meson - - name: checkout merge ref - uses: actions/checkout@main - with: - path: merge.src + sudo apt install $apt_build_deps + eval "$get_pip_build_deps" - name: checkout base ref uses: actions/checkout@main with: @@ -30,26 +29,83 @@ jobs: meson Build.base base.src $build_options ninja -C Build.base DESTDIR=$PWD/base ninja -C Build.base install + - id: out + run: | + # print versions and abi versions + eval "$getabidef_def" + base_abi=$(getabidef base$prefix) + echo base abi : $base_abi + ./base$prefix/bin/irssi --version + echo "::set-output name=base_abi::$base_abi" + - uses: actions/upload-artifact@v2 + with: + name: base.inst + path: base + retention-days: 1 + build-merge-ref: + runs-on: ubuntu-latest + outputs: + merge_abi: ${{ steps.out.outputs.merge_abi }} + steps: + - name: set PATH + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: prepare required software + run: | + sudo apt install $apt_build_deps + eval "$get_pip_build_deps" + - name: checkout merge ref + uses: actions/checkout@main + with: + path: merge.src - name: build merge ref run: | meson Build.merge merge.src $build_options ninja -C Build.merge DESTDIR=$PWD/merge ninja -C Build.merge install - - run: | + - id: out + run: | # print versions and abi versions - getabidef() { awk '$1=="#define" && $2=="IRSSI_ABI_VERSION" { print $3 }' "$1"/include/irssi/src/common.h; } - base_abi=$(getabidef base$prefix) - echo base abi : $base_abi - ./base$prefix/bin/irssi --version - echo "base_abi=$base_abi" >> $GITHUB_ENV + eval "$getabidef_def" merge_abi=$(getabidef merge$prefix) echo merge abi : $merge_abi ./merge$prefix/bin/irssi --version - echo "merge_abi=$merge_abi" >> $GITHUB_ENV + echo "::set-output name=merge_abi::$merge_abi" + - uses: actions/upload-artifact@v2 + with: + name: merge.inst + path: merge + retention-days: 1 + check-abi-diff: + runs-on: ubuntu-latest + needs: + - build-merge-ref + - build-base-ref + env: + base_abi: ${{ needs.build-base-ref.outputs.base_abi }} + merge_abi: ${{ needs.build-merge-ref.outputs.merge_abi }} + steps: + - name: prepare required software + run: | + sudo apt install abigail-tools + - name: fetch base build + uses: actions/download-artifact@v2 + with: + name: base.inst + path: base + - name: fetch merge build + uses: actions/download-artifact@v2 + with: + name: merge.inst + path: merge - run: | # abipkgdiff - abipkgdiff -l base merge && diff_ret=0 || diff_ret=$? + abipkgdiff -l base merge >abipkgdiff.out && diff_ret=0 || diff_ret=$? echo "diff_ret=$diff_ret" >> $GITHUB_ENV + cat abipkgdiff.out + - uses: actions/upload-artifact@v2 + with: + path: abipkgdiff.out - run: | # Check if no changes are needed if [ "$diff_ret" -ne 0 ]; then diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4558a244..64e5442f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,21 +1,107 @@ on: [pull_request] name: Check Irssi +env: + apt_build_deps: libutf8proc-dev libperl-dev libotr5-dev + apt_build_deps_meson: ninja-build + apt_build_deps_autotools: autoconf automake libtool + get_pip_build_deps_meson: pip3 install setuptools; pip3 install wheel; pip3 install meson${meson_ver:+==${meson_ver}} + build_options_meson: -Dwith-proxy=yes -Dwith-bot=yes -Dwith-perl=yes -Dwith-otr=yes + build_options_configure: --with-proxy=module --with-bot --with-perl=module --with-otr=module + prefix: ~/irssi-build jobs: - install: + dist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@main - - name: install - uses: irssi-import/actions-irssi/check-irssi@master - with: - args: before_install install - - name: unit_tests - uses: irssi-import/actions-irssi/check-irssi@master - with: - args: unit_tests after_unit_tests - - name: script - uses: irssi-import/actions-irssi/check-irssi@master - env: - TERM: xterm - with: - args: before_script script after_script + - name: prepare required software + run: | + sudo apt install $apt_build_deps $apt_build_deps_autotools + - uses: actions/checkout@main + - name: make dist + run: | + # make dist + ./autogen.sh $build_options_configure + make dist + - uses: actions/upload-artifact@v2 + with: + path: irssi-*.tar.gz + retention-days: 1 + install: + runs-on: ${{ matrix.os }} + env: + CC: ${{ matrix.compiler }} + needs: dist + strategy: + matrix: + os: [ubuntu-16.04, ubuntu-latest] + builder: [meson, configure] + compiler: [clang, gcc] + include: + - os: ubuntu-16.04 + builder: meson + meson_ver: 0.49.2 + steps: + - name: fetch dist + uses: actions/download-artifact@v2 + - name: set PATH + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: prepare required software + env: + meson_ver: ${{ matrix.meson_ver }} + run: | + sudo apt install $apt_build_deps $apt_build_deps_${{ matrix.builder }} + eval "$get_pip_build_deps_${{ matrix.builder }}" + curl -SLf https://github.com/irssi-import/actions-irssi/raw/master/check-irssi/render.pl -o ~/render.pl && chmod +x ~/render.pl + - name: unpack archive + run: tar xaf artifact/irssi-*.tar.gz + - name: build and install with meson + run: | + # ninja install + cd irssi-*/ + meson Build $build_options_meson --prefix=${prefix/\~/~} + ninja -C Build + ninja -C Build install + if: ${{ matrix.builder == 'meson' }} + - name: build and install with Makefile + run: | + # make install + cd irssi-*/ + mkdir Build + cd Build + ../configure $build_options_configure --prefix=${prefix/\~/~} --enable-always-build-tests + make CFLAGS="-Wall -Werror -Werror=declaration-after-statement" + make install + if: ${{ matrix.builder == 'configure' }} + - name: run tests with Makefile + run: | + # make check + cd irssi-*/Build + make -C tests -sk check + find -name test-suite.log -exec cat {} + + if: ${{ matrix.builder == 'configure' }} + - name: run tests with Meson + run: | + # ninja test + cd irssi-*/ + ninja -C Build test + find -name testlog.txt -exec sed -i -e '/Inherited environment:.* GITHUB/d' {} + -exec cat {} + + if: ${{ matrix.builder == 'meson' }} + - name: run launch test + env: + TERM: xterm + run: | + # automated irssi launch test + cd + mkdir irssi-test + echo 'echo automated irssi launch test + ^set settings_autosave off + ^set -clear log_close_string + ^set -clear log_day_changed + ^set -clear log_open_string + ^set log_timestamp * + ^window log on' > irssi-test/startup + echo load perl >> irssi-test/startup + echo load proxy >> irssi-test/startup + echo ^quit >> irssi-test/startup + irssi-build/bin/irssi --home irssi-test | ~/render.pl + cat irc.log.* From 7379833b53ed098bd11c4aa6a2e4dc554a574e57 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 6 Jan 2021 22:22:00 +0100 Subject: [PATCH 0718/1198] move clang-format-xs into utils --- .github/workflows/clangformat.yml | 2 +- .../clangformat => utils/clang-format-xs}/clang-format-xs | 0 .../clangformat => utils/clang-format-xs}/format-xs-1.pl | 0 .../clangformat => utils/clang-format-xs}/format-xs-2.pl | 0 .../clangformat => utils/clang-format-xs}/format-xs-xml.pl | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename {.github/workflows/clangformat => utils/clang-format-xs}/clang-format-xs (100%) rename {.github/workflows/clangformat => utils/clang-format-xs}/format-xs-1.pl (100%) rename {.github/workflows/clangformat => utils/clang-format-xs}/format-xs-2.pl (100%) rename {.github/workflows/clangformat => utils/clang-format-xs}/format-xs-xml.pl (100%) diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index 070227bf..b959fe92 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -13,7 +13,7 @@ jobs: - name: configure clang-format run: | - git config clangformat.binary $PWD/.github/workflows/clangformat/clang-format-xs + git config clangformat.binary $PWD/utils/clang-format-xs/clang-format-xs git config clangformat.extensions c,h,xs - name: run git-clang-format and Check if no changes are needed run: diff --git a/.github/workflows/clangformat/clang-format-xs b/utils/clang-format-xs/clang-format-xs similarity index 100% rename from .github/workflows/clangformat/clang-format-xs rename to utils/clang-format-xs/clang-format-xs diff --git a/.github/workflows/clangformat/format-xs-1.pl b/utils/clang-format-xs/format-xs-1.pl similarity index 100% rename from .github/workflows/clangformat/format-xs-1.pl rename to utils/clang-format-xs/format-xs-1.pl diff --git a/.github/workflows/clangformat/format-xs-2.pl b/utils/clang-format-xs/format-xs-2.pl similarity index 100% rename from .github/workflows/clangformat/format-xs-2.pl rename to utils/clang-format-xs/format-xs-2.pl diff --git a/.github/workflows/clangformat/format-xs-xml.pl b/utils/clang-format-xs/format-xs-xml.pl similarity index 100% rename from .github/workflows/clangformat/format-xs-xml.pl rename to utils/clang-format-xs/format-xs-xml.pl From 57408b19d5f34540b7b83feb280d0c36661a7f1a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 16:50:02 +0100 Subject: [PATCH 0719/1198] put proper versions in PACKAGE_VERSION --- utils/irssi-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/irssi-version.sh b/utils/irssi-version.sh index 41970cb2..b096fd90 100755 --- a/utils/irssi-version.sh +++ b/utils/irssi-version.sh @@ -22,7 +22,7 @@ echo "#define IRSSI_VERSION_TIME $VERSION_TIME" if echo "${VERSION}" | grep -q -- -head; then # -head version, get extra details from git if we can - git_version=$(GIT_DIR=$1/.git git describe --dirty --long --always --tags 2>/dev/null) + git_version=$(GIT_DIR=$1/.git git describe --dirty --long --tags --match '[0-9]*.[0-9]*' 2>/dev/null) if [ $? = 0 ]; then echo "#undef PACKAGE_VERSION" echo "#define PACKAGE_VERSION \"${git_version}\"" From 168ba937c15fd8392172c3039837e9faf04a95e2 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 6 Jan 2021 22:23:23 +0100 Subject: [PATCH 0720/1198] remove travis --- .github/workflows/check.yml | 6 +++- .travis.yml | 65 ------------------------------------- README.md | 2 +- 3 files changed, 6 insertions(+), 67 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 64e5442f..55499ce3 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,4 +1,8 @@ -on: [pull_request] +on: + push: + branches: + - master + pull_request: name: Check Irssi env: apt_build_deps: libutf8proc-dev libperl-dev libotr5-dev diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 896048d6..00000000 --- a/.travis.yml +++ /dev/null @@ -1,65 +0,0 @@ -sudo: false -dist: xenial -language: perl -perl: - # ~stretch - - "5.24-shrplib" - - "system-perl" -env: - - CC=clang UNITTESTS=false - - CC=gcc UNITTESTS=false - - CC=clang UNITTESTS=true -matrix: - exclude: - - env: CC=clang UNITTESTS=true - perl: "system-perl" - allow_failures: - - env: CC=clang UNITTESTS=true - -addons: - apt: - packages: - - libperl-dev - - elinks - - libgcrypt11-dev - - libotr5-dev - -before_install: - - perl -V - - pushd ~ - - curl -sSLf https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip | funzip > bin/ninja - - chmod +x bin/ninja - - curl -sSLf https://github.com/mesonbuild/meson/releases/download/0.51.1/meson-0.51.1.tar.gz | tar xz - - ( cd bin ; ln -s ../meson-*/meson.py meson ) - - curl -sSLf https://github.com/irssi-import/glib-travis-build/releases/download/2.58.3/travis-xenial-glib-2.58.3.tar.xz | tar xJ - - export PKG_CONFIG_PATH=$HOME/glib-build/lib/x86_64-linux-gnu/pkgconfig - - export LD_LIBRARY_PATH=$HOME/glib-build/lib/x86_64-linux-gnu - - popd - -install: - - meson Build -Dwith-proxy=yes -Dwith-bot=yes -Dwith-perl=yes -Dwith-otr=yes --prefix=$HOME/irssi-build - - ninja -C Build - - ninja -C Build install - -before_script: - - pushd ~ - - mkdir irssi-test - - echo echo automated irssi launch test > irssi-test/startup; - echo ^set settings_autosave off >> irssi-test/startup; - echo ^set -clear log_close_string >> irssi-test/startup; - echo ^set -clear log_day_changed >> irssi-test/startup; - echo ^set -clear log_open_string >> irssi-test/startup; - echo ^set log_timestamp '* ' >> irssi-test/startup; - echo ^window log on >> irssi-test/startup - - echo load perl >> irssi-test/startup - - echo load proxy >> irssi-test/startup - - echo ^quit >> irssi-test/startup - -script: - - irssi-build/bin/irssi --home irssi-test - - popd - - if $UNITTESTS; then ninja -C Build test; fi - -after_script: - - cat ~/irc.log.* - - find -name testlog.txt -exec sed -i -e '/Inherited environment:.* TRAVIS/d' {} + -exec cat {} + diff --git a/README.md b/README.md index f73b58a0..8b857eeb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [Irssi](https://irssi.org/) -[![Build Status](https://travis-ci.org/irssi/irssi.svg?branch=master)](https://travis-ci.org/irssi/irssi) +![Build Status](https://github.com/irssi/irssi/workflows/Check%20Irssi/badge.svg?branch=master) Irssi is a modular chat client that is most commonly known for its text mode user interface, but 80% of the code isn't text mode From 9cbdf9175e81988053c2290aab2c9380be333ae3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 16:50:02 +0100 Subject: [PATCH 0721/1198] put proper versions in PACKAGE_VERSION --- utils/irssi-version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/irssi-version.sh b/utils/irssi-version.sh index 41970cb2..b096fd90 100755 --- a/utils/irssi-version.sh +++ b/utils/irssi-version.sh @@ -22,7 +22,7 @@ echo "#define IRSSI_VERSION_TIME $VERSION_TIME" if echo "${VERSION}" | grep -q -- -head; then # -head version, get extra details from git if we can - git_version=$(GIT_DIR=$1/.git git describe --dirty --long --always --tags 2>/dev/null) + git_version=$(GIT_DIR=$1/.git git describe --dirty --long --tags --match '[0-9]*.[0-9]*' 2>/dev/null) if [ $? = 0 ]; then echo "#undef PACKAGE_VERSION" echo "#define PACKAGE_VERSION \"${git_version}\"" From edb2f699d181c109522c07d5f943e6dae16cb4fa Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 12:57:23 +0100 Subject: [PATCH 0722/1198] correct wrong function prefixes: g_input -> i_input --- src/common.h | 11 +++++------ src/core/misc.c | 27 ++++++++++++--------------- src/core/misc.h | 3 +-- src/core/net-disconnect.c | 3 +-- src/core/net-sendbuffer.c | 3 +-- src/core/servers.c | 21 ++++++++------------- src/fe-common/core/fe-exec.c | 5 ++--- src/fe-text/gui-readline.c | 5 ++--- src/irc/core/irc.c | 6 ++---- src/irc/dcc/dcc-chat.c | 18 +++++++----------- src/irc/dcc/dcc-get.c | 23 +++++++++-------------- src/irc/dcc/dcc-send.c | 21 ++++++++------------- src/irc/dcc/dcc-server.c | 12 ++++++------ src/irc/proxy/listen.c | 6 ++---- src/otr/key.c | 3 ++- src/perl/common/Core.xs | 4 ++-- src/perl/perl-sources.c | 4 ++-- 17 files changed, 72 insertions(+), 103 deletions(-) diff --git a/src/common.h b/src/common.h index 3036397b..02bdbeb8 100644 --- a/src/common.h +++ b/src/common.h @@ -45,15 +45,14 @@ typedef guint64 uoff_t; #define PRIuUOFF_T G_GUINT64_FORMAT /* input functions */ -#define G_INPUT_READ (1 << 0) -#define G_INPUT_WRITE (1 << 1) +#define I_INPUT_READ (1 << 0) +#define I_INPUT_WRITE (1 << 1) typedef void (*GInputFunction) (void *data, GIOChannel *source, int condition); -int g_input_add(GIOChannel *source, int condition, - GInputFunction function, void *data); -int g_input_add_full(GIOChannel *source, int priority, int condition, - GInputFunction function, void *data); +int i_input_add(GIOChannel *source, int condition, GInputFunction function, void *data); +int i_input_add_full(GIOChannel *source, int priority, int condition, GInputFunction function, + void *data); /* return full path for ~/.irssi */ const char *get_irssi_dir(void); diff --git a/src/core/misc.c b/src/core/misc.c index 25e4f32b..35c2f571 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -37,15 +37,15 @@ static int irssi_io_invoke(GIOChannel *source, GIOCondition condition, if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { /* error, we have to call the function.. */ if (rec->condition & G_IO_IN) - icond |= G_INPUT_READ; + icond |= I_INPUT_READ; else - icond |= G_INPUT_WRITE; + icond |= I_INPUT_WRITE; } if (condition & (G_IO_IN | G_IO_PRI)) - icond |= G_INPUT_READ; + icond |= I_INPUT_READ; if (condition & G_IO_OUT) - icond |= G_INPUT_WRITE; + icond |= I_INPUT_WRITE; if (rec->condition & icond) rec->function(rec->data, source, icond); @@ -53,8 +53,8 @@ static int irssi_io_invoke(GIOChannel *source, GIOCondition condition, return TRUE; } -int g_input_add_full(GIOChannel *source, int priority, int condition, - GInputFunction function, void *data) +int i_input_add_full(GIOChannel *source, int priority, int condition, GInputFunction function, + void *data) { IRSSI_INPUT_REC *rec; unsigned int result; @@ -66,9 +66,9 @@ int g_input_add_full(GIOChannel *source, int priority, int condition, rec->data = data; cond = (GIOCondition) (G_IO_ERR|G_IO_HUP|G_IO_NVAL); - if (condition & G_INPUT_READ) + if (condition & I_INPUT_READ) cond |= G_IO_IN|G_IO_PRI; - if (condition & G_INPUT_WRITE) + if (condition & I_INPUT_WRITE) cond |= G_IO_OUT; result = g_io_add_watch_full(source, priority, cond, @@ -77,19 +77,16 @@ int g_input_add_full(GIOChannel *source, int priority, int condition, return result; } -int g_input_add(GIOChannel *source, int condition, - GInputFunction function, void *data) +int i_input_add(GIOChannel *source, int condition, GInputFunction function, void *data) { - return g_input_add_full(source, G_PRIORITY_DEFAULT, condition, - function, data); + return i_input_add_full(source, G_PRIORITY_DEFAULT, condition, function, data); } /* easy way to bypass glib polling of io channel internal buffer */ -int g_input_add_poll(int fd, int priority, int condition, - GInputFunction function, void *data) +int i_input_add_poll(int fd, int priority, int condition, GInputFunction function, void *data) { GIOChannel *source = g_io_channel_unix_new(fd); - int ret = g_input_add_full(source, priority, condition, function, data); + int ret = i_input_add_full(source, priority, condition, function, data); g_io_channel_unref(source); return ret; } diff --git a/src/core/misc.h b/src/core/misc.h index cd5cf29c..6c117648 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -1,8 +1,7 @@ #ifndef IRSSI_CORE_MISC_H #define IRSSI_CORE_MISC_H -int g_input_add_poll(int fd, int priority, int condition, - GInputFunction function, void *data); +int i_input_add_poll(int fd, int priority, int condition, GInputFunction function, void *data); /* `str' should be type char[MAX_INT_STRLEN] */ #define ltoa(str, num) \ diff --git a/src/core/net-disconnect.c b/src/core/net-disconnect.c index 27540767..a2f7e290 100644 --- a/src/core/net-disconnect.c +++ b/src/core/net-disconnect.c @@ -97,8 +97,7 @@ void net_disconnect_later(GIOChannel *handle) rec = g_new(NET_DISCONNECT_REC, 1); rec->created = time(NULL); rec->handle = handle; - rec->tag = g_input_add(handle, G_INPUT_READ, - (GInputFunction) sig_disconnect, rec); + rec->tag = i_input_add(handle, I_INPUT_READ, (GInputFunction) sig_disconnect, rec); if (timeout_tag == -1) { timeout_tag = g_timeout_add(10000, (GSourceFunc) diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c index a085fac7..0cb462a1 100644 --- a/src/core/net-sendbuffer.c +++ b/src/core/net-sendbuffer.c @@ -132,8 +132,7 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size) /* everything couldn't be sent. */ if (rec->send_tag == -1) { rec->send_tag = - g_input_add(rec->handle, G_INPUT_WRITE, - (GInputFunction) sig_sendbuffer, rec); + i_input_add(rec->handle, I_INPUT_WRITE, (GInputFunction) sig_sendbuffer, rec); } return buffer_add(rec, data, size) ? 0 : -1; diff --git a/src/core/servers.c b/src/core/servers.c index 7709e3a2..11dfeba3 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -184,10 +184,9 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han if (error & 1) { if (server->connect_tag != -1) g_source_remove(server->connect_tag); - server->connect_tag = g_input_add(handle, error == 1 ? G_INPUT_READ : G_INPUT_WRITE, - (GInputFunction) - server_connect_callback_init_ssl, - server); + server->connect_tag = + i_input_add(handle, error == 1 ? I_INPUT_READ : I_INPUT_WRITE, + (GInputFunction) server_connect_callback_init_ssl, server); return; } @@ -253,11 +252,9 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, if (server->connrec->use_tls) server_connect_callback_init_ssl(server, handle); else - server->connect_tag = - g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ, - (GInputFunction) - server_connect_callback_init, - server); + server->connect_tag = + i_input_add(handle, I_INPUT_WRITE | I_INPUT_READ, + (GInputFunction) server_connect_callback_init, server); } } @@ -418,10 +415,8 @@ int server_start_connect(SERVER_REC *server) net_gethostbyname_nonblock(connect_address, server->connect_pipe[1], 0); server->connect_tag = - g_input_add(server->connect_pipe[0], G_INPUT_READ, - (GInputFunction) - server_connect_callback_readpipe, - server); + i_input_add(server->connect_pipe[0], I_INPUT_READ, + (GInputFunction) server_connect_callback_readpipe, server); server->connect_time = time(NULL); lookup_servers = g_slist_append(lookup_servers, server); diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index dcd4ecb5..a69b3e7c 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -524,9 +524,8 @@ static void handle_exec(const char *args, GHashTable *optlist, level = g_hash_table_lookup(optlist, "level"); rec->level = level == NULL ? MSGLEVEL_CLIENTCRAP : level2bits(level, NULL); - rec->read_tag = g_input_add(rec->in, G_INPUT_READ, - (GInputFunction) sig_exec_input_reader, - rec); + rec->read_tag = + i_input_add(rec->in, I_INPUT_READ, (GInputFunction) sig_exec_input_reader, rec); processes = g_slist_append(processes, rec); if (rec->target == NULL && interactive) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index d56ebfb8..f848ba1b 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -85,9 +85,8 @@ static void sig_input(void); void input_listen_init(int handle) { - readtag = g_input_add_poll(handle, - G_PRIORITY_HIGH, G_INPUT_READ, - (GInputFunction) sig_input, NULL); + readtag = i_input_add_poll(handle, G_PRIORITY_HIGH, I_INPUT_READ, + (GInputFunction) sig_input, NULL); } void input_listen_deinit(void) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index ef7a3ad1..f3f9f307 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -491,10 +491,8 @@ static void irc_init_server(IRC_SERVER_REC *server) if (!IS_IRC_SERVER(server)) return; - server->readtag = - g_input_add(net_sendbuffer_handle(server->handle), - G_INPUT_READ, - (GInputFunction) irc_parse_incoming, server); + server->readtag = i_input_add(net_sendbuffer_handle(server->handle), I_INPUT_READ, + (GInputFunction) irc_parse_incoming, server); } void irc_irc_init(void) diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index 987a5ba9..3f471eac 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -355,8 +355,7 @@ static void dcc_chat_listen(CHAT_DCC_REC *dcc) memcpy(&dcc->addr, &ip, sizeof(IPADDR)); net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; - dcc->tagread = g_input_add(handle, G_INPUT_READ, - (GInputFunction) dcc_chat_input, dcc); + dcc->tagread = i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc); signal_emit("dcc connected", 1, dcc); } @@ -379,8 +378,7 @@ static void sig_chat_connected(CHAT_DCC_REC *dcc) dcc->starttime = time(NULL); dcc->sendbuf = net_sendbuffer_create(dcc->handle, 0); - dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_chat_input, dcc); + dcc->tagread = i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc); signal_emit("dcc connected", 1, dcc); } @@ -397,9 +395,8 @@ static void dcc_chat_connect(CHAT_DCC_REC *dcc) dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port); if (dcc->handle != NULL) { - dcc->tagconn = g_input_add(dcc->handle, - G_INPUT_WRITE | G_INPUT_READ, - (GInputFunction) sig_chat_connected, dcc); + dcc->tagconn = i_input_add(dcc->handle, I_INPUT_WRITE | I_INPUT_READ, + (GInputFunction) sig_chat_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); @@ -428,8 +425,8 @@ static void dcc_chat_passive(CHAT_DCC_REC *dcc) cmd_return_error(CMDERR_ERRNO); dcc->handle = handle; - dcc->tagconn = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_chat_listen, dcc); + dcc->tagconn = + i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc); /* Let's send the reply to the other client! */ dcc_ip2str(&own_ip, host); @@ -508,8 +505,7 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server) dcc->handle = handle; dcc->tagconn = - g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_chat_listen, dcc); + i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc); /* send the chat request */ signal_emit("dcc request send", 1, dcc); diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 73a06590..5af557ea 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -112,9 +112,8 @@ void dcc_get_send_received(GET_DCC_REC *dcc) last 1-3 bytes should be sent later. these happen probably never, but I just want to do it right.. :) */ if (dcc->tagwrite == -1) { - dcc->tagwrite = g_input_add(dcc->handle, G_INPUT_WRITE, - (GInputFunction) sig_dccget_send, - dcc); + dcc->tagwrite = + i_input_add(dcc->handle, I_INPUT_WRITE, (GInputFunction) sig_dccget_send, dcc); } } @@ -285,8 +284,8 @@ void sig_dccget_connected(GET_DCC_REC *dcc) dcc_close(DCC(dcc)); return; } - dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) sig_dccget_receive, dcc); + dcc->tagread = + i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) sig_dccget_receive, dcc); signal_emit("dcc connected", 1, dcc); if (dcc->from_dccserver) { @@ -311,11 +310,8 @@ void dcc_get_connect(GET_DCC_REC *dcc) dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port); if (dcc->handle != NULL) { - dcc->tagconn = - g_input_add(dcc->handle, - G_INPUT_WRITE | G_INPUT_READ, - (GInputFunction) sig_dccget_connected, - dcc); + dcc->tagconn = i_input_add(dcc->handle, I_INPUT_WRITE | I_INPUT_READ, + (GInputFunction) sig_dccget_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); @@ -344,8 +340,8 @@ static void dcc_get_listen(GET_DCC_REC *dcc) net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; - dcc->tagconn = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, - (GInputFunction) sig_dccget_connected, dcc); + dcc->tagconn = i_input_add(handle, I_INPUT_READ | I_INPUT_WRITE, + (GInputFunction) sig_dccget_connected, dcc); } void dcc_get_passive(GET_DCC_REC *dcc) @@ -361,8 +357,7 @@ void dcc_get_passive(GET_DCC_REC *dcc) cmd_return_error(CMDERR_ERRNO); dcc->handle = handle; - dcc->tagconn = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_get_listen, dcc); + dcc->tagconn = i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_get_listen, dcc); /* Let's send the reply to the other client! */ dcc_ip2str(&own_ip, host); diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c index 6eabd25f..eccb8d37 100644 --- a/src/irc/dcc/dcc-send.c +++ b/src/irc/dcc/dcc-send.c @@ -336,10 +336,8 @@ static void dcc_send_connected(SEND_DCC_REC *dcc) net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; - dcc->tagread = g_input_add(handle, G_INPUT_READ, - (GInputFunction) dcc_send_read_size, dcc); - dcc->tagwrite = g_input_add(handle, G_INPUT_WRITE, - (GInputFunction) dcc_send_data, dcc); + dcc->tagread = i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_send_read_size, dcc); + dcc->tagwrite = i_input_add(handle, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc); signal_emit("dcc connected", 1, dcc); } @@ -352,12 +350,10 @@ static void dcc_send_connect(SEND_DCC_REC *dcc) if (dcc->handle != NULL) { dcc->starttime = time(NULL); - dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_send_read_size, - dcc); - dcc->tagwrite = g_input_add(dcc->handle, G_INPUT_WRITE, - (GInputFunction) dcc_send_data, - dcc); + dcc->tagread = i_input_add(dcc->handle, I_INPUT_READ, + (GInputFunction) dcc_send_read_size, dcc); + dcc->tagwrite = + i_input_add(dcc->handle, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc); signal_emit("dcc connected", 1, dcc); } else { /* error connecting */ @@ -436,9 +432,8 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname, dcc->queue = queue; dcc->file_quoted = strchr(fname, ' ') != NULL; if (!passive) { - dcc->tagconn = g_input_add(handle, G_INPUT_READ, - (GInputFunction) dcc_send_connected, - dcc); + dcc->tagconn = + i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_send_connected, dcc); } /* Generate an ID for this send if using passive protocol */ diff --git a/src/irc/dcc/dcc-server.c b/src/irc/dcc/dcc-server.c index 9c20e9bf..4d1e94aa 100644 --- a/src/irc/dcc/dcc-server.c +++ b/src/irc/dcc/dcc-server.c @@ -183,8 +183,8 @@ static void dcc_server_listen(SERVER_DCC_REC *dcc) memcpy(&newdcc->addr, &ip, sizeof(IPADDR)); net_ip2host(&newdcc->addr, newdcc->addrstr); newdcc->port = port; - newdcc->tagread = g_input_add(handle, G_INPUT_READ, - (GInputFunction) dcc_server_input, newdcc); + newdcc->tagread = + i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_server_input, newdcc); signal_emit("dcc connected", 1, newdcc); } @@ -210,8 +210,8 @@ static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg) memcpy(&dccchat->addr, &dcc->addr, sizeof(IPADDR)); net_ip2host(&dccchat->addr, dccchat->addrstr); dccchat->port = dcc->port; - dccchat->tagread = g_input_add(dccchat->handle, G_INPUT_READ, - (GInputFunction) dcc_chat_input, dccchat); + dccchat->tagread = i_input_add(dccchat->handle, I_INPUT_READ, + (GInputFunction) dcc_chat_input, dccchat); dcc->connection_established = 1; signal_emit("dcc connected", 1, dccchat); @@ -347,8 +347,8 @@ static void cmd_dcc_server(const char *data, IRC_SERVER_REC *server) dcc = dcc_server_create(server, flags); dcc->handle = handle; dcc->port = atoi(port); - dcc->tagconn = g_input_add(dcc->handle, G_INPUT_READ, - (GInputFunction) dcc_server_listen, dcc); + dcc->tagconn = + i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_server_listen, dcc); signal_emit("dcc server started", 1, dcc); diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 1c53369c..1183c8d7 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -470,8 +470,7 @@ static void sig_listen(LISTEN_REC *listen) rec->server = servers == NULL ? NULL : IRC_SERVER(server_find_chatnet(listen->ircnet)); } - rec->recv_tag = g_input_add(handle, G_INPUT_READ, - (GInputFunction) sig_listen_client, rec); + rec->recv_tag = i_input_add(handle, I_INPUT_READ, (GInputFunction) sig_listen_client, rec); proxy_clients = g_slist_prepend(proxy_clients, rec); listen->clients = g_slist_prepend(listen->clients, rec); @@ -739,8 +738,7 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path) rec->port = port; rec->port_or_path = g_strdup(port_or_path); - rec->tag = g_input_add(rec->handle, G_INPUT_READ, - (GInputFunction) sig_listen, rec); + rec->tag = i_input_add(rec->handle, I_INPUT_READ, (GInputFunction) sig_listen, rec); proxy_listens = g_slist_append(proxy_listens, rec); } diff --git a/src/otr/key.c b/src/otr/key.c index 27de0226..26565c9a 100644 --- a/src/otr/key.c +++ b/src/otr/key.c @@ -252,7 +252,8 @@ void key_gen_run(struct otr_user_state *ustate, const char *account_name) if (pid > 0) { /* Parent process */ pidwait_add(pid); - worker->tag = g_input_add(worker->pipes[0], G_INPUT_READ, (GInputFunction)read_key_gen_status, worker); + worker->tag = i_input_add(worker->pipes[0], I_INPUT_READ, + (GInputFunction) read_key_gen_status, worker); return; } diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index 7ae18943..9e582a70 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -258,14 +258,14 @@ CODE: int INPUT_READ() CODE: - RETVAL = G_INPUT_READ; + RETVAL = I_INPUT_READ; OUTPUT: RETVAL int INPUT_WRITE() CODE: - RETVAL = G_INPUT_WRITE; + RETVAL = I_INPUT_WRITE; OUTPUT: RETVAL diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 69d86f1f..9f5773f1 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -139,8 +139,8 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once) rec->func = perl_func_sv_inc(func, pkg); rec->data = SvREFCNT_inc(data); - rec->tag = g_input_add_poll(source, G_PRIORITY_DEFAULT, condition, - (GInputFunction) perl_source_event, rec); + rec->tag = i_input_add_poll(source, G_PRIORITY_DEFAULT, condition, + (GInputFunction) perl_source_event, rec); perl_sources = g_slist_append(perl_sources, rec); return rec->tag; From 91817964729dc34da23ba63832f18361cc11fd01 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 13:11:09 +0100 Subject: [PATCH 0723/1198] correct wrong function prefixes: g_istr -> i_istr --- src/core/commands.c | 3 +-- src/core/misc.c | 6 +++--- src/core/misc.h | 6 +++--- src/core/nicklist.c | 3 +-- src/core/settings.c | 3 +-- src/fe-common/core/completion.c | 12 ++++++++---- src/fe-common/core/themes.c | 3 +-- src/fe-common/irc/fe-netjoin.c | 3 +-- src/fe-fuzz/server.c | 3 +-- src/irc/core/irc-servers.c | 8 +++----- src/irc/core/irc-session.c | 4 ++-- src/irc/flood/flood.c | 3 +-- src/lib-config/parse.c | 6 +++--- tests/irc/flood/test-796.c | 3 +-- 14 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/core/commands.c b/src/core/commands.c index 198b1327..e2bee576 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -740,8 +740,7 @@ int cmd_get_params(const char *data, gpointer *free_me, int count, ...) opthash = (GHashTable **) va_arg(args, GHashTable **); rec->options = *opthash = - g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); ignore_unknown = count & PARAM_FLAG_UNKNOWN_OPTIONS; error = get_cmd_options(&datad, ignore_unknown, diff --git a/src/core/misc.c b/src/core/misc.c index 35c2f571..d0c2a49e 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -408,17 +408,17 @@ char *convert_home(const char *path) } } -int g_istr_equal(gconstpointer v, gconstpointer v2) +int i_istr_equal(gconstpointer v, gconstpointer v2) { return g_ascii_strcasecmp((const char *) v, (const char *) v2) == 0; } -int g_istr_cmp(gconstpointer v, gconstpointer v2) +int i_istr_cmp(gconstpointer v, gconstpointer v2) { return g_ascii_strcasecmp((const char *) v, (const char *) v2); } -guint g_istr_hash(gconstpointer v) +guint i_istr_hash(gconstpointer v) { const signed char *p; guint32 h = 5381; diff --git a/src/core/misc.h b/src/core/misc.h index 6c117648..a441a468 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -41,11 +41,11 @@ GList *optlist_remove_known(const char *cmd, GHashTable *optlist); char *convert_home(const char *path); /* Case-insensitive string hash functions */ -int g_istr_equal(gconstpointer v, gconstpointer v2); -unsigned int g_istr_hash(gconstpointer v); +int i_istr_equal(gconstpointer v, gconstpointer v2); +unsigned int i_istr_hash(gconstpointer v); /* Case-insensitive GCompareFunc func */ -int g_istr_cmp(gconstpointer v, gconstpointer v2); +int i_istr_cmp(gconstpointer v, gconstpointer v2); /* Find `mask' from `data', you can use * and ? wildcards. */ int match_wildcards(const char *mask, const char *data); diff --git a/src/core/nicklist.c b/src/core/nicklist.c index f2aa1315..34c4b24b 100644 --- a/src/core/nicklist.c +++ b/src/core/nicklist.c @@ -456,8 +456,7 @@ static void sig_channel_created(CHANNEL_REC *channel) { g_return_if_fail(IS_CHANNEL(channel)); - channel->nicks = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + channel->nicks = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); } static void nicklist_remove_hash(gpointer key, NICK_REC *nick, diff --git a/src/core/settings.c b/src/core/settings.c index f8c0b9df..1720d922 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -876,8 +876,7 @@ static int sig_autosave(void) void settings_init(void) { - settings = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + settings = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); last_errors = NULL; last_invalid_modules = NULL; diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 0102bd2c..a897c452 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -425,7 +425,8 @@ static GList *completion_get_settings(const char *key, SettingType type) SETTINGS_REC *rec = tmp->data; 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); + complist = g_list_insert_sorted(complist, g_strdup(rec->key), + (GCompareFunc) i_istr_cmp); } g_slist_free(sets); return complist; @@ -460,7 +461,8 @@ static GList *completion_get_aliases(const char *alias, char cmdchar) be appended after command completions and kept in uppercase to show it's an alias */ if (glist_find_icase_string(complist, word) == NULL) - complist = g_list_insert_sorted(complist, word, (GCompareFunc) g_istr_cmp); + complist = + g_list_insert_sorted(complist, word, (GCompareFunc) i_istr_cmp); else g_free(word); } @@ -489,7 +491,8 @@ static GList *completion_get_commands(const char *cmd, char cmdchar) word = cmdchar == '\0' ? g_strdup(rec->cmd) : g_strdup_printf("%c%s", cmdchar, rec->cmd); if (glist_find_icase_string(complist, word) == NULL) - complist = g_list_insert_sorted(complist, word, (GCompareFunc) g_istr_cmp); + complist = + g_list_insert_sorted(complist, word, (GCompareFunc) i_istr_cmp); else g_free(word); } @@ -523,7 +526,8 @@ static GList *completion_get_subcommands(const char *cmd) continue; if (g_ascii_strncasecmp(rec->cmd, cmd, len) == 0) - complist = g_list_insert_sorted(complist, g_strdup(rec->cmd+skip), (GCompareFunc) g_istr_cmp); + complist = g_list_insert_sorted(complist, g_strdup(rec->cmd + skip), + (GCompareFunc) i_istr_cmp); } return complist; } diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index ff737c41..04f00477 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -56,8 +56,7 @@ THEME_REC *theme_create(const char *path, const char *name) rec->name = g_strdup(name); rec->abstracts = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); - rec->modules = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + rec->modules = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); themes = g_slist_append(themes, rec); signal_emit("theme created", 1, rec); diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index 602eaf20..f6d9e4b3 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -176,8 +176,7 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe /* save nicks to string, clear now_channels and remove the same channels from old_channels list */ - channels = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + channels = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); for (tmp = server->netjoins; tmp != NULL; tmp = next) { NETJOIN_REC *rec = tmp->data; diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index e8caafa0..a444494d 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -102,8 +102,7 @@ void event_connected(IRC_SERVER_REC *server, const char *data, const char *from) void irc_server_init_bare_minimum(IRC_SERVER_REC *server) { server->rawlog = rawlog_create(); - server->isupport = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); /* set the standards */ g_hash_table_insert(server->isupport, g_strdup("CHANMODES"), g_strdup("beI,k,l,imnpst")); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 9779ab58..fa02094e 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -283,8 +283,7 @@ static void server_init(IRC_SERVER_REC *server) g_free(cmd); } - server->isupport = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); /* set the standards */ g_hash_table_insert(server->isupport, g_strdup("CHANMODES"), g_strdup("beI,k,l,imnpst")); @@ -417,10 +416,9 @@ static void sig_connected(IRC_SERVER_REC *server) (QUERY_REC *(*)(SERVER_REC *, const char *)) irc_query_find; server->nick_comp_func = irc_nickcmp_rfc1459; - server->splits = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + server->splits = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); - if (!server->session_reconnect) + if (!server->session_reconnect) server_init(server); } diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index ec2c86ee..6b817099 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -106,8 +106,8 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, 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); + server->isupport = + g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); } node = config_node_section(NULL, node, "isupport", -1); diff --git a/src/irc/flood/flood.c b/src/irc/flood/flood.c index a7425b90..a1472648 100644 --- a/src/irc/flood/flood.c +++ b/src/irc/flood/flood.c @@ -120,8 +120,7 @@ static void flood_init_server(IRC_SERVER_REC *server) rec = g_new0(MODULE_SERVER_REC, 1); MODULE_DATA_SET(server, rec); - rec->floodlist = g_hash_table_new((GHashFunc) g_istr_hash, - (GCompareFunc) g_istr_equal); + rec->floodlist = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); } static void flood_hash_destroy(const char *key, FLOOD_REC *flood) diff --git a/src/lib-config/parse.c b/src/lib-config/parse.c index c106fc46..e4ff1abb 100644 --- a/src/lib-config/parse.c +++ b/src/lib-config/parse.c @@ -20,13 +20,13 @@ #include "module.h" -static int g_istr_equal(gconstpointer v, gconstpointer v2) +static int i_istr_equal(gconstpointer v, gconstpointer v2) { return g_ascii_strcasecmp((const char *) v, (const char *) v2) == 0; } /* a char* hash function from ASU */ -static unsigned int g_istr_hash(gconstpointer v) +static unsigned int i_istr_hash(gconstpointer v) { const char *s = (const char *) v; unsigned int h = 0, g; @@ -314,7 +314,7 @@ CONFIG_REC *config_open(const char *fname, int create_mode) rec->create_mode = create_mode; rec->mainnode = g_new0(CONFIG_NODE, 1); rec->mainnode->type = NODE_TYPE_BLOCK; - rec->cache = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal); + rec->cache = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); rec->cache_nodes = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal); return rec; diff --git a/tests/irc/flood/test-796.c b/tests/irc/flood/test-796.c index 9e8aeee7..a2864144 100644 --- a/tests/irc/flood/test-796.c +++ b/tests/irc/flood/test-796.c @@ -102,8 +102,7 @@ static void server_destroy_flood_tear_down(ServerDestroyFloodData *fixture, cons 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); + server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); /* set the standards */ g_hash_table_insert(server->isupport, g_strdup("CHANMODES"), g_strdup("beI,k,l,imnpst")); From 50ed476623c54c0ce80cf81190fe339f41e205be Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 15:42:20 +0100 Subject: [PATCH 0724/1198] correct wrong function prefixes: g_io_channel -> i_io_channel --- src/core/net-nonblock.c | 8 ++++---- src/core/network.c | 14 +++++++------- src/core/network.h | 6 +++--- src/core/servers.c | 4 ++-- src/core/session.c | 2 +- src/fe-common/core/fe-exec.c | 4 ++-- src/irc/proxy/listen.c | 4 ++-- src/otr/key.c | 8 ++++---- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 1ad5f42f..643884ee 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -62,9 +62,9 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_l rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; } - g_io_channel_write_block(pipe, &rec, sizeof(rec)); + i_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.errlen != 0) - g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); + i_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); if (pid == 0) _exit(99); @@ -82,7 +82,7 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); /* get ip+error */ - if (g_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) { + if (i_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) { rec->errorstr = g_strdup_printf("Host name lookup: %s", g_strerror(errno)); return -1; @@ -92,7 +92,7 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) /* read error string, if we can't read everything for some reason, just ignore it. */ rec->errorstr = g_malloc0(rec->errlen+1); - g_io_channel_read_block(pipe, rec->errorstr, rec->errlen); + i_io_channel_read_block(pipe, rec->errorstr, rec->errlen); } return 0; diff --git a/src/core/network.c b/src/core/network.c index 87b91698..85fe9896 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -39,7 +39,7 @@ union sockaddr_union { #define SIZEOF_SOCKADDR(so) ((so).sa.sa_family == AF_INET6 ? \ sizeof(so.sin6) : sizeof(so.sin)) -GIOChannel *g_io_channel_new(int handle) +GIOChannel *i_io_channel_new(int handle) { GIOChannel *chan; chan = g_io_channel_unix_new(handle); @@ -48,7 +48,7 @@ GIOChannel *g_io_channel_new(int handle) return chan; } -int g_io_channel_write_block(GIOChannel *channel, void *data, int len) +int i_io_channel_write_block(GIOChannel *channel, void *data, int len) { gsize ret; int sent; @@ -63,7 +63,7 @@ int g_io_channel_write_block(GIOChannel *channel, void *data, int len) return sent < len ? -1 : 0; } -int g_io_channel_read_block(GIOChannel *channel, void *data, int len) +int i_io_channel_read_block(GIOChannel *channel, void *data, int len) { time_t maxwait; gsize ret; @@ -211,7 +211,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) if (handle == -1) return (NULL); - return g_io_channel_new(handle); + return i_io_channel_new(handle); } /* Connect to named UNIX socket */ @@ -242,7 +242,7 @@ GIOChannel *net_connect_unix(const char *path) return NULL; } - return g_io_channel_new(handle); + return i_io_channel_new(handle); } /* Disconnect socket */ @@ -298,7 +298,7 @@ GIOChannel *net_listen(IPADDR *my_ip, int *port) /* start listening */ if (listen(handle, 1) >= 0) - return g_io_channel_new(handle); + return i_io_channel_new(handle); } } @@ -327,7 +327,7 @@ GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port) if (port != NULL) *port = sin_get_port(&so); fcntl(ret, F_SETFL, O_NONBLOCK); - return g_io_channel_new(ret); + return i_io_channel_new(ret); } /* Read data from socket, return number of bytes read, -1 = error */ diff --git a/src/core/network.h b/src/core/network.h index 1776005d..0747f018 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -31,13 +31,13 @@ struct _IPADDR { extern IPADDR ip4_any; -GIOChannel *g_io_channel_new(int handle); +GIOChannel *i_io_channel_new(int handle); /* Returns 1 if IPADDRs are the same. */ /* Deprecated since it is unused. It will be deleted in a later release. */ int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED; -int g_io_channel_write_block(GIOChannel *channel, void *data, int len); -int g_io_channel_read_block(GIOChannel *channel, void *data, int len); +int i_io_channel_write_block(GIOChannel *channel, void *data, int len); +int i_io_channel_read_block(GIOChannel *channel, void *data, int len); int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); diff --git a/src/core/servers.c b/src/core/servers.c index 11dfeba3..841700d4 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -406,8 +406,8 @@ int server_start_connect(SERVER_REC *server) return FALSE; } - server->connect_pipe[0] = g_io_channel_new(fd[0]); - server->connect_pipe[1] = g_io_channel_new(fd[1]); + server->connect_pipe[0] = i_io_channel_new(fd[0]); + server->connect_pipe[1] = i_io_channel_new(fd[1]); connect_address = server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->address; diff --git a/src/core/session.c b/src/core/session.c index 0dc36fef..6f3908e5 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -262,7 +262,7 @@ static void session_restore_server(CONFIG_NODE *node) chatnet, password, nick); if (conn != NULL) { conn->reconnection = TRUE; - conn->connect_handle = g_io_channel_new(handle); + conn->connect_handle = i_io_channel_new(handle); server = proto->server_init_connect(conn); server->version = g_strdup(config_node_get_str(node, "version", NULL)); diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c index a69b3e7c..0e929bae 100644 --- a/src/fe-common/core/fe-exec.c +++ b/src/fe-common/core/fe-exec.c @@ -302,9 +302,9 @@ static void process_exec(PROCESS_REC *rec, const char *cmd) if (rec->pid != 0) { /* parent process */ - GIOChannel *outio = g_io_channel_new(in[1]); + GIOChannel *outio = i_io_channel_new(in[1]); - rec->in = g_io_channel_new(out[0]); + rec->in = i_io_channel_new(out[0]); rec->out = net_sendbuffer_create(outio, 0); close(out[1]); diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 1183c8d7..19aba87d 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -74,7 +74,7 @@ static GIOChannel *net_listen_unix(const char *path) goto error_unlink; } - return g_io_channel_new(handle); + return i_io_channel_new(handle); error_unlink: unlink(sa.sun_path); @@ -99,7 +99,7 @@ static GIOChannel *net_accept_unix(GIOChannel *handle) return NULL; fcntl(ret, F_SETFL, O_NONBLOCK); - return g_io_channel_new(ret); + return i_io_channel_new(ret); } static void remove_client(CLIENT_REC *rec) diff --git a/src/otr/key.c b/src/otr/key.c index 26565c9a..36eb9f9d 100644 --- a/src/otr/key.c +++ b/src/otr/key.c @@ -107,7 +107,7 @@ static void emit_event(GIOChannel *pipe, enum key_gen_status status, gcry_error_ event.status = status; event.error = error; - g_io_channel_write_block(pipe, &event, sizeof(event)); + i_io_channel_write_block(pipe, &event, sizeof(event)); } /* @@ -137,7 +137,7 @@ static void read_key_gen_status(struct key_gen_worker *worker, GIOChannel *pipe) fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); - if (g_io_channel_read_block(pipe, &event, sizeof(event)) == -1) { + if (i_io_channel_read_block(pipe, &event, sizeof(event)) == -1) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_OTR_KEYGEN_FAILED, key_gen_state.account_name, @@ -244,8 +244,8 @@ void key_gen_run(struct otr_user_state *ustate, const char *account_name) return; } - worker->pipes[0] = g_io_channel_new(fd[0]); - worker->pipes[1] = g_io_channel_new(fd[1]); + worker->pipes[0] = i_io_channel_new(fd[0]); + worker->pipes[1] = i_io_channel_new(fd[1]); pid = fork(); From 8405c6970aaef56eef00659e19968d01f404be7a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 15:44:10 +0100 Subject: [PATCH 0725/1198] correct wrong function prefixes: g_hash_free_value -> i_hash_free_value --- src/fe-common/core/fe-messages.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index c1d87b2b..c4469178 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -774,7 +774,7 @@ static void sig_channel_joined(CHANNEL_REC *channel) } } -static void g_hash_free_value(void *key, void *value) +static void i_hash_free_value(void *key, void *value) { g_free(value); } @@ -825,7 +825,7 @@ void fe_messages_init(void) void fe_messages_deinit(void) { - g_hash_table_foreach(printnicks, (GHFunc) g_hash_free_value, NULL); + g_hash_table_foreach(printnicks, (GHFunc) i_hash_free_value, NULL); g_hash_table_destroy(printnicks); signal_remove("message public", (SIGNAL_FUNC) sig_message_public); From b5ddc55fe663f49cfdb89ba8fce9de26def00579 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 5 Jan 2021 21:35:18 +0100 Subject: [PATCH 0726/1198] correct wrong function prefixes: gslist -> i_slist --- src/core/channels.c | 10 ++++------ src/core/commands.c | 7 +++---- src/core/log.c | 2 +- src/core/misc.c | 14 ++++++------- src/core/misc.h | 14 ++++++------- src/core/settings.c | 5 ++--- src/fe-common/core/fe-common-core.c | 2 +- src/fe-common/irc/fe-modes.c | 2 +- src/fe-common/irc/fe-netjoin.c | 5 ++--- src/fe-common/irc/notifylist/fe-notifylist.c | 2 +- src/irc/core/irc-cap.c | 21 ++++++++++---------- src/irc/core/irc-servers.c | 4 ++-- src/irc/core/servers-redirect.c | 2 +- src/irc/dcc/dcc.c | 4 ++-- src/irc/notifylist/notify-ison.c | 2 +- src/perl/common/Settings.xs | 2 +- src/perl/perl-common.c | 2 +- 17 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/core/channels.c b/src/core/channels.c index edc30544..68209a7c 100644 --- a/src/core/channels.c +++ b/src/core/channels.c @@ -126,9 +126,8 @@ CHANNEL_REC *channel_find(SERVER_REC *server, const char *name) return channel_find_server(server, name); /* find from any server */ - return gslist_foreach_find(servers, - (FOREACH_FIND_FUNC) channel_find_server, - (void *) name); + return i_slist_foreach_find(servers, (FOREACH_FIND_FUNC) channel_find_server, + (void *) name); } void channel_change_name(CHANNEL_REC *channel, const char *name) @@ -153,9 +152,8 @@ void channel_change_visible_name(CHANNEL_REC *channel, const char *name) static CHANNEL_REC *channel_find_servers(GSList *servers, const char *name) { - return gslist_foreach_find(servers, - (FOREACH_FIND_FUNC) channel_find_server, - (void *) name); + return i_slist_foreach_find(servers, (FOREACH_FIND_FUNC) channel_find_server, + (void *) name); } static GSList *servers_find_chatnet_except(SERVER_REC *server) diff --git a/src/core/commands.c b/src/core/commands.c index e2bee576..deb5fe90 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -431,7 +431,7 @@ static void command_calc_options(COMMAND_REC *rec, const char *options) g_strfreev(optlist); /* linked list -> string[] */ - str = gslist_to_string(list, " "); + str = i_slist_to_string(list, " "); rec->options = g_strsplit(str, " ", -1); g_free(str); @@ -831,7 +831,7 @@ void commands_remove_module(const char *module) COMMAND_REC *rec = tmp->data; next = tmp->next; - modlist = gslist_find_string(rec->modules, module); + modlist = i_slist_find_string(rec->modules, module); if (modlist != NULL) command_module_unbind_all(rec, modlist->data); } @@ -865,8 +865,7 @@ static int cmd_protocol_match(COMMAND_REC *cmd, SERVER_REC *server) #define alias_runstack_pop(alias) \ alias_runstack = g_slist_remove(alias_runstack, alias) -#define alias_runstack_find(alias) \ - (gslist_find_icase_string(alias_runstack, alias) != NULL) +#define alias_runstack_find(alias) (i_slist_find_icase_string(alias_runstack, alias) != NULL) static void parse_command(const char *command, int expand_aliases, SERVER_REC *server, void *item) diff --git a/src/core/log.c b/src/core/log.c index 3e260fe7..cb6f1edd 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -561,7 +561,7 @@ static void log_read_config(void) if (node != NULL) log_items_read_config(node, log); - if (log->autoopen || gslist_find_string(fnames, log->fname)) + if (log->autoopen || i_slist_find_string(fnames, log->fname)) log_start_logging(log); } diff --git a/src/core/misc.c b/src/core/misc.c index d0c2a49e..576d23f2 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -167,7 +167,7 @@ int strarray_find(char **array, const char *item) return -1; } -GSList *gslist_find_string(GSList *list, const char *key) +GSList *i_slist_find_string(GSList *list, const char *key) { for (; list != NULL; list = list->next) if (g_strcmp0(list->data, key) == 0) return list; @@ -175,7 +175,7 @@ GSList *gslist_find_string(GSList *list, const char *key) return NULL; } -GSList *gslist_find_icase_string(GSList *list, const char *key) +GSList *i_slist_find_icase_string(GSList *list, const char *key) { for (; list != NULL; list = list->next) if (g_ascii_strcasecmp(list->data, key) == 0) return list; @@ -183,7 +183,7 @@ GSList *gslist_find_icase_string(GSList *list, const char *key) return NULL; } -void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data) +void *i_slist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data) { void *ret; @@ -197,7 +197,7 @@ void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data return NULL; } -void gslist_free_full (GSList *list, GDestroyNotify free_func) +void i_slist_free_full(GSList *list, GDestroyNotify free_func) { GSList *tmp; @@ -210,7 +210,7 @@ void gslist_free_full (GSList *list, GDestroyNotify free_func) g_slist_free(list); } -GSList *gslist_remove_string (GSList *list, const char *str) +GSList *i_slist_remove_string(GSList *list, const char *str) { GSList *l; @@ -221,7 +221,7 @@ GSList *gslist_remove_string (GSList *list, const char *str) return list; } -GSList *gslist_delete_string (GSList *list, const char *str, GDestroyNotify free_func) +GSList *i_slist_delete_string(GSList *list, const char *str, GDestroyNotify free_func) { GSList *l; @@ -255,7 +255,7 @@ char *gslistptr_to_string(GSList *list, int offset, const char *delimiter) } /* `list' contains char* */ -char *gslist_to_string(GSList *list, const char *delimiter) +char *i_slist_to_string(GSList *list, const char *delimiter) { GString *str; char *ret; diff --git a/src/core/misc.h b/src/core/misc.h index a441a468..0774bbba 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -19,21 +19,21 @@ int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; #pragma GCC diagnostic pop -GSList *gslist_find_string(GSList *list, const char *key); -GSList *gslist_find_icase_string(GSList *list, const char *key); +GSList *i_slist_find_string(GSList *list, const char *key); +GSList *i_slist_find_icase_string(GSList *list, const char *key); GList *glist_find_string(GList *list, const char *key); GList *glist_find_icase_string(GList *list, const char *key); -GSList *gslist_remove_string (GSList *list, const char *str) G_GNUC_DEPRECATED; -GSList *gslist_delete_string (GSList *list, const char *str, GDestroyNotify free_func); +GSList *i_slist_remove_string(GSList *list, const char *str) G_GNUC_DEPRECATED; +GSList *i_slist_delete_string(GSList *list, const char *str, GDestroyNotify free_func); -void gslist_free_full (GSList *list, GDestroyNotify free_func); +void i_slist_free_full(GSList *list, GDestroyNotify free_func); -void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data); +void *i_slist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, const void *data); /* `list' contains pointer to structure with a char* to string. */ char *gslistptr_to_string(GSList *list, int offset, const char *delimiter); /* `list' contains char* */ -char *gslist_to_string(GSList *list, const char *delimiter); +char *i_slist_to_string(GSList *list, const char *delimiter); GList *optlist_remove_known(const char *cmd, GHashTable *optlist); diff --git a/src/core/settings.c b/src/core/settings.c index 1720d922..04c7bbe6 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -613,9 +613,8 @@ void settings_check_module(const char *module) } } if (count > 0) { - if (gslist_find_icase_string(last_invalid_modules, - module) == NULL) { - /* mark this module having invalid settings */ + if (i_slist_find_icase_string(last_invalid_modules, module) == NULL) { + /* mark this module having invalid settings */ last_invalid_modules = g_slist_append(last_invalid_modules, g_strdup(module)); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index c7cdd995..be6631b3 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -357,7 +357,7 @@ static void autoconnect_servers(void) if (rec->autoconnect && (rec->chatnet == NULL || - gslist_find_icase_string(chatnets, rec->chatnet) == NULL)) { + i_slist_find_icase_string(chatnets, rec->chatnet) == NULL)) { if (rec->chatnet != NULL) { chatnets = g_slist_append(chatnets, rec->chatnet); str = g_strdup_printf("-network %s %s %d", rec->chatnet, rec->address, rec->port); diff --git a/src/fe-common/irc/fe-modes.c b/src/fe-common/irc/fe-modes.c index 9ea2414d..623fca0c 100644 --- a/src/fe-common/irc/fe-modes.c +++ b/src/fe-common/irc/fe-modes.c @@ -84,7 +84,7 @@ static void print_mode(MODE_REC *rec) tmp = modes; modes = NULL; - nicks = gslist_to_string(rec->nicks, ", "); + nicks = i_slist_to_string(rec->nicks, ", "); printformat(rec->channel->server, rec->channel->visible_name, rec->level, IRCTXT_CHANMODE_CHANGE, rec->channel->visible_name, rec->mode, nicks, ""); g_free(nicks); diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c index f6d9e4b3..ea41f7fa 100644 --- a/src/fe-common/irc/fe-netjoin.c +++ b/src/fe-common/irc/fe-netjoin.c @@ -212,8 +212,7 @@ static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channe } /* remove the channel from old_channels too */ - old = gslist_find_icase_string(rec->old_channels, - realchannel); + old = i_slist_find_icase_string(rec->old_channels, realchannel); if (old != NULL) { void *data = old->data; rec->old_channels = @@ -340,7 +339,7 @@ static void msg_join(IRC_SERVER_REC *server, const char *channel, /* if this was not a channel they split from, treat it normally */ if (netjoin != NULL) { - if (!gslist_find_icase_string(netjoin->old_channels, channel)) + if (!i_slist_find_icase_string(netjoin->old_channels, channel)) return; } else { channels = split->channels; diff --git a/src/fe-common/irc/notifylist/fe-notifylist.c b/src/fe-common/irc/notifylist/fe-notifylist.c index 579b1824..68b98a09 100644 --- a/src/fe-common/irc/notifylist/fe-notifylist.c +++ b/src/fe-common/irc/notifylist/fe-notifylist.c @@ -46,7 +46,7 @@ static GSList *mask_add_once(GSList *list, const char *mask) str = ptr == NULL ? g_strdup(mask) : g_strndup(mask, (int) (ptr-mask)); - if (gslist_find_icase_string(list, str) == NULL) + if (i_slist_find_icase_string(list, str) == NULL) return g_slist_append(list, str); g_free(str); diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index bcf5b5df..61a80066 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -31,19 +31,18 @@ int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) /* If the negotiation hasn't been completed yet just queue the requests */ if (!server->cap_complete) { - if (enable && !gslist_find_string(server->cap_queue, cap)) { + if (enable && !i_slist_find_string(server->cap_queue, cap)) { server->cap_queue = g_slist_prepend(server->cap_queue, g_strdup(cap)); return TRUE; - } - else if (!enable && gslist_find_string(server->cap_queue, cap)) { - server->cap_queue = gslist_delete_string(server->cap_queue, cap, g_free); + } else if (!enable && i_slist_find_string(server->cap_queue, cap)) { + server->cap_queue = i_slist_delete_string(server->cap_queue, cap, g_free); return TRUE; } return FALSE; } - if (enable && !gslist_find_string(server->cap_active, cap)) { + if (enable && !i_slist_find_string(server->cap_active, cap)) { /* Make sure the required cap is supported by the server */ if (!g_hash_table_lookup_extended(server->cap_supported, cap, NULL, NULL)) return FALSE; @@ -51,8 +50,7 @@ int irc_cap_toggle (IRC_SERVER_REC *server, char *cap, int enable) signal_emit("server cap req", 2, server, cap); irc_send_cmdv(server, "CAP REQ %s", cap); return TRUE; - } - else if (!enable && gslist_find_string(server->cap_active, cap)) { + } else if (!enable && i_slist_find_string(server->cap_active, cap)) { char *negcap = g_strdup_printf("-%s", cap); signal_emit("server cap req", 2, server, negcap); @@ -200,7 +198,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add } /* Clear the queue here */ - gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); + i_slist_free_full(server->cap_queue, (GDestroyNotify) g_free); server->cap_queue = NULL; /* If the server doesn't support any cap we requested close the negotiation here */ @@ -223,8 +221,9 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add disable = (*caps[i] == '-'); if (disable) - server->cap_active = gslist_delete_string(server->cap_active, caps[i] + 1, g_free); - else if (!gslist_find_string(server->cap_active, caps[i])) + server->cap_active = + i_slist_delete_string(server->cap_active, caps[i] + 1, g_free); + else if (!i_slist_find_string(server->cap_active, caps[i])) server->cap_active = g_slist_prepend(server->cap_active, g_strdup(caps[i])); if (!strcmp(caps[i], "sasl")) @@ -273,7 +272,7 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add cap_emit_signal(server, "delete", key); /* The server removed this CAP, remove it from the list * of the active ones if we had requested it */ - server->cap_active = gslist_delete_string(server->cap_active, key, g_free); + server->cap_active = i_slist_delete_string(server->cap_active, key, g_free); /* We don't transfer the ownership of those two * variables this time, just free them when we're done. */ g_free(key); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index fa02094e..cde6a4fc 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -443,7 +443,7 @@ static void sig_destroyed(IRC_SERVER_REC *server) g_slist_free(server->cmdqueue); server->cmdqueue = NULL; - gslist_free_full(server->cap_active, (GDestroyNotify) g_free); + i_slist_free_full(server->cap_active, (GDestroyNotify) g_free); server->cap_active = NULL; if (server->cap_supported) { @@ -451,7 +451,7 @@ static void sig_destroyed(IRC_SERVER_REC *server) server->cap_supported = NULL; } - gslist_free_full(server->cap_queue, (GDestroyNotify) g_free); + i_slist_free_full(server->cap_queue, (GDestroyNotify) g_free); server->cap_queue = NULL; /* was g_free_and_null, but can't use on a GString */ diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c index 770aa4c2..2790c75a 100644 --- a/src/irc/core/servers-redirect.c +++ b/src/irc/core/servers-redirect.c @@ -219,7 +219,7 @@ static char *signal_list_move(GSList **signals, const char *event) GSList *link; char *linkevent, *linksignal; - link = gslist_find_string(*signals, event); + link = i_slist_find_string(*signals, event); if (link == NULL) return NULL; diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index 4c276ac6..bb1c6c22 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -55,7 +55,7 @@ void dcc_unregister_type(const char *type) { GSList *pos; - pos = gslist_find_string(dcc_types, type); + pos = i_slist_find_string(dcc_types, type); if (pos != NULL) { void *tmp = pos->data; dcc_types = g_slist_remove(dcc_types, pos->data); @@ -65,7 +65,7 @@ void dcc_unregister_type(const char *type) int dcc_str2type(const char *str) { - if (gslist_find_string(dcc_types, str) == NULL) + if (i_slist_find_string(dcc_types, str) == NULL) return -1; return module_get_uniq_id_str("DCC", str); diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index 910c0b73..32316038 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -279,7 +279,7 @@ static void ison_check_parts(IRC_SERVER_REC *server) NOTIFY_NICK_REC *rec = tmp->data; next = tmp->next; - if (gslist_find_icase_string(mserver->ison_tempusers, rec->nick) != NULL) + if (i_slist_find_icase_string(mserver->ison_tempusers, rec->nick) != NULL) continue; notifylist_left(server, rec); diff --git a/src/perl/common/Settings.xs b/src/perl/common/Settings.xs index d1bce856..20596c86 100644 --- a/src/perl/common/Settings.xs +++ b/src/perl/common/Settings.xs @@ -26,7 +26,7 @@ static void perl_settings_remove(const char *key) g_return_if_fail(script != NULL); list = g_hash_table_lookup(perl_settings, script); - pos = gslist_find_icase_string(list, key); + pos = i_slist_find_icase_string(list, key); if (pos != NULL) { list = g_slist_remove(list, pos->data); g_hash_table_insert(perl_settings, script, list); diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index 0c2b90e7..7eaab8eb 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -664,7 +664,7 @@ static void perl_unregister_protocol(CHAT_PROTOCOL_REC *rec) GSList *item; void *data; - item = gslist_find_icase_string(use_protocols, rec->name); + item = i_slist_find_icase_string(use_protocols, rec->name); if (item != NULL) { data = item->data; use_protocols = g_slist_remove(use_protocols, data); From aa653aa3892b363d32b9096ff17a1083f2a60102 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 7 Jan 2021 10:09:29 +0100 Subject: [PATCH 0727/1198] correct wrong function prefixes: glog_func -> i_log_func --- src/fe-common/core/fe-common-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index be6631b3..8f412198 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -254,8 +254,7 @@ void fe_common_core_deinit(void) signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); } -void glog_func(const char *log_domain, GLogLevelFlags log_level, - const char *message) +void i_log_func(const char *log_domain, GLogLevelFlags log_level, const char *message) { const char *reason; @@ -459,7 +458,7 @@ void fe_common_core_finish_init(void) signal_add_first("setup changed", (SIGNAL_FUNC) sig_setup_changed); /* _after_ windows are created.. */ - g_log_set_default_handler((GLogFunc) glog_func, NULL); + g_log_set_default_handler((GLogFunc) i_log_func, NULL); if (setup_changed) signal_emit("setup changed", 0); From 504cf217838052204fac34547efcef72af9c58a5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 15:50:34 +0100 Subject: [PATCH 0728/1198] correct wrong function prefixes: remove g_free_true --- src/fe-text/textbuffer-view.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index bc7cc5a8..9af3cb3c 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -1376,12 +1376,6 @@ void textbuffer_view_remove_lines_by_level(TEXT_BUFFER_VIEW_REC *view, int level term_refresh_thaw(); } -static int g_free_true(void *data) -{ - g_free(data); - return TRUE; -} - /* Remove all lines from buffer. */ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view) { @@ -1389,8 +1383,8 @@ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view) textbuffer_remove_all_lines(view->buffer); - g_hash_table_foreach_remove(view->bookmarks, - (GHRFunc) g_free_true, NULL); + g_hash_table_foreach(view->bookmarks, (GHFunc) g_free, NULL); + g_hash_table_remove_all(view->bookmarks); textbuffer_view_reset_cache(view); textbuffer_view_clear(view); From 68da49db784591139b1b45a61231286347eb6eaf Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 4 Jan 2021 16:18:54 +0100 Subject: [PATCH 0729/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 02bdbeb8..bb339f1f 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 32 +#define IRSSI_ABI_VERSION 33 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 16b1d587036d4becc71bfeec202f83bed1362884 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 7 Jan 2021 09:12:17 +0100 Subject: [PATCH 0730/1198] Abort Irssi on wrong entries in the channels or servers config --- src/core/channels-setup.c | 13 +++++++++++-- src/core/servers-setup.c | 13 +++++++++++-- src/fe-text/irssi.c | 25 ++++++++++++++++++++----- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index cd323a84..c72f057c 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -207,9 +207,18 @@ static void channels_read_config(void) /* Read channels */ node = iconfig_node_traverse("channels", FALSE); if (node != NULL) { + int i = 0; tmp = config_node_first(node->value); - for (; tmp != NULL; tmp = config_node_next(tmp)) - channel_setup_read(tmp->data); + for (; tmp != NULL; tmp = config_node_next(tmp), i++) { + node = tmp->data; + if (node->type != NODE_TYPE_BLOCK) { + g_critical("Expected block node at `channels[%d]' was of %s type. " + "Corrupt config?", + i, node->type == NODE_TYPE_LIST ? "list" : "scalar"); + } else { + channel_setup_read(node); + } + } } } diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 6e4e238a..43653c43 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -625,9 +625,18 @@ static void read_servers(void) /* Read servers */ node = iconfig_node_traverse("servers", FALSE); if (node != NULL) { + int i = 0; tmp = config_node_first(node->value); - for (; tmp != NULL; tmp = config_node_next(tmp)) - server_setup_read(tmp->data); + for (; tmp != NULL; tmp = config_node_next(tmp), i++) { + node = tmp->data; + if (node->type != NODE_TYPE_BLOCK) { + g_critical("Expected block node at `servers[%d]' was of %s type. " + "Corrupt config?", + i, node->type == NODE_TYPE_LIST ? "list" : "scalar"); + } else { + server_setup_read(node); + } + } } } diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 1b891522..5c20eb37 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -162,6 +162,16 @@ static void textui_init(void) signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit); } +static int critical_fatal_section_begin(void) +{ + return g_log_set_always_fatal(G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL); +} + +static void critical_fatal_section_end(int loglev) +{ + g_log_set_always_fatal(loglev); +} + static void textui_finish_init(void) { int loglev; @@ -182,10 +192,9 @@ static void textui_finish_init(void) mainwindows_layout_init(); gui_windows_init(); /* Temporarily raise the fatal level to abort on config errors. */ - loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL); + loglev = critical_fatal_section_begin(); statusbar_init(); - g_log_set_always_fatal(loglev); - term_refresh_thaw(); + critical_fatal_section_end(loglev); settings_check(); @@ -202,7 +211,12 @@ static void textui_finish_init(void) dirty_check(); + /* Temporarily raise the fatal level to abort on config errors. */ + loglev = critical_fatal_section_begin(); fe_common_core_finish_init(); + critical_fatal_section_end(loglev); + term_refresh_thaw(); + signal_emit("irssi init finished", 0); statusbar_redraw(NULL, TRUE); @@ -329,7 +343,7 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); /* Temporarily raise the fatal level to abort on config errors. */ - loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL); + loglev = critical_fatal_section_begin(); textui_init(); if (!term_init()) { @@ -337,7 +351,8 @@ int main(int argc, char **argv) return 1; } - g_log_set_always_fatal(loglev); + critical_fatal_section_end(loglev); + textui_finish_init(); main_loop = g_main_loop_new(NULL, TRUE); From 4db0535b32d85821974f3e8f8dd598575b9870b3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 7 Jan 2021 18:31:41 +0100 Subject: [PATCH 0731/1198] undraft setname --- src/irc/core/irc-servers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index b7d31038..e775e505 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -20,7 +20,7 @@ #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" #define CAP_EXTENDED_JOIN "extended-join" -#define CAP_SETNAME "draft/setname" +#define CAP_SETNAME "setname" #define CAP_INVITE_NOTIFY "invite-notify" #define CAP_AWAY_NOTIFY "away-notify" #define CAP_CHGHOST "chghost" From b7bea3d2f38f47e2917134ef2509e44042457513 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 7 Jan 2021 20:00:26 +0100 Subject: [PATCH 0732/1198] Update ignore.in --- docs/help/in/ignore.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/help/in/ignore.in b/docs/help/in/ignore.in index cb2393d2..0fbf970d 100644 --- a/docs/help/in/ignore.in +++ b/docs/help/in/ignore.in @@ -37,13 +37,13 @@ /IGNORE #irssi ALL -PUBLIC -ACTIONS /IGNORE -replies *!*@*.irssi.org ALL /IGNORE -regexp -pattern (away|gone|back|playing|returned) * ACTIONS + /IGNORE -regexp -pattern (away|gone|back|playing|returned) #channel ACTIONS /IGNORE *zzz* NICKS /IGNORE *afk* NICKS /IGNORE *away* NICKS /IGNORE #irssi NO_ACT JOINS PARTS QUITS /IGNORE mike NO_ACT -MSGS /IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS - /IGNORE -regexp -pattern %9See also:%9 ACCEPT, SILENCE, UNIGNORE From a76debde58439fcb0f4d51633f8b60c00671fe51 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 20 Jan 2021 09:58:25 +0100 Subject: [PATCH 0733/1198] unfix breakage in python setuptools see pypa/setuptools#2541 --- .github/workflows/check.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 55499ce3..038d2416 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -8,7 +8,7 @@ env: apt_build_deps: libutf8proc-dev libperl-dev libotr5-dev apt_build_deps_meson: ninja-build apt_build_deps_autotools: autoconf automake libtool - get_pip_build_deps_meson: pip3 install setuptools; pip3 install wheel; pip3 install meson${meson_ver:+==${meson_ver}} + get_pip_build_deps_meson: pip3 install setuptools${setuptools_ver}; pip3 install wheel; pip3 install meson${meson_ver} build_options_meson: -Dwith-proxy=yes -Dwith-bot=yes -Dwith-perl=yes -Dwith-otr=yes build_options_configure: --with-proxy=module --with-bot --with-perl=module --with-otr=module prefix: ~/irssi-build @@ -42,7 +42,8 @@ jobs: include: - os: ubuntu-16.04 builder: meson - meson_ver: 0.49.2 + meson_ver: ==0.49.2 + setuptools_ver: <51 steps: - name: fetch dist uses: actions/download-artifact@v2 @@ -52,6 +53,7 @@ jobs: - name: prepare required software env: meson_ver: ${{ matrix.meson_ver }} + setuptools_ver: ${{ matrix.setuptools_ver }} run: | sudo apt install $apt_build_deps $apt_build_deps_${{ matrix.builder }} eval "$get_pip_build_deps_${{ matrix.builder }}" From feb83b20584b4e33a9a5427841995d8311fc6aee Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 30 Jan 2021 23:21:14 +0100 Subject: [PATCH 0734/1198] two more wrong prefixes --- src/core/misc.c | 4 ++-- src/core/misc.h | 4 ++-- src/fe-common/core/chat-completion.c | 16 ++++++++-------- src/fe-common/core/completion.c | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 576d23f2..c66bbd6d 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -293,7 +293,7 @@ GList *optlist_remove_known(const char *cmd, GHashTable *optlist) return list; } -GList *glist_find_string(GList *list, const char *key) +GList *i_list_find_string(GList *list, const char *key) { for (; list != NULL; list = list->next) if (g_strcmp0(list->data, key) == 0) return list; @@ -301,7 +301,7 @@ GList *glist_find_string(GList *list, const char *key) return NULL; } -GList *glist_find_icase_string(GList *list, const char *key) +GList *i_list_find_icase_string(GList *list, const char *key) { for (; list != NULL; list = list->next) if (g_ascii_strcasecmp(list->data, key) == 0) return list; diff --git a/src/core/misc.h b/src/core/misc.h index 0774bbba..76f5644b 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -21,8 +21,8 @@ long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATE GSList *i_slist_find_string(GSList *list, const char *key); GSList *i_slist_find_icase_string(GSList *list, const char *key); -GList *glist_find_string(GList *list, const char *key); -GList *glist_find_icase_string(GList *list, const char *key); +GList *i_list_find_string(GList *list, const char *key); +GList *i_list_find_icase_string(GList *list, const char *key); GSList *i_slist_remove_string(GSList *list, const char *str) G_GNUC_DEPRECATED; GSList *i_slist_delete_string(GSList *list, const char *str, GDestroyNotify free_func); diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index fb052f7f..be16db7e 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -374,10 +374,10 @@ static void complete_from_nicklist(GList **outlist, CHANNEL_REC *channel, for (tmp = mchannel->lastmsgs; tmp != NULL; tmp = tmp->next) { LAST_MSG_REC *rec = tmp->data; - if ((match_case? strncmp(rec->nick, nick, len) - : g_ascii_strncasecmp(rec->nick, nick, len)) == 0 && - (match_case? glist_find_string(*outlist, rec->nick) - : glist_find_icase_string(*outlist, rec->nick)) == NULL) { + if ((match_case ? strncmp(rec->nick, nick, len) : + g_ascii_strncasecmp(rec->nick, nick, len)) == 0 && + (match_case ? i_list_find_string(*outlist, rec->nick) : + i_list_find_icase_string(*outlist, rec->nick)) == NULL) { str = g_strconcat(rec->nick, suffix, NULL); if (completion_lowercase) ascii_strdown(str); if (rec->own) @@ -435,7 +435,7 @@ static GList *completion_nicks_nonstrict(CHANNEL_REC *channel, if (completion_lowercase) ascii_strdown(tnick); - if (glist_find_icase_string(list, tnick) == NULL) + if (i_list_find_icase_string(list, tnick) == NULL) list = g_list_append(list, tnick); else g_free(tnick); @@ -482,7 +482,7 @@ static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, str = g_strconcat(rec->nick, suffix, NULL); if (completion_lowercase) ascii_strdown(str); - if (glist_find_icase_string(list, str) == NULL) + if (i_list_find_icase_string(list, str) == NULL) list = g_list_append(list, str); else g_free(str); @@ -505,7 +505,7 @@ static GList *completion_joinlist(GList *list1, GList *list2) old = list2; while (list2 != NULL) { - if (!glist_find_icase_string(list1, list2->data)) + if (!i_list_find_icase_string(list1, list2->data)) list1 = g_list_append(list1, list2->data); else g_free(list2->data); @@ -570,7 +570,7 @@ GList *completion_get_channels(SERVER_REC *server, const char *word) CHANNEL_SETUP_REC *rec = tmp->data; if (g_ascii_strncasecmp(rec->name, word, len) == 0 && - glist_find_icase_string(list, rec->name) == NULL) + i_list_find_icase_string(list, rec->name) == NULL) list = g_list_append(list, g_strdup(rec->name)); } diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index a897c452..06ac124c 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -460,7 +460,7 @@ static GList *completion_get_aliases(const char *alias, char cmdchar) /* add matching alias to completion list, aliases will be appended after command completions and kept in uppercase to show it's an alias */ - if (glist_find_icase_string(complist, word) == NULL) + if (i_list_find_icase_string(complist, word) == NULL) complist = g_list_insert_sorted(complist, word, (GCompareFunc) i_istr_cmp); else @@ -490,7 +490,7 @@ static GList *completion_get_commands(const char *cmd, char cmdchar) if (g_ascii_strncasecmp(rec->cmd, cmd, len) == 0) { word = cmdchar == '\0' ? g_strdup(rec->cmd) : g_strdup_printf("%c%s", cmdchar, rec->cmd); - if (glist_find_icase_string(complist, word) == NULL) + if (i_list_find_icase_string(complist, word) == NULL) complist = g_list_insert_sorted(complist, word, (GCompareFunc) i_istr_cmp); else From e7f3946583f1f0fbd5c1847ba717130149cf54e8 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 2 Feb 2021 00:24:34 +0100 Subject: [PATCH 0735/1198] configure automake with nostdinc the current directoryh won't be added to the compiler's -I path --- configure.ac | 2 +- src/core/Makefile.am | 1 + src/fe-common/core/Makefile.am | 1 + src/fe-common/irc/Makefile.am | 1 + src/fe-common/irc/dcc/Makefile.am | 1 + src/fe-common/irc/notifylist/Makefile.am | 1 + src/fe-fuzz/Makefile.am | 1 + src/fe-fuzz/fe-common/core/Makefile.am | 1 + src/fe-fuzz/irc/core/Makefile.am | 1 + src/fe-none/Makefile.am | 1 + src/fe-text/Makefile.am | 1 + src/irc/core/Makefile.am | 1 + src/irc/dcc/Makefile.am | 1 + src/irc/flood/Makefile.am | 1 + src/irc/notifylist/Makefile.am | 1 + src/irc/proxy/Makefile.am | 1 + src/lib-config/Makefile.am | 1 + src/otr/Makefile.am | 1 + src/perl/Makefile.am | 2 ++ tests/fe-common/core/Makefile.am | 1 + tests/fe-text/Makefile.am | 1 + tests/irc/core/Makefile.am | 1 + tests/irc/flood/Makefile.am | 1 + 23 files changed, 24 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 453fcd33..cafd2970 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_PREREQ(2.50) AC_CONFIG_HEADERS([irssi-config.h]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.9 no-define foreign subdir-objects]) +AM_INIT_AUTOMAKE([1.9 no-define foreign subdir-objects nostdinc]) AM_SILENT_RULES([yes]) diff --git a/src/core/Makefile.am b/src/core/Makefile.am index b49dad18..493c42b2 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libcore.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DMODULEDIR=\""$(libdir)/irssi/modules"\" diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am index 7e76d3a0..01e934e0 100644 --- a/src/fe-common/core/Makefile.am +++ b/src/fe-common/core/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libfe_common_core.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DTHEMESDIR=\""$(datadir)/irssi/themes"\" diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am index 401720f6..8a04bee4 100644 --- a/src/fe-common/irc/Makefile.am +++ b/src/fe-common/irc/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = dcc notifylist noinst_LIBRARIES = libfe_common_irc.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-common/irc/dcc/Makefile.am b/src/fe-common/irc/dcc/Makefile.am index 0be3cffa..feee349d 100644 --- a/src/fe-common/irc/dcc/Makefile.am +++ b/src/fe-common/irc/dcc/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libfe_irc_dcc.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-common/irc/notifylist/Makefile.am b/src/fe-common/irc/notifylist/Makefile.am index 6fca7676..5eecb5fb 100644 --- a/src/fe-common/irc/notifylist/Makefile.am +++ b/src/fe-common/irc/notifylist/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libfe_irc_notifylist.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ -DHELPDIR=\""$(datadir)/irssi/help"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" diff --git a/src/fe-fuzz/Makefile.am b/src/fe-fuzz/Makefile.am index d54c3291..3efa83b6 100644 --- a/src/fe-fuzz/Makefile.am +++ b/src/fe-fuzz/Makefile.am @@ -6,6 +6,7 @@ bin_PROGRAMS = irssi-fuzz server-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) irssi_fuzz_DEPENDENCIES = @COMMON_LIBS@ diff --git a/src/fe-fuzz/fe-common/core/Makefile.am b/src/fe-fuzz/fe-common/core/Makefile.am index 8fcd59b3..8f6ae477 100644 --- a/src/fe-fuzz/fe-common/core/Makefile.am +++ b/src/fe-fuzz/fe-common/core/Makefile.am @@ -4,6 +4,7 @@ bin_PROGRAMS = theme-load-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) LDADD = \ diff --git a/src/fe-fuzz/irc/core/Makefile.am b/src/fe-fuzz/irc/core/Makefile.am index 33f7664d..9221e29e 100644 --- a/src/fe-fuzz/irc/core/Makefile.am +++ b/src/fe-fuzz/irc/core/Makefile.am @@ -4,6 +4,7 @@ bin_PROGRAMS = event-get-params-fuzz CCLD=$(CXX) $(CXXFLAGS) AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) LDADD = \ diff --git a/src/fe-none/Makefile.am b/src/fe-none/Makefile.am index 44c23d6e..bbcd63f8 100644 --- a/src/fe-none/Makefile.am +++ b/src/fe-none/Makefile.am @@ -1,6 +1,7 @@ bin_PROGRAMS = botti AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) botti_DEPENDENCIES = @COMMON_NOUI_LIBS@ diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index c7044ba9..d97cbfa5 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -1,6 +1,7 @@ bin_PROGRAMS = irssi AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) irssi_DEPENDENCIES = \ diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am index 858d7fcb..5881481b 100644 --- a/src/irc/core/Makefile.am +++ b/src/irc/core/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libirc_core.a AM_CPPFLAGS = \ + -I$(top_builddir) \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) diff --git a/src/irc/dcc/Makefile.am b/src/irc/dcc/Makefile.am index 887a65d2..c5592f7f 100644 --- a/src/irc/dcc/Makefile.am +++ b/src/irc/dcc/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libirc_dcc.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) libirc_dcc_a_SOURCES = \ diff --git a/src/irc/flood/Makefile.am b/src/irc/flood/Makefile.am index 7a49001d..4b37cede 100644 --- a/src/irc/flood/Makefile.am +++ b/src/irc/flood/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libirc_flood.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) libirc_flood_a_SOURCES = \ diff --git a/src/irc/notifylist/Makefile.am b/src/irc/notifylist/Makefile.am index 9bc0fd8b..3f913d58 100644 --- a/src/irc/notifylist/Makefile.am +++ b/src/irc/notifylist/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libirc_notifylist.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) libirc_notifylist_a_SOURCES = \ diff --git a/src/irc/proxy/Makefile.am b/src/irc/proxy/Makefile.am index 2e7259ad..437a6dc0 100644 --- a/src/irc/proxy/Makefile.am +++ b/src/irc/proxy/Makefile.am @@ -2,6 +2,7 @@ moduledir = $(libdir)/irssi/modules module_LTLIBRARIES = libirc_proxy.la AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) libirc_proxy.a: diff --git a/src/lib-config/Makefile.am b/src/lib-config/Makefile.am index 4912aa9b..cd319edb 100644 --- a/src/lib-config/Makefile.am +++ b/src/lib-config/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libirssi_config.a AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) libirssi_config_a_SOURCES = \ diff --git a/src/otr/Makefile.am b/src/otr/Makefile.am index 149b952d..b9b82d9a 100644 --- a/src/otr/Makefile.am +++ b/src/otr/Makefile.am @@ -8,6 +8,7 @@ EXTRA_LTLIBRARIES = \ libotr_core_static.la AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) \ $(OTR_CFLAGS) diff --git a/src/perl/Makefile.am b/src/perl/Makefile.am index ad937457..ca81d3c6 100644 --- a/src/perl/Makefile.am +++ b/src/perl/Makefile.am @@ -15,6 +15,8 @@ perl-core.lo: irssi-core.pl.h perl-signals.lo: perl-signals-list.h AM_CPPFLAGS = \ + -I$(top_builddir) \ + -I$(builddir) \ $(GLIB_CFLAGS) \ -DSCRIPTDIR=\""$(datadir)/irssi/scripts"\" \ -DPERL_USE_LIB=\""$(PERL_USE_LIB)"\" \ diff --git a/tests/fe-common/core/Makefile.am b/tests/fe-common/core/Makefile.am index eb7e2c7f..15287601 100644 --- a/tests/fe-common/core/Makefile.am +++ b/tests/fe-common/core/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=fe-common/core AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) test_programs = test-formats diff --git a/tests/fe-text/Makefile.am b/tests/fe-text/Makefile.am index 8f44dded..a0e1d0f5 100644 --- a/tests/fe-text/Makefile.am +++ b/tests/fe-text/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=fe-text AM_CPPFLAGS = \ + -I$(top_builddir) \ $(GLIB_CFLAGS) test_programs = test-paste-join-multiline diff --git a/tests/irc/core/Makefile.am b/tests/irc/core/Makefile.am index fbf001da..503989a9 100644 --- a/tests/irc/core/Makefile.am +++ b/tests/irc/core/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=irc/core AM_CPPFLAGS = \ + -I$(top_builddir) \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) diff --git a/tests/irc/flood/Makefile.am b/tests/irc/flood/Makefile.am index f815504d..6c4eec84 100644 --- a/tests/irc/flood/Makefile.am +++ b/tests/irc/flood/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/utils/glib-tap.mk PACKAGE_STRING=irc/flood AM_CPPFLAGS = \ + -I$(top_builddir) \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ $(GLIB_CFLAGS) From 33bfd88d9ecb6a89992d9c3c7bc5ec9665c3538c Mon Sep 17 00:00:00 2001 From: ihsinme <61293369+ihsinme@users.noreply.github.com> Date: Fri, 5 Feb 2021 18:34:54 +0300 Subject: [PATCH 0736/1198] Update gui-entry.c --- 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 d1cc8811..4fde83c8 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -835,7 +835,7 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ } if (entry->utf8) - while (entry->pos-size-w > 0 && + while (entry->pos > size-w && i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; memmove(entry->text + entry->pos - size, entry->text + entry->pos, From 5e88c107f1bfeee9a0f62a5a47017b47f69f9c47 Mon Sep 17 00:00:00 2001 From: ihsinme <61293369+ihsinme@users.noreply.github.com> Date: Fri, 5 Feb 2021 18:36:15 +0300 Subject: [PATCH 0737/1198] Update gui-entry.c --- 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 4fde83c8..3995319e 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -835,7 +835,7 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ } if (entry->utf8) - while (entry->pos > size-w && + while (entry->pos > size+w && i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; memmove(entry->text + entry->pos - size, entry->text + entry->pos, From 39ed1ba0552ea03239cd056cb788ba51e47bef75 Mon Sep 17 00:00:00 2001 From: ihsinme <61293369+ihsinme@users.noreply.github.com> Date: Fri, 5 Feb 2021 22:48:43 +0300 Subject: [PATCH 0738/1198] Update gui-entry.c --- src/fe-text/gui-entry.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 3995319e..25965495 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -835,8 +835,8 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_ } if (entry->utf8) - while (entry->pos > size+w && - i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++; + while (entry->pos > size + w && i_wcwidth(entry->text[entry->pos - size - w]) == 0) + w++; memmove(entry->text + entry->pos - size, entry->text + entry->pos, (entry->text_len-entry->pos+1) * sizeof(unichar)); From 23e4bfa1db0bc3397e74ea0f075f90a7e40350ac Mon Sep 17 00:00:00 2001 From: ihsinme <61293369+ihsinme@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:17:09 +0300 Subject: [PATCH 0739/1198] Update write-buffer.c --- src/core/write-buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/write-buffer.c b/src/core/write-buffer.c index 475e41b8..a1401542 100644 --- a/src/core/write-buffer.c +++ b/src/core/write-buffer.c @@ -63,14 +63,14 @@ int write_buffer(int handle, const void *data, int size) const char *cdata = data; int next_size; + if (size <= 0) + return size; + if (write_buffer_max_blocks <= 0) { /* no write buffer */ return write(handle, data, size); } - if (size <= 0) - return size; - rec = g_hash_table_lookup(buffers, GINT_TO_POINTER(handle)); if (rec == NULL) { rec = g_new0(BUFFER_REC, 1); From a426d669dc729a78f862db52754ed968a17ab818 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 18 Feb 2021 14:47:07 +0100 Subject: [PATCH 0740/1198] Update dcc-get.c --- src/irc/dcc/dcc-get.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c index 5af557ea..0214387b 100644 --- a/src/irc/dcc/dcc-get.c +++ b/src/irc/dcc/dcc-get.c @@ -177,6 +177,7 @@ static void sig_dccget_receive(GET_DCC_REC *dcc) return; } dcc->transfd += ret; + break; } /* send number of total bytes received */ From ccf59868e244cd2ff88eb851f7e959a357aa8df0 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 24 Feb 2021 21:57:11 +0100 Subject: [PATCH 0741/1198] update deprecated GLib symbol g_main_quit -> g_main_loop_quit --- src/fe-none/irssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-none/irssi.c b/src/fe-none/irssi.c index e7b4c427..6a02ff6a 100644 --- a/src/fe-none/irssi.c +++ b/src/fe-none/irssi.c @@ -39,7 +39,7 @@ static int reload; static void sig_exit(void) { - g_main_quit(main_loop); + g_main_loop_quit(main_loop); } static void sig_reload(void) From 33d8cc3254bd8b2232efeb0b91eb52719c5d5e41 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Mon, 6 Apr 2020 11:55:57 +0200 Subject: [PATCH 0742/1198] GLib < 2.56 compat code for g_date_time_new_from_iso8601 --- src/fe-text/textbuffer-formats.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 84aaebb9..17ec118a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -16,6 +16,21 @@ TEXT_BUFFER_REC *color_buf; int scrollback_format; +#if GLIB_CHECK_VERSION(2, 56, 0) +/* nothing */ +#else +/* compatibility code for old GLib */ +static GDateTime *g_date_time_new_from_iso8601(const gchar *iso_date, GTimeZone *default_tz) +{ + GTimeVal time; + if (g_time_val_from_iso8601(iso_date, &time)) { + return g_date_time_new_from_timeval_utc(&time); + } else { + return NULL; + } +} +#endif + static void collector_free(GSList **collector) { while (*collector) { From d535a79730ea291a1dfe9f5be190009eecc1e275 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Tue, 20 Aug 2019 01:47:52 +0200 Subject: [PATCH 0743/1198] implement server-time --- src/core/expandos.c | 24 +++++++-- src/core/expandos.h | 1 + src/core/refstrings.c | 11 +++- src/core/refstrings.h | 2 + src/core/server-rec.h | 3 ++ src/core/servers.c | 25 ++++++++- src/core/servers.h | 7 +++ src/fe-common/core/formats.c | 26 ++++++---- src/fe-common/core/formats.h | 1 + src/fe-text/gui-printtext.c | 9 ++-- src/fe-text/textbuffer-formats.c | 76 ++++++++++++++++++++++++--- src/fe-text/textbuffer-formats.h | 6 +++ src/fe-text/textbuffer.c | 18 ++++--- src/fe-text/textbuffer.h | 2 + src/irc/core/irc-servers.c | 1 + src/irc/core/irc-servers.h | 1 + src/irc/core/irc.c | 89 +++++++++++++++++++++++++++++--- src/irc/core/irc.h | 3 ++ src/perl/common/Server.xs | 14 +++++ src/perl/irc/Irc.xs | 21 +++++++- src/perl/textui/TextBuffer.xs | 26 ++++++++++ 21 files changed, 325 insertions(+), 41 deletions(-) diff --git a/src/core/expandos.c b/src/core/expandos.c index 9280b6f3..0f317e51 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -48,6 +48,7 @@ typedef struct { } EXPANDO_REC; const char *current_expando = NULL; +time_t reference_time = (time_t) -1; time_t current_time = (time_t)-1; static int timer_tag; @@ -59,6 +60,7 @@ static char *last_privmsg_from, *last_public_from; static char *sysname, *sysrelease, *sysarch; static char *timestamp_format; +static char *timestamp_format_alt; static int timestamp_seconds; static time_t last_timestamp; @@ -441,12 +443,24 @@ static char *expando_time(SERVER_REC *server, void *item, int *free_ret) time_t now; struct tm *tm; char str[256]; + char *format; - now = current_time != (time_t)-1 ? current_time : time(NULL); + now = current_time != (time_t) -1 ? current_time : time(NULL); tm = localtime(&now); + format = timestamp_format; - if (strftime(str, sizeof(str), timestamp_format, tm) == 0) - return ""; + if (reference_time != (time_t) -1) { + time_t ref = reference_time; + struct tm tm_ref; + if (localtime_r(&ref, &tm_ref)) { + if (tm_ref.tm_yday != tm->tm_yday || tm_ref.tm_year != tm->tm_year) { + format = timestamp_format_alt; + } + } + } + + if (strftime(str, sizeof(str), format, tm) == 0) + return ""; *free_ret = TRUE; return g_strdup(str); @@ -576,7 +590,9 @@ static int sig_timer(void) static void read_settings(void) { g_free_not_null(timestamp_format); + g_free_not_null(timestamp_format_alt); timestamp_format = g_strdup(settings_get_str("timestamp_format")); + timestamp_format_alt = g_strdup(settings_get_str("timestamp_format_alt")); timestamp_seconds = strstr(timestamp_format, "%r") != NULL || @@ -594,6 +610,7 @@ void expandos_init(void) #endif settings_add_str("misc", "STATUS_OPER", "*"); settings_add_str("lookandfeel", "timestamp_format", "%H:%M"); + settings_add_str("lookandfeel", "timestamp_format_alt", "%a %e %b %H:%M"); settings_add_bool("lookandfeel", "chanmode_expando_strip", FALSE); last_sent_msg = NULL; last_sent_msg_body = NULL; @@ -730,6 +747,7 @@ void expandos_deinit(void) g_free_not_null(sysrelease); g_free_not_null(sysarch); g_free_not_null(timestamp_format); + g_free_not_null(timestamp_format_alt); g_source_remove(timer_tag); signal_remove("message public", (SIGNAL_FUNC) sig_message_public); diff --git a/src/core/expandos.h b/src/core/expandos.h index c03333a7..17cee608 100644 --- a/src/core/expandos.h +++ b/src/core/expandos.h @@ -18,6 +18,7 @@ typedef char* (*EXPANDO_FUNC) extern const char *current_expando; extern time_t current_time; +extern time_t reference_time; /* Create expando - overrides any existing ones. ... = signal, type, ..., NULL - list of signals that might change the diff --git a/src/core/refstrings.c b/src/core/refstrings.c index 4b675fa5..8391766d 100644 --- a/src/core/refstrings.c +++ b/src/core/refstrings.c @@ -3,7 +3,16 @@ #include #if GLIB_CHECK_VERSION(2, 58, 0) -/* nothing */ + +/* callback implementation for GHashTable */ +#undef i_refstr_release +void i_refstr_release(char *str) +{ + if (str != NULL) { + g_ref_string_release(str); + } +} + #else GHashTable *i_refstr_table; diff --git a/src/core/refstrings.h b/src/core/refstrings.h index 79036a20..35f52176 100644 --- a/src/core/refstrings.h +++ b/src/core/refstrings.h @@ -6,6 +6,8 @@ #if GLIB_CHECK_VERSION(2, 58, 0) #define i_refstr_init() /* nothing */ +/* callback implementation */ +void i_refstr_release(char *str); #define i_refstr_release(str) ((str) == NULL ? NULL : g_ref_string_release(str)) #define i_refstr_intern(str) ((str) == NULL ? NULL : g_ref_string_new_intern(str)) #define i_refstr_deinit() /* nothing */ diff --git a/src/core/server-rec.h b/src/core/server-rec.h index c36c8abb..6c7c63e3 100644 --- a/src/core/server-rec.h +++ b/src/core/server-rec.h @@ -44,6 +44,9 @@ int lag; /* server lag in milliseconds */ GSList *channels; GSList *queries; +/* transient meta data stash */ +GHashTable *current_incoming_meta; + /* -- support for multiple server types -- */ /* -- must not be NULL: -- */ diff --git a/src/core/servers.c b/src/core/servers.c index 841700d4..a20d5f4a 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -19,14 +19,15 @@ */ #include "module.h" -#include #include +#include #include #include #include -#include #include +#include #include +#include #include #include @@ -354,6 +355,9 @@ void server_connect_init(SERVER_REC *server) MODULE_DATA_INIT(server); server->type = module_get_uniq_id("SERVER", 0); server_ref(server); + server->current_incoming_meta = + g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); server->nick = g_strdup(server->connrec->nick); if (server->connrec->username == NULL || *server->connrec->username == '\0') { @@ -535,6 +539,7 @@ int server_unref(SERVER_REC *server) g_free(server->away_reason); g_free(server->nick); g_free(server->tag); + g_hash_table_destroy(server->current_incoming_meta); server->type = 0; g_free(server); @@ -655,6 +660,22 @@ void server_change_nick(SERVER_REC *server, const char *nick) signal_emit("server nick changed", 1, server); } +void server_meta_stash(SERVER_REC *server, const char *meta_key, const char *meta_value) +{ + g_hash_table_replace(server->current_incoming_meta, i_refstr_intern(meta_key), + g_strdup(meta_value)); +} + +const char *server_meta_stash_find(SERVER_REC *server, const char *meta_key) +{ + return g_hash_table_lookup(server->current_incoming_meta, meta_key); +} + +void server_meta_clear_all(SERVER_REC *server) +{ + g_hash_table_remove_all(server->current_incoming_meta); +} + /* Update own IPv4 and IPv6 records */ void server_connect_own_ip_save(SERVER_CONNECT_REC *conn, IPADDR *ip4, IPADDR *ip6) diff --git a/src/core/servers.h b/src/core/servers.h index 7b998c8d..d52603eb 100644 --- a/src/core/servers.h +++ b/src/core/servers.h @@ -66,6 +66,13 @@ void server_connect_failed(SERVER_REC *server, const char *msg); /* Change your nick */ void server_change_nick(SERVER_REC *server, const char *nick); +/* Push meta data onto the server stash */ +void server_meta_stash(SERVER_REC *server, const char *meta_key, const char *meta_value); +/* Get a value from the stash */ +const char *server_meta_stash_find(SERVER_REC *server, const char *meta_key); +/* clear meta stash */ +void server_meta_clear_all(SERVER_REC *server); + /* Update own IPv4 and IPv6 records */ void server_connect_own_ip_save(SERVER_CONNECT_REC *conn, IPADDR *ip4, IPADDR *ip6); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index eb47646e..de3898ee 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -406,16 +406,10 @@ void format_read_arglist(va_list va, FORMAT_REC *format, } } } -void format_create_dest(TEXT_DEST_REC *dest, - void *server, const char *target, - int level, WINDOW_REC *window) -{ - format_create_dest_tag(dest, server, NULL, target, level, window); -} -void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, - const char *server_tag, const char *target, - int level, WINDOW_REC *window) +void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char *server_tag, + const char *target, int level, WINDOW_REC *window, + GHashTable *meta) { memset(dest, 0, sizeof(TEXT_DEST_REC)); @@ -425,6 +419,20 @@ void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, dest->level = level; dest->window = window != NULL ? window : window_find_closest(server, target, level); + dest->meta = meta; +} + +void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, + const char *target, int level, WINDOW_REC *window) +{ + format_create_dest_tag_meta(dest, server, server_tag, target, level, window, + server != NULL ? SERVER(server)->current_incoming_meta : NULL); +} + +void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level, + WINDOW_REC *window) +{ + format_create_dest_tag(dest, server, NULL, target, level, window); } /* Return length of text part in string (ie. without % codes) */ diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 226348de..530f42bf 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -64,6 +64,7 @@ typedef struct _TEXT_DEST_REC { int hilight_priority; char *hilight_color; int flags; + GHashTable *meta; } TEXT_DEST_REC; #define window_get_theme(window) \ diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index a92c6f3b..d317456b 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -348,14 +348,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor, return; } - lineinfo.level = dest == NULL ? 0 : dest->level; gui = WINDOW_GUI(window); - lineinfo.time = (gui->use_insert_after && gui->insert_after_time) ? - gui->insert_after_time : time(NULL); + view = gui->view; + + lineinfo.level = dest == NULL ? 0 : dest->level; + lineinfo.time = + (gui->use_insert_after && gui->insert_after_time) ? gui->insert_after_time : time(NULL); lineinfo.format = dest != NULL && dest->flags & PRINT_FLAG_FORMAT ? LINE_INFO_FORMAT_SET : NULL; - view = gui->view; insert_after = gui->use_insert_after ? gui->insert_after : view->buffer->cur_line; diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 17ec118a..e3d331f1 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -14,7 +14,8 @@ #include TEXT_BUFFER_REC *color_buf; -int scrollback_format; +gboolean scrollback_format; +gboolean show_server_time; #if GLIB_CHECK_VERSION(2, 56, 0) /* nothing */ @@ -101,6 +102,55 @@ static void format_rec_set_dest(TEXT_BUFFER_FORMAT_REC *rec, const TEXT_DEST_REC rec->flags = dest->flags & ~PRINT_FLAG_FORMAT; } +void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) +{ + if (rec == NULL) + return; + + if (rec->hash != NULL) + g_hash_table_destroy(rec->hash); + + g_free(rec); +} + +static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) +{ + if (meta->hash == NULL) { + meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + (GDestroyNotify) i_refstr_release, + (GDestroyNotify) g_free); + } +} + +static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash) +{ + struct _TEXT_BUFFER_META_REC *meta; + GHashTableIter iter; + const char *key; + const char *val; + + if (meta_hash == NULL || g_hash_table_size(meta_hash) == 0) + return NULL; + + meta = g_new0(struct _TEXT_BUFFER_META_REC, 1); + + g_hash_table_iter_init(&iter, meta_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + if (g_strcmp0("time", key) == 0) { + GDateTime *time; + if ((time = g_date_time_new_from_iso8601(val, NULL)) != NULL) { + meta->server_time = g_date_time_to_unix(time); + g_date_time_unref(time); + } + } else { + meta_hash_create(meta); + g_hash_table_replace(meta->hash, i_refstr_intern(key), g_strdup(val)); + } + } + + return meta; +} + static LINE_INFO_REC *store_lineinfo_tmp(TEXT_DEST_REC *dest) { GUI_WINDOW_REC *gui; @@ -135,7 +185,7 @@ static void free_lineinfo_tmp(WINDOW_REC *window) info = buffer->cur_info->data; buffer->cur_info = g_slist_delete_link(buffer->cur_info, buffer->cur_info); - textbuffer_format_rec_free(info->format); + textbuffer_line_info_free1(info); g_free(info); } @@ -226,14 +276,17 @@ static void sig_gui_print_text_finished(WINDOW_REC *window, TEXT_DEST_REC *dest) info->format->expando_cache = reverse_collector(info->format->expando_cache); format_rec_set_dest(info->format, dest); + info->meta = line_meta_create(dest->meta); + info->level |= MSGLEVEL_FORMAT; /* the line will be inserted into the view with textbuffer_view_insert_line by gui-printtext.c:view_add_eol */ insert_after = textbuffer_insert(buffer, insert_after, (const unsigned char[]){}, 0, info); - /* the TEXT_BUFFER_FORMAT_REC pointer is now owned by the textbuffer */ + /* the TEXT_BUFFER_FORMAT_REC and meta pointer is now owned by the textbuffer */ info->format = LINE_INFO_FORMAT_SET; + info->meta = NULL; if (gui->use_insert_after) gui->insert_after = insert_after; @@ -309,12 +362,14 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) THEME_REC *theme; int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; + TEXT_BUFFER_META_REC *meta; char *str; curr = line; line = NULL; - format_rec = curr->info.format; + meta = curr->info.meta; + format_create_dest_tag( &dest, format_rec->server_tag != NULL ? server_find_tag(format_rec->server_tag) : NULL, @@ -341,7 +396,12 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) } if (text != NULL && *text != '\0') { - current_time = curr->info.time; + reference_time = curr->info.time; + if (show_server_time && meta != NULL && meta->server_time != 0) { + current_time = meta->server_time; + } else { + current_time = curr->info.time; + } tmp = format_get_level_tag(theme, &dest); str = !theme->info_eol ? format_add_linestart(text, tmp) : @@ -349,7 +409,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) g_free_not_null(tmp); g_free_not_null(text); text = str; - tmp = format_get_line_start(theme, &dest, curr->info.time); + tmp = format_get_line_start(theme, &dest, current_time); str = !theme->info_eol ? format_add_linestart(text, tmp) : format_add_lineend(text, tmp); g_free_not_null(tmp); @@ -360,7 +420,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) dest.flags |= PRINT_FLAG_FORMAT; - current_time = (time_t) -1; + reference_time = current_time = (time_t) -1; } else if (format_rec->format != NULL) { g_free(text); text = NULL; @@ -378,11 +438,13 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) static void read_settings(void) { scrollback_format = settings_get_bool("scrollback_format"); + show_server_time = settings_get_bool("show_server_time"); } void textbuffer_formats_init(void) { settings_add_bool("lookandfeel", "scrollback_format", TRUE); + settings_add_bool("lookandfeel", "show_server_time", FALSE); read_settings(); signal_add("print format", (SIGNAL_FUNC) sig_print_format); diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index b57f61c9..d595df8a 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -3,6 +3,11 @@ #include +typedef struct _TEXT_BUFFER_META_REC { + gint64 server_time; + GHashTable *hash; +} TEXT_BUFFER_META_REC; + typedef struct _TEXT_BUFFER_FORMAT_REC { char *module; char *format; @@ -17,6 +22,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { } TEXT_BUFFER_FORMAT_REC; void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec); +void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec); char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line); void textbuffer_formats_init(void); void textbuffer_formats_deinit(void); diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index b8fd2090..8761507b 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -54,8 +54,7 @@ void textbuffer_destroy(TEXT_BUFFER_REC *buffer) g_string_free(buffer->cur_text, TRUE); for (tmp = buffer->cur_info; tmp != NULL; tmp = tmp->next) { LINE_INFO_REC *info = buffer->cur_info->data; - textbuffer_format_rec_free(info->format); - g_free(info->text); + textbuffer_line_info_free1(info); g_free(info); } g_slist_free(buffer->cur_info); @@ -64,6 +63,13 @@ void textbuffer_destroy(TEXT_BUFFER_REC *buffer) g_slice_free(TEXT_BUFFER_REC, buffer); } +void textbuffer_line_info_free1(LINE_INFO_REC *info) +{ + textbuffer_format_rec_free(info->format); + textbuffer_meta_rec_free(info->meta); + g_free(info->text); +} + static void text_chunk_append(TEXT_BUFFER_REC *buffer, const unsigned char *data, int len) { @@ -198,8 +204,7 @@ void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line) line->prev = line->next = NULL; buffer->lines_count--; - g_free(line->info.text); - textbuffer_format_rec_free(line->info.format); + textbuffer_line_info_free1(&line->info); g_slice_free(LINE_REC, line); } @@ -212,10 +217,9 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer) while (buffer->first_line != NULL) { line = buffer->first_line->next; - g_free(buffer->first_line->info.text); - textbuffer_format_rec_free(buffer->first_line->info.format); + textbuffer_line_info_free1(&buffer->first_line->info); g_slice_free(LINE_REC, buffer->first_line); - buffer->first_line = line; + buffer->first_line = line; } buffer->lines_count = 0; diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 5aaa817c..bb4e820a 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -17,6 +17,7 @@ typedef struct { int level; time_t time; char *text; + struct _TEXT_BUFFER_META_REC *meta; struct _TEXT_BUFFER_FORMAT_REC *format; } LINE_INFO_REC; @@ -84,6 +85,7 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, void textbuffer_remove(TEXT_BUFFER_REC *buffer, LINE_REC *line); /* Removes all lines from buffer, ignoring reference counters */ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer); +void textbuffer_line_info_free1(LINE_INFO_REC *info); void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, GString *str); GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index cde6a4fc..f29a8f91 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -242,6 +242,7 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_CHGHOST, TRUE); irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE); + irc_cap_toggle(server, CAP_SERVER_TIME, TRUE); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index e775e505..4833972a 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -26,6 +26,7 @@ #define CAP_CHGHOST "chghost" #define CAP_ACCOUNT_NOTIFY "account-notify" #define CAP_SELF_MESSAGE "znc.in/self-message" +#define CAP_SERVER_TIME "server-time" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index f3f9f307..96a09333 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -19,14 +19,15 @@ */ #include "module.h" -#include -#include -#include -#include #include +#include +#include +#include +#include +#include -#include #include +#include #include char *current_server_event; @@ -383,11 +384,83 @@ static void irc_server_event(IRC_SERVER_REC *server, const char *line, g_free(event); } -static void irc_server_event_tags(IRC_SERVER_REC *server, const char *line, - const char *nick, const char *address, const char *tags) +static void unescape_tag(char *tag) { + char *tmp; + + if (tag == NULL) + return; + + tmp = tag; + for (; *tmp != '\0'; tmp++, tag++) { + if (*tmp == '\\') { + tmp++; + switch (*tmp) { + case ':': + *tag = ';'; + break; + case 'n': + *tag = '\n'; + break; + case 'r': + *tag = '\r'; + break; + case 's': + *tag = ' '; + break; + default: + *tag = *tmp; + break; + } + } else { + *tag = *tmp; + } + } + *tag = '\0'; +} + +static gboolean i_str0_equal(const char *s1, const char *s2) +{ + return g_strcmp0(s1, s2) == 0; +} + +GHashTable *irc_parse_message_tags(const char *tags) +{ + char **split, **tmp, **kv; + GHashTable *hash; + + hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) i_str0_equal, + (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); + split = g_strsplit(tags, ";", -1); + for (tmp = split; *tmp != NULL; tmp++) { + kv = g_strsplit(*tmp, "=", 2); + unescape_tag(kv[1]); + g_hash_table_replace(hash, i_refstr_intern(kv[0]), + g_strdup(kv[1] == NULL ? "" : kv[1])); + g_strfreev(kv); + } + g_strfreev(split); + return hash; +} + +static void irc_server_event_tags(IRC_SERVER_REC *server, const char *line, const char *nick, + const char *address, const char *tags) +{ + char *timestr; + GHashTable *tags_hash = NULL; + + if (tags != NULL && *tags != '\0') { + tags_hash = irc_parse_message_tags(tags); + if ((timestr = g_hash_table_lookup(tags_hash, "time")) != NULL) { + server_meta_stash(SERVER(server), "time", timestr); + } + } + if (*line != '\0') signal_emit_id(signal_server_event, 4, server, line, nick, address); + + if (tags_hash != NULL) + g_hash_table_destroy(tags_hash); } static char *irc_parse_prefix(char *line, char **nick, char **address, char **tags) @@ -449,6 +522,8 @@ static void irc_parse_incoming_line(IRC_SERVER_REC *server, char *line) line = irc_parse_prefix(line, &nick, &address, &tags); if (*line != '\0' || tags != NULL) signal_emit_id(signal_server_event_tags, 5, server, line, nick, address, tags); + + server_meta_clear_all(SERVER(server)); } /* input function: handle incoming server messages */ diff --git a/src/irc/core/irc.h b/src/irc/core/irc.h index 3f1a9887..8803f662 100644 --- a/src/irc/core/irc.h +++ b/src/irc/core/irc.h @@ -48,6 +48,9 @@ void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd); void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int send_now, int immediate, int raw); +/* Extract a tag value from tags */ +GHashTable *irc_parse_message_tags(const char *tags); + /* Get count parameters from data */ #include char *event_get_param(char **data); diff --git a/src/perl/common/Server.xs b/src/perl/common/Server.xs index 7ed41109..60878a6a 100644 --- a/src/perl/common/Server.xs +++ b/src/perl/common/Server.xs @@ -103,3 +103,17 @@ send_message(server, target, msg, target_type) CODE: server->send_message(server, target, msg, target_type); +void +server_meta_stash(server, meta_key, meta_value) + Irssi::Server server + char *meta_key + char *meta_value + +char * +server_meta_stash_find(server, meta_key) + Irssi::Server server + char *meta_key +CODE: + RETVAL = (char *) server_meta_stash_find(server, meta_key); +OUTPUT: + RETVAL diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index f64d9728..f973da22 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -199,10 +199,29 @@ static PLAIN_OBJECT_INIT_REC irc_plains[] = { { NULL, NULL } }; -MODULE = Irssi::Irc PACKAGE = Irssi::Irc +MODULE = Irssi::Irc PACKAGE = Irssi::Irc PREFIX = irc_ PROTOTYPES: ENABLE +void +irc_parse_message_tags(tags) + char *tags +PREINIT: + HV *hv; + GHashTable *hash; + GHashTableIter iter; + char *key; + char *val; +PPCODE: + hv = newHV(); + hash = irc_parse_message_tags(tags); + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + (void) hv_store(hv, key, strlen(key), new_pv(val), 0); + } + g_hash_table_destroy(hash); + XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); + void init() PREINIT: diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index ae3973c8..4859f3da 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -68,3 +68,29 @@ PPCODE: (void) hv_store(hv, "text", 4, new_pv(l->info.text), 0); } XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); + +void +textbuffer_line_get_meta(line) + Irssi::TextUI::Line line +PREINIT: + HV *hv; + LINE_REC *l; + TEXT_BUFFER_META_REC *m; + GHashTableIter iter; + char *key; + char *val; +PPCODE: + hv = newHV(); + l = line->line; + if (l->info.meta != NULL) { + m = l->info.meta; + if (m->hash != NULL) { + g_hash_table_iter_init(&iter, m->hash); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + (void) hv_store(hv, key, strlen(key), new_pv(val), 0); + } + } + (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); + } + XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); From 322df0d2c8e1c0c836a9cdaeaf481e7b2ece2086 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 25 Feb 2021 10:50:51 +0100 Subject: [PATCH 0744/1198] replace refstring macro implementation with C functions --- src/core/refstrings.c | 34 ++++++++++++++++++++++++++++++---- src/core/refstrings.h | 16 ---------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/core/refstrings.c b/src/core/refstrings.c index 8391766d..8f220f6f 100644 --- a/src/core/refstrings.c +++ b/src/core/refstrings.c @@ -1,16 +1,42 @@ +#include #include #include #if GLIB_CHECK_VERSION(2, 58, 0) -/* callback implementation for GHashTable */ -#undef i_refstr_release +void i_refstr_init(void) +{ + /* nothing */ +} + +char *i_refstr_intern(const char *str) +{ + if (str == NULL) { + return NULL; + } + + return g_ref_string_new_intern(str); +} + void i_refstr_release(char *str) { - if (str != NULL) { - g_ref_string_release(str); + if (str == NULL) { + return; } + + g_ref_string_release(str); +} + +void i_refstr_deinit(void) +{ + /* nothing */ +} + +char *i_refstr_table_size_info(void) +{ + /* not available */ + return NULL; } #else diff --git a/src/core/refstrings.h b/src/core/refstrings.h index 35f52176..89ef84d1 100644 --- a/src/core/refstrings.h +++ b/src/core/refstrings.h @@ -1,20 +1,6 @@ #ifndef IRSSI_CORE_REFSTRINGS_H #define IRSSI_CORE_REFSTRINGS_H -#include - -#if GLIB_CHECK_VERSION(2, 58, 0) - -#define i_refstr_init() /* nothing */ -/* callback implementation */ -void i_refstr_release(char *str); -#define i_refstr_release(str) ((str) == NULL ? NULL : g_ref_string_release(str)) -#define i_refstr_intern(str) ((str) == NULL ? NULL : g_ref_string_new_intern(str)) -#define i_refstr_deinit() /* nothing */ -#define i_refstr_table_size_info() NULL - -#else - void i_refstr_init(void); char *i_refstr_intern(const char *str); void i_refstr_release(char *str); @@ -22,5 +8,3 @@ void i_refstr_deinit(void); char *i_refstr_table_size_info(void); #endif - -#endif From 3ea25fb7046897da5f8143be78e13b2e90778aa2 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 25 Feb 2021 10:59:19 +0100 Subject: [PATCH 0745/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index bb339f1f..39045de7 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 33 +#define IRSSI_ABI_VERSION 34 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 7adf81f9b530937bdad561a46c09e847ba78604a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 28 Jan 2021 21:25:53 +0100 Subject: [PATCH 0746/1198] raise glib version requirement to 2.32 for g_hash_table_contains --- INSTALL | 2 +- README.md | 2 +- configure.ac | 2 +- meson.build | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 712678e4..3dbe2ebd 100644 --- a/INSTALL +++ b/INSTALL @@ -5,7 +5,7 @@ To compile Irssi you need: - meson-0.49 build system with ninja-1.5 or greater -- glib-2.28 or greater +- glib-2.32 or greater - openssl (for ssl support) - perl-5.6 or greater (for Perl support) - terminfo or ncurses (for text frontend) diff --git a/README.md b/README.md index 8b857eeb..08be65b4 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ make && sudo make install ### Requirements -- [glib-2.28](https://wiki.gnome.org/Projects/GLib) or greater +- [glib-2.32](https://wiki.gnome.org/Projects/GLib) or greater - [openssl](https://www.openssl.org/) - [perl-5.6](https://www.perl.org/) or greater (for perl support) - terminfo or ncurses (for text frontend) diff --git a/configure.ac b/configure.ac index cafd2970..41a053fd 100644 --- a/configure.ac +++ b/configure.ac @@ -273,7 +273,7 @@ for try in 1 2; do echo "*** trying without -lgmodule" glib_modules= fi - AM_PATH_GLIB_2_0(2.28.0,,, $glib_modules) + AM_PATH_GLIB_2_0(2.32.0,,, $glib_modules) if test "$GLIB_LIBS"; then if test $glib_modules = gmodule; then AC_DEFINE(HAVE_GMODULE) diff --git a/meson.build b/meson.build index f54db548..bd076a4d 100644 --- a/meson.build +++ b/meson.build @@ -166,7 +166,7 @@ message('*** Or alternatively install your distribution\'s package') message('*** On Debian: sudo apt-get install libglib2.0-dev') message('*** On Redhat: dnf install glib2-devel') if not require_glib_internal - glib_dep = dependency('glib-2.0', version : '>=2.28', required : not want_glib_internal, static : want_static_dependency) + glib_dep = dependency('glib-2.0', version : '>=2.32', required : not want_glib_internal, static : want_static_dependency) else glib_dep = dependency('', required : false) endif From bf1376e34ef0a5adfa0fca1bc0679b539690e8ae Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 28 Jan 2021 21:47:11 +0100 Subject: [PATCH 0747/1198] update clang-format to clang-format-11, fixes enum bug --- .github/workflows/clangformat.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index b959fe92..59beb928 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -2,8 +2,10 @@ on: [pull_request] name: clang-format jobs: check-clang-format: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: + - name: install clang-format + run: sudo apt install clang-format-11 - uses: actions/checkout@main - name: fetch target ref run: @@ -18,7 +20,7 @@ jobs: - name: run git-clang-format and Check if no changes are needed run: | - git-clang-format-9 --diff FETCH_HEAD HEAD | tee git-clang-format.diff + CLANG_FORMAT=clang-format-11 git-clang-format-11 --diff FETCH_HEAD HEAD | tee git-clang-format.diff cmp -s <(echo no modified files to format) git-clang-format.diff || cmp -s <(echo -n) git-clang-format.diff - uses: actions/upload-artifact@v1 if: failure() From dc8719910052000b1f920d62d3762a38059c528f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 5 Jan 2021 21:34:09 +0100 Subject: [PATCH 0748/1198] better account tracking --- src/fe-common/irc/fe-whois.c | 2 + src/irc/core/channels-query.c | 105 ++++++++++++++++++++++-- src/irc/core/irc-commands.c | 21 ++--- src/irc/core/irc-nicklist.c | 138 +++++++++++++++++++++++++++----- src/irc/core/massjoin.c | 15 ++-- src/irc/core/servers-redirect.c | 11 ++- 6 files changed, 247 insertions(+), 45 deletions(-) diff --git a/src/fe-common/irc/fe-whois.c b/src/fe-common/irc/fe-whois.c index 9a31cd9e..b0eeb19a 100644 --- a/src/fe-common/irc/fe-whois.c +++ b/src/fe-common/irc/fe-whois.c @@ -415,6 +415,7 @@ void fe_whois_init(void) signal_add("event 319", (SIGNAL_FUNC) event_whois_channels); signal_add("event 313", (SIGNAL_FUNC) event_whois_oper); signal_add("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_add("whois account", (SIGNAL_FUNC) event_whois_auth); signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode); signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost); signal_add("event 379", (SIGNAL_FUNC) event_whois_modes); @@ -438,6 +439,7 @@ void fe_whois_deinit(void) signal_remove("event 319", (SIGNAL_FUNC) event_whois_channels); signal_remove("event 313", (SIGNAL_FUNC) event_whois_oper); signal_remove("event 330", (SIGNAL_FUNC) event_whois_auth); + signal_remove("whois account", (SIGNAL_FUNC) event_whois_auth); signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode); signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost); signal_remove("event 379", (SIGNAL_FUNC) event_whois_modes); diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 8f90af64..8bf60587 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -229,15 +229,19 @@ static void query_send(IRC_SERVER_REC *server, int query) break; case CHANNEL_QUERY_WHO: - cmd = g_strdup_printf("WHO %s", chanstr_commas); + if (server->isupport != NULL && + g_hash_table_lookup(server->isupport, "whox") != NULL) { + cmd = g_strdup_printf("WHO %s %%tcuhnfdar,743", chanstr_commas); + } else { + cmd = g_strdup_printf("WHO %s", chanstr_commas); + } - server_redirect_event(server, "who", - server->one_endofwho ? 1 : count, - chanstr, -1, - "chanquery abort", - "event 315", "chanquery who end", - "event 352", "silent event who", - "", "chanquery abort", NULL); + server_redirect_event(server, "who", server->one_endofwho ? 1 : count, chanstr, -1, + "chanquery abort", /* failure signal */ + "event 315", "chanquery who end", /* */ + "event 352", "silent event who", /* */ + "event 354", "silent event whox", /* */ + "", "chanquery abort", NULL); break; case CHANNEL_QUERY_BMODE: @@ -395,6 +399,87 @@ static void channel_got_query(IRC_CHANNEL_REC *chanrec, int query_type) query_check(chanrec->server); } +static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char *nick, + const char *address) +{ + char *params, *channel, *ptr, *account; + GSList *nicks, *tmp; + IRC_CHANNEL_REC *chanrec; + NICK_REC *nickrec; + + g_return_if_fail(data != NULL); + + if (i_slist_find_string(server->cap_active, CAP_EXTENDED_JOIN)) { + /* no need to chase accounts */ + return; + } + + if (g_ascii_strcasecmp(nick, server->nick) == 0) { + /* You joined, do nothing */ + return; + } + + params = event_get_params(data, 3, &channel, NULL, NULL); + + ptr = strchr(channel, 7); /* ^G does something weird.. */ + if (ptr != NULL) + *ptr = '\0'; + + /* find channel */ + chanrec = irc_channel_find(server, channel); + if (chanrec == NULL) { + g_free(params); + return; + } + + g_free(params); + + if (!chanrec->wholist) { + return; + } + + /* find nick */ + nickrec = nicklist_find(CHANNEL(chanrec), nick); + if (nickrec == NULL) { + return; + } + + if (nickrec->account != NULL) { + return; + } + + account = NULL; + + /* Check if user is already in some other channel, get the account from there */ + nicks = nicklist_get_same(SERVER(server), nick); + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + if (rec->account != NULL) { + account = rec->account; + break; + } + } + g_slist_free(nicks); + + if (account != NULL) { + nicklist_set_account(CHANNEL(chanrec), nickrec, account); + return; + } + + if (g_hash_table_size(chanrec->nicks) < settings_get_int("channel_max_who_sync") && + server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL) { + char *cmd; + server_redirect_event(server, "who user", 1, nick, -1, NULL, /* failure signal */ + "event 354", "silent event whox useraccount", /* */ + "", "event empty", /* */ + NULL); + cmd = g_strdup_printf("WHO %s %%tna,745", nick); + irc_send_cmd(server, cmd); + g_free(cmd); + } +} + static void event_channel_mode(IRC_SERVER_REC *server, const char *data, const char *nick) { @@ -493,6 +578,8 @@ void channels_query_init(void) signal_add("channel joined", (SIGNAL_FUNC) sig_channel_joined); signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); + signal_add("event join", (SIGNAL_FUNC) sig_event_join); + signal_add("chanquery mode", (SIGNAL_FUNC) event_channel_mode); signal_add("chanquery who end", (SIGNAL_FUNC) event_end_of_who); @@ -507,6 +594,8 @@ void channels_query_deinit(void) signal_remove("channel joined", (SIGNAL_FUNC) sig_channel_joined); signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); + signal_remove("event join", (SIGNAL_FUNC) sig_event_join); + signal_remove("chanquery mode", (SIGNAL_FUNC) event_channel_mode); signal_remove("chanquery who end", (SIGNAL_FUNC) event_end_of_who); diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index f6c25641..935c6b42 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -438,15 +438,18 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server, query = get_redirect_nicklist(query, &free_nick); 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); + 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 330", "whois account", /* */ + "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; diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index cc630a58..4965e1bf 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -29,6 +29,34 @@ #include #include +static void nicklist_set_modes(IRC_CHANNEL_REC *channel, NICK_REC *rec, gboolean op, + gboolean halfop, gboolean voice, const char *prefixes, + gboolean send_changed) +{ + gboolean changed = FALSE; + if (rec->op != op) { + rec->op = op; + changed = TRUE; + } + if (rec->halfop != halfop) { + rec->halfop = halfop; + changed = TRUE; + } + if (rec->voice != voice) { + rec->voice = voice; + changed = TRUE; + } + + if (prefixes != NULL && g_strcmp0(rec->prefixes, prefixes) != 0) { + g_strlcpy(rec->prefixes, prefixes, sizeof(rec->prefixes)); + changed = TRUE; + } + + if (changed && send_changed) { + signal_emit("nicklist changed", 3, channel, rec, rec->nick); + } +} + /* Add new nick to list */ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, int op, int halfop, int voice, int send_massjoin, @@ -42,14 +70,8 @@ NICK_REC *irc_nicklist_insert(IRC_CHANNEL_REC *channel, const char *nick, rec = g_new0(NICK_REC, 1); rec->nick = g_strdup(nick); - if (op) rec->op = TRUE; - if (halfop) rec->halfop = TRUE; - if (voice) rec->voice = TRUE; rec->send_massjoin = send_massjoin; - - if (prefixes != NULL) { - g_strlcpy(rec->prefixes, prefixes, sizeof(rec->prefixes)); - } + nicklist_set_modes(channel, rec, op, halfop, voice, prefixes, FALSE); nicklist_insert(CHANNEL(channel), rec); return rec; @@ -154,11 +176,14 @@ static void event_names_list(IRC_SERVER_REC *server, const char *data) if (host != NULL) *host++ = '\0'; - if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) { + rec = nicklist_find((CHANNEL_REC *) chanrec, ptr); + if (rec == NULL) { rec = irc_nicklist_insert(chanrec, ptr, op, halfop, voice, FALSE, prefixes); if (host != NULL) nicklist_set_host(CHANNEL(chanrec), rec, host); + } else { + nicklist_set_modes(chanrec, rec, op, halfop, voice, prefixes, TRUE); } } @@ -196,23 +221,13 @@ static void event_end_of_names(IRC_SERVER_REC *server, const char *data) g_free(params); } -static void event_who(SERVER_REC *server, const char *data) +static void fill_who(SERVER_REC *server, const char *channel, const char *user, const char *host, + const char *nick, const char *stat, const char *hops, const char *account, + const char *realname) { - char *params, *nick, *channel, *user, *host, *stat, *realname, *hops; CHANNEL_REC *chanrec; NICK_REC *nickrec; - g_return_if_fail(data != NULL); - - params = event_get_params(data, 8, NULL, &channel, &user, &host, - NULL, &nick, &stat, &realname); - - /* get hop count */ - hops = realname; - while (*realname != '\0' && *realname != ' ') realname++; - if (*realname == ' ') - *realname++ = '\0'; - /* update host, realname, hopcount */ chanrec = channel_find(server, channel); nickrec = chanrec == NULL ? NULL : @@ -223,15 +238,88 @@ static void event_who(SERVER_REC *server, const char *data) nicklist_set_host(chanrec, nickrec, str); g_free(str); } - if (nickrec->realname == NULL) + if (nickrec->realname == NULL) { nickrec->realname = g_strdup(realname); + } + if (nickrec->account == NULL && account != NULL) { + nicklist_set_account(chanrec, nickrec, + strcmp(account, "0") == 0 ? "*" : account); + } sscanf(hops, "%d", &nickrec->hops); } nicklist_update_flags(server, nick, strchr(stat, 'G') != NULL, /* gone */ strchr(stat, '*') != NULL); /* ircop */ +} +static void event_who(SERVER_REC *server, const char *data) +{ + char *params, *nick, *channel, *user, *host, *stat, *realname, *hops; + + g_return_if_fail(data != NULL); + + params = + event_get_params(data, 8, NULL, &channel, &user, &host, NULL, &nick, &stat, &realname); + + /* get hop count */ + hops = realname; + while (*realname != '\0' && *realname != ' ') + realname++; + if (*realname == ' ') + *realname++ = '\0'; + + fill_who(server, channel, user, host, nick, stat, hops, NULL, realname); + + g_free(params); +} + +static void event_whox_743(SERVER_REC *server, const char *data) +{ + char *params, *id, *nick, *channel, *user, *host, *stat, *hops, *account, *realname; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 10, NULL, &id, &channel, &user, &host, &nick, &stat, &hops, + &account, &realname); + + if (g_strcmp0(id, "743") != 0) { + g_free(params); + return; + } + + fill_who(server, channel, user, host, nick, stat, hops, account, realname); + + g_free(params); +} + +static void event_whox_745(SERVER_REC *server, const char *data) +{ + char *params, *id, *nick, *account; + GSList *nicks, *tmp; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 4, NULL, &id, &nick, &account); + + if (g_strcmp0(id, "745") != 0) { + g_free(params); + return; + } + + if (strcmp(account, "0") == 0) { + account = "*"; + } + + nicks = nicklist_get_same(SERVER(server), nick); + for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) { + NICK_REC *rec = tmp->next->data; + + if (rec->account == NULL || g_strcmp0(rec->account, account) != 0) { + nicklist_set_account(CHANNEL(tmp->data), rec, account); + } + } + g_slist_free(nicks); g_free(params); } @@ -510,7 +598,10 @@ void irc_nicklist_init(void) { signal_add_first("event nick", (SIGNAL_FUNC) event_nick); signal_add_first("event 352", (SIGNAL_FUNC) event_who); + signal_add_first("event 354", (SIGNAL_FUNC) event_whox_743); signal_add("silent event who", (SIGNAL_FUNC) event_who); + signal_add("silent event whox", (SIGNAL_FUNC) event_whox_743); + signal_add("silent event whox useraccount", (SIGNAL_FUNC) event_whox_745); signal_add("silent event whois", (SIGNAL_FUNC) event_whois); signal_add_first("event 311", (SIGNAL_FUNC) event_whois); signal_add_first("whois away", (SIGNAL_FUNC) event_whois_away); @@ -534,7 +625,10 @@ void irc_nicklist_deinit(void) { signal_remove("event nick", (SIGNAL_FUNC) event_nick); signal_remove("event 352", (SIGNAL_FUNC) event_who); + signal_remove("event 354", (SIGNAL_FUNC) event_whox_743); signal_remove("silent event who", (SIGNAL_FUNC) event_who); + signal_remove("silent event whox", (SIGNAL_FUNC) event_whox_743); + signal_remove("silent event whox useraccount", (SIGNAL_FUNC) event_whox_745); signal_remove("silent event whois", (SIGNAL_FUNC) event_whois); signal_remove("event 311", (SIGNAL_FUNC) event_whois); signal_remove("whois away", (SIGNAL_FUNC) event_whois_away); diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 2405f947..98802f7f 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -39,12 +39,15 @@ static void event_join(IRC_SERVER_REC *server, const char *data, IRC_CHANNEL_REC *chanrec; NICK_REC *nickrec; GSList *nicks, *tmp; + gboolean send_massjoin; g_return_if_fail(data != NULL); if (g_ascii_strcasecmp(nick, server->nick) == 0) { - /* You joined, no need to do anything here */ - return; + /* You joined, do not massjoin */ + send_massjoin = FALSE; + } else { + send_massjoin = TRUE; } params = event_get_params(data, 3, &channel, &account, &realname); @@ -68,14 +71,14 @@ static void event_join(IRC_SERVER_REC *server, const char *data, } /* add user to nicklist */ - nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, TRUE, NULL); + nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, send_massjoin, NULL); if (*account != '\0' && g_strcmp0(nickrec->account, account) != 0) { nicklist_set_account(CHANNEL(chanrec), nickrec, account); } nicklist_set_host(CHANNEL(chanrec), nickrec, address); - if (chanrec->massjoins == 0) { + if (send_massjoin && chanrec->massjoins == 0) { /* no nicks waiting in massjoin queue */ chanrec->massjoin_start = time(NULL); chanrec->last_massjoins = 0; @@ -104,7 +107,9 @@ static void event_join(IRC_SERVER_REC *server, const char *data, nickrec->realname = g_strdup(realname); } - chanrec->massjoins++; + if (send_massjoin) { + chanrec->massjoins++; + } g_free(params); } diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c index 2790c75a..066ba82f 100644 --- a/src/irc/core/servers-redirect.c +++ b/src/irc/core/servers-redirect.c @@ -671,7 +671,16 @@ void servers_redirect_init(void) NULL, NULL); - /* LIST */ + /* WHO user */ + server_redirect_register("who user", FALSE, 0, /* */ + "event 352", 5, /* An element of the WHO */ + "event 354", -1, /* WHOX element */ + NULL, /* */ + "event 315", 1, /* End of WHO */ + NULL, /* */ + NULL); + + /* LIST */ server_redirect_register("list", FALSE, 0, "event 321", 1, /* Begins the LIST */ NULL, From 04035ab7ca0f085f84cf7edaa1f86a071fe1db42 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 28 Jan 2021 21:32:52 +0100 Subject: [PATCH 0749/1198] Track the account queries which are in progress --- src/irc/core/channels-query.c | 39 +++++++++++++++++---------------- src/irc/core/irc-channels.h | 18 +++++++++++++++ src/irc/core/irc-nicklist.c | 7 ++++-- src/irc/core/irc-servers.h | 2 +- src/irc/core/massjoin.c | 3 +++ src/irc/core/servers-redirect.c | 2 +- 6 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 8bf60587..9e284754 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -50,23 +50,6 @@ loop: #include #include -enum { - CHANNEL_QUERY_MODE, - CHANNEL_QUERY_WHO, - CHANNEL_QUERY_BMODE, - - CHANNEL_QUERIES -}; - -#define CHANNEL_IS_MODE_QUERY(a) ((a) != CHANNEL_QUERY_WHO) - -typedef struct { - int current_query_type; /* query type that is currently being asked */ - GSList *current_queries; /* All channels that are currently being queried */ - - GSList *queries[CHANNEL_QUERIES]; /* All queries that need to be asked from server */ -} SERVER_QUERY_REC; - static void sig_connected(IRC_SERVER_REC *server) { SERVER_QUERY_REC *rec; @@ -76,7 +59,9 @@ static void sig_connected(IRC_SERVER_REC *server) return; rec = g_new0(SERVER_QUERY_REC, 1); - server->chanqueries = rec; + rec->accountqueries = g_hash_table_new_full( + (GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal, (GDestroyNotify) g_free, NULL); + server->chanqueries = rec; } static void sig_disconnected(IRC_SERVER_REC *server) @@ -91,6 +76,8 @@ static void sig_disconnected(IRC_SERVER_REC *server) rec = server->chanqueries; g_return_if_fail(rec != NULL); + g_hash_table_foreach(rec->accountqueries, (GHFunc) g_free, NULL); + g_hash_table_destroy(rec->accountqueries); for (n = 0; n < CHANNEL_QUERIES; n++) g_slist_free(rec->queries[n]); g_slist_free(rec->current_queries); @@ -399,6 +386,12 @@ static void channel_got_query(IRC_CHANNEL_REC *chanrec, int query_type) query_check(chanrec->server); } +static void query_useraccount_error(IRC_SERVER_REC *server, const char *cmd, const char *arg) +{ + /* query failed, ignore it but remove the marker */ + g_hash_table_remove(server->chanqueries->accountqueries, arg); +} + static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char *nick, const char *address) { @@ -448,6 +441,10 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char return; } + if (g_hash_table_contains(server->chanqueries->accountqueries, nick)) { + /* query already sent */ + return; + } account = NULL; /* Check if user is already in some other channel, get the account from there */ @@ -470,11 +467,13 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char if (g_hash_table_size(chanrec->nicks) < settings_get_int("channel_max_who_sync") && server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL) { char *cmd; - server_redirect_event(server, "who user", 1, nick, -1, NULL, /* failure signal */ + server_redirect_event(server, "who user", 1, nick, -1, + "chanquery useraccount abort", /* failure signal */ "event 354", "silent event whox useraccount", /* */ "", "event empty", /* */ NULL); cmd = g_strdup_printf("WHO %s %%tna,745", nick); + g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick)); irc_send_cmd(server, cmd); g_free(cmd); } @@ -585,6 +584,7 @@ void channels_query_init(void) signal_add("chanquery ban end", (SIGNAL_FUNC) event_end_of_banlist); signal_add("chanquery abort", (SIGNAL_FUNC) query_current_error); + signal_add("chanquery useraccount abort", (SIGNAL_FUNC) query_useraccount_error); } void channels_query_deinit(void) @@ -601,4 +601,5 @@ void channels_query_deinit(void) signal_remove("chanquery ban end", (SIGNAL_FUNC) event_end_of_banlist); signal_remove("chanquery abort", (SIGNAL_FUNC) query_current_error); + signal_remove("chanquery useraccount abort", (SIGNAL_FUNC) query_useraccount_error); } diff --git a/src/irc/core/irc-channels.h b/src/irc/core/irc-channels.h index 4ed7fd73..769ddf2f 100644 --- a/src/irc/core/irc-channels.h +++ b/src/irc/core/irc-channels.h @@ -11,6 +11,16 @@ #define IS_IRC_CHANNEL(channel) \ (IRC_CHANNEL(channel) ? TRUE : FALSE) +enum { + CHANNEL_QUERY_MODE, + CHANNEL_QUERY_WHO, + CHANNEL_QUERY_BMODE, + + CHANNEL_QUERIES +}; + +#define CHANNEL_IS_MODE_QUERY(a) ((a) != CHANNEL_QUERY_WHO) + #define STRUCT_SERVER_REC IRC_SERVER_REC struct _IRC_CHANNEL_REC { #include @@ -22,6 +32,14 @@ struct _IRC_CHANNEL_REC { int last_massjoins; /* Massjoins when last checked in timeout function */ }; +typedef struct _SERVER_QUERY_REC { + int current_query_type; /* query type that is currently being asked */ + GSList *current_queries; /* All channels that are currently being queried */ + + GSList *queries[CHANNEL_QUERIES]; /* All queries that need to be asked from server */ + GHashTable *accountqueries; /* Per-nick account queries */ +} SERVER_QUERY_REC; + void irc_channels_init(void); void irc_channels_deinit(void); diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 4965e1bf..76543ac1 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -293,7 +293,7 @@ static void event_whox_743(SERVER_REC *server, const char *data) g_free(params); } -static void event_whox_745(SERVER_REC *server, const char *data) +static void event_whox_745(IRC_SERVER_REC *server, const char *data) { char *params, *id, *nick, *account; GSList *nicks, *tmp; @@ -306,6 +306,7 @@ static void event_whox_745(SERVER_REC *server, const char *data) g_free(params); return; } + g_hash_table_remove(server->chanqueries->accountqueries, nick); if (strcmp(account, "0") == 0) { account = "*"; @@ -503,7 +504,9 @@ static void event_nick(IRC_SERVER_REC *server, const char *data, server_change_nick(SERVER(server), nick); } - nicklist_rename(SERVER(server), orignick, nick); + /* invalidate any outstanding accountqueries for the old nick */ + g_hash_table_remove(server->chanqueries->accountqueries, orignick); + nicklist_rename(SERVER(server), orignick, nick); g_free(params); } diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 4833972a..14560611 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -136,7 +136,7 @@ struct _IRC_SERVER_REC { GSList *rejoin_channels; /* try to join to these channels after a while - channels go here if they're "temporarily unavailable" because of netsplits */ - void *chanqueries; + struct _SERVER_QUERY_REC *chanqueries; GHashTable *isupport; struct modes_type modes[256]; /* Stores the modes sent by a server in an isupport reply */ diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 98802f7f..b83bdabf 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -222,6 +222,9 @@ static void event_quit(IRC_SERVER_REC *server, const char *data, nicklist_remove(CHANNEL(channel), nickrec); } g_slist_free(nicks); + + /* invalidate any outstanding accountqueries for the nick */ + g_hash_table_remove(server->chanqueries->accountqueries, nick); } static void event_kick(IRC_SERVER_REC *server, const char *data) diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c index 066ba82f..a4b7b64f 100644 --- a/src/irc/core/servers-redirect.c +++ b/src/irc/core/servers-redirect.c @@ -442,7 +442,7 @@ static void redirect_abort(IRC_SERVER_REC *server, REDIRECT_REC *rec) g_free(str); if (rec->failure_signal != NULL) - signal_emit(rec->failure_signal, 1, server); + signal_emit(rec->failure_signal, 3, server, rec->cmd->name, rec->arg); } else if (rec->last_signal != NULL) { /* emit the last signal */ signal_emit(rec->last_signal, 1, server); From 04089d5866bf415732785ae908e014541d5a0bc9 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 29 Jan 2021 14:11:07 +0100 Subject: [PATCH 0750/1198] purge whos from queue --- src/irc/core/channels-query.c | 50 ++++++++++++++++++++++++++++++++++- src/irc/core/irc-channels.h | 2 ++ src/irc/core/irc-nicklist.c | 2 +- src/irc/core/massjoin.c | 2 +- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 9e284754..7274ab81 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -50,6 +50,8 @@ loop: #include #include +#define WHO_Ps_PPtna_745 "WHO %s %%tna,745" + static void sig_connected(IRC_SERVER_REC *server) { SERVER_QUERY_REC *rec; @@ -386,6 +388,52 @@ static void channel_got_query(IRC_CHANNEL_REC *chanrec, int query_type) query_check(chanrec->server); } +void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *nick) +{ + GSList *tmp, *next, *prev; + REDIRECT_REC *redirect; + char *cmd, *target_cmd; + gboolean was_removed; + + /* remove the marker */ + was_removed = g_hash_table_remove(server->chanqueries->accountqueries, nick); + + /* if it was removed we may have an outstanding query */ + if (was_removed) { + target_cmd = g_strdup_printf(WHO_Ps_PPtna_745, nick); + + /* remove queued WHO command */ + prev = NULL; + for (tmp = server->cmdqueue; tmp != NULL; tmp = next) { + next = tmp->next->next; + cmd = tmp->data; + redirect = tmp->next->data; + + if (g_strcmp0(cmd, target_cmd) == 0) { + if (prev != NULL) + prev->next = next; + else + server->cmdqueue = next; + + /* remove the redirection */ + g_slist_free_1(tmp->next); + if (redirect != NULL) + server_redirect_destroy(redirect); + + /* remove the command */ + g_slist_free_1(tmp); + g_free(cmd); + + server->cmdcount--; + } else { + prev = tmp; + } + } + + g_free(target_cmd); + } +} + static void query_useraccount_error(IRC_SERVER_REC *server, const char *cmd, const char *arg) { /* query failed, ignore it but remove the marker */ @@ -472,7 +520,7 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char "event 354", "silent event whox useraccount", /* */ "", "event empty", /* */ NULL); - cmd = g_strdup_printf("WHO %s %%tna,745", nick); + cmd = g_strdup_printf(WHO_Ps_PPtna_745, nick); g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick)); irc_send_cmd(server, cmd); g_free(cmd); diff --git a/src/irc/core/irc-channels.h b/src/irc/core/irc-channels.h index 769ddf2f..67b550d5 100644 --- a/src/irc/core/irc-channels.h +++ b/src/irc/core/irc-channels.h @@ -40,6 +40,8 @@ typedef struct _SERVER_QUERY_REC { GHashTable *accountqueries; /* Per-nick account queries */ } SERVER_QUERY_REC; +void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *nick); + void irc_channels_init(void); void irc_channels_deinit(void); diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index 76543ac1..f62f3d49 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -505,7 +505,7 @@ static void event_nick(IRC_SERVER_REC *server, const char *data, } /* invalidate any outstanding accountqueries for the old nick */ - g_hash_table_remove(server->chanqueries->accountqueries, orignick); + irc_channels_query_purge_accountquery(server, orignick); nicklist_rename(SERVER(server), orignick, nick); g_free(params); } diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index b83bdabf..61e2615f 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -224,7 +224,7 @@ static void event_quit(IRC_SERVER_REC *server, const char *data, g_slist_free(nicks); /* invalidate any outstanding accountqueries for the nick */ - g_hash_table_remove(server->chanqueries->accountqueries, nick); + irc_channels_query_purge_accountquery(server, nick); } static void event_kick(IRC_SERVER_REC *server, const char *data) From a0a9a82673b8079da834243e57516b6a105b62f3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 1 Feb 2021 20:01:38 +0100 Subject: [PATCH 0751/1198] fix missing output --- src/fe-common/irc/fe-events-numeric.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c index 37fdf30a..f78289c0 100644 --- a/src/fe-common/irc/fe-events-numeric.c +++ b/src/fe-common/irc/fe-events-numeric.c @@ -724,6 +724,7 @@ void fe_events_numeric_init(void) signal_add("event 004", (SIGNAL_FUNC) event_received); signal_add("event 005", (SIGNAL_FUNC) event_received); signal_add("event 254", (SIGNAL_FUNC) event_received); + signal_add("event 354", (SIGNAL_FUNC) event_received); signal_add("event 364", (SIGNAL_FUNC) event_received); signal_add("event 365", (SIGNAL_FUNC) event_received); signal_add("event 381", (SIGNAL_FUNC) event_received); @@ -814,6 +815,7 @@ void fe_events_numeric_deinit(void) signal_remove("event 004", (SIGNAL_FUNC) event_received); signal_remove("event 005", (SIGNAL_FUNC) event_received); signal_remove("event 254", (SIGNAL_FUNC) event_received); + signal_remove("event 354", (SIGNAL_FUNC) event_received); signal_remove("event 364", (SIGNAL_FUNC) event_received); signal_remove("event 365", (SIGNAL_FUNC) event_received); signal_remove("event 381", (SIGNAL_FUNC) event_received); From 09c17c3302742be94da39996bf0ffac455bafd1e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 1 Feb 2021 21:59:32 +0100 Subject: [PATCH 0752/1198] maybe this matches the command now --- src/irc/core/channels-query.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 7274ab81..664b429e 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -400,7 +400,7 @@ void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *n /* if it was removed we may have an outstanding query */ if (was_removed) { - target_cmd = g_strdup_printf(WHO_Ps_PPtna_745, nick); + target_cmd = g_strdup_printf(WHO_Ps_PPtna_745 "\r\n", nick); /* remove queued WHO command */ prev = NULL; From b11f9733457bb191aebc81dc9734da200f9e7dba Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 6 Feb 2021 22:17:29 +0100 Subject: [PATCH 0753/1198] fix off by one --- src/irc/core/channels-query.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 664b429e..dc29e914 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -426,7 +426,7 @@ void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *n server->cmdcount--; } else { - prev = tmp; + prev = tmp->next; } } From 79be775f2bf653a886b351e3552d4c8cbdb35f26 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 26 Feb 2021 14:28:37 +0100 Subject: [PATCH 0754/1198] queue the who command on join --- src/irc/core/channels-query.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index dc29e914..ad8d898c 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -250,7 +250,8 @@ static void query_send(IRC_SERVER_REC *server, int query) cmd = NULL; } - irc_send_cmd(server, cmd); + /* queue the command */ + irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE); g_free(chanstr); g_free(chanstr_commas); From 3a929898e2c569412cd36e7c14a3ea1ff65955c8 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 26 Feb 2021 14:28:51 +0100 Subject: [PATCH 0755/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 39045de7..ccd000d5 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 34 +#define IRSSI_ABI_VERSION 35 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From a8144cd98fdb08c1d942195f65fbc604f7bd3055 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 26 Feb 2021 20:25:48 +0100 Subject: [PATCH 0756/1198] skip parsing empty tags Credit to OSS-Fuzz --- src/irc/core/irc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 96a09333..a5bd608b 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -433,6 +433,8 @@ GHashTable *irc_parse_message_tags(const char *tags) (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); split = g_strsplit(tags, ";", -1); for (tmp = split; *tmp != NULL; tmp++) { + if (*tmp[0] == '\0') + continue; kv = g_strsplit(*tmp, "=", 2); unescape_tag(kv[1]); g_hash_table_replace(hash, i_refstr_intern(kv[0]), From 4c069f5c8f3b63d8ba8556ba8292e1f5972508d6 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Feb 2021 18:31:00 +0100 Subject: [PATCH 0757/1198] stop parsing on lone tag escape It's C Credit to OSS-Fuzz --- src/irc/core/irc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index a5bd608b..8ecda85b 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -395,6 +395,8 @@ static void unescape_tag(char *tag) for (; *tmp != '\0'; tmp++, tag++) { if (*tmp == '\\') { tmp++; + if (*tmp == '\0') + break; switch (*tmp) { case ':': *tag = ';'; From 04b44a8f8d3bc12122bb583ec458c1a3c744c58c Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Feb 2021 21:02:48 +0100 Subject: [PATCH 0758/1198] Revert "queue the who command on join" This reverts commit 79be775f2bf653a886b351e3552d4c8cbdb35f26. --- src/irc/core/channels-query.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index ad8d898c..dc29e914 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -250,8 +250,7 @@ static void query_send(IRC_SERVER_REC *server, int query) cmd = NULL; } - /* queue the command */ - irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE); + irc_send_cmd(server, cmd); g_free(chanstr); g_free(chanstr_commas); From 6eeec6a1129c1ce050ea44f283a7f81c8cc70144 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Feb 2021 21:04:02 +0100 Subject: [PATCH 0759/1198] fix double free --- src/irc/core/channels-query.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index dc29e914..b90e32f5 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -78,7 +78,6 @@ static void sig_disconnected(IRC_SERVER_REC *server) rec = server->chanqueries; g_return_if_fail(rec != NULL); - g_hash_table_foreach(rec->accountqueries, (GHFunc) g_free, NULL); g_hash_table_destroy(rec->accountqueries); for (n = 0; n < CHANNEL_QUERIES; n++) g_slist_free(rec->queries[n]); From 18ee6bb6f9a16b993407fe27b964071dc2bf9e44 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Feb 2021 21:05:30 +0100 Subject: [PATCH 0760/1198] queue the who command on join --- src/irc/core/channels-query.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index b90e32f5..4e972121 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -521,7 +521,8 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char NULL); cmd = g_strdup_printf(WHO_Ps_PPtna_745, nick); g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick)); - irc_send_cmd(server, cmd); + /* queue the command */ + irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE); g_free(cmd); } } From b957d3ad4b948007f94d4fc9d3a46e21386f2680 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Feb 2021 21:30:29 +0100 Subject: [PATCH 0761/1198] add constants for WHOX queries --- src/irc/core/channels-query.c | 22 ++++++++++++++++++---- src/irc/core/irc-channels.h | 4 ++++ src/irc/core/irc-nicklist.c | 20 ++++++++++---------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 4e972121..97e982b7 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -50,7 +50,21 @@ loop: #include #include -#define WHO_Ps_PPtna_745 "WHO %s %%tna,745" +/* here are the WHOX commands we send. the full spec can be found on [1]. + + (1) WHOX_CHANNEL_FULL_CMD for getting the user list when we join a channel. we request the fields + c (channel), u (user), h (host), n (nick), f (flags), d (hops), a (important, account!), and + r (the real name goes last because it os the only that can contain spaces.) we request all + those fields as they are also included in the "regular" WHO reply we would get without WHOX. + + (2) WHOX_USERACCOUNT_CMD for getting the account names of people that joined. this code is + obviously only used when we don't have extended-joins. we request n (nick) and a (account) + only, and we only send WHO nick with this command. + + [1] https://github.com/UndernetIRC/ircu2/blob/u2_10_12_branch/doc/readme.who + */ +#define WHOX_CHANNEL_FULL_CMD "WHO %s %%tcuhnfdar," WHOX_CHANNEL_FULL_ID +#define WHOX_USERACCOUNT_CMD "WHO %s %%tna," WHOX_USERACCOUNT_ID static void sig_connected(IRC_SERVER_REC *server) { @@ -219,7 +233,7 @@ static void query_send(IRC_SERVER_REC *server, int query) case CHANNEL_QUERY_WHO: if (server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL) { - cmd = g_strdup_printf("WHO %s %%tcuhnfdar,743", chanstr_commas); + cmd = g_strdup_printf(WHOX_CHANNEL_FULL_CMD, chanstr_commas); } else { cmd = g_strdup_printf("WHO %s", chanstr_commas); } @@ -399,7 +413,7 @@ void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *n /* if it was removed we may have an outstanding query */ if (was_removed) { - target_cmd = g_strdup_printf(WHO_Ps_PPtna_745 "\r\n", nick); + target_cmd = g_strdup_printf(WHOX_USERACCOUNT_CMD "\r\n", nick); /* remove queued WHO command */ prev = NULL; @@ -519,7 +533,7 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char "event 354", "silent event whox useraccount", /* */ "", "event empty", /* */ NULL); - cmd = g_strdup_printf(WHO_Ps_PPtna_745, nick); + cmd = g_strdup_printf(WHOX_USERACCOUNT_CMD, nick); g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick)); /* queue the command */ irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE); diff --git a/src/irc/core/irc-channels.h b/src/irc/core/irc-channels.h index 67b550d5..0f955dd8 100644 --- a/src/irc/core/irc-channels.h +++ b/src/irc/core/irc-channels.h @@ -19,6 +19,10 @@ enum { CHANNEL_QUERIES }; +/* arbitrary 3-digit identifiers so we can find our WHOX responses */ +#define WHOX_CHANNEL_FULL_ID "743" +#define WHOX_USERACCOUNT_ID "745" + #define CHANNEL_IS_MODE_QUERY(a) ((a) != CHANNEL_QUERY_WHO) #define STRUCT_SERVER_REC IRC_SERVER_REC diff --git a/src/irc/core/irc-nicklist.c b/src/irc/core/irc-nicklist.c index f62f3d49..f62a96f2 100644 --- a/src/irc/core/irc-nicklist.c +++ b/src/irc/core/irc-nicklist.c @@ -274,7 +274,7 @@ static void event_who(SERVER_REC *server, const char *data) g_free(params); } -static void event_whox_743(SERVER_REC *server, const char *data) +static void event_whox_channel_full(SERVER_REC *server, const char *data) { char *params, *id, *nick, *channel, *user, *host, *stat, *hops, *account, *realname; @@ -283,7 +283,7 @@ static void event_whox_743(SERVER_REC *server, const char *data) params = event_get_params(data, 10, NULL, &id, &channel, &user, &host, &nick, &stat, &hops, &account, &realname); - if (g_strcmp0(id, "743") != 0) { + if (g_strcmp0(id, WHOX_CHANNEL_FULL_ID) != 0) { g_free(params); return; } @@ -293,7 +293,7 @@ static void event_whox_743(SERVER_REC *server, const char *data) g_free(params); } -static void event_whox_745(IRC_SERVER_REC *server, const char *data) +static void event_whox_useraccount(IRC_SERVER_REC *server, const char *data) { char *params, *id, *nick, *account; GSList *nicks, *tmp; @@ -302,7 +302,7 @@ static void event_whox_745(IRC_SERVER_REC *server, const char *data) params = event_get_params(data, 4, NULL, &id, &nick, &account); - if (g_strcmp0(id, "745") != 0) { + if (g_strcmp0(id, WHOX_USERACCOUNT_ID) != 0) { g_free(params); return; } @@ -601,10 +601,10 @@ void irc_nicklist_init(void) { signal_add_first("event nick", (SIGNAL_FUNC) event_nick); signal_add_first("event 352", (SIGNAL_FUNC) event_who); - signal_add_first("event 354", (SIGNAL_FUNC) event_whox_743); + signal_add_first("event 354", (SIGNAL_FUNC) event_whox_channel_full); signal_add("silent event who", (SIGNAL_FUNC) event_who); - signal_add("silent event whox", (SIGNAL_FUNC) event_whox_743); - signal_add("silent event whox useraccount", (SIGNAL_FUNC) event_whox_745); + signal_add("silent event whox", (SIGNAL_FUNC) event_whox_channel_full); + signal_add("silent event whox useraccount", (SIGNAL_FUNC) event_whox_useraccount); signal_add("silent event whois", (SIGNAL_FUNC) event_whois); signal_add_first("event 311", (SIGNAL_FUNC) event_whois); signal_add_first("whois away", (SIGNAL_FUNC) event_whois_away); @@ -628,10 +628,10 @@ void irc_nicklist_deinit(void) { signal_remove("event nick", (SIGNAL_FUNC) event_nick); signal_remove("event 352", (SIGNAL_FUNC) event_who); - signal_remove("event 354", (SIGNAL_FUNC) event_whox_743); + signal_remove("event 354", (SIGNAL_FUNC) event_whox_channel_full); signal_remove("silent event who", (SIGNAL_FUNC) event_who); - signal_remove("silent event whox", (SIGNAL_FUNC) event_whox_743); - signal_remove("silent event whox useraccount", (SIGNAL_FUNC) event_whox_745); + signal_remove("silent event whox", (SIGNAL_FUNC) event_whox_channel_full); + signal_remove("silent event whox useraccount", (SIGNAL_FUNC) event_whox_useraccount); signal_remove("silent event whois", (SIGNAL_FUNC) event_whois); signal_remove("event 311", (SIGNAL_FUNC) event_whois); signal_remove("whois away", (SIGNAL_FUNC) event_whois_away); From 53c91623c53ecdd94457a7fba826a1da0277f718 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 3 Mar 2021 17:39:19 +0100 Subject: [PATCH 0762/1198] fix level uninitialised Credit to OSS-Fuzz --- src/fe-common/irc/fe-irc-messages.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index d287bf1f..714b2eb2 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -87,11 +87,6 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, /* and clean the rest here */ cleantarget = get_visible_target(IRC_SERVER(server), cleantarget); - if (ignore_check_plus(server, nick, address, cleantarget, msg, &level, TRUE)) { - g_free(prefix); - return; - } - chanrec = channel_find(server, cleantarget); nickmode = channel_get_nickmode(chanrec, nick); @@ -111,6 +106,14 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, if (for_me) level |= MSGLEVEL_HILIGHT; + if (ignore_check_plus(server, nick, address, cleantarget, msg, &level, TRUE)) { + g_free(nickmode); + g_free(color); + g_free(optarget); + g_free(prefix); + return; + } + if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); From 4e1aad6679648c6ec0ee4d436b03dec5684eac5e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 5 Mar 2021 20:28:10 +0100 Subject: [PATCH 0763/1198] fix assertion failure when the line does not have text (yet) --- src/fe-text/textbuffer.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 8761507b..5a5ddf21 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -238,14 +238,15 @@ void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, g_string_truncate(str, 0); - ptr = textbuffer_line_get_text(buffer, line); - if (coloring == 0) { - tmp = ptr; - ptr = strip_codes(tmp); - g_free(tmp); + if ((ptr = textbuffer_line_get_text(buffer, line)) != NULL) { + if (coloring == 0) { + tmp = ptr; + ptr = strip_codes(tmp); + g_free(tmp); + } + g_string_append(str, ptr); + g_free(ptr); } - g_string_append(str, ptr); - g_free(ptr); } GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, From 5f1fe607e4f472bdf71ef55de8a1be0f0a1d0fff Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 3 Mar 2021 17:18:55 +0100 Subject: [PATCH 0764/1198] Test CIFuzz offering --- .github/workflows/cifuzz.yml | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 00000000..9f956d5c --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,40 @@ +name: CIFuzz +on: + pull_request: + paths: + - 'src/core/**/*.c' + - 'src/fe-common/core/**/*.c' + - 'src/fe-text/gui-*.c' + - 'src/irc/**/*.c' + - 'src/fe-common/irc/**/*.c' + - 'src/lib-config/**/*.c' + - 'tests/**/*.c' + - '.github/workflows/cifuzz.yml' +jobs: + Fuzzing: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer: [address, undefined, memory] + steps: + - name: Build Fuzzers (${{ matrix.sanitizer }}) + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'irssi' + dry-run: false + sanitizer: ${{ matrix.sanitizer }} + - name: Run Fuzzers (${{ matrix.sanitizer }}) + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'irssi' + fuzz-seconds: 600 + dry-run: false + sanitizer: ${{ matrix.sanitizer }} + - name: Upload Crash + uses: actions/upload-artifact@v1 + if: failure() && steps.build.outcome == 'success' + with: + name: ${{ matrix.sanitizer }}-artifacts + path: ./out/artifacts From f5339edbbc921dc225ba5fba2cc59d19b08db7c7 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 12 Mar 2021 21:15:58 +0100 Subject: [PATCH 0765/1198] fail redirects on freenode 263 --- src/irc/core/servers-redirect.c | 38 +++++++++++++++++++++++++++------ src/irc/core/servers-redirect.h | 5 ++--- src/perl/irc/Server.xs | 7 +++--- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c index 2790c75a..72601d34 100644 --- a/src/irc/core/servers-redirect.c +++ b/src/irc/core/servers-redirect.c @@ -39,6 +39,7 @@ typedef struct { int remote; int timeout; + int pos; GSList *start, *stop, *opt; /* char *event, int argpos, ... */ } REDIRECT_CMD_REC; @@ -151,13 +152,11 @@ void server_redirect_register(const char *command, va_end(va); - server_redirect_register_list(command, remote, timeout, - start, stop, opt); + server_redirect_register_list(command, remote, timeout, start, stop, opt, 0); } -void server_redirect_register_list(const char *command, - int remote, int timeout, - GSList *start, GSList *stop, GSList *opt) +void server_redirect_register_list(const char *command, int remote, int timeout, GSList *start, + GSList *stop, GSList *opt, int pos) { REDIRECT_CMD_REC *rec; gpointer key, value; @@ -181,7 +180,8 @@ void server_redirect_register_list(const char *command, rec->start = start; rec->stop = stop; rec->opt = opt; - g_hash_table_insert(command_redirects, rec->name, rec); + rec->pos = pos; + g_hash_table_insert(command_redirects, rec->name, rec); } void server_redirect_event(IRC_SERVER_REC *server, const char *command, @@ -483,6 +483,32 @@ static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event, } } + if (g_strcmp0("event 263", event) == 0) { /* RPL_TRYAGAIN */ + char *params, *command; + params = event_get_params(args, 3, NULL, &command, NULL); + + for (tmp = server->redirects; tmp != NULL; tmp = next) { + REDIRECT_REC *rec = tmp->data; + + next = tmp->next; + + if (rec == redirect) + break; + + if (g_slist_find(server->redirect_active, rec) != NULL) + continue; + + if (redirect_args_match(rec->cmd->name, command, rec->cmd->pos)) { + /* the server crashed our command with RPL_TRYAGAIN, send the + failure */ + rec->aborted = TRUE; + redirect_abort(server, rec); + break; + } + } + g_free(params); + } + /* remove the destroyed, non-remote and timeouted remote redirections that should have happened before this redirection */ now = time(NULL); diff --git a/src/irc/core/servers-redirect.h b/src/irc/core/servers-redirect.h index f8ca605f..0d8b63f8 100644 --- a/src/irc/core/servers-redirect.h +++ b/src/irc/core/servers-redirect.h @@ -22,9 +22,8 @@ void server_redirect_register(const char *command, int remote, int timeout, ...); /* start/stop/opt lists shouldn't be free'd after, and their strings should be dynamically allocated */ -void server_redirect_register_list(const char *command, - int remote, int timeout, - GSList *start, GSList *stop, GSList *opt); +void server_redirect_register_list(const char *command, int remote, int timeout, GSList *start, + GSList *stop, GSList *opt, int pos); /* Specify that the next command sent to server will be redirected. NOTE: This command MUST be called before irc_send_cmd(). diff --git a/src/perl/irc/Server.xs b/src/perl/irc/Server.xs index a42f5c82..54361ec9 100644 --- a/src/perl/irc/Server.xs +++ b/src/perl/irc/Server.xs @@ -97,10 +97,9 @@ server_redirect_register(command, remote, timeout, start, stop, opt) SV *stop SV *opt CODE: - server_redirect_register_list(command, remote, timeout, - register_hash2list(hvref(start)), - register_hash2list(hvref(stop)), - register_hash2list(hvref(opt))); + server_redirect_register_list(command, remote, timeout, register_hash2list(hvref(start)), + register_hash2list(hvref(stop)), + register_hash2list(hvref(opt)), 1); void server_redirect_event(server, command, count, arg, remote, failure_signal, signals) From 9ce3420440e0305031a2d81321915084f62e79f0 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 12 Mar 2021 23:17:53 +0100 Subject: [PATCH 0766/1198] printformats --- src/perl/ui/Themes.xs | 49 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/perl/ui/Themes.xs b/src/perl/ui/Themes.xs index ab7c1909..e9e56395 100644 --- a/src/perl/ui/Themes.xs +++ b/src/perl/ui/Themes.xs @@ -1,20 +1,26 @@ #define PERL_NO_GET_CONTEXT #include "module.h" -static void printformat_perl(TEXT_DEST_REC *dest, char *format, char **arglist) +static void printformat_module_perl(TEXT_DEST_REC *dest, const char *module, char *format, + char **arglist) { - char *module; int formatnum; - module = g_strdup(perl_get_package()); formatnum = format_find_tag(module, format); if (formatnum < 0) { die("printformat(): unregistered format '%s'", format); - g_free(module); return; } printformat_module_dest_charargs(module, dest, formatnum, arglist); +} + +static void printformat_perl(TEXT_DEST_REC *dest, char *format, char **arglist) +{ + char *module; + + module = g_strdup(perl_get_package()); + printformat_module_perl(dest, module, format, arglist); g_free(module); } @@ -226,6 +232,41 @@ CODE: printformat_perl(&dest, format, arglist); +#******************************* +MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::TextDest +#******************************* + +void +printformat(dest, format, ...) + Irssi::UI::TextDest dest + char *format +PREINIT: + char *arglist[MAX_FORMAT_PARAMS + 1]; + int n; +CODE: + memset(arglist, 0, sizeof(arglist)); + for (n = 2; n < items && n < MAX_FORMAT_PARAMS + 2; n++) { + arglist[n - 2] = SvPV_nolen(ST(n)); + } + + printformat_perl(dest, format, arglist); + +void +printformat_module(dest, module, format, ...) + Irssi::UI::TextDest dest + char *module + char *format +PREINIT: + char *arglist[MAX_FORMAT_PARAMS + 1]; + int n; +CODE: + memset(arglist, 0, sizeof(arglist)); + for (n = 3; n < items && n < MAX_FORMAT_PARAMS + 3; n++) { + arglist[n - 3] = SvPV_nolen(ST(n)); + } + + printformat_module_perl(dest, module, format, arglist); + #******************************* MODULE = Irssi::UI::Themes PACKAGE = Irssi::UI::Theme PREFIX = theme_ #******************************* From 7d213da88acb6dfbdcae799dba1d8e9c05490c67 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 28 Jan 2021 21:47:11 +0100 Subject: [PATCH 0767/1198] update clang-format to clang-format-11, fixes enum bug --- .github/workflows/clangformat.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/clangformat.yml b/.github/workflows/clangformat.yml index b959fe92..59beb928 100644 --- a/.github/workflows/clangformat.yml +++ b/.github/workflows/clangformat.yml @@ -2,8 +2,10 @@ on: [pull_request] name: clang-format jobs: check-clang-format: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: + - name: install clang-format + run: sudo apt install clang-format-11 - uses: actions/checkout@main - name: fetch target ref run: @@ -18,7 +20,7 @@ jobs: - name: run git-clang-format and Check if no changes are needed run: | - git-clang-format-9 --diff FETCH_HEAD HEAD | tee git-clang-format.diff + CLANG_FORMAT=clang-format-11 git-clang-format-11 --diff FETCH_HEAD HEAD | tee git-clang-format.diff cmp -s <(echo no modified files to format) git-clang-format.diff || cmp -s <(echo -n) git-clang-format.diff - uses: actions/upload-artifact@v1 if: failure() From 25ad30d5e42e918358ef325ea59db9d52ea477f3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 13 Mar 2021 21:51:01 +0100 Subject: [PATCH 0768/1198] add format_string_expand to Perl --- src/perl/ui/Formats.xs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs index 8e34b7b9..fbd0cbf4 100644 --- a/src/perl/ui/Formats.xs +++ b/src/perl/ui/Formats.xs @@ -50,6 +50,16 @@ format_real_length(str, len) char *str int len +void +format_string_expand(str) + char *str +PREINIT: + char *ret; +PPCODE: + ret = format_string_expand(str, NULL); + XPUSHs(sv_2mortal(new_pv(ret))); + g_free(ret); + void strip_codes(input) char *input From 030da3ec9c62e7c30b4a6ebe49a285aed278a5b5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 14 Mar 2021 18:31:56 +0100 Subject: [PATCH 0769/1198] add format_string_expand and format_string_unexpand methods to Perl --- src/fe-common/core/formats.c | 163 +++++++++++++++++++++++++++++++ src/fe-common/core/formats.h | 1 + src/fe-text/textbuffer-formats.c | 6 +- src/fe-text/textbuffer-formats.h | 2 +- src/fe-text/textbuffer-view.c | 2 +- src/fe-text/textbuffer.c | 10 +- src/fe-text/textbuffer.h | 7 ++ src/perl/textui/TextBuffer.xs | 32 ++++++ src/perl/ui/Formats.xs | 9 ++ 9 files changed, 226 insertions(+), 6 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index de3898ee..51588afb 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -38,6 +38,7 @@ static const char *format_backs = "04261537"; static const char *format_fores = "kbgcrmyw"; static const char *format_boldfores = "KBGCRMYW"; +static const char *ext_color_al = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static int signal_gui_print_text; static int hide_text_style, hide_server_tags, hide_colors; @@ -121,10 +122,23 @@ void format_ext_color(GString *out, int bg, int color) : FORMAT_COLOR_EXT3); g_string_append_c(out, FORMAT_COLOR_NOCHANGE + ((color-0x10)%0x50)); } + if (!bg && color < 0x10) g_string_append_c(out, FORMAT_COLOR_NOCHANGE); } +static void format_ext_color_unexpand(GString *out, gboolean bg, int base, char color) +{ + unsigned char value = base + (unsigned char) color - FORMAT_COLOR_NOCHANGE - 0x10; + + g_string_append_c(out, '%'); + g_string_append_c(out, bg ? 'x' : 'X'); + if (value > 214) + value += 10; + g_string_append_c(out, '1' + (value / 36)); + g_string_append_c(out, ext_color_al[value % 36]); +} + #ifdef TERM_TRUECOLOR void unformat_24bit_color(char **ptr, int off, int *fgcolor, int *bgcolor, int *flags) { @@ -152,6 +166,28 @@ void unformat_24bit_color(char **ptr, int off, int *fgcolor, int *bgcolor, int * *flags |= GUI_PRINT_FLAG_COLOR_24_FG; } } + +static void format_24bit_color_unexpand(GString *out, int off, const char **ptr) +{ + unsigned int color; + unsigned char rgbx[4]; + unsigned int i; + for (i = 0; i < 4; ++i) { + if ((*ptr)[i + off] == '\0') + return; + rgbx[i] = (*ptr)[i + off]; + } + rgbx[3] -= 0x20; + *ptr += 4; + g_string_append_c(out, '%'); + for (i = 0; i < 3; ++i) { + if (rgbx[3] & (0x10 << i)) + rgbx[i] -= 0x20; + } + color = rgbx[0] << 16 | rgbx[1] << 8 | rgbx[2]; + g_string_append_c(out, rgbx[3] & 0x1 ? 'z' : 'Z'); + g_string_append_printf(out, "%06X", color); +} #endif void format_24bit_color(GString *out, int bg, unsigned int color) @@ -308,6 +344,16 @@ int format_expand_styles(GString *out, const char **format, int *flags) format_24bit_color(out, fmt == 'z', tmp2); break; + case 'o': + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_COLOR_NOCHANGE); + g_string_append_c(out, (char) -1); + break; + case 'O': + g_string_append_c(out, 4); + g_string_append_c(out, (char) -1); + g_string_append_c(out, FORMAT_COLOR_NOCHANGE); + break; default: /* check if it's a background color */ p = strchr(format_backs, fmt); @@ -557,6 +603,123 @@ char *format_string_expand(const char *text, int *flags) return ret; } +inline static void format_flag_unexpand(GString *out, char flag) +{ + g_string_append_c(out, '%'); + g_string_append_c(out, flag); +} + +char *format_string_unexpand(const char *text, int flags) +{ + GString *out; + + g_return_val_if_fail(text != NULL, NULL); + + out = g_string_sized_new(strlen(text)); + while (*text != '\0') { + switch (*text) { + case '%': + g_string_append(out, "%%"); + break; + case 4: + text++; + if (*text == '\0') + break; + switch (*text) { + case FORMAT_COLOR_EXT1: + format_ext_color_unexpand(out, FALSE, 0x10, *++text); + break; + case FORMAT_COLOR_EXT1_BG: + format_ext_color_unexpand(out, TRUE, 0x10, *++text); + break; + case FORMAT_COLOR_EXT2: + format_ext_color_unexpand(out, FALSE, 0x60, *++text); + break; + case FORMAT_COLOR_EXT2_BG: + format_ext_color_unexpand(out, TRUE, 0x60, *++text); + break; + case FORMAT_COLOR_EXT3: + format_ext_color_unexpand(out, FALSE, 0xb0, *++text); + break; + case FORMAT_COLOR_EXT3_BG: + format_ext_color_unexpand(out, TRUE, 0xb0, *++text); + break; +#ifdef TERM_TRUECOLOR + case FORMAT_COLOR_24: + format_24bit_color_unexpand(out, 1, &text); + break; +#endif + case FORMAT_STYLE_BLINK: + format_flag_unexpand(out, 'F'); + break; + case FORMAT_STYLE_UNDERLINE: + format_flag_unexpand(out, 'U'); + break; + case FORMAT_STYLE_BOLD: + format_flag_unexpand(out, '9'); + break; + case FORMAT_STYLE_REVERSE: + format_flag_unexpand(out, '8'); + break; + case FORMAT_STYLE_INDENT: + format_flag_unexpand(out, '|'); + break; + case FORMAT_STYLE_ITALIC: + format_flag_unexpand(out, 'I'); + break; + case FORMAT_STYLE_DEFAULTS: + format_flag_unexpand(out, 'N'); + break; + case FORMAT_STYLE_CLRTOEOL: + format_flag_unexpand(out, '>'); + break; + case FORMAT_STYLE_MONOSPACE: + format_flag_unexpand(out, '#'); + break; + default: + if (*text != FORMAT_COLOR_NOCHANGE) { + unsigned int value = (unsigned char) *text - '0'; + + g_string_append_c(out, '%'); + if (value < 8) { + g_string_append_c(out, format_fores[value]); + } else if (value < 16) { + g_string_append_c(out, format_boldfores[value - 8]); + } else { + g_string_append_c(out, 'O'); + } + } + text++; + if (*text == '\0') + break; + + if (*text != FORMAT_COLOR_NOCHANGE) { + unsigned int value = (unsigned char) *text - '0'; + + g_string_append_c(out, '%'); + if (value < 8) { + g_string_append_c(out, format_backs[value]); + } else if (value < 16) { + g_string_append(out, "x0"); + g_string_append_c(out, ext_color_al[value]); + } else { + g_string_append_c(out, 'o'); + } + } + break; + } + break; + default: + g_string_append_c(out, *text); + break; + } + if (*text != '\0') + text++; + } + + return g_string_free(out, FALSE); +} + static char *format_get_text_args(TEXT_DEST_REC *dest, const char *text, char **arglist) { diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 530f42bf..12274638 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -81,6 +81,7 @@ int format_get_length(const char *str); int format_real_length(const char *str, int len); char *format_string_expand(const char *text, int *flags); +char *format_string_unexpand(const char *text, int flags); char *format_get_text(const char *module, WINDOW_REC *window, void *server, const char *target, diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index e3d331f1..2aa06cb2 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -344,7 +344,7 @@ static char *fallback_format(TEXT_BUFFER_FORMAT_REC *format_rec) return g_string_free(bs, FALSE); } -char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) +char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean raw) { TEXT_DEST_REC dest; GUI_WINDOW_REC *gui; @@ -430,6 +430,10 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line) format_create_dest(&dest, NULL, NULL, line->info.level, buffer->window); text = g_strdup(line->info.text); } + + if (raw) + return text; + tmp = parse_colors(&dest, text); g_free(text); return tmp; diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index d595df8a..17a907c1 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -23,7 +23,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec); void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec); -char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line); +char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean raw); void textbuffer_formats_init(void); void textbuffer_formats_deinit(void); diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index 9af3cb3c..79f3522c 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -274,7 +274,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line) linecount = 1; lines = NULL; - line_text = textbuffer_line_get_text(view->buffer, line); + line_text = textbuffer_line_get_text(view->buffer, line, FALSE); if (line_text != NULL) { for (ptr = (unsigned char *) line_text;;) { if (*ptr == '\0') diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 5a5ddf21..25fce22f 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -238,11 +238,15 @@ void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, g_string_truncate(str, 0); - if ((ptr = textbuffer_line_get_text(buffer, line)) != NULL) { - if (coloring == 0) { + if ((ptr = textbuffer_line_get_text(buffer, line, coloring == COLORING_RAW)) != NULL) { + if (coloring == COLORING_STRIP) { tmp = ptr; ptr = strip_codes(tmp); g_free(tmp); + } else if (coloring == COLORING_UNEXPAND) { + tmp = ptr; + ptr = format_string_unexpand(tmp, 0); + g_free(tmp); } g_string_append(str, ptr); g_free(ptr); @@ -288,7 +292,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, (line->info.level & nolevel) == 0; if (*text != '\0') { - textbuffer_line2text(buffer, line, FALSE, str); + textbuffer_line2text(buffer, line, 0, str); if (line_matched) { line_matched = regexp ? diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index bb4e820a..5f5f9a27 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -11,6 +11,13 @@ enum { LINE_CMD_EOL=0x80, /* line ends here */ }; +enum { + COLORING_STRIP = 0, + COLORING_EXPAND = 1, + COLORING_UNEXPAND = 2, + COLORING_RAW = 3, +}; + struct _TEXT_BUFFER_FORMAT_REC; typedef struct { diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 4859f3da..6695eae0 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -6,6 +6,38 @@ MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi PROTOTYPES: ENABLE +#******************************* +MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi +#******************************* + +int +COLORING_STRIP() +CODE: + RETVAL = COLORING_STRIP; +OUTPUT: + RETVAL + +int +COLORING_EXPAND() +CODE: + RETVAL = COLORING_EXPAND; +OUTPUT: + RETVAL + +int +COLORING_UNEXPAND() +CODE: + RETVAL = COLORING_UNEXPAND; +OUTPUT: + RETVAL + +int +COLORING_RAW() +CODE: + RETVAL = COLORING_RAW; +OUTPUT: + RETVAL + #******************************* MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi::TextUI::Line PREFIX = textbuffer_line_ #******************************* diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs index fbd0cbf4..c03e6bb5 100644 --- a/src/perl/ui/Formats.xs +++ b/src/perl/ui/Formats.xs @@ -70,6 +70,15 @@ PPCODE: XPUSHs(sv_2mortal(new_pv(ret))); g_free(ret); +void +format_string_unexpand(input) + char *input +PREINIT: + char *ret; +PPCODE: + ret = format_string_unexpand(input, 0); + XPUSHs(sv_2mortal(new_pv(ret))); + g_free(ret); void format_create_dest(target, level=MSGLEVEL_CLIENTNOTICE, window=NULL) From a0142ce38463e3835ff67e14efcafefdd6d4a084 Mon Sep 17 00:00:00 2001 From: jesopo Date: Wed, 17 Mar 2021 20:29:07 +0000 Subject: [PATCH 0770/1198] add IRC_CHATNET_REC->usermode to perl chatnet hashes --- src/perl/irc/Irc.xs | 9 +++++++++ src/perl/irc/module.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index f973da22..7ee47180 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -3,6 +3,12 @@ static int initialized = FALSE; +static void perl_irc_chatnet_fill_hash(HV *hv, IRC_CHATNET_REC *chatnet) +{ + perl_chatnet_fill_hash(hv, (CHATNET_REC *) chatnet); + (void) hv_store(hv, "usermode", 8, new_pv(chatnet->usermode), 0); +} + static void perl_irc_connect_fill_hash(HV *hv, IRC_SERVER_CONNECT_REC *conn) { perl_connect_fill_hash(hv, (SERVER_CONNECT_REC *) conn); @@ -233,6 +239,9 @@ CODE: chat_type = chat_protocol_lookup("IRC"); + irssi_add_object(module_get_uniq_id("CHATNET", 0), + chat_type, "Irssi::Irc::Chatnet", + (PERL_OBJECT_FUNC) perl_irc_chatnet_fill_hash); irssi_add_object(module_get_uniq_id("SERVER CONNECT", 0), chat_type, "Irssi::Irc::Connect", (PERL_OBJECT_FUNC) perl_irc_connect_fill_hash); diff --git a/src/perl/irc/module.h b/src/perl/irc/module.h index 71801419..3dcfb065 100644 --- a/src/perl/irc/module.h +++ b/src/perl/irc/module.h @@ -1,6 +1,7 @@ #include #include +#include #include #include #include From 0b82f14151dad5f106c208d25818816a8f782a54 Mon Sep 17 00:00:00 2001 From: Misty De Meo Date: Fri, 26 Mar 2021 19:20:22 -0700 Subject: [PATCH 0771/1198] Add a check for term.h If term.h is present, use that instead of defining prototypes for the terminfo functions in terminfo-core.c. This causes problems on certain platforms (e.g. Apple aarch64) due to the functions being prototyped as non-variadic but called as variadic. If term.h isn't found, it falls back to the old behaviour. Fixes #1238. --- configure.ac | 4 ++++ meson.build | 1 + src/fe-text/terminfo-core.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index cafd2970..87baddec 100644 --- a/configure.ac +++ b/configure.ac @@ -355,6 +355,10 @@ if test "x$want_textui" != "xno"; then AC_SUBST(TEXTUI_LIBS) LIBS="$TEXTUI_NO_LIBS" + AC_CHECK_HEADER([term.h], [ + AC_DEFINE(HAVE_TERM_H, [], [Define to 1 if you have the `term.h' header.]) + ]) + fi dnl ** diff --git a/meson.build b/meson.build index f54db548..43a6eced 100644 --- a/meson.build +++ b/meson.build @@ -525,6 +525,7 @@ headers = [ 'sys/time.h', 'sys/utsname.h', 'dirent.h', + 'term.h', 'unistd.h', ] foreach h : headers diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index d2273d71..6be54c32 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -12,6 +12,9 @@ inline static int term_putchar(int c) return fputc(c, current_term->out); } +#ifdef HAVE_TERM_H +#include +#else /* Don't bother including curses.h because of these - they might not even be defined there */ char *tparm(); @@ -21,6 +24,8 @@ int setupterm(); char *tigetstr(); int tigetnum(); int tigetflag(); +#endif + #define term_getstr(x, buffer) tigetstr(x.ti_name) #define term_getnum(x) tigetnum(x.ti_name); #define term_getflag(x) tigetflag(x.ti_name); From c5cc58d34e0f9a26aeec8481fa843d89d01b132f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Mar 2021 21:17:15 +0100 Subject: [PATCH 0772/1198] remove unused include --- src/core/tls.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/tls.h b/src/core/tls.h index 791bde86..1e1a1038 100644 --- a/src/core/tls.h +++ b/src/core/tls.h @@ -21,8 +21,6 @@ #include -#include - typedef struct _TLS_REC TLS_REC; typedef struct _TLS_CERT_REC TLS_CERT_REC; typedef struct _TLS_CERT_ENTRY_REC TLS_CERT_ENTRY_REC; From 8b597cb75320c7c6ba4fcaefc75c8020899f465c Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 1 Apr 2021 21:21:06 +0200 Subject: [PATCH 0773/1198] fix clang formatting --- .clang-format | 2 +- src/perl/irc/Irc.xs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.clang-format b/.clang-format index 1180910e..a0cb79c0 100644 --- a/.clang-format +++ b/.clang-format @@ -27,7 +27,7 @@ Language: Cpp Cpp11BracedListStyle: false MaxEmptyLinesToKeep: 1 PointerAlignment: Right -SortIncludes: true +SortIncludes: false SpaceAfterCStyleCast: true SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 7ee47180..33be93d5 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -239,9 +239,8 @@ CODE: chat_type = chat_protocol_lookup("IRC"); - irssi_add_object(module_get_uniq_id("CHATNET", 0), - chat_type, "Irssi::Irc::Chatnet", - (PERL_OBJECT_FUNC) perl_irc_chatnet_fill_hash); + irssi_add_object(module_get_uniq_id("CHATNET", 0), chat_type, "Irssi::Irc::Chatnet", + (PERL_OBJECT_FUNC) perl_irc_chatnet_fill_hash); irssi_add_object(module_get_uniq_id("SERVER CONNECT", 0), chat_type, "Irssi::Irc::Connect", (PERL_OBJECT_FUNC) perl_irc_connect_fill_hash); From 4c25bef29c9ab5e5892c66800fbc03064d788b02 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 1 Apr 2021 21:53:30 +0200 Subject: [PATCH 0774/1198] don't bother if we don't have a nick Credit to OSS-Fuzz --- src/irc/core/massjoin.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/irc/core/massjoin.c b/src/irc/core/massjoin.c index 61e2615f..b8b8912f 100644 --- a/src/irc/core/massjoin.c +++ b/src/irc/core/massjoin.c @@ -72,6 +72,11 @@ static void event_join(IRC_SERVER_REC *server, const char *data, /* add user to nicklist */ nickrec = irc_nicklist_insert(chanrec, nick, FALSE, FALSE, FALSE, send_massjoin, NULL); + if (nickrec == NULL) { + /* invalid nick? */ + g_free(params); + return; + } if (*account != '\0' && g_strcmp0(nickrec->account, account) != 0) { nicklist_set_account(CHANNEL(chanrec), nickrec, account); } From 80926476fc4c17dea9f24f9da753f7443b8c05e1 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 15 Jan 2021 23:32:25 +0100 Subject: [PATCH 0775/1198] do not beep on hidden lines with /set beep_msg_level ... -hidden --- src/core/settings.c | 17 +++++++++++++++++ src/core/settings.h | 1 + src/fe-common/core/printtext.c | 18 ++++++++++++++++-- src/perl/common/Settings.xs | 4 ++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/core/settings.c b/src/core/settings.c index 04c7bbe6..28f953ba 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -138,6 +138,23 @@ int settings_get_level(const char *key) return str == NULL ? 0 : level2bits(str, NULL); } +int settings_get_level_negative(const char *key) +{ + const char *str, *tmp, *all_levels; + int levels; + + str = settings_get_str_type(key, SETTING_TYPE_LEVEL); + if (str == NULL) + return 0; + + all_levels = bits2level(~0); + tmp = g_strdup_printf("%s %s", all_levels, str); + levels = level2bits(tmp, NULL) ^ level2bits(all_levels, NULL); + g_free((char *) tmp); + g_free((char *) all_levels); + return levels; +} + int settings_get_size(const char *key) { const char *str; diff --git a/src/core/settings.h b/src/core/settings.h index 3a8a4646..9c78b3db 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -66,6 +66,7 @@ int settings_get_int(const char *key); int settings_get_bool(const char *key); int settings_get_time(const char *key); /* as milliseconds */ int settings_get_level(const char *key); +int settings_get_level_negative(const char *key); int settings_get_size(const char *key); /* as bytes */ int settings_get_choice(const char *key); char *settings_get_print(SETTINGS_REC *rec); diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index 6869fba3..18652689 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -32,13 +32,14 @@ #include #include -static int beep_msg_level, beep_when_away, beep_when_window_active; +static int beep_msg_level, beep_msg_level_ignore, beep_when_away, beep_when_window_active; static int signal_gui_print_text_finished; static int signal_print_starting; static int signal_print_text; static int signal_print_format; static int signal_print_noformat; +static int signal_window_hilight_check; static int sending_print_starting; @@ -404,7 +405,18 @@ static void msg_beep_check(TEXT_DEST_REC *dest) (beep_when_away || (dest->server != NULL && !dest->server->usermode_away)) && (beep_when_window_active || dest->window != active_win)) { - signal_emit("beep", 0); + if (beep_msg_level_ignore & MSGLEVEL_HIDDEN) { + int cb_ignore = 0; + if (signal_emit_id(signal_window_hilight_check, 4, dest, NULL, NULL, + &cb_ignore), + cb_ignore) { + return; + } + } else if (beep_msg_level_ignore & dest->level) { + return; + } + + signal_emit("beep", 0); } } @@ -521,6 +533,7 @@ static void sig_gui_dialog(const char *type, const char *text) static void read_settings(void) { beep_msg_level = settings_get_level("beep_msg_level"); + beep_msg_level_ignore = settings_get_level_negative("beep_msg_level"); beep_when_away = settings_get_bool("beep_when_away"); beep_when_window_active = settings_get_bool("beep_when_window_active"); } @@ -533,6 +546,7 @@ void printtext_init(void) signal_print_text = signal_get_uniq_id("print text"); signal_print_format = signal_get_uniq_id("print format"); signal_print_noformat = signal_get_uniq_id("print noformat"); + signal_window_hilight_check = signal_get_uniq_id("window hilight check"); read_settings(); signal_add("print text", (SIGNAL_FUNC) sig_print_text); diff --git a/src/perl/common/Settings.xs b/src/perl/common/Settings.xs index 20596c86..2da23400 100644 --- a/src/perl/common/Settings.xs +++ b/src/perl/common/Settings.xs @@ -96,6 +96,10 @@ int settings_get_level(key) char *key +int +settings_get_level_negative(key) + char *key + int settings_get_size(key) char *key From 7a3a383772fd50b6ae5ce7f0418d22871b2c28d5 Mon Sep 17 00:00:00 2001 From: ihsinme Date: Fri, 2 Apr 2021 14:21:06 +0300 Subject: [PATCH 0776/1198] Update sasl.c --- src/irc/core/sasl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/sasl.c b/src/irc/core/sasl.c index 22a10ec7..9bc40ff2 100644 --- a/src/irc/core/sasl.c +++ b/src/irc/core/sasl.c @@ -158,6 +158,7 @@ static gboolean sasl_reassemble_incoming(IRC_SERVER_REC *server, const char *fra * Fail authentication with this server. They have sent too much data. */ if (enc_req->len > AUTHENTICATE_MAX_SIZE) { + g_string_free(enc_req, TRUE); return FALSE; } From d20d2753da32d38bf5a4b3749f4daa10b8b8a86d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 15 Mar 2021 20:24:00 +0100 Subject: [PATCH 0777/1198] autoload modules from default setting --- src/core/core.c | 1 + src/fe-common/core/fe-common-core.c | 1 + src/fe-common/core/fe-modules.c | 18 +++++++++++++++++- src/fe-text/irssi.c | 17 +++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/core/core.c b/src/core/core.c index 34649c81..cbe3eb7c 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -269,6 +269,7 @@ void core_init(void) settings_add_str("misc", "ignore_signals", ""); settings_add_bool("misc", "override_coredump_limit", FALSE); settings_add_bool("misc", "quit_on_hup", FALSE); + settings_add_str("misc", "autoload_modules", "perl otr"); #ifdef HAVE_SYS_RESOURCE_H getrlimit(RLIMIT_CORE, &orig_core_rlimit); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 8f412198..63df1698 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -464,6 +464,7 @@ void fe_common_core_finish_init(void) signal_emit("setup changed", 0); autorun_startup(); + signal_emit("module autoload", 0); autoconnect_servers(); } diff --git a/src/fe-common/core/fe-modules.c b/src/fe-common/core/fe-modules.c index 9ad594cb..01b603f5 100644 --- a/src/fe-common/core/fe-modules.c +++ b/src/fe-common/core/fe-modules.c @@ -170,15 +170,25 @@ static void cmd_load(const char *data) char *rootmodule, *submodule; char **module_prefixes; void *free_arg; + gboolean silent; + GHashTable *optlist; g_return_if_fail(data != NULL); - if (!cmd_get_params(data, &free_arg, 2 , &rootmodule, &submodule)) + if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS, "load", &optlist, &rootmodule, + &submodule)) return; + silent = g_hash_table_lookup(optlist, "silent") != NULL; + if (*rootmodule == '\0') cmd_load_list(); else { + if (silent) { + signal_add_first("module error", (SIGNAL_FUNC) signal_stop); + signal_add_first("module loaded", (SIGNAL_FUNC) signal_stop); + } + module_prefixes = module_prefixes_get(); if (*submodule == '\0') module_load(rootmodule, module_prefixes); @@ -187,6 +197,11 @@ static void cmd_load(const char *data) module_prefixes); } module_prefixes_free(module_prefixes); + + if (silent) { + signal_remove("module error", (SIGNAL_FUNC) signal_stop); + signal_remove("module loaded", (SIGNAL_FUNC) signal_stop); + } } cmd_params_free(free_arg); @@ -244,6 +259,7 @@ void fe_modules_init(void) command_bind("load", NULL, (SIGNAL_FUNC) cmd_load); command_bind("unload", NULL, (SIGNAL_FUNC) cmd_unload); + command_set_options("load", "silent"); } void fe_modules_deinit(void) diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 5c20eb37..fbaa303a 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -102,6 +102,21 @@ static void sig_settings_userinfo_changed(gpointer changedp) user_settings_changed = GPOINTER_TO_UINT(changedp); } +static void sig_autoload_modules(void) +{ + char **list, **module; + list = g_strsplit_set(settings_get_str("autoload_modules"), " ,", -1); + for (module = list; *module != NULL; module++) { + char *tmp; + if ((tmp = strchr(*module, ':')) != NULL) + *tmp = ' '; + tmp = g_strdup_printf("-silent %s", *module); + signal_emit("command load", 1, tmp); + g_free(tmp); + } + g_strfreev(list); +} + /* redraw irssi's screen.. */ void irssi_redraw(void) { @@ -159,6 +174,7 @@ static void textui_init(void) theme_register(gui_text_formats); signal_add("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed); + signal_add("module autoload", (SIGNAL_FUNC) sig_autoload_modules); signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit); } @@ -262,6 +278,7 @@ static void textui_deinit(void) dirty_check(); /* one last time to print any quit messages */ signal_remove("settings userinfo changed", (SIGNAL_FUNC) sig_settings_userinfo_changed); + signal_remove("module autoload", (SIGNAL_FUNC) sig_autoload_modules); signal_remove("gui exit", (SIGNAL_FUNC) sig_exit); lastlog_deinit(); From b4ab8c1ada0ca01db97eadd6c0fd412668920326 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 3 Apr 2021 21:32:04 +0200 Subject: [PATCH 0778/1198] missing strdup on netsplits w/o chan --- src/fe-common/irc/fe-netsplit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c index 4b7850da..b76d4ce7 100644 --- a/src/fe-common/irc/fe-netsplit.c +++ b/src/fe-common/irc/fe-netsplit.c @@ -320,9 +320,9 @@ static void split_print(NETSPLIT_REC *rec, SERVER_REC *server) char *chanstr; chan = rec->channels->data; - chanstr = chan == NULL ? "" : - g_strconcat(chan->op ? "@" : - (chan->voice ? "+" : ""), chan->name, NULL); + chanstr = chan == NULL ? + g_strdup("") : + g_strconcat(chan->op ? "@" : (chan->voice ? "+" : ""), chan->name, NULL); printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_NETSPLITS_LINE, rec->nick, chanstr, rec->server->server, From efd705ba594fa50f7b04c3f0b415fa4173b8a2b5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 3 Apr 2021 21:54:53 +0200 Subject: [PATCH 0779/1198] fix crash on /connect /dev/null --- src/core/servers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/servers.c b/src/core/servers.c index a20d5f4a..143158ba 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -244,7 +244,9 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, server->no_reconnect = TRUE; server->connection_lost = TRUE; - server->connrec->last_failed_family = ip->family; + if (ip != NULL) { + server->connrec->last_failed_family = ip->family; + } server_connect_failed(server, errmsg2 ? errmsg2 : errmsg); g_free(errmsg2); } else { From 1e54b92220b0eba2af63226d41e9c8ea197677d0 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 3 Apr 2021 22:38:00 +0200 Subject: [PATCH 0780/1198] fix crash on /connect -tls fixes #1239 --- src/core/servers.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/servers.c b/src/core/servers.c index 143158ba..77b88fa9 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -208,7 +208,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, const char *errmsg; char *errmsg2; char ipaddr[MAX_IP_LEN]; - int port; + int port = 0; g_return_if_fail(ip != NULL || unix_socket != NULL); @@ -222,12 +222,21 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4; port = server->connrec->proxy != NULL ? server->connrec->proxy_port : server->connrec->port; - handle = server->connrec->use_tls ? - net_connect_ip_ssl(ip, port, own_ip, server) : net_connect_ip(ip, port, own_ip); + handle = net_connect_ip(ip, port, own_ip); } else { handle = net_connect_unix(unix_socket); } + if (server->connrec->use_tls && handle != NULL) { + server->handle = net_sendbuffer_create(handle, 0); + handle = net_start_ssl(server); + if (handle == NULL) { + net_sendbuffer_destroy(server->handle, TRUE); + } else { + server->handle->handle = handle; + } + } + if (handle == NULL) { /* failed */ errmsg = g_strerror(errno); @@ -251,7 +260,8 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, g_free(errmsg2); } else { server->connrec->last_failed_family = 0; - server->handle = net_sendbuffer_create(handle, 0); + if (!server->connrec->use_tls) + server->handle = net_sendbuffer_create(handle, 0); if (server->connrec->use_tls) server_connect_callback_init_ssl(server, handle); else From 46493c051b73822838cb6d2af264248a0125d150 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 16 Jan 2021 00:31:56 +0100 Subject: [PATCH 0781/1198] add /IGNORE ... NOHILIGHT to ignore some hilights --- src/core/ignore.c | 21 ++++++++++----------- src/core/ignore.h | 9 ++++----- src/core/levels.c | 6 ++++++ src/fe-common/core/fe-ignore.c | 8 ++++++++ src/fe-common/core/fe-messages.c | 5 +++++ src/fe-common/irc/fe-irc-messages.c | 6 ++++++ 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 14fa585e..0bc12ed3 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -81,7 +81,7 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) * used as a flag to indicate it should only look at ignore items with NO_ACT. * However we also want to allow NO_ACT combined with levels, so mask it out and * match levels if set. */ -#define FLAG_MSGLEVELS ( MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN ) +#define FLAG_MSGLEVELS (MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN | MSGLEVEL_NOHILIGHT) static int ignore_match_level(IGNORE_REC *rec, int level, int flags) { level &= ~FLAG_MSGLEVELS; @@ -214,6 +214,9 @@ int ignore_check_plus(SERVER_REC *server, const char *nick, const char *address, if (ignore_check_flags(server, nick, address, target, msg, olevel, MSGLEVEL_HIDDEN)) *level |= MSGLEVEL_HIDDEN; + if (ignore_check_flags(server, nick, address, target, msg, olevel, MSGLEVEL_NOHILIGHT)) + *level |= MSGLEVEL_NOHILIGHT; + return FALSE; } @@ -252,6 +255,12 @@ IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0) continue; + if ((flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) == 0) + continue; + + if (!(flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) != 0) + continue; + if ((rec->mask == NULL && mask != NULL) || (rec->mask != NULL && mask == NULL)) continue; @@ -299,16 +308,6 @@ 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); -} - -IGNORE_REC *ignore_find_hidden(const char *servertag, const char *mask, char **channels, int hidden) -{ - return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_HIDDEN); -} - static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; diff --git a/src/core/ignore.h b/src/core/ignore.h index bf55a76b..739514a9 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -31,9 +31,10 @@ int ignore_check_plus(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int *level, int test_ignore); enum { - IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ - IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ - IGNORE_FIND_HIDDEN = 0x04, /* Exclude the targets with HIDDEN level */ + IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ + IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ + IGNORE_FIND_HIDDEN = 0x04, /* Exclude the targets with HIDDEN level */ + IGNORE_FIND_NOHILIGHT = 0x08, /* Exclude the targets with NOHILIGHT level */ }; IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, @@ -42,8 +43,6 @@ IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const cha /* 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); -IGNORE_REC *ignore_find_hidden(const char *servertag, const char *mask, char **channels, int hidden); void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/core/levels.c b/src/core/levels.c index 9102696e..e62bc68c 100644 --- a/src/core/levels.c +++ b/src/core/levels.c @@ -61,6 +61,9 @@ int level_get(const char *level) if (g_ascii_strcasecmp(level, "NO_ACT") == 0) return MSGLEVEL_NO_ACT; + if (g_ascii_strcasecmp(level, "NOHILIGHT") == 0) + return MSGLEVEL_NOHILIGHT; + if (g_ascii_strcasecmp(level, "HIDDEN") == 0) return MSGLEVEL_HIDDEN; @@ -154,6 +157,9 @@ char *bits2level(int bits) } } + if (bits & MSGLEVEL_NOHILIGHT) + g_string_append(str, "NOHILIGHT "); + if (bits & MSGLEVEL_HIDDEN) g_string_append(str, "HIDDEN "); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 890d2c19..276169df 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -169,6 +169,8 @@ static void cmd_ignore(const char *data) flags |= IGNORE_FIND_NOACT; if (level & MSGLEVEL_HIDDEN) flags |= IGNORE_FIND_HIDDEN; + if (level & MSGLEVEL_NOHILIGHT) + flags |= IGNORE_FIND_NOHILIGHT; rec = ignore_find_full(servertag, mask, patternarg, channels, flags); new_ignore = rec == NULL; @@ -198,6 +200,12 @@ static void cmd_ignore(const char *data) rec->level |= MSGLEVEL_ALL; } + if (rec->level == MSGLEVEL_NOHILIGHT) { + /* If only NOHILIGHT was specified add all levels; it makes no + * sense on its own. */ + rec->level |= MSGLEVEL_ALL; + } + if (new_ignore && rec->level == 0) { /* tried to unignore levels from nonexisting ignore */ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index c4469178..355d4fd4 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -202,6 +202,11 @@ static void sig_message_public(SERVER_REC *server, const char *msg, level |= MSGLEVEL_HILIGHT; ignore_check_plus(server, nick, address, target, msg, &level, FALSE); + if (level & MSGLEVEL_NOHILIGHT) { + for_me = FALSE; + g_free_and_null(color); + level &= ~MSGLEVEL_HILIGHT; + } if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); diff --git a/src/fe-common/irc/fe-irc-messages.c b/src/fe-common/irc/fe-irc-messages.c index 714b2eb2..2e71b34f 100644 --- a/src/fe-common/irc/fe-irc-messages.c +++ b/src/fe-common/irc/fe-irc-messages.c @@ -114,6 +114,12 @@ static void sig_message_irc_op_public(SERVER_REC *server, const char *msg, return; } + if (level & MSGLEVEL_NOHILIGHT) { + for_me = FALSE; + g_free_and_null(color); + level &= ~MSGLEVEL_HILIGHT; + } + if (settings_get_bool("emphasis")) msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg); From 308400154b76897413f02987b9b8997fd6482af4 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 7 Apr 2021 21:36:27 +0200 Subject: [PATCH 0782/1198] fix crash on tls error --- src/core/servers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/servers.c b/src/core/servers.c index 77b88fa9..159af0e1 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -232,6 +232,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, handle = net_start_ssl(server); if (handle == NULL) { net_sendbuffer_destroy(server->handle, TRUE); + server->handle = NULL; } else { server->handle->handle = handle; } From 51508ff1d38b47760068da8c9ce0229e3eed3f05 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Sun, 5 Apr 2020 13:18:54 +0200 Subject: [PATCH 0783/1198] use starttls --- src/core/chat-commands.c | 4 +- src/core/servers-setup.c | 42 ++--- src/core/servers-setup.h | 4 + src/fe-common/core/fe-server.c | 2 +- src/fe-common/irc/fe-irc-server.c | 67 +++++--- src/irc/core/irc-cap.c | 100 +++++++----- src/irc/core/irc-commands.c | 2 +- src/irc/core/irc-servers-reconnect.c | 2 + src/irc/core/irc-servers-setup.c | 16 +- src/irc/core/irc-servers-setup.h | 1 + src/irc/core/irc-servers.c | 235 +++++++++++++++++++++------ src/irc/core/irc-servers.h | 7 + src/irc/core/irc.c | 2 + 13 files changed, 346 insertions(+), 138 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index ae44ef63..8c70bfc6 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -71,8 +71,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, if (chatnet == NULL) chatnet = g_hash_table_lookup(optlist, "network"); - conn = server_create_conn(proto != NULL ? proto->id : -1, addr, - atoi(portstr), chatnet, password, nick); + conn = server_create_conn_opt(proto != NULL ? proto->id : -1, addr, atoi(portstr), chatnet, + password, nick, optlist); if (conn == NULL) { signal_emit("error command", 1, GINT_TO_POINTER(CMDERR_NO_SERVER_DEFINED)); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 43653c43..ea15e2a8 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -140,8 +140,8 @@ void server_setup_fill_reconn(SERVER_CONNECT_REC *conn, signal_emit("server setup fill reconn", 2, conn, sserver); } -static void server_setup_fill(SERVER_CONNECT_REC *conn, - const char *address, int port) +static void server_setup_fill(SERVER_CONNECT_REC *conn, const char *address, int port, + GHashTable *optlist) { g_return_if_fail(conn != NULL); g_return_if_fail(address != NULL); @@ -177,7 +177,7 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn, memcpy(conn->own_ip6, source_host_ip6, sizeof(IPADDR)); } - signal_emit("server setup fill connect", 1, conn); + signal_emit("server setup fill connect", 2, conn, optlist); } static void server_setup_fill_server(SERVER_CONNECT_REC *conn, @@ -219,10 +219,9 @@ static void server_setup_fill_chatnet(SERVER_CONNECT_REC *conn, signal_emit("server setup fill chatnet", 2, conn, chatnet); } -static SERVER_CONNECT_REC * -create_addr_conn(int chat_type, const char *address, int port, - const char *chatnet, const char *password, - const char *nick) +static SERVER_CONNECT_REC *create_addr_conn(int chat_type, const char *address, int port, + const char *chatnet, const char *password, + const char *nick, GHashTable *optlist) { CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; @@ -250,7 +249,7 @@ create_addr_conn(int chat_type, const char *address, int port, conn->chatnet = g_strdup(chatnet); /* fill in the defaults */ - server_setup_fill(conn, address, port); + server_setup_fill(conn, address, port, optlist); /* fill the rest from chat network settings */ chatnetrec = chatnet != NULL ? chatnet_find(chatnet) : @@ -279,9 +278,8 @@ create_addr_conn(int chat_type, const char *address, int port, /* Connect to server where last connect succeeded (or we haven't tried to connect yet). If there's no such server, connect to server where we haven't connected for the longest time */ -static SERVER_CONNECT_REC * -create_chatnet_conn(const char *dest, int port, - const char *password, const char *nick) +static SERVER_CONNECT_REC *create_chatnet_conn(const char *dest, int port, const char *password, + const char *nick, GHashTable *optlist) { SERVER_SETUP_REC *bestrec; GSList *tmp; @@ -308,16 +306,15 @@ create_chatnet_conn(const char *dest, int port, } return bestrec == NULL ? NULL : - create_addr_conn(bestrec->chat_type, bestrec->address, 0, - dest, NULL, nick); + create_addr_conn(bestrec->chat_type, bestrec->address, 0, dest, + NULL, nick, optlist); } /* Create server connection record. `dest' is required, rest can be NULL. `dest' is either a server address or chat network */ -SERVER_CONNECT_REC * -server_create_conn(int chat_type, const char *dest, int port, - const char *chatnet, const char *password, - const char *nick) +SERVER_CONNECT_REC *server_create_conn_opt(int chat_type, const char *dest, int port, + const char *chatnet, const char *password, + const char *nick, GHashTable *optlist) { SERVER_CONNECT_REC *rec; CHATNET_REC *chatrec; @@ -326,7 +323,7 @@ server_create_conn(int chat_type, const char *dest, int port, chatrec = chatnet_find(dest); if (chatrec != NULL) { - rec = create_chatnet_conn(chatrec->name, port, password, nick); + rec = create_chatnet_conn(chatrec->name, port, password, nick, optlist); /* If rec is NULL the chatnet has no url to connect to */ return rec; } @@ -335,8 +332,13 @@ server_create_conn(int chat_type, const char *dest, int port, if (chatrec != NULL) chatnet = chatrec->name; - return create_addr_conn(chat_type, dest, port, - chatnet, password, nick); + return create_addr_conn(chat_type, dest, port, chatnet, password, nick, optlist); +} + +SERVER_CONNECT_REC *server_create_conn(int chat_type, const char *dest, int port, + const char *chatnet, const char *password, const char *nick) +{ + return server_create_conn_opt(chat_type, dest, port, chatnet, password, nick, NULL); } /* Find matching server from setup. Try to find record with a same port, diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index 296a94fa..f35c3873 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -31,6 +31,10 @@ server_create_conn(int chat_type, const char *dest, int port, const char *chatnet, const char *password, const char *nick); +SERVER_CONNECT_REC *server_create_conn_opt(int chat_type, const char *dest, int port, + const char *chatnet, const char *password, + const char *nick, GHashTable *optlist); + /* 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/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 5ed67170..0bf9a104 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -246,7 +246,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec->own_ip4 = rec->own_ip6 = NULL; } - signal_emit("server add fill", 2, rec, optlist); + signal_emit("server add fill", 3, rec, optlist, GINT_TO_POINTER(add)); server_setup_add(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index 7e3a6300..b5697c96 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -51,12 +51,12 @@ const char *get_visible_target(IRC_SERVER_REC *server, const char *target) return target; } -/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] [-tls_pass ] - [-tls_verify] [-tls_cafile ] [-tls_capath ] - [-tls_ciphers ] +/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] + [-tls_pass ] [-tls_verify] [-tls_cafile ] + [-tls_capath ] [-tls_ciphers ] [-starttls | -nostarttls] [-auto | -noauto] [-network ] [-host ] - [-cmdspeed ] [-cmdmax ] [-port ] -
[ []] */ + [-cmdspeed ] [-cmdmax ] [-port ]
[ + []] */ /* NOTE: -network replaces the old -ircnet flag. */ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, GHashTable *optlist) @@ -85,6 +85,12 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value); value = g_hash_table_lookup(optlist, "querychans"); if (value != NULL && *value != '\0') rec->max_query_chans = atoi(value); + if (g_hash_table_lookup(optlist, "nonostarttls")) + rec->starttls = -1; + if (g_hash_table_lookup(optlist, "nostarttls")) + rec->starttls = 0; + if (g_hash_table_lookup(optlist, "starttls")) + rec->starttls = 1; } /* SYNTAX: SERVER LIST */ @@ -108,29 +114,31 @@ static void cmd_server_list(const char *data) g_string_append(str, "autoconnect, "); if (rec->no_proxy) g_string_append(str, "noproxy, "); - if (rec->use_tls) { + if (rec->starttls >= 0) + g_string_append_printf(str, "%sstarttls, ", rec->starttls ? "" : "no"); + if (rec->use_tls) g_string_append(str, "tls, "); - if (rec->tls_cert) { - g_string_append_printf(str, "tls_cert: %s, ", rec->tls_cert); - if (rec->tls_pkey) - g_string_append_printf(str, "tls_pkey: %s, ", rec->tls_pkey); - if (rec->tls_pass) - g_string_append_printf(str, "(pass), "); - } - if (rec->tls_verify) - g_string_append(str, "tls_verify, "); - if (rec->tls_cafile) - g_string_append_printf(str, "tls_cafile: %s, ", rec->tls_cafile); - if (rec->tls_capath) - g_string_append_printf(str, "tls_capath: %s, ", rec->tls_capath); - if (rec->tls_ciphers) - g_string_append_printf(str, "tls_ciphers: %s, ", rec->tls_ciphers); - if (rec->tls_pinned_cert) - g_string_append_printf(str, "tls_pinned_cert: %s, ", rec->tls_pinned_cert); - if (rec->tls_pinned_pubkey) - g_string_append_printf(str, "tls_pinned_pubkey: %s, ", rec->tls_pinned_pubkey); - + if (rec->tls_cert) { + g_string_append_printf(str, "tls_cert: %s, ", rec->tls_cert); + if (rec->tls_pkey) + g_string_append_printf(str, "tls_pkey: %s, ", rec->tls_pkey); + if (rec->tls_pass) + g_string_append_printf(str, "(pass), "); } + if (rec->tls_verify) + g_string_append(str, "tls_verify, "); + if (rec->tls_cafile) + g_string_append_printf(str, "tls_cafile: %s, ", rec->tls_cafile); + if (rec->tls_capath) + g_string_append_printf(str, "tls_capath: %s, ", rec->tls_capath); + if (rec->tls_ciphers) + g_string_append_printf(str, "tls_ciphers: %s, ", rec->tls_ciphers); + if (rec->tls_pinned_cert) + g_string_append_printf(str, "tls_pinned_cert: %s, ", rec->tls_pinned_cert); + if (rec->tls_pinned_pubkey) + g_string_append_printf(str, "tls_pinned_pubkey: %s, ", + rec->tls_pinned_pubkey); + if (rec->max_cmds_at_once > 0) g_string_append_printf(str, "cmdmax: %d, ", rec->max_cmds_at_once); if (rec->cmd_queue_speed > 0) @@ -155,7 +163,12 @@ void fe_irc_server_init(void) signal_add("server add fill", (SIGNAL_FUNC) sig_server_add_fill); command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list); - command_set_options("server add", "-ircnet -network -cmdspeed -cmdmax -querychans"); + command_set_options( + "server add", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls nonostarttls"); + command_set_options( + "server modify", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls nonostarttls"); } void fe_irc_server_deinit(void) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 61a80066..ce7e1616 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -104,12 +104,54 @@ static gboolean parse_cap_name(char *name, char **key, char **val) return TRUE; } +static void cap_process_request_queue(IRC_SERVER_REC *server) +{ + /* No CAP has been requested */ + if (server->cap_queue == NULL) { + irc_cap_finish_negotiation(server); + } else { + GSList *tmp; + GString *cmd; + int avail_caps = 0; + + cmd = g_string_new("CAP REQ :"); + + /* To process the queue in order, we need to reverse the stack once */ + server->cap_queue = g_slist_reverse(server->cap_queue); + + /* Check whether the cap is supported by the server */ + for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { + if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, + NULL)) { + if (avail_caps > 0) + g_string_append_c(cmd, ' '); + g_string_append(cmd, tmp->data); + + avail_caps++; + } + } + + /* Clear the queue here */ + i_slist_free_full(server->cap_queue, (GDestroyNotify) g_free); + server->cap_queue = NULL; + + /* If the server doesn't support any cap we requested close the negotiation here */ + if (avail_caps > 0) { + signal_emit("server cap req", 2, server, + cmd->str + sizeof("CAP REQ :") - 1); + irc_send_cmd_now(server, cmd->str); + } else { + irc_cap_finish_negotiation(server); + } + + g_string_free(cmd, TRUE); + } +} + static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *address) { - GSList *tmp; - GString *cmd; char *params, *evt, *list, *star, **caps; - int i, caps_length, disable, avail_caps, multiline; + int i, caps_length, disable, multiline; params = event_get_params(args, 4, NULL, &evt, &star, &list); if (params == NULL) @@ -174,42 +216,20 @@ static void event_cap (IRC_SERVER_REC *server, char *args, char *nick, char *add /* A multiline response is always terminated by a normal one, * wait until we receive that one to require any CAP */ if (multiline == FALSE) { - /* No CAP has been requested */ - if (server->cap_queue == NULL) { - irc_cap_finish_negotiation(server); - } - else { - cmd = g_string_new("CAP REQ :"); - - avail_caps = 0; - - /* To process the queue in order, we need to reverse the stack once */ - server->cap_queue = g_slist_reverse(server->cap_queue); - - /* Check whether the cap is supported by the server */ - for (tmp = server->cap_queue; tmp != NULL; tmp = tmp->next) { - if (g_hash_table_lookup_extended(server->cap_supported, tmp->data, NULL, NULL)) { - if (avail_caps > 0) - g_string_append_c(cmd, ' '); - g_string_append(cmd, tmp->data); - - avail_caps++; - } - } - - /* Clear the queue here */ - i_slist_free_full(server->cap_queue, (GDestroyNotify) g_free); - server->cap_queue = NULL; - - /* If the server doesn't support any cap we requested close the negotiation here */ - if (avail_caps > 0) { - signal_emit("server cap req", 2, server, cmd->str + sizeof("CAP REQ :") - 1); - irc_send_cmd_now(server, cmd->str); - } else { - irc_cap_finish_negotiation(server); - } - - g_string_free(cmd, TRUE); + gboolean want_starttls = + i_slist_find_string(server->cap_queue, CAP_STARTTLS) != NULL; + server->cap_queue = + i_slist_delete_string(server->cap_queue, CAP_STARTTLS, g_free); + if (server->connrec->starttls) { + /* the connection has requested starttls, + no more data must be sent now */ + } else if (want_starttls && + g_hash_table_lookup_extended(server->cap_supported, CAP_STARTTLS, + NULL, NULL)) { + irc_server_send_starttls(server); + /* no more data must be sent now */ + } else { + cap_process_request_queue(server); } } } @@ -301,12 +321,14 @@ static void event_invalid_cap (IRC_SERVER_REC *server, const char *data, const c void irc_cap_init (void) { + signal_add_last("server cap continue", (SIGNAL_FUNC) cap_process_request_queue); signal_add_first("event cap", (SIGNAL_FUNC) event_cap); signal_add_first("event 410", (SIGNAL_FUNC) event_invalid_cap); } void irc_cap_deinit (void) { + signal_remove("server cap continue", (SIGNAL_FUNC) cap_process_request_queue); signal_remove("event cap", (SIGNAL_FUNC) event_cap); signal_remove("event 410", (SIGNAL_FUNC) event_invalid_cap); } diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 935c6b42..8c8179e0 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -1053,7 +1053,7 @@ void irc_commands_init(void) signal_add("whois end", (SIGNAL_FUNC) event_end_of_whois); signal_add("whowas event", (SIGNAL_FUNC) event_whowas); - command_set_options("connect", "+ircnet"); + command_set_options("connect", "+ircnet starttls nostarttls"); command_set_options("topic", "delete"); command_set_options("list", "yes"); command_set_options("away", "one all"); diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index cfe28a1a..4a8d2908 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -51,6 +51,8 @@ static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, rec->sasl_mechanism = src->sasl_mechanism; rec->sasl_username = g_strdup(src->sasl_username); rec->sasl_password = g_strdup(src->sasl_password); + rec->no_starttls = src->no_starttls; + rec->starttls = src->starttls; *dest = (SERVER_CONNECT_REC *) rec; } diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 5f1290a2..74edb47b 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -44,9 +44,13 @@ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn, conn->max_cmds_at_once = sserver->max_cmds_at_once; if (sserver->max_query_chans > 0) conn->max_query_chans = sserver->max_query_chans; + if (sserver->starttls == 0) + conn->no_starttls = 1; + else if (sserver->starttls == 1) + conn->starttls = 1; } -static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn) +static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn, GHashTable *optlist) { const char *value; @@ -60,6 +64,11 @@ static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn) value = settings_get_str("usermode"); conn->usermode = (value != NULL && *value != '\0') ? g_strdup(value) : NULL; + + if (g_hash_table_lookup(optlist, "starttls") != NULL) + conn->starttls = 1; + else if (g_hash_table_lookup(optlist, "nostarttls") != NULL) + conn->no_starttls = 1; } static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, @@ -174,6 +183,7 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0); rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); + rec->starttls = config_node_get_bool(node, "starttls", -1); } static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, @@ -188,6 +198,10 @@ static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, iconfig_node_set_int(node, "cmd_queue_speed", rec->cmd_queue_speed); if (rec->max_query_chans > 0) iconfig_node_set_int(node, "max_query_chans", rec->max_query_chans); + if (rec->starttls >= 0) + iconfig_node_set_bool(node, "starttls", rec->starttls); + else + iconfig_node_set_str(node, "starttls", NULL); } void irc_servers_setup_init(void) diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index d3bafdef..8fbb311e 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -18,6 +18,7 @@ typedef struct { int max_cmds_at_once; int cmd_queue_speed; int max_query_chans; + int starttls; } IRC_SERVER_SETUP_REC; void irc_servers_setup_init(void); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index f29a8f91..29b389f4 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -20,10 +20,11 @@ #include "module.h" -#include -#include -#include #include +#include +#include +#include +#include #include #include @@ -207,17 +208,17 @@ static char **split_message(SERVER_REC *server, const char *target, strlen(target)); } -static void server_init(IRC_SERVER_REC *server) +static void server_init_2(IRC_SERVER_REC *server); +static void server_init_1(IRC_SERVER_REC *server) { IRC_SERVER_CONNECT_REC *conn; - char *address, *ptr, *username, *cmd; + char *cmd; g_return_if_fail(server != NULL); conn = server->connrec; - if (conn->proxy != NULL && conn->proxy_password != NULL && - *conn->proxy_password != '\0') { + if (conn->proxy != NULL && conn->proxy_password != NULL && *conn->proxy_password != '\0') { cmd = g_strdup_printf("PASS %s", conn->proxy_password); irc_send_cmd_now(server, cmd); g_free(cmd); @@ -243,45 +244,8 @@ static void server_init(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE); irc_cap_toggle(server, CAP_SERVER_TIME, TRUE); - - irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); - - if (conn->password != NULL && *conn->password != '\0') { - /* send password */ - cmd = g_strdup_printf("PASS %s", conn->password); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } - - /* send nick */ - cmd = g_strdup_printf("NICK %s", conn->nick); - irc_send_cmd_now(server, cmd); - g_free(cmd); - - /* send user/realname */ - address = server->connrec->address; - ptr = strrchr(address, ':'); - if (ptr != NULL) { - /* IPv6 address .. doesn't work here, use the string after - the last : char */ - address = ptr+1; - if (*address == '\0') - address = "x"; - } - - username = g_strdup(conn->username); - ptr = strchr(username, ' '); - if (ptr != NULL) *ptr = '\0'; - - cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname); - irc_send_cmd_now(server, cmd); - g_free(cmd); - g_free(username); - - if (conn->proxy != NULL && conn->proxy_string_after != NULL) { - cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port); - irc_send_cmd_now(server, cmd); - g_free(cmd); + if (!conn->use_tls && (conn->starttls || !conn->no_starttls)) { + irc_cap_toggle(server, CAP_STARTTLS, TRUE); } server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); @@ -296,6 +260,163 @@ static void server_init(IRC_SERVER_REC *server) /* this will reset to 1 sec after we get the 001 event */ server->wait_cmd = g_get_real_time(); server->wait_cmd += 120 * G_USEC_PER_SEC; + + irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); + /* to detect non-CAP servers, send this bogus join */ + irc_send_cmd_now(server, "JOIN "); + if (conn->starttls) + irc_server_send_starttls(server); +} + +static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle) +{ + int error; + + if (server->starttls_tag) { + g_source_remove(server->starttls_tag); + server->starttls_tag = 0; + } + + error = irssi_ssl_handshake(handle); + if (error == -1) { + server->connection_lost = TRUE; + server_disconnect((SERVER_REC *) server); + return; + } + if (error & 1) { /* wait */ + server->starttls_tag = + i_input_add(handle, error == 1 ? I_INPUT_READ : I_INPUT_WRITE, + (GInputFunction) init_ssl_loop, server); + return; + } + /* continue */ + rawlog_redirect(server->rawlog, "Now talking encrypted"); + signal_emit("server connection switched", 1, server); + if (!server->cap_supported) { + server_init_2(server); + } else { + signal_emit("server cap continue", 1, server); + } + + server->connrec->starttls = 1; + if (settings_get_bool("starttls_sts")) { + IRC_SERVER_SETUP_REC *ssetup = IRC_SERVER_SETUP(server_setup_find( + server->connrec->address, server->connrec->port, server->connrec->chatnet)); + if (ssetup != NULL) { + ssetup->starttls = 1; + server_setup_add((SERVER_SETUP_REC *) ssetup); + } + } +} + +#include +void irc_server_send_starttls(IRC_SERVER_REC *server) +{ + g_return_if_fail(server != NULL); + + g_warning("Now attempting STARTTLS"); + irc_send_cmd_now(server, "STARTTLS"); +} + +static void event_starttls(IRC_SERVER_REC *server, const char *data) +{ + GIOChannel *ssl_handle; + + g_return_if_fail(server != NULL); + + if (!IS_IRC_SERVER(server)) + return; + + if (server->handle->readbuffer != NULL && + !line_split_is_empty(server->handle->readbuffer)) { + char *str; + line_split("", -1, &str, &server->handle->readbuffer); + } + ssl_handle = net_start_ssl((SERVER_REC *) server); + if (ssl_handle != NULL) { + g_source_remove(server->readtag); + server->readtag = -1; + server->handle->handle = ssl_handle; + init_ssl_loop(server, server->handle->handle); + } else { + g_warning("net_start_ssl failed"); + } +} + +static void event_registerfirst(IRC_SERVER_REC *server, const char *data) +{ + g_return_if_fail(server != NULL); + + if (!IS_IRC_SERVER(server)) + return; + + if (server->connected) + return; + + if (!server->cap_supported && !server->connrec->starttls) + server_init_2(server); +} + +static void event_capend(IRC_SERVER_REC *server) +{ + g_return_if_fail(server != NULL); + + if (!IS_IRC_SERVER(server)) + return; + + if (server->connected) + return; + + server_init_2(server); +} + +static void server_init_2(IRC_SERVER_REC *server) +{ + IRC_SERVER_CONNECT_REC *conn; + char *address, *ptr, *username, *cmd; + + g_return_if_fail(server != NULL); + + conn = server->connrec; + + if (conn->password != NULL && *conn->password != '\0') { + /* send password */ + cmd = g_strdup_printf("PASS %s", conn->password); + irc_send_cmd_now(server, cmd); + g_free(cmd); + } + + /* send nick */ + cmd = g_strdup_printf("NICK %s", conn->nick); + irc_send_cmd_now(server, cmd); + g_free(cmd); + + /* send user/realname */ + address = server->connrec->address; + ptr = strrchr(address, ':'); + if (ptr != NULL) { + /* IPv6 address .. doesn't work here, use the string after + the last : char */ + address = ptr + 1; + if (*address == '\0') + address = "x"; + } + + username = g_strdup(conn->username); + ptr = strchr(username, ' '); + if (ptr != NULL) + *ptr = '\0'; + + cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname); + irc_send_cmd_now(server, cmd); + g_free(cmd); + g_free(username); + + if (conn->proxy != NULL && conn->proxy_string_after != NULL) { + cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port); + irc_send_cmd_now(server, cmd); + g_free(cmd); + } } SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn) @@ -420,7 +541,7 @@ static void sig_connected(IRC_SERVER_REC *server) server->splits = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); if (!server->session_reconnect) - server_init(server); + server_init_1(server); } static void isupport_destroy_hash(void *key, void *value) @@ -429,6 +550,17 @@ static void isupport_destroy_hash(void *key, void *value) g_free(value); } +static void sig_disconnected(IRC_SERVER_REC *server) +{ + if (!IS_IRC_SERVER(server)) + return; + + if (server->starttls_tag) { + g_source_remove(server->starttls_tag); + server->starttls_tag = 0; + } +} + static void sig_destroyed(IRC_SERVER_REC *server) { GSList *tmp; @@ -1048,6 +1180,7 @@ void irc_server_init_isupport(IRC_SERVER_REC *server) void irc_servers_init(void) { + settings_add_bool("servers", "starttls_sts", TRUE); settings_add_choice("servers", "rejoin_channels_on_reconnect", 1, "off;on;auto"); settings_add_str("misc", "usermode", DEFAULT_USER_MODE); settings_add_str("misc", "split_line_start", ""); @@ -1059,9 +1192,13 @@ void irc_servers_init(void) cmd_tag = -1; signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); + signal_add_first("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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); + signal_add("event 670", (SIGNAL_FUNC) event_starttls); + signal_add("event 451", (SIGNAL_FUNC) event_registerfirst); + signal_add("server cap end", (SIGNAL_FUNC) event_capend); signal_add("event 001", (SIGNAL_FUNC) event_connected); signal_add("event 004", (SIGNAL_FUNC) event_server_info); signal_add("event 005", (SIGNAL_FUNC) event_isupport); @@ -1087,9 +1224,13 @@ 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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); + signal_remove("event 670", (SIGNAL_FUNC) event_starttls); + signal_remove("event 451", (SIGNAL_FUNC) event_registerfirst); + signal_remove("server cap end", (SIGNAL_FUNC) event_capend); signal_remove("event 001", (SIGNAL_FUNC) event_connected); signal_remove("event 004", (SIGNAL_FUNC) event_server_info); signal_remove("event 005", (SIGNAL_FUNC) event_isupport); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 14560611..753666ff 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -27,6 +27,7 @@ #define CAP_ACCOUNT_NOTIFY "account-notify" #define CAP_SELF_MESSAGE "znc.in/self-message" #define CAP_SERVER_TIME "server-time" +#define CAP_STARTTLS "tls" /* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */ #define IRC_SERVER(server) \ @@ -42,6 +43,7 @@ #define IS_IRC_SERVER_CONNECT(conn) \ (IRC_SERVER_CONNECT(conn) ? TRUE : FALSE) +/* clang-format off */ /* all strings should be either NULL or dynamically allocated */ /* address and nick are mandatory, rest are optional */ struct _IRC_SERVER_CONNECT_REC { @@ -59,7 +61,10 @@ struct _IRC_SERVER_CONNECT_REC { int max_query_chans; int max_kicks, max_msgs, max_modes, max_whois; + int no_starttls:1; + int starttls:1; }; +/* clang-format on */ #define STRUCT_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC struct _IRC_SERVER_REC { @@ -136,6 +141,7 @@ struct _IRC_SERVER_REC { GSList *rejoin_channels; /* try to join to these channels after a while - channels go here if they're "temporarily unavailable" because of netsplits */ + guint starttls_tag; /* Holds the source id of the running timeout */ struct _SERVER_QUERY_REC *chanqueries; GHashTable *isupport; @@ -155,6 +161,7 @@ void irc_server_purge_output(IRC_SERVER_REC *server, const char *target); like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */ char *irc_server_get_channels(IRC_SERVER_REC *server); +void irc_server_send_starttls(IRC_SERVER_REC *server); /* INTERNAL: */ void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data); diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 8ecda85b..628d7130 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -579,6 +579,7 @@ void irc_irc_init(void) signal_add("server event", (SIGNAL_FUNC) irc_server_event); signal_add("server event tags", (SIGNAL_FUNC) irc_server_event_tags); signal_add("server connected", (SIGNAL_FUNC) irc_init_server); + signal_add("server connection switched", (SIGNAL_FUNC) irc_init_server); signal_add("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line); current_server_event = NULL; @@ -593,5 +594,6 @@ void irc_irc_deinit(void) signal_remove("server event", (SIGNAL_FUNC) irc_server_event); signal_remove("server event tags", (SIGNAL_FUNC) irc_server_event_tags); signal_remove("server connected", (SIGNAL_FUNC) irc_init_server); + signal_remove("server connection switched", (SIGNAL_FUNC) irc_init_server); signal_remove("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line); } From 9668217509f81f1b7887f14b8d0885622cf20ad5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 6 Apr 2021 17:40:37 +0200 Subject: [PATCH 0784/1198] changes suggested by ahf --- src/core/chat-commands.c | 22 +++++++++++++--------- src/fe-common/irc/fe-irc-server.c | 27 +++++++++++++++------------ src/irc/core/irc-commands.c | 2 +- src/irc/core/irc-servers-reconnect.c | 2 +- src/irc/core/irc-servers-setup.c | 6 +++--- src/irc/core/irc-servers.c | 4 ++-- src/irc/core/irc-servers.h | 2 +- 7 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 8c70bfc6..92bb9db8 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -99,6 +99,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, else if (g_hash_table_lookup(optlist, "4") != NULL) conn->family = AF_INET; + if (g_hash_table_lookup(optlist, "notls") != NULL) + conn->use_tls = FALSE; if (g_hash_table_lookup(optlist, "tls") != NULL || g_hash_table_lookup(optlist, "ssl") != NULL) conn->use_tls = TRUE; if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) @@ -107,6 +109,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, conn->tls_pkey = g_strdup(tmp); if ((tmp = g_hash_table_lookup(optlist, "tls_pass")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) conn->tls_pass = g_strdup(tmp); + if (g_hash_table_lookup(optlist, "notls_verify") != NULL) + conn->tls_verify = FALSE; if (g_hash_table_lookup(optlist, "tls_verify") != NULL || g_hash_table_lookup(optlist, "ssl_verify") != NULL) conn->tls_verify = TRUE; if ((tmp = g_hash_table_lookup(optlist, "tls_cafile")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) @@ -149,13 +153,13 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, return conn; } -/* SYNTAX: CONNECT [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] [-tls_pass ] +/* SYNTAX: CONNECT [-4 | -6] [-tls_cert ] [-tls_pkey ] [-tls_pass ] [-tls_verify] [-tls_cafile ] [-tls_capath ] - [-tls_ciphers ] [-tls_pinned_cert ] [-tls_pinned_pubkey ] - [-!] [-noautosendcmd] - [-noproxy] [-network ] [-host ] - [-rawlog ] -
| [ [ []]] */ + [-tls_ciphers ] [-tls_pinned_cert ] + [-tls_pinned_pubkey ] [-!] [-noautosendcmd] [-tls | -notls] + [-starttls | -disallow_starttls] [-noproxy] [-network ] + [-host ] [-rawlog ] +
| [ [ []]] */ /* NOTE: -network replaces the old -ircnet flag. */ static void cmd_connect(const char *data) { @@ -520,9 +524,9 @@ void chat_commands_init(void) command_set_options( "connect", "4 6 !! -network ~ssl ~+ssl_cert ~+ssl_pkey ~+ssl_pass ~ssl_verify ~+ssl_cafile " - "~+ssl_capath ~+ssl_ciphers ~+ssl_pinned_cert ~+ssl_pinned_pubkey tls +tls_cert " - "+tls_pkey +tls_pass tls_verify +tls_cafile +tls_capath +tls_ciphers +tls_pinned_cert " - "+tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); + "~+ssl_capath ~+ssl_ciphers ~+ssl_pinned_cert ~+ssl_pinned_pubkey tls notls +tls_cert " + "+tls_pkey +tls_pass tls_verify notls_verify +tls_cafile +tls_capath +tls_ciphers " + "+tls_pinned_cert +tls_pinned_pubkey +host noproxy -rawlog noautosendcmd"); command_set_options("msg", "channel nick"); } diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index b5697c96..d30aa45d 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -51,9 +51,10 @@ const char *get_visible_target(IRC_SERVER_REC *server, const char *target) return target; } -/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-tls] [-tls_cert ] [-tls_pkey ] +/* SYNTAX: SERVER ADD|MODIFY [-4 | -6] [-tls_cert ] [-tls_pkey ] [-tls_pass ] [-tls_verify] [-tls_cafile ] - [-tls_capath ] [-tls_ciphers ] [-starttls | -nostarttls] + [-tls_capath ] [-tls_ciphers ] [-tls | -notls] + [-starttls | -nostarttls | -disallow_starttls | -nodisallow_starttls] [-auto | -noauto] [-network ] [-host ] [-cmdspeed ] [-cmdmax ] [-port ]
[ []] */ @@ -85,9 +86,10 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value); value = g_hash_table_lookup(optlist, "querychans"); if (value != NULL && *value != '\0') rec->max_query_chans = atoi(value); - if (g_hash_table_lookup(optlist, "nonostarttls")) + if (g_hash_table_lookup(optlist, "nodisallow_starttls") || + g_hash_table_lookup(optlist, "nostarttls")) rec->starttls = -1; - if (g_hash_table_lookup(optlist, "nostarttls")) + if (g_hash_table_lookup(optlist, "disallow_starttls")) rec->starttls = 0; if (g_hash_table_lookup(optlist, "starttls")) rec->starttls = 1; @@ -114,8 +116,10 @@ static void cmd_server_list(const char *data) g_string_append(str, "autoconnect, "); if (rec->no_proxy) g_string_append(str, "noproxy, "); - if (rec->starttls >= 0) - g_string_append_printf(str, "%sstarttls, ", rec->starttls ? "" : "no"); + if (rec->starttls == 0) + g_string_append(str, "disallow_starttls, "); + if (rec->starttls == 1) + g_string_append(str, "starttls, "); if (rec->use_tls) g_string_append(str, "tls, "); if (rec->tls_cert) { @@ -163,12 +167,11 @@ void fe_irc_server_init(void) signal_add("server add fill", (SIGNAL_FUNC) sig_server_add_fill); command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list); - command_set_options( - "server add", - "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls nonostarttls"); - command_set_options( - "server modify", - "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls nonostarttls"); + command_set_options("server add", "-ircnet -network -cmdspeed -cmdmax -querychans starttls " + "nostarttls disallow_starttls nodisallow_starttls"); + command_set_options("server modify", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls " + "disallow_starttls nodisallow_starttls"); } void fe_irc_server_deinit(void) diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 8c8179e0..9cc8afe8 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -1053,7 +1053,7 @@ void irc_commands_init(void) signal_add("whois end", (SIGNAL_FUNC) event_end_of_whois); signal_add("whowas event", (SIGNAL_FUNC) event_whowas); - command_set_options("connect", "+ircnet starttls nostarttls"); + command_set_options("connect", "+ircnet starttls disallow_starttls"); command_set_options("topic", "delete"); command_set_options("list", "yes"); command_set_options("away", "one all"); diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index 4a8d2908..f0e6f345 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -51,7 +51,7 @@ static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, rec->sasl_mechanism = src->sasl_mechanism; rec->sasl_username = g_strdup(src->sasl_username); rec->sasl_password = g_strdup(src->sasl_password); - rec->no_starttls = src->no_starttls; + rec->disallow_starttls = src->disallow_starttls; rec->starttls = src->starttls; *dest = (SERVER_CONNECT_REC *) rec; } diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 74edb47b..6ba22862 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -45,7 +45,7 @@ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn, if (sserver->max_query_chans > 0) conn->max_query_chans = sserver->max_query_chans; if (sserver->starttls == 0) - conn->no_starttls = 1; + conn->disallow_starttls = 1; else if (sserver->starttls == 1) conn->starttls = 1; } @@ -67,8 +67,8 @@ static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn, GHashTab if (g_hash_table_lookup(optlist, "starttls") != NULL) conn->starttls = 1; - else if (g_hash_table_lookup(optlist, "nostarttls") != NULL) - conn->no_starttls = 1; + else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) + conn->disallow_starttls = 1; } static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 29b389f4..bcad3f9e 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -244,7 +244,7 @@ static void server_init_1(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE); irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE); irc_cap_toggle(server, CAP_SERVER_TIME, TRUE); - if (!conn->use_tls && (conn->starttls || !conn->no_starttls)) { + if (!conn->use_tls && (conn->starttls || !conn->disallow_starttls)) { irc_cap_toggle(server, CAP_STARTTLS, TRUE); } @@ -314,7 +314,7 @@ void irc_server_send_starttls(IRC_SERVER_REC *server) { g_return_if_fail(server != NULL); - g_warning("Now attempting STARTTLS"); + g_warning("[%s] Now attempting STARTTLS", server->tag); irc_send_cmd_now(server, "STARTTLS"); } diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 753666ff..16e2061e 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -61,7 +61,7 @@ struct _IRC_SERVER_CONNECT_REC { int max_query_chans; int max_kicks, max_msgs, max_modes, max_whois; - int no_starttls:1; + int disallow_starttls:1; int starttls:1; }; /* clang-format on */ From db2fed0d38f1da819e041ca5668368415b5fa590 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 6 Apr 2021 20:29:13 +0200 Subject: [PATCH 0785/1198] fix reconnect to use tls settings --- src/core/servers-reconnect.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index 0cfac2ec..a9d9422b 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -239,8 +239,11 @@ static void sig_reconnect(SERVER_REC *server) if (reconnect_time == -1 || !server_should_reconnect(server)) return; - conn = server_connect_copy_skeleton(server->connrec, FALSE); - g_return_if_fail(conn != NULL); + sserver = server_setup_find(server->connrec->address, server->connrec->port, + server->connrec->chatnet); + + conn = server_connect_copy_skeleton(server->connrec, sserver == NULL); + g_return_if_fail(conn != NULL); /* save the server status */ if (server->connected) { @@ -249,10 +252,6 @@ static void sig_reconnect(SERVER_REC *server) reconnect_save_status(conn, server); } - sserver = server_setup_find(server->connrec->address, - server->connrec->port, - server->connrec->chatnet); - if (sserver != NULL) { /* save the last connection time/status */ sserver->last_connect = server->connect_time == 0 ? From f2795abcc59f4c2a7f509071ec4398759b47e964 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 6 Apr 2021 19:31:10 +0200 Subject: [PATCH 0786/1198] actually use the tls settings on upgrade, and disconnect gracefully --- src/core/servers-setup.c | 9 ++++++- src/core/session.c | 32 +++++++++++++++++-------- src/fe-common/core/fe-server.c | 8 ++----- src/irc/core/channels-query.c | 2 ++ src/irc/core/irc-servers-reconnect.c | 3 ++- src/irc/core/irc-servers.c | 35 ++++++++++++++++++++++------ src/irc/core/irc-servers.h | 8 ++++++- src/irc/core/irc-session.c | 29 ++++++++++++++++++++++- src/irc/core/netsplit.c | 3 +++ src/irc/notifylist/notifylist.c | 3 +++ src/perl/irc/Server.xs | 13 +++++++++-- 11 files changed, 116 insertions(+), 29 deletions(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index ea15e2a8..c6612e84 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -338,7 +338,14 @@ SERVER_CONNECT_REC *server_create_conn_opt(int chat_type, const char *dest, int SERVER_CONNECT_REC *server_create_conn(int chat_type, const char *dest, int port, const char *chatnet, const char *password, const char *nick) { - return server_create_conn_opt(chat_type, dest, port, chatnet, password, nick, NULL); + SERVER_CONNECT_REC *ret; + GHashTable *opt; + + opt = g_hash_table_new(NULL, NULL); + ret = server_create_conn_opt(chat_type, dest, port, chatnet, password, nick, opt); + g_hash_table_destroy(opt); + + return ret; } /* Find matching server from setup. Try to find record with a same port, diff --git a/src/core/session.c b/src/core/session.c index 6f3908e5..5fe481fb 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -254,23 +254,35 @@ static void session_restore_server(CONFIG_NODE *node) proto = chat_protocol_find(chat_type); if (proto == NULL || proto->not_initialized) { - if (handle < 0) close(handle); + if (handle >= 0) + close(handle); return; } conn = server_create_conn(proto->id, address, port, chatnet, password, nick); - if (conn != NULL) { - conn->reconnection = TRUE; - conn->connect_handle = i_io_channel_new(handle); + if (conn == NULL) + return; - server = proto->server_init_connect(conn); - server->version = g_strdup(config_node_get_str(node, "version", NULL)); - server->session_reconnect = TRUE; - signal_emit("session restore server", 2, server, node); + conn->use_tls = config_node_get_bool(node, "use_tls", FALSE); + conn->tls_cert = g_strdup(config_node_get_str(node, "tls_cert", NULL)); + conn->tls_pkey = g_strdup(config_node_get_str(node, "tls_pkey", NULL)); + conn->tls_verify = config_node_get_bool(node, "tls_verify", TRUE); + conn->tls_cafile = g_strdup(config_node_get_str(node, "tls_cafile", NULL)); + conn->tls_capath = g_strdup(config_node_get_str(node, "tls_capath", NULL)); + conn->tls_ciphers = g_strdup(config_node_get_str(node, "tls_ciphers", NULL)); + conn->tls_pinned_cert = g_strdup(config_node_get_str(node, "tls_pinned_cert", NULL)); + conn->tls_pinned_pubkey = g_strdup(config_node_get_str(node, "tls_pinned_pubkey", NULL)); - proto->server_connect(server); - } + conn->reconnection = TRUE; + conn->connect_handle = i_io_channel_new(handle); + + server = proto->server_init_connect(conn); + server->version = g_strdup(config_node_get_str(node, "version", NULL)); + server->session_reconnect = TRUE; + signal_emit("session restore server", 2, server, node); + + proto->server_connect(server); } static void sig_session_save(CONFIG_REC *config) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 0bf9a104..5e51e511 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -165,14 +165,10 @@ static void cmd_server_add_modify(const char *data, gboolean add) else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; - if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) { + if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) rec->use_tls = TRUE; - } - else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) { + else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) rec->use_tls = FALSE; - /* tls_verify implies use_tls, disable it explicitly */ - rec->tls_verify = FALSE; - } value = g_hash_table_lookup(optlist, "tls_cert"); if (value == NULL) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 97e982b7..6cf3dd2b 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -90,6 +90,8 @@ static void sig_disconnected(IRC_SERVER_REC *server) return; rec = server->chanqueries; + if (rec == NULL) + return; g_return_if_fail(rec != NULL); g_hash_table_destroy(rec->accountqueries); diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index f0e6f345..cc34c6d3 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -64,7 +64,8 @@ static void sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC *conn, return; g_free_not_null(conn->channels); - conn->channels = irc_server_get_channels(server); + conn->channels = + irc_server_get_channels(server, settings_get_choice("rejoin_channels_on_reconnect")); g_free_not_null(conn->usermode); conn->usermode = g_strdup(server->wanted_usermode); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index bcad3f9e..00a6458b 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -469,6 +469,26 @@ void irc_server_connect(SERVER_REC *server) { g_return_if_fail(server != NULL); + if (server->connrec->connect_handle != NULL) { + IRC_SERVER_CONNECT_REC *conn; + int tls_disconnect; + + conn = ((IRC_SERVER_REC *) server)->connrec; + tls_disconnect = conn->use_tls || conn->starttls; + + if (tls_disconnect) { + /* we cannot use it, it is encrypted. force a reconnect */ + g_io_channel_unref(conn->connect_handle); + conn->connect_handle = NULL; + server->session_reconnect = FALSE; + server_connect_ref((SERVER_CONNECT_REC *) conn); + server_disconnect(server); + server_connect((SERVER_CONNECT_REC *) conn); + server_connect_unref((SERVER_CONNECT_REC *) conn); + return; + } + } + if (!server_start_connect(server)) { server_connect_unref(server->connrec); g_free(server); @@ -782,20 +802,17 @@ void irc_servers_start_cmd_timeout(void) /* Return a string of all channels (and keys, if any have them) in server, like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */ -char *irc_server_get_channels(IRC_SERVER_REC *server) +char *irc_server_get_channels(IRC_SERVER_REC *server, int rejoin_channels_mode) { GSList *tmp; GString *chans, *keys; char *ret; int use_keys; - int rejoin_channels_mode; g_return_val_if_fail(server != NULL, FALSE); - rejoin_channels_mode = settings_get_choice("rejoin_channels_on_reconnect"); - /* do we want to rejoin channels in the first place? */ - if(rejoin_channels_mode == 0) + if (rejoin_channels_mode == REJOIN_CHANNELS_MODE_OFF) return g_strdup(""); chans = g_string_new(NULL); @@ -806,7 +823,9 @@ char *irc_server_get_channels(IRC_SERVER_REC *server) for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *channel = tmp->data; CHANNEL_SETUP_REC *setup = channel_setup_find(channel->name, channel->server->connrec->chatnet); - if ((setup != NULL && setup->autojoin && rejoin_channels_mode == 2) || rejoin_channels_mode == 1) { + if ((setup != NULL && setup->autojoin && + rejoin_channels_mode == REJOIN_CHANNELS_MODE_AUTO) || + rejoin_channels_mode == REJOIN_CHANNELS_MODE_ON) { g_string_append_printf(chans, "%s,", channel->name); g_string_append_printf(keys, "%s,", channel->key == NULL ? "x" : channel->key); if (channel->key != NULL) @@ -819,7 +838,9 @@ char *irc_server_get_channels(IRC_SERVER_REC *server) REJOIN_REC *rec = tmp->data; CHANNEL_SETUP_REC *setup = channel_setup_find(rec->channel, server->tag); - if ((setup != NULL && setup->autojoin && rejoin_channels_mode == 2) || rejoin_channels_mode == 1) { + if ((setup != NULL && setup->autojoin && + rejoin_channels_mode == REJOIN_CHANNELS_MODE_AUTO) || + rejoin_channels_mode == REJOIN_CHANNELS_MODE_ON) { g_string_append_printf(chans, "%s,", rec->channel); g_string_append_printf(keys, "%s,", rec->key == NULL ? "x" : rec->key); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 16e2061e..04d1f693 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -157,9 +157,15 @@ void irc_server_connect(SERVER_REC *server); /* Purge server output, either all or for specified target */ void irc_server_purge_output(IRC_SERVER_REC *server, const char *target); +enum { + REJOIN_CHANNELS_MODE_OFF = 0, /* */ + REJOIN_CHANNELS_MODE_ON, + REJOIN_CHANNELS_MODE_AUTO +}; + /* Return a string of all channels (and keys, if any have them) in server, like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */ -char *irc_server_get_channels(IRC_SERVER_REC *server); +char *irc_server_get_channels(IRC_SERVER_REC *server, int rejoin_channels_mode); void irc_server_send_starttls(IRC_SERVER_REC *server); /* INTERNAL: */ diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index 6b817099..70683c4f 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config, GSList *tmp; CONFIG_NODE *isupport; struct _isupport_data isupport_data; + int tls_disconnect; if (!IS_IRC_SERVER(server)) return; @@ -58,7 +60,15 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config, break; } } - net_sendbuffer_flush(server->handle); + /* we cannot upgrade TLS (yet?) */ + tls_disconnect = server->connrec->use_tls || server->connrec->starttls; + if (tls_disconnect) { + config_node_set_str(config, node, "rejoin_channels", + irc_server_get_channels(server, REJOIN_CHANNELS_MODE_ON)); + irc_send_cmd_now(server, "QUIT :[TLS] Client upgrade"); + } + + net_sendbuffer_flush(server->handle); config_node_set_str(config, node, "real_address", server->real_address); config_node_set_str(config, node, "userhost", server->userhost); @@ -71,18 +81,26 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config, 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_int(config, node, "starttls", + server->connrec->disallow_starttls ? 0 : + server->connrec->starttls ? 1 : + -1); + 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; isupport_data.node = isupport; g_hash_table_foreach(server->isupport, (GHFunc) session_isupport_foreach, &isupport_data); + + /* we have to defer the disconnect to irc_server_connect */ } static void sig_session_restore_server(IRC_SERVER_REC *server, CONFIG_NODE *node) { GSList *tmp; + int starttls_mode; if (!IS_IRC_SERVER(server)) return; @@ -105,6 +123,14 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, g_free(server->connrec->sasl_password); server->connrec->sasl_password = g_strdup(config_node_get_str(node, "sasl_password", NULL)); + server->connrec->channels = g_strdup(config_node_get_str(node, "rejoin_channels", NULL)); + + starttls_mode = config_node_get_int(node, "starttls", -1); + if (starttls_mode == 0) + server->connrec->disallow_starttls = 1; + if (starttls_mode == 1) + server->connrec->starttls = 1; + if (server->isupport == NULL) { server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal); @@ -123,6 +149,7 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, } irc_server_init_isupport(server); + /* we will reconnect in irc_server_connect if the connection was TLS */ } static void sig_session_restore_nick(IRC_CHANNEL_REC *channel, diff --git a/src/irc/core/netsplit.c b/src/irc/core/netsplit.c index 1463f962..38b63fe5 100644 --- a/src/irc/core/netsplit.c +++ b/src/irc/core/netsplit.c @@ -381,6 +381,9 @@ static void sig_disconnected(IRC_SERVER_REC *server) if (!IS_IRC_SERVER(server)) return; + if (server->splits == NULL) + return; + g_hash_table_foreach(server->splits, (GHFunc) netsplit_destroy_hash, server); g_hash_table_destroy(server->splits); diff --git a/src/irc/notifylist/notifylist.c b/src/irc/notifylist/notifylist.c index 158b4dea..73737b37 100644 --- a/src/irc/notifylist/notifylist.c +++ b/src/irc/notifylist/notifylist.c @@ -209,6 +209,9 @@ static void notifylist_deinit_server(IRC_SERVER_REC *server) return; mserver = MODULE_DATA(server); + if (!mserver) + return; + while (mserver->notify_users != NULL) { rec = mserver->notify_users->data; diff --git a/src/perl/irc/Server.xs b/src/perl/irc/Server.xs index 54361ec9..fef3698f 100644 --- a/src/perl/irc/Server.xs +++ b/src/perl/irc/Server.xs @@ -1,5 +1,6 @@ #define PERL_NO_GET_CONTEXT #include "module.h" +#include static GSList *register_hash2list(HV *hv) { @@ -47,12 +48,20 @@ MODULE = Irssi::Irc::Server PACKAGE = Irssi::Irc::Server PREFIX = irc_server_ PROTOTYPES: ENABLE void -irc_server_get_channels(server) +irc_server_get_channels(server, rejoin_channels_mode = "") Irssi::Irc::Server server + char *rejoin_channels_mode PREINIT: char *ret; + int mode; + SETTINGS_REC *setting; PPCODE: - ret = irc_server_get_channels(server); + setting = settings_get_record("rejoin_channels_on_reconnect"); + mode = strarray_find(setting->choices, rejoin_channels_mode); + if (mode < 0) + mode = setting->default_value.v_int; + + ret = irc_server_get_channels(server, mode); XPUSHs(sv_2mortal(new_pv(ret))); g_free(ret); From 2a0f1d7636a9fd941fbb04f52fe9c23b3263406a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 7 Apr 2021 11:05:05 +0200 Subject: [PATCH 0787/1198] fix fe-fuzz --- src/fe-fuzz/server.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index a444494d..a2ffb9e9 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -177,12 +177,23 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { for (; *lines != NULL; lines++) { gchar *prefixedLine; + int disconnected; if (prefixedChoice) { prefixedLine = g_strdup_printf(":user %s\n", *lines); } else { prefixedLine = g_strdup_printf("%s\n", *lines); } + server_ref(server); signal_emit("server incoming", 2, server, prefixedLine); + disconnected = server->disconnected; + if (disconnected) { + server_connect_unref(server->connrec); + } + server_unref(server); + if (disconnected) { + /* reconnect */ + test_server(); + } g_free(prefixedLine); } From 244a8c72b4d1226469f1193b3ca58946c01d9e00 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 7 Apr 2021 22:18:05 +0200 Subject: [PATCH 0788/1198] verify tls connection --- irssi.conf | 4 +- src/core/chat-commands.c | 47 +------------------- src/core/servers-setup.c | 74 ++++++++++++++++++++++++++++--- src/fe-common/core/fe-server.c | 39 +++++++++++----- src/fe-common/irc/fe-irc-server.c | 8 ++-- src/irc/core/irc-servers-setup.c | 17 ++++++- src/irc/core/irc-servers.c | 1 + src/irc/core/irc-session.c | 4 +- 8 files changed, 123 insertions(+), 71 deletions(-) diff --git a/irssi.conf b/irssi.conf index 174d0552..80c2b9c3 100644 --- a/irssi.conf +++ b/irssi.conf @@ -1,10 +1,10 @@ servers = ( { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, - { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; }, + { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, - { address = "eu.irc6.net"; chatnet = "IRCnet"; port = "6667"; use_tls = "yes"; }, + { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 92bb9db8..dd8dbe75 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -40,7 +40,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; GHashTable *optlist; - char *addr, *portstr, *password, *nick, *chatnet, *host, *tmp; + char *addr, *portstr, *password, *nick, *chatnet, *host; void *free_arg; g_return_val_if_fail(data != NULL, NULL); @@ -94,50 +94,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, if (strchr(addr, '/') != NULL) conn->unix_socket = TRUE; - if (g_hash_table_lookup(optlist, "6") != NULL) - conn->family = AF_INET6; - else if (g_hash_table_lookup(optlist, "4") != NULL) - conn->family = AF_INET; - - if (g_hash_table_lookup(optlist, "notls") != NULL) - conn->use_tls = FALSE; - if (g_hash_table_lookup(optlist, "tls") != NULL || g_hash_table_lookup(optlist, "ssl") != NULL) - conn->use_tls = TRUE; - if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) - conn->tls_cert = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pkey")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) - conn->tls_pkey = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pass")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) - conn->tls_pass = g_strdup(tmp); - if (g_hash_table_lookup(optlist, "notls_verify") != NULL) - conn->tls_verify = FALSE; - if (g_hash_table_lookup(optlist, "tls_verify") != NULL || g_hash_table_lookup(optlist, "ssl_verify") != NULL) - conn->tls_verify = TRUE; - if ((tmp = g_hash_table_lookup(optlist, "tls_cafile")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) - conn->tls_cafile = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_capath")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL) - conn->tls_capath = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_ciphers")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_ciphers")) != NULL) - conn->tls_ciphers = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_cert")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pinned_cert")) != NULL) - conn->tls_pinned_cert = g_strdup(tmp); - if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_pubkey")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pinned_pubkey")) != NULL) - conn->tls_pinned_pubkey = g_strdup(tmp); - if ((conn->tls_capath != NULL && conn->tls_capath[0] != '\0') - || (conn->tls_cafile != NULL && conn->tls_cafile[0] != '\0')) - conn->tls_verify = TRUE; - if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) - conn->use_tls = TRUE; - - if (g_hash_table_lookup(optlist, "!") != NULL) - conn->no_autojoin_channels = TRUE; - - if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) - conn->no_autosendcmd = TRUE; - - if (g_hash_table_lookup(optlist, "noproxy") != NULL) - g_free_and_null(conn->proxy); - + /* TLS options are handled in server_create_conn_opt ... -> server_setup_fill_optlist */ *rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog")); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index c6612e84..357e8ebe 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -180,6 +180,68 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn, const char *address, int signal_emit("server setup fill connect", 2, conn, optlist); } +static void server_setup_fill_optlist(SERVER_CONNECT_REC *conn, GHashTable *optlist) +{ + char *tmp; + + if (g_hash_table_lookup(optlist, "6") != NULL) + conn->family = AF_INET6; + else if (g_hash_table_lookup(optlist, "4") != NULL) + conn->family = AF_INET; + + /* ad-hoc TLS settings from command optlist */ + if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) + conn->tls_cert = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pkey")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) + conn->tls_pkey = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pass")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) + conn->tls_pass = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_cafile")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) + conn->tls_cafile = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_capath")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL) + conn->tls_capath = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_ciphers")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_ciphers")) != NULL) + conn->tls_ciphers = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_cert")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pinned_cert")) != NULL) + conn->tls_pinned_cert = g_strdup(tmp); + if ((tmp = g_hash_table_lookup(optlist, "tls_pinned_pubkey")) != NULL || + (tmp = g_hash_table_lookup(optlist, "ssl_pinned_pubkey")) != NULL) + conn->tls_pinned_pubkey = g_strdup(tmp); + if ((conn->tls_capath != NULL && conn->tls_capath[0] != '\0') || + (conn->tls_cafile != NULL && conn->tls_cafile[0] != '\0')) + conn->tls_verify = TRUE; + if (g_hash_table_lookup(optlist, "notls_verify") != NULL) + conn->tls_verify = FALSE; + if (g_hash_table_lookup(optlist, "tls_verify") != NULL || + g_hash_table_lookup(optlist, "ssl_verify") != NULL) + conn->tls_verify = TRUE; + if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) + conn->use_tls = TRUE; + if (g_hash_table_lookup(optlist, "notls") != NULL) + conn->use_tls = FALSE; + if (g_hash_table_lookup(optlist, "tls") != NULL || + g_hash_table_lookup(optlist, "ssl") != NULL) + conn->use_tls = TRUE; + + if (g_hash_table_lookup(optlist, "!") != NULL) + conn->no_autojoin_channels = TRUE; + + if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) + conn->no_autosendcmd = TRUE; + + if (g_hash_table_lookup(optlist, "noproxy") != NULL) + g_free_and_null(conn->proxy); + + signal_emit("server setup fill optlist", 2, conn, optlist); +} + static void server_setup_fill_server(SERVER_CONNECT_REC *conn, SERVER_SETUP_REC *sserver) { @@ -262,6 +324,10 @@ static SERVER_CONNECT_REC *create_addr_conn(int chat_type, const char *address, if (sserver != NULL) server_setup_fill_server(conn, sserver); + /* fill the optlist overrides */ + if (g_hash_table_size(optlist)) + server_setup_fill_optlist(conn, optlist); + /* nick / password given in command line overrides all settings */ if (password && *password) { g_free_not_null(conn->password); @@ -418,7 +484,8 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) rec->password = g_strdup(config_node_get_str(node, "password", NULL)); rec->use_tls = config_node_get_bool(node, "use_tls", FALSE) || config_node_get_bool(node, "use_ssl", FALSE); - rec->tls_verify = config_node_get_bool(node, "tls_verify", FALSE) || config_node_get_bool(node, "ssl_verify", FALSE); + rec->tls_verify = config_node_get_bool(node, "tls_verify", TRUE) || + config_node_get_bool(node, "ssl_verify", FALSE); value = config_node_get_str(node, "tls_cert", NULL); if (value == NULL) @@ -460,11 +527,6 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) value = config_node_get_str(node, "ssl_pinned_pubkey", NULL); rec->tls_pinned_pubkey = g_strdup(value); - if (rec->tls_cafile || rec->tls_capath) - rec->tls_verify = TRUE; - if (rec->tls_cert != NULL || rec->tls_verify) - rec->use_tls = TRUE; - rec->port = port; rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE); rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE); diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 5e51e511..e0100618 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -101,6 +101,7 @@ static SERVER_SETUP_REC *create_server_setup(GHashTable *optlist) server = rec->create_server_setup(); server->chat_type = rec->id; + server->tls_verify = TRUE; return server; } @@ -110,6 +111,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) SERVER_SETUP_REC *rec; char *addr, *portstr, *password, *value, *chatnet; void *free_arg; + gboolean newrec; int port; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, @@ -135,6 +137,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec = server_setup_find(addr, port, chatnet); if (rec == NULL) { + newrec = TRUE; if (add == FALSE) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_NOT_FOUND, addr, port); @@ -150,6 +153,7 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec->address = g_strdup(addr); rec->port = port; } else { + newrec = FALSE; if (*portstr != '\0' || g_hash_table_lookup(optlist, "port")) rec->port = port; @@ -165,16 +169,17 @@ static void cmd_server_add_modify(const char *data, gboolean add) else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; - if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) - rec->use_tls = TRUE; - else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) - rec->use_tls = FALSE; - value = g_hash_table_lookup(optlist, "tls_cert"); if (value == NULL) value = g_hash_table_lookup(optlist, "ssl_cert"); - if (value != NULL && *value != '\0') + if (value != NULL && *value != '\0') { rec->tls_cert = g_strdup(value); + if (newrec) { + /* convenience and backward compatibility, turn on tls if tls_cert is given + */ + rec->use_tls = TRUE; + } + } value = g_hash_table_lookup(optlist, "tls_pkey"); if (value == NULL) @@ -188,11 +193,6 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (value != NULL && *value != '\0') rec->tls_pass = g_strdup(value); - if (g_hash_table_lookup(optlist, "tls_verify") || g_hash_table_lookup(optlist, "ssl_verify")) - rec->tls_verify = TRUE; - else if (g_hash_table_lookup(optlist, "notls_verify") || g_hash_table_lookup(optlist, "nossl_verify")) - rec->tls_verify = FALSE; - value = g_hash_table_lookup(optlist, "tls_cafile"); if (value == NULL) value = g_hash_table_lookup(optlist, "ssl_cafile"); @@ -227,8 +227,23 @@ static void cmd_server_add_modify(const char *data, gboolean add) || (rec->tls_capath != NULL && rec->tls_capath[0] != '\0')) rec->tls_verify = TRUE; - if ((rec->tls_cert != NULL && rec->tls_cert[0] != '\0') || rec->tls_verify == TRUE) + if (g_hash_table_lookup(optlist, "tls_verify") || + g_hash_table_lookup(optlist, "ssl_verify")) { + rec->tls_verify = TRUE; + if (newrec) { + /* convenience and backward compatibility, turn on tls if tls_verify is + * given */ + rec->use_tls = TRUE; + } + } else if (g_hash_table_lookup(optlist, "notls_verify") || + g_hash_table_lookup(optlist, "nossl_verify")) { + rec->tls_verify = FALSE; + } + + if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) rec->use_tls = TRUE; + else if (g_hash_table_lookup(optlist, "notls") || g_hash_table_lookup(optlist, "nossl")) + rec->use_tls = FALSE; if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index d30aa45d..66483991 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -91,8 +91,10 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, rec->starttls = -1; if (g_hash_table_lookup(optlist, "disallow_starttls")) rec->starttls = 0; - if (g_hash_table_lookup(optlist, "starttls")) + if (g_hash_table_lookup(optlist, "starttls")) { rec->starttls = 1; + rec->use_tls = 0; + } } /* SYNTAX: SERVER LIST */ @@ -129,8 +131,8 @@ static void cmd_server_list(const char *data) if (rec->tls_pass) g_string_append_printf(str, "(pass), "); } - if (rec->tls_verify) - g_string_append(str, "tls_verify, "); + if (!rec->tls_verify) + g_string_append(str, "notls_verify, "); if (rec->tls_cafile) g_string_append_printf(str, "tls_cafile: %s, ", rec->tls_cafile); if (rec->tls_capath) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 6ba22862..a48e1e92 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -64,11 +64,19 @@ static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn, GHashTab value = settings_get_str("usermode"); conn->usermode = (value != NULL && *value != '\0') ? g_strdup(value) : NULL; +} - if (g_hash_table_lookup(optlist, "starttls") != NULL) +static void sig_server_setup_fill_optlist(IRC_SERVER_CONNECT_REC *conn, GHashTable *optlist) +{ + if (!IS_IRC_SERVER_CONNECT(conn)) + return; + + if (g_hash_table_lookup(optlist, "starttls") != NULL) { conn->starttls = 1; - else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) + conn->use_tls = 0; + } else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) { conn->disallow_starttls = 1; + } } static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, @@ -184,6 +192,9 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); rec->starttls = config_node_get_bool(node, "starttls", -1); + if (rec->starttls == 1) { + rec->use_tls = 0; + } } static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, @@ -213,6 +224,7 @@ void irc_servers_setup_init(void) signal_add("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn); signal_add("server setup fill connect", (SIGNAL_FUNC) sig_server_setup_fill_connect); signal_add("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet); + signal_add("server setup fill optlist", (SIGNAL_FUNC) sig_server_setup_fill_optlist); signal_add("server setup read", (SIGNAL_FUNC) sig_server_setup_read); signal_add("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved); } @@ -222,6 +234,7 @@ void irc_servers_setup_deinit(void) signal_remove("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn); signal_remove("server setup fill connect", (SIGNAL_FUNC) sig_server_setup_fill_connect); signal_remove("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet); + signal_remove("server setup fill optlist", (SIGNAL_FUNC) sig_server_setup_fill_optlist); signal_remove("server setup read", (SIGNAL_FUNC) sig_server_setup_read); signal_remove("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved); } diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 00a6458b..62d47db1 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -470,6 +470,7 @@ void irc_server_connect(SERVER_REC *server) g_return_if_fail(server != NULL); if (server->connrec->connect_handle != NULL) { + /* an existing handle from upgrade */ IRC_SERVER_CONNECT_REC *conn; int tls_disconnect; diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index 70683c4f..164e68bc 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -128,8 +128,10 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, starttls_mode = config_node_get_int(node, "starttls", -1); if (starttls_mode == 0) server->connrec->disallow_starttls = 1; - if (starttls_mode == 1) + if (starttls_mode == 1) { server->connrec->starttls = 1; + server->connrec->use_tls = 0; + } if (server->isupport == NULL) { server->isupport = From 085c08e65c7624dd5264dbacaee913e36e95c170 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 7 Apr 2021 22:29:48 +0200 Subject: [PATCH 0789/1198] use enum --- src/fe-common/irc/fe-irc-server.c | 10 +++++----- src/irc/core/irc-servers-setup.c | 10 +++++----- src/irc/core/irc-servers-setup.h | 6 ++++++ src/irc/core/irc-servers.c | 2 +- src/irc/core/irc-session.c | 13 +++++++------ 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index 66483991..f637a7e8 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -88,11 +88,11 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, if (value != NULL && *value != '\0') rec->max_query_chans = atoi(value); if (g_hash_table_lookup(optlist, "nodisallow_starttls") || g_hash_table_lookup(optlist, "nostarttls")) - rec->starttls = -1; + rec->starttls = STARTTLS_NOTSET; if (g_hash_table_lookup(optlist, "disallow_starttls")) - rec->starttls = 0; + rec->starttls = STARTTLS_DISALLOW; if (g_hash_table_lookup(optlist, "starttls")) { - rec->starttls = 1; + rec->starttls = STARTTLS_ENABLED; rec->use_tls = 0; } } @@ -118,9 +118,9 @@ static void cmd_server_list(const char *data) g_string_append(str, "autoconnect, "); if (rec->no_proxy) g_string_append(str, "noproxy, "); - if (rec->starttls == 0) + if (rec->starttls == STARTTLS_DISALLOW) g_string_append(str, "disallow_starttls, "); - if (rec->starttls == 1) + if (rec->starttls == STARTTLS_ENABLED) g_string_append(str, "starttls, "); if (rec->use_tls) g_string_append(str, "tls, "); diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index a48e1e92..739e364e 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -44,9 +44,9 @@ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn, conn->max_cmds_at_once = sserver->max_cmds_at_once; if (sserver->max_query_chans > 0) conn->max_query_chans = sserver->max_query_chans; - if (sserver->starttls == 0) + if (sserver->starttls == STARTTLS_DISALLOW) conn->disallow_starttls = 1; - else if (sserver->starttls == 1) + else if (sserver->starttls == STARTTLS_ENABLED) conn->starttls = 1; } @@ -191,8 +191,8 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0); rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); - rec->starttls = config_node_get_bool(node, "starttls", -1); - if (rec->starttls == 1) { + rec->starttls = config_node_get_bool(node, "starttls", STARTTLS_NOTSET); + if (rec->starttls == STARTTLS_ENABLED) { rec->use_tls = 0; } } @@ -209,7 +209,7 @@ static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, iconfig_node_set_int(node, "cmd_queue_speed", rec->cmd_queue_speed); if (rec->max_query_chans > 0) iconfig_node_set_int(node, "max_query_chans", rec->max_query_chans); - if (rec->starttls >= 0) + if (rec->starttls != STARTTLS_NOTSET) iconfig_node_set_bool(node, "starttls", rec->starttls); else iconfig_node_set_str(node, "starttls", NULL); diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index 8fbb311e..47bdc012 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -11,6 +11,12 @@ #define IS_IRC_SERVER_SETUP(server) \ (IRC_SERVER_SETUP(server) ? TRUE : FALSE) +enum { + STARTTLS_DISALLOW = -1, /* */ + STARTTLS_NOTSET = 0, + STARTTLS_ENABLED = 1 +}; + typedef struct { #include diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 62d47db1..0326bc65 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -303,7 +303,7 @@ static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle) IRC_SERVER_SETUP_REC *ssetup = IRC_SERVER_SETUP(server_setup_find( server->connrec->address, server->connrec->port, server->connrec->chatnet)); if (ssetup != NULL) { - ssetup->starttls = 1; + ssetup->starttls = STARTTLS_ENABLED; server_setup_add((SERVER_SETUP_REC *) ssetup); } } diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index 164e68bc..ac71f986 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -82,9 +83,9 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config, config_node_set_str(config, node, "sasl_password", server->connrec->sasl_password); config_node_set_int(config, node, "starttls", - server->connrec->disallow_starttls ? 0 : - server->connrec->starttls ? 1 : - -1); + server->connrec->disallow_starttls ? STARTTLS_DISALLOW : + server->connrec->starttls ? STARTTLS_ENABLED : + STARTTLS_NOTSET); config_node_set_bool(config, node, "isupport_sent", server->isupport_sent); isupport = config_node_section(config, node, "isupport", NODE_TYPE_BLOCK); @@ -125,10 +126,10 @@ static void sig_session_restore_server(IRC_SERVER_REC *server, server->connrec->channels = g_strdup(config_node_get_str(node, "rejoin_channels", NULL)); - starttls_mode = config_node_get_int(node, "starttls", -1); - if (starttls_mode == 0) + starttls_mode = config_node_get_int(node, "starttls", STARTTLS_NOTSET); + if (starttls_mode == STARTTLS_DISALLOW) server->connrec->disallow_starttls = 1; - if (starttls_mode == 1) { + if (starttls_mode == STARTTLS_ENABLED) { server->connrec->starttls = 1; server->connrec->use_tls = 0; } From 61237ee6c0b459c0a9d210e4b4d3f6f186ec0c92 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 8 Apr 2021 21:16:55 +0200 Subject: [PATCH 0790/1198] reorder code --- src/irc/core/irc-servers.c | 101 ++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 0326bc65..8d4f8a9e 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -208,7 +208,55 @@ static char **split_message(SERVER_REC *server, const char *target, strlen(target)); } -static void server_init_2(IRC_SERVER_REC *server); +static void server_init_2(IRC_SERVER_REC *server) +{ + IRC_SERVER_CONNECT_REC *conn; + char *address, *ptr, *username, *cmd; + + g_return_if_fail(server != NULL); + + conn = server->connrec; + + if (conn->password != NULL && *conn->password != '\0') { + /* send password */ + cmd = g_strdup_printf("PASS %s", conn->password); + irc_send_cmd_now(server, cmd); + g_free(cmd); + } + + /* send nick */ + cmd = g_strdup_printf("NICK %s", conn->nick); + irc_send_cmd_now(server, cmd); + g_free(cmd); + + /* send user/realname */ + address = server->connrec->address; + ptr = strrchr(address, ':'); + if (ptr != NULL) { + /* IPv6 address .. doesn't work here, use the string after + the last : char */ + address = ptr + 1; + if (*address == '\0') + address = "x"; + } + + username = g_strdup(conn->username); + ptr = strchr(username, ' '); + if (ptr != NULL) + *ptr = '\0'; + + cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname); + irc_send_cmd_now(server, cmd); + g_free(cmd); + g_free(username); + + if (conn->proxy != NULL && conn->proxy_string_after != NULL) { + cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port); + irc_send_cmd_now(server, cmd); + g_free(cmd); + } +} + static void server_init_1(IRC_SERVER_REC *server) { IRC_SERVER_CONNECT_REC *conn; @@ -271,6 +319,7 @@ static void server_init_1(IRC_SERVER_REC *server) static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle) { int error; + server->connrec->starttls = 1; if (server->starttls_tag) { g_source_remove(server->starttls_tag); @@ -298,7 +347,6 @@ static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle) signal_emit("server cap continue", 1, server); } - server->connrec->starttls = 1; if (settings_get_bool("starttls_sts")) { IRC_SERVER_SETUP_REC *ssetup = IRC_SERVER_SETUP(server_setup_find( server->connrec->address, server->connrec->port, server->connrec->chatnet)); @@ -370,55 +418,6 @@ static void event_capend(IRC_SERVER_REC *server) server_init_2(server); } -static void server_init_2(IRC_SERVER_REC *server) -{ - IRC_SERVER_CONNECT_REC *conn; - char *address, *ptr, *username, *cmd; - - g_return_if_fail(server != NULL); - - conn = server->connrec; - - if (conn->password != NULL && *conn->password != '\0') { - /* send password */ - cmd = g_strdup_printf("PASS %s", conn->password); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } - - /* send nick */ - cmd = g_strdup_printf("NICK %s", conn->nick); - irc_send_cmd_now(server, cmd); - g_free(cmd); - - /* send user/realname */ - address = server->connrec->address; - ptr = strrchr(address, ':'); - if (ptr != NULL) { - /* IPv6 address .. doesn't work here, use the string after - the last : char */ - address = ptr + 1; - if (*address == '\0') - address = "x"; - } - - username = g_strdup(conn->username); - ptr = strchr(username, ' '); - if (ptr != NULL) - *ptr = '\0'; - - cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname); - irc_send_cmd_now(server, cmd); - g_free(cmd); - g_free(username); - - if (conn->proxy != NULL && conn->proxy_string_after != NULL) { - cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port); - irc_send_cmd_now(server, cmd); - g_free(cmd); - } -} - SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn) { IRC_SERVER_CONNECT_REC *ircconn; From 8a5d5d384ed20cefa3fdc4a65d27fac3e4913a7b Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 8 Apr 2021 22:28:35 +0200 Subject: [PATCH 0791/1198] add nocap flag --- src/fe-common/irc/fe-irc-server.c | 24 +++++++++++++++++++++--- src/fe-common/irc/module-formats.c | 1 + src/fe-common/irc/module-formats.h | 1 + src/irc/core/irc-commands.c | 2 +- src/irc/core/irc-servers-reconnect.c | 1 + src/irc/core/irc-servers-setup.c | 9 +++++++++ src/irc/core/irc-servers-setup.h | 1 + src/irc/core/irc-servers.c | 11 ++++++++--- src/irc/core/irc-servers.h | 1 + src/irc/core/irc-session.c | 2 ++ 10 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c index f637a7e8..fbd70404 100644 --- a/src/fe-common/irc/fe-irc-server.c +++ b/src/fe-common/irc/fe-irc-server.c @@ -95,6 +95,19 @@ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, rec->starttls = STARTTLS_ENABLED; rec->use_tls = 0; } + if (g_hash_table_lookup(optlist, "nocap")) + rec->no_cap = 1; + if (g_hash_table_lookup(optlist, "cap")) + rec->no_cap = 0; +} + +static void sig_server_waiting_info(IRC_SERVER_REC *server, const char *version) +{ + if (!IS_IRC_SERVER(server)) + return; + + printformat(server, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SERVER_WAITING_CAP_LS, server, + version); } /* SYNTAX: SERVER LIST */ @@ -118,6 +131,8 @@ static void cmd_server_list(const char *data) g_string_append(str, "autoconnect, "); if (rec->no_proxy) g_string_append(str, "noproxy, "); + if (rec->no_cap) + g_string_append(str, "nocap, "); if (rec->starttls == STARTTLS_DISALLOW) g_string_append(str, "disallow_starttls, "); if (rec->starttls == STARTTLS_ENABLED) @@ -167,17 +182,20 @@ static void cmd_server_list(const char *data) void fe_irc_server_init(void) { signal_add("server add fill", (SIGNAL_FUNC) sig_server_add_fill); + signal_add("server waiting cap ls", (SIGNAL_FUNC) sig_server_waiting_info); command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list); - command_set_options("server add", "-ircnet -network -cmdspeed -cmdmax -querychans starttls " - "nostarttls disallow_starttls nodisallow_starttls"); + command_set_options("server add", + "-ircnet -network -cmdspeed -cmdmax -querychans starttls " + "nostarttls disallow_starttls nodisallow_starttls cap nocap"); command_set_options("server modify", "-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls " - "disallow_starttls nodisallow_starttls"); + "disallow_starttls nodisallow_starttls cap nocap"); } void fe_irc_server_deinit(void) { signal_remove("server add fill", (SIGNAL_FUNC) sig_server_add_fill); + signal_remove("server waiting cap ls", (SIGNAL_FUNC) sig_server_waiting_info); command_unbind("server list", (SIGNAL_FUNC) cmd_server_list); } diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c index d4c00f25..1a96cbce 100644 --- a/src/fe-common/irc/module-formats.c +++ b/src/fe-common/irc/module-formats.c @@ -45,6 +45,7 @@ FORMAT_REC fecommon_irc_formats[] = { { "setupserver_header", "%#Server Port Network Settings", 0 }, { "setupserver_line", "%#%|$[!20]0 $[5]1 $[10]2 $3", 4, { 0, 1, 0, 0 } }, { "setupserver_footer", "", 0 }, + { "server_waiting_cap_ls", "Waiting for CAP LS response...", 2, { 0, 0 } }, { "sasl_success", "SASL authentication succeeded", 0 }, { "sasl_error", "Cannot authenticate via SASL ($0)", 1, { 0 } }, { "cap_req", "Capabilities requested: $0", 1, { 0 } }, diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h index 892b77c8..5abd04a4 100644 --- a/src/fe-common/irc/module-formats.h +++ b/src/fe-common/irc/module-formats.h @@ -23,6 +23,7 @@ enum { IRCTXT_SETUPSERVER_HEADER, IRCTXT_SETUPSERVER_LINE, IRCTXT_SETUPSERVER_FOOTER, + IRCTXT_SERVER_WAITING_CAP_LS, IRCTXT_SASL_SUCCESS, IRCTXT_SASL_ERROR, IRCTXT_CAP_REQ, diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 9cc8afe8..cba909c1 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -1053,7 +1053,7 @@ void irc_commands_init(void) signal_add("whois end", (SIGNAL_FUNC) event_end_of_whois); signal_add("whowas event", (SIGNAL_FUNC) event_whowas); - command_set_options("connect", "+ircnet starttls disallow_starttls"); + command_set_options("connect", "+ircnet starttls disallow_starttls nocap"); command_set_options("topic", "delete"); command_set_options("list", "yes"); command_set_options("away", "one all"); diff --git a/src/irc/core/irc-servers-reconnect.c b/src/irc/core/irc-servers-reconnect.c index cc34c6d3..e18a5a9b 100644 --- a/src/irc/core/irc-servers-reconnect.c +++ b/src/irc/core/irc-servers-reconnect.c @@ -53,6 +53,7 @@ static void sig_server_connect_copy(SERVER_CONNECT_REC **dest, rec->sasl_password = g_strdup(src->sasl_password); rec->disallow_starttls = src->disallow_starttls; rec->starttls = src->starttls; + rec->no_cap = src->no_cap; *dest = (SERVER_CONNECT_REC *) rec; } diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 739e364e..5299ef04 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -48,6 +48,8 @@ static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn, conn->disallow_starttls = 1; else if (sserver->starttls == STARTTLS_ENABLED) conn->starttls = 1; + if (sserver->no_cap) + conn->no_cap = 1; } static void sig_server_setup_fill_connect(IRC_SERVER_CONNECT_REC *conn, GHashTable *optlist) @@ -77,6 +79,10 @@ static void sig_server_setup_fill_optlist(IRC_SERVER_CONNECT_REC *conn, GHashTab } else if (g_hash_table_lookup(optlist, "disallow_starttls") != NULL) { conn->disallow_starttls = 1; } + if (g_hash_table_lookup(optlist, "nocap")) + conn->no_cap = 1; + if (g_hash_table_lookup(optlist, "cap")) + conn->no_cap = 0; } static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, @@ -195,6 +201,7 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) if (rec->starttls == STARTTLS_ENABLED) { rec->use_tls = 0; } + rec->no_cap = config_node_get_bool(node, "no_cap", FALSE); } static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, @@ -213,6 +220,8 @@ static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec, iconfig_node_set_bool(node, "starttls", rec->starttls); else iconfig_node_set_str(node, "starttls", NULL); + if (rec->no_cap) + iconfig_node_set_bool(node, "no_cap", TRUE); } void irc_servers_setup_init(void) diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index 47bdc012..7b11a2fe 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -25,6 +25,7 @@ typedef struct { int cmd_queue_speed; int max_query_chans; int starttls; + int no_cap : 1; } IRC_SERVER_SETUP_REC; void irc_servers_setup_init(void); diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 8d4f8a9e..06f3d3c8 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -309,11 +309,16 @@ static void server_init_1(IRC_SERVER_REC *server) server->wait_cmd = g_get_real_time(); server->wait_cmd += 120 * G_USEC_PER_SEC; - irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); - /* to detect non-CAP servers, send this bogus join */ - irc_send_cmd_now(server, "JOIN "); + if (!conn->no_cap) { + signal_emit("server waiting cap ls", 2, server, CAP_LS_VERSION); + irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); + /* to detect non-CAP servers, send this bogus join */ + irc_send_cmd_now(server, "JOIN "); + } if (conn->starttls) irc_server_send_starttls(server); + else if (conn->no_cap) + server_init_2(server); } static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle) diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 04d1f693..544baba9 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -63,6 +63,7 @@ struct _IRC_SERVER_CONNECT_REC { int max_kicks, max_msgs, max_modes, max_whois; int disallow_starttls:1; int starttls:1; + int no_cap:1; }; /* clang-format on */ diff --git a/src/irc/core/irc-session.c b/src/irc/core/irc-session.c index ac71f986..49d9a3f2 100644 --- a/src/irc/core/irc-session.c +++ b/src/irc/core/irc-session.c @@ -87,6 +87,7 @@ static void sig_session_save_server(IRC_SERVER_REC *server, CONFIG_REC *config, server->connrec->starttls ? STARTTLS_ENABLED : STARTTLS_NOTSET); + config_node_set_bool(config, node, "no_cap", server->connrec->no_cap); 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; @@ -115,6 +116,7 @@ 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->no_cap = config_node_get_bool(node, "no_cap", 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 From 645d80d3b8bcf17b09b7e22ccf251da3fb0b8a9e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 9 Apr 2021 19:03:41 +0200 Subject: [PATCH 0792/1198] Merge tag '1.2.3' into integrate/1.2.3 --- NEWS | 40 +++++++++++++++++++++++++++++++++++++++- src/fe-text/textbuffer.c | 2 +- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 2e6e5025..1bdffd82 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,42 @@ -v1.3-head 2019-xx-xx The Irssi team +v1.3-head 2021-xx-xx The Irssi team + +v1.2.3 2021-04-11 The Irssi team + - Fix the compilation of utf8proc (#1021) + - Fix wrong call to free. By Zero King (#1076) + - Fix a colour reset in true colour themes when encountering + mIRC colours (#1059) + - Fix memory leak on malformed CAP requests (#1120) + - Fix an erroneous free of SASL data. Credit to Oss-Fuzz (#1128, + #1130) + - Re-set the TLS flag when reconnecting (#1027, #1134) + - Fix the scrollback getting stuck after /clear (#1115, #1136) + - Fix the input of Ctrl+C as the first character (#1153, #1154) + - Fix crash on quit during unloading of modules on certain + platforms (#1167) + - Fix Irssi freezing input after Ctrl+Space on GLib >2.62 (#1180, + #1183) + - Fix layout of IDCHANs. By Lauri Tirkkonen (#1197) + - Fix crash when server got reconnected before it was properly + connected (#1210, #1211) + - Fix multiple identical active caps (#1249) + - Minor help corrections (#1156, #1213, #1214, #1255) + - Remove erroneous colour in the colorless theme. Reported and + fixed by Nutchanon Wetchasit (#1220, #1221) + - Fix invalid bounds calculation when editing the text + entry. Found and fixed by Sergey Valentey (#1269) + - Fix passing of negative size in buffer writes. Found and + fixed by Sergey Valentey (#1270) + - Fix Irssi freezing on slow hardware and fast DCC transfers (#159, + #1271) + - Fix compilation on Solaris (#1291) + - Fix null pointer dereference when receiving broken JOIN + record. Credit to Oss-Fuzz (#1292) + - Fix crash on /connect to some sockets (#1239, #1298) + - Fix Irssi rendering on Apple ARM. By Misty De Méo (#1267, + #1268, #1290) + - Fix crash on /lastlog with broken lines (#1281, #1299) + - Fix memory leak when receiving bogus SASL authentication + data. Found and fixed by Sergey Valentey (#1293) v1.2.2 2019-08-29 The Irssi team - Fix a use after free issue when receiving IRCv3 CAP diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 25fce22f..8a206f2c 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -236,7 +236,7 @@ void textbuffer_line2text(TEXT_BUFFER_REC *buffer, LINE_REC *line, int coloring, g_return_if_fail(line != NULL); g_return_if_fail(str != NULL); - g_string_truncate(str, 0); + g_string_truncate(str, 0); if ((ptr = textbuffer_line_get_text(buffer, line, coloring == COLORING_RAW)) != NULL) { if (coloring == COLORING_STRIP) { From 8bb4875007bfebf99f826971ed756e4f0284363a Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Sat, 10 Apr 2021 09:44:53 +0200 Subject: [PATCH 0793/1198] Ignore files generated by ./autogen.sh --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 79e4d4bb..217ce3a8 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,8 @@ src/fe-fuzz/crash-* src/fe-fuzz/oom-* /core +/irssi-1.pc +/irssi/ /tests/fe-common/core/test-formats /tests/fe-common/core/test-formats.log /tests/fe-common/core/test-formats.trs From 90003a2bf652ed660946ebf1f5f17693331e9df5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 18 Apr 2021 11:38:20 +0200 Subject: [PATCH 0794/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index ccd000d5..bdbafca7 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 35 +#define IRSSI_ABI_VERSION 36 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 3dbfac5699c6887b7149a0b1c805c4730f63d0f4 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 20 Apr 2021 09:11:06 +0200 Subject: [PATCH 0795/1198] fuzz test --- .github/workflows/cifuzz.yml | 1 + src/fe-fuzz/server.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 9f956d5c..a32e335d 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -8,6 +8,7 @@ on: - 'src/irc/**/*.c' - 'src/fe-common/irc/**/*.c' - 'src/lib-config/**/*.c' + - 'src/fe-fuzz/**/*.c' - 'tests/**/*.c' - '.github/workflows/cifuzz.yml' jobs: diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index a2ffb9e9..83ce7bfa 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -186,9 +186,11 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { server_ref(server); signal_emit("server incoming", 2, server, prefixedLine); disconnected = server->disconnected; + /* if (disconnected) { - server_connect_unref(server->connrec); + server_connect_unref(server->connrec); } + */ server_unref(server); if (disconnected) { /* reconnect */ From 4fa72e857c6a21160e8cc7d85425fffcb6fff09a Mon Sep 17 00:00:00 2001 From: nia Date: Mon, 26 Apr 2021 10:31:34 +0200 Subject: [PATCH 0796/1198] Fix build on operating systems with X/Open Curses, version 2 Add the missing arguments to tparm. X/Open Curses specifies tparm takes a fixed number of 10 arguments, while ncurses has implemented it as a varargs function. tiparm is a standardized version of varargs tparm, support in both NetBSD libcurses and ncurses, but not by older versions of Solaris. This is an alternate fix to the one proposed in irssi/irssi/#1305 that should keep compatibility with older versions of Solaris by avoiding tiparm. --- src/fe-text/terminfo-core.c | 92 ++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index 6be54c32..0a09aa3f 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -110,14 +110,14 @@ static TERMINFO_REC tcaps[] = { /* Move cursor (cursor_address / cup) */ static void _move_cup(TERM_REC *term, int x, int y) { - tput(tparm(term->TI_cup, y, x)); + tput(tparm(term->TI_cup, y, x, 0, 0, 0, 0, 0, 0, 0)); } /* Move cursor (column_address+row_address / hpa+vpa) */ static void _move_pa(TERM_REC *term, int x, int y) { - tput(tparm(term->TI_hpa, x)); - tput(tparm(term->TI_vpa, y)); + tput(tparm(term->TI_hpa, x, 0, 0, 0, 0, 0, 0, 0, 0)); + tput(tparm(term->TI_vpa, y, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Move cursor from a known position */ @@ -133,38 +133,38 @@ static void _move_relative(TERM_REC *term, int oldx, int oldy, int x, int y) if (oldx > 0 && y == oldy) { /* move cursor left/right */ if (x == oldx-1 && term->TI_cub1) { - tput(tparm(term->TI_cub1)); + tput(tparm(term->TI_cub1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); return; } if (x == oldx+1 && y == oldy && term->TI_cuf1) { - tput(tparm(term->TI_cuf1)); + tput(tparm(term->TI_cuf1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); return; } } /* fallback to absolute positioning */ if (term->TI_cup) { - tput(tparm(term->TI_cup, y, x)); + tput(tparm(term->TI_cup, y, x, 0, 0, 0, 0, 0, 0, 0)); return; } if (oldy != y) - tput(tparm(term->TI_vpa, y)); + tput(tparm(term->TI_vpa, y, 0, 0, 0, 0, 0, 0, 0, 0)); if (oldx != x) - tput(tparm(term->TI_hpa, x)); + tput(tparm(term->TI_hpa, x, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Set cursor visible/invisible */ static void _set_cursor_visible(TERM_REC *term, int set) { - tput(tparm(set ? term->TI_cnorm : term->TI_civis)); + tput(tparm(set ? term->TI_cnorm : term->TI_civis, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } #define scroll_region_setup(term, y1, y2) \ if ((term)->TI_csr != NULL) \ - tput(tparm((term)->TI_csr, y1, y2)); \ + tput(tparm((term)->TI_csr, y1, y2, 0, 0, 0, 0, 0, 0, 0)); \ else if ((term)->TI_wind != NULL) \ - tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width-1)); + tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width-1, 0, 0, 0, 0, 0)); /* Scroll (change_scroll_region+parm_rindex+parm_index / csr+rin+indn) */ static void _scroll_region(TERM_REC *term, int y1, int y2, int count) @@ -175,10 +175,10 @@ static void _scroll_region(TERM_REC *term, int y1, int y2, int count) term->move(term, 0, y1); if (count > 0) { term->move(term, 0, y2); - tput(tparm(term->TI_indn, count, count)); + tput(tparm(term->TI_indn, count, count, 0, 0, 0, 0, 0, 0, 0)); } else if (count < 0) { term->move(term, 0, y1); - tput(tparm(term->TI_rin, -count, -count)); + tput(tparm(term->TI_rin, -count, -count, 0, 0, 0, 0, 0, 0, 0)); } /* reset the scrolling region to full screen */ @@ -196,11 +196,11 @@ static void _scroll_region_1(TERM_REC *term, int y1, int y2, int count) if (count > 0) { term->move(term, 0, y2); for (i = 0; i < count; i++) - tput(tparm(term->TI_ind)); + tput(tparm(term->TI_ind, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (count < 0) { term->move(term, 0, y1); for (i = count; i < 0; i++) - tput(tparm(term->TI_ri)); + tput(tparm(term->TI_ri, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* reset the scrolling region to full screen */ @@ -217,14 +217,14 @@ static void _scroll_line(TERM_REC *term, int y1, int y2, int count) if (count > 0) { term->move(term, 0, y1); - tput(tparm(term->TI_dl, count, count)); + tput(tparm(term->TI_dl, count, count, 0, 0, 0, 0, 0, 0, 0)); term->move(term, 0, y2-count+1); - tput(tparm(term->TI_il, count, count)); + tput(tparm(term->TI_il, count, count, 0, 0, 0, 0, 0, 0, 0)); } else if (count < 0) { term->move(term, 0, y2+count+1); - tput(tparm(term->TI_dl, -count, -count)); + tput(tparm(term->TI_dl, -count, -count, 0, 0, 0, 0, 0, 0, 0)); term->move(term, 0, y1); - tput(tparm(term->TI_il, -count, -count)); + tput(tparm(term->TI_il, -count, -count, 0, 0, 0, 0, 0, 0, 0)); } /* reset the scrolling region to full screen */ @@ -239,38 +239,38 @@ static void _scroll_line_1(TERM_REC *term, int y1, int y2, int count) if (count > 0) { term->move(term, 0, y1); for (i = 0; i < count; i++) - tput(tparm(term->TI_dl1)); + tput(tparm(term->TI_dl1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); term->move(term, 0, y2-count+1); for (i = 0; i < count; i++) - tput(tparm(term->TI_il1)); + tput(tparm(term->TI_il1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (count < 0) { term->move(term, 0, y2+count+1); for (i = count; i < 0; i++) - tput(tparm(term->TI_dl1)); + tput(tparm(term->TI_dl1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); term->move(term, 0, y1); for (i = count; i < 0; i++) - tput(tparm(term->TI_il1)); + tput(tparm(term->TI_il1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } } /* Clear screen (clear_screen / clear) */ static void _clear_screen(TERM_REC *term) { - tput(tparm(term->TI_clear)); + tput(tparm(term->TI_clear, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Clear screen (clr_eos / ed) */ static void _clear_eos(TERM_REC *term) { term->move(term, 0, 0); - tput(tparm(term->TI_ed)); + tput(tparm(term->TI_ed, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Clear screen (parm_delete_line / dl) */ static void _clear_del(TERM_REC *term) { term->move(term, 0, 0); - tput(tparm(term->TI_dl, term->height, term->height)); + tput(tparm(term->TI_dl, term->height, term->height, 0, 0, 0, 0, 0, 0, 0)); } /* Clear screen (delete_line / dl1) */ @@ -280,19 +280,19 @@ static void _clear_del_1(TERM_REC *term) term->move(term, 0, 0); for (i = 0; i < term->height; i++) - tput(tparm(term->TI_dl1)); + tput(tparm(term->TI_dl1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Clear to end of line (clr_eol / el) */ static void _clrtoeol(TERM_REC *term) { - tput(tparm(term->TI_el)); + tput(tparm(term->TI_el, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Repeat character (rep / rp) */ static void _repeat(TERM_REC *term, char chr, int count) { - tput(tparm(term->TI_rep, chr, count)); + tput(tparm(term->TI_rep, chr, count, 0, 0, 0, 0, 0, 0, 0)); } /* Repeat character (manual) */ @@ -307,42 +307,42 @@ static void _repeat_manual(TERM_REC *term, char chr, int count) /* Reset all terminal attributes */ static void _set_normal(TERM_REC *term) { - tput(tparm(term->TI_normal)); + tput(tparm(term->TI_normal, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } static void _set_blink(TERM_REC *term) { - tput(tparm(term->TI_blink)); + tput(tparm(term->TI_blink, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Reverse on */ static void _set_reverse(TERM_REC *term) { - tput(tparm(term->TI_rev)); + tput(tparm(term->TI_rev, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Bold on */ static void _set_bold(TERM_REC *term) { - tput(tparm(term->TI_bold)); + tput(tparm(term->TI_bold, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Underline on/off */ static void _set_uline(TERM_REC *term, int set) { - tput(tparm(set ? term->TI_smul : term->TI_rmul)); + tput(tparm(set ? term->TI_smul : term->TI_rmul, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Standout on/off */ static void _set_standout(TERM_REC *term, int set) { - tput(tparm(set ? term->TI_smso : term->TI_rmso)); + tput(tparm(set ? term->TI_smso : term->TI_rmso, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Italic on/off */ static void _set_italic(TERM_REC *term, int set) { - tput(tparm(set ? term->TI_sitm : term->TI_ritm)); + tput(tparm(set ? term->TI_sitm : term->TI_ritm, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Standout on (fallback for reverse) */ @@ -367,19 +367,19 @@ inline static int color256(const TERM_REC *term, const int color) { /* Change foreground color */ static void _set_fg(TERM_REC *term, int color) { - tput(tparm(term->TI_fg[color256(term, color)])); + tput(tparm(term->TI_fg[color256(term, color)], 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Change background color */ static void _set_bg(TERM_REC *term, int color) { - tput(tparm(term->TI_bg[color256(term, color)])); + tput(tparm(term->TI_bg[color256(term, color)], 0, 0, 0, 0, 0, 0, 0, 0, 0)); } /* Beep */ static void _beep(TERM_REC *term) { - tput(tparm(term->TI_bel)); + tput(tparm(term->TI_bel, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } static void _ignore(TERM_REC *term) @@ -393,7 +393,7 @@ static void _ignore_parm(TERM_REC *term, int param) static void terminfo_set_appkey_mode(TERM_REC *term, int set) { if (term->TI_smkx && term->TI_rmkx) - tput(tparm(set ? term->TI_smkx : term->TI_rmkx)); + tput(tparm(set ? term->TI_smkx : term->TI_rmkx, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } static void term_dec_set_bracketed_paste_mode(int enable) @@ -478,11 +478,11 @@ void terminfo_setup_colors(TERM_REC *term, int force) if (term->TI_setaf) { for (i = 0; i < term->TI_colors; i++) { color = i < 16 ? ansitab[i] : i; - term->TI_fg[i] = g_strdup(tparm(term->TI_setaf, color, 0)); + term->TI_fg[i] = g_strdup(tparm(term->TI_setaf, color, 0, 0, 0, 0, 0, 0, 0, 0)); } } else if (term->TI_setf) { for (i = 0; i < term->TI_colors; i++) - term->TI_fg[i] = g_strdup(tparm(term->TI_setf, i, 0)); + term->TI_fg[i] = g_strdup(tparm(term->TI_setf, i, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (force) { for (i = 0; i < 8; i++) term->TI_fg[i] = g_strdup_printf("\033[%dm", 30+ansitab[i]); @@ -491,11 +491,11 @@ void terminfo_setup_colors(TERM_REC *term, int force) if (term->TI_setab) { for (i = 0; i < term->TI_colors; i++) { color = i < 16 ? ansitab[i] : i; - term->TI_bg[i] = g_strdup(tparm(term->TI_setab, color, 0)); + term->TI_bg[i] = g_strdup(tparm(term->TI_setab, color, 0, 0, 0, 0, 0, 0, 0, 0)); } } else if (term->TI_setb) { for (i = 0; i < term->TI_colors; i++) - term->TI_bg[i] = g_strdup(tparm(term->TI_setb, i, 0)); + term->TI_bg[i] = g_strdup(tparm(term->TI_setb, i, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (force) { for (i = 0; i < 8; i++) term->TI_bg[i] = g_strdup_printf("\033[%dm", 40+ansitab[i]); @@ -539,7 +539,7 @@ static void terminfo_input_deinit(TERM_REC *term) void terminfo_cont(TERM_REC *term) { if (term->TI_smcup) - tput(tparm(term->TI_smcup)); + tput(tparm(term->TI_smcup, 0, 0, 0, 0, 0, 0, 0, 0, 0)); if (term->appkey_enabled) terminfo_set_appkey_mode(term, TRUE); @@ -562,7 +562,7 @@ void terminfo_stop(TERM_REC *term) /* stop cup-mode */ if (term->TI_rmcup) - tput(tparm(term->TI_rmcup)); + tput(tparm(term->TI_rmcup, 0, 0, 0, 0, 0, 0, 0, 0, 0)); if (term->appkey_enabled) terminfo_set_appkey_mode(term, FALSE); From 2122daa3f3c9cb0a74182d1c23590e4949f38746 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 30 Apr 2021 10:27:47 +0200 Subject: [PATCH 0797/1198] Run clang-format --- src/fe-text/terminfo-core.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index 0a09aa3f..7c21d509 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -134,23 +134,23 @@ static void _move_relative(TERM_REC *term, int oldx, int oldy, int x, int y) /* move cursor left/right */ if (x == oldx-1 && term->TI_cub1) { tput(tparm(term->TI_cub1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - return; + return; } if (x == oldx+1 && y == oldy && term->TI_cuf1) { tput(tparm(term->TI_cuf1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - return; + return; } } /* fallback to absolute positioning */ if (term->TI_cup) { tput(tparm(term->TI_cup, y, x, 0, 0, 0, 0, 0, 0, 0)); - return; + return; } if (oldy != y) tput(tparm(term->TI_vpa, y, 0, 0, 0, 0, 0, 0, 0, 0)); - if (oldx != x) + if (oldx != x) tput(tparm(term->TI_hpa, x, 0, 0, 0, 0, 0, 0, 0, 0)); } @@ -160,11 +160,11 @@ static void _set_cursor_visible(TERM_REC *term, int set) tput(tparm(set ? term->TI_cnorm : term->TI_civis, 0, 0, 0, 0, 0, 0, 0, 0, 0)); } -#define scroll_region_setup(term, y1, y2) \ - if ((term)->TI_csr != NULL) \ - tput(tparm((term)->TI_csr, y1, y2, 0, 0, 0, 0, 0, 0, 0)); \ - else if ((term)->TI_wind != NULL) \ - tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width-1, 0, 0, 0, 0, 0)); +#define scroll_region_setup(term, y1, y2) \ + if ((term)->TI_csr != NULL) \ + tput(tparm((term)->TI_csr, y1, y2, 0, 0, 0, 0, 0, 0, 0)); \ + else if ((term)->TI_wind != NULL) \ + tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width - 1, 0, 0, 0, 0, 0)); /* Scroll (change_scroll_region+parm_rindex+parm_index / csr+rin+indn) */ static void _scroll_region(TERM_REC *term, int y1, int y2, int count) @@ -478,11 +478,12 @@ void terminfo_setup_colors(TERM_REC *term, int force) if (term->TI_setaf) { for (i = 0; i < term->TI_colors; i++) { color = i < 16 ? ansitab[i] : i; - term->TI_fg[i] = g_strdup(tparm(term->TI_setaf, color, 0, 0, 0, 0, 0, 0, 0, 0)); + term->TI_fg[i] = + g_strdup(tparm(term->TI_setaf, color, 0, 0, 0, 0, 0, 0, 0, 0)); } } else if (term->TI_setf) { for (i = 0; i < term->TI_colors; i++) - term->TI_fg[i] = g_strdup(tparm(term->TI_setf, i, 0, 0, 0, 0, 0, 0, 0, 0)); + term->TI_fg[i] = g_strdup(tparm(term->TI_setf, i, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (force) { for (i = 0; i < 8; i++) term->TI_fg[i] = g_strdup_printf("\033[%dm", 30+ansitab[i]); @@ -491,11 +492,12 @@ void terminfo_setup_colors(TERM_REC *term, int force) if (term->TI_setab) { for (i = 0; i < term->TI_colors; i++) { color = i < 16 ? ansitab[i] : i; - term->TI_bg[i] = g_strdup(tparm(term->TI_setab, color, 0, 0, 0, 0, 0, 0, 0, 0)); + term->TI_bg[i] = + g_strdup(tparm(term->TI_setab, color, 0, 0, 0, 0, 0, 0, 0, 0)); } } else if (term->TI_setb) { for (i = 0; i < term->TI_colors; i++) - term->TI_bg[i] = g_strdup(tparm(term->TI_setb, i, 0, 0, 0, 0, 0, 0, 0, 0)); + term->TI_bg[i] = g_strdup(tparm(term->TI_setb, i, 0, 0, 0, 0, 0, 0, 0, 0)); } else if (force) { for (i = 0; i < 8; i++) term->TI_bg[i] = g_strdup_printf("\033[%dm", 40+ansitab[i]); From f5303c153ca0becd9d74873ac6df469320007aea Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 10 May 2021 08:34:19 +0200 Subject: [PATCH 0798/1198] slightly improve nocap detection Fixes #1311 --- src/irc/core/irc-servers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 06f3d3c8..676e8cb9 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -313,7 +313,8 @@ static void server_init_1(IRC_SERVER_REC *server) signal_emit("server waiting cap ls", 2, server, CAP_LS_VERSION); irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION); /* to detect non-CAP servers, send this bogus join */ - irc_send_cmd_now(server, "JOIN "); + /* the : will make INSPIRCD respond with 451 instead of 461, too */ + irc_send_cmd_now(server, "JOIN :"); } if (conn->starttls) irc_server_send_starttls(server); From dcbc895e26813a36fbcd789d4b5eb25ad9f91df9 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 10 May 2021 10:13:35 +0200 Subject: [PATCH 0799/1198] downgrade meson in github actions --- .github/workflows/abicheck.yml | 2 +- .github/workflows/check.yml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index eceaa32e..a1b57662 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -4,7 +4,7 @@ env: build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes -Dc_args=-DPERL_EUPXS_ALWAYS_EXPORT prefix: /usr/local apt_build_deps: ninja-build libutf8proc-dev libperl-dev libotr5-dev - get_pip_build_deps: pip3 install setuptools; pip3 install wheel; pip3 install meson + get_pip_build_deps: pip3 install setuptools; pip3 install wheel; pip3 install 'meson<0.58.0' getabidef_def: getabidef() { awk '$1=="#define" && $2=="IRSSI_ABI_VERSION" { print $3 }' "$1"/include/irssi/src/common.h; } jobs: build-base-ref: diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 038d2416..7bdd2dea 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -34,16 +34,25 @@ jobs: env: CC: ${{ matrix.compiler }} needs: dist + continue-on-error: ${{ contains(matrix.flags, 'FAILURE-OK') }} strategy: + fail-fast: false matrix: os: [ubuntu-16.04, ubuntu-latest] builder: [meson, configure] compiler: [clang, gcc] + flags: [regular] include: - os: ubuntu-16.04 builder: meson meson_ver: ==0.49.2 setuptools_ver: <51 + - os: ubuntu-latest + builder: meson + meson_ver: <0.58.0 + - os: ubuntu-latest + builder: meson + flags: meson-latest FAILURE-OK steps: - name: fetch dist uses: actions/download-artifact@v2 From af489b2d5f4ff1bbbb517d84f1cb9d97e89bcebf Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 10 May 2021 13:07:22 +0200 Subject: [PATCH 0800/1198] fix build with meson 0.58.0 --- .github/workflows/abicheck.yml | 2 +- .github/workflows/check.yml | 2 +- src/perl/meson.build | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index a1b57662..4e14353d 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -4,7 +4,7 @@ env: build_options: -Dbuildtype=debug -Denable-true-color=yes -Dwith-proxy=yes -Dc_args=-DPERL_EUPXS_ALWAYS_EXPORT prefix: /usr/local apt_build_deps: ninja-build libutf8proc-dev libperl-dev libotr5-dev - get_pip_build_deps: pip3 install setuptools; pip3 install wheel; pip3 install 'meson<0.58.0' + get_pip_build_deps: pip3 install setuptools; pip3 install wheel; pip3 install 'meson<0.59.0' getabidef_def: getabidef() { awk '$1=="#define" && $2=="IRSSI_ABI_VERSION" { print $3 }' "$1"/include/irssi/src/common.h; } jobs: build-base-ref: diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 7bdd2dea..aeaf6c27 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -49,7 +49,7 @@ jobs: setuptools_ver: <51 - os: ubuntu-latest builder: meson - meson_ver: <0.58.0 + meson_ver: <0.59.0 - os: ubuntu-latest builder: meson flags: meson-latest FAILURE-OK diff --git a/src/perl/meson.build b/src/perl/meson.build index 6a2aaa85..d81173d9 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -14,6 +14,9 @@ irssi_core_pl_h = custom_target('irssi-core.pl.h', command : [file2header, '@INPUT@', 'irssi_core_code'], ) +# required as of Meson 0.58.0 +generated_files_inc = include_directories('.') + libperl_core_a = shared_module('perl_core', files( 'perl-common.c', @@ -29,7 +32,7 @@ libperl_core_a = shared_module('perl_core', def_perl_use_lib, '-D' + 'PERL_STATIC_LIBS' + '=' + 0.to_string(), ], - include_directories : rootinc, + include_directories : [ rootinc ] + [ generated_files_inc ], implicit_include_directories : false, install : true, install_dir : moduledir, From a3248d43ecc315358b1dfe596684cacf4083d744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claes=20N=C3=A4st=C3=A9n?= Date: Sat, 15 May 2021 18:10:02 +0200 Subject: [PATCH 0801/1198] Use g_strndup, strndup is not available on old platforms strndup is not available on Solaris 10, to ensure building is ok use glib function. --- src/otr/otr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/otr/otr.c b/src/otr/otr.c index 80604513..abe24726 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -643,7 +643,7 @@ static enum otr_msg_status enqueue_otr_fragment(const char *msg, struct otr_peer * Dup the string with enough space for the NULL byte since we are * about to free it before passing it to the caller. */ - *full_msg = strndup(opc->full_msg, opc->msg_len + 1); + *full_msg = g_strndup(opc->full_msg, opc->msg_len + 1); /* Reset everything. */ free(opc->full_msg); opc->full_msg = NULL; From 5779306df01dc7c92f4e0bb20a69ab56547d7611 Mon Sep 17 00:00:00 2001 From: Mathis Beer Date: Thu, 20 May 2021 10:20:33 +0200 Subject: [PATCH 0802/1198] Add aliases for ns, ms, os, cs shorthand commands supported by many servers to message services easily. --- irssi.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/irssi.conf b/irssi.conf index 80c2b9c3..edaeb3f5 100644 --- a/irssi.conf +++ b/irssi.conf @@ -115,6 +115,7 @@ aliases = { C = "CLEAR"; CALC = "EXEC - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi"; CHAT = "DCC CHAT"; + CS = "QUOTE CS"; DATE = "TIME"; DEHIGHLIGHT = "DEHILIGHT"; DESCRIBE = "ACTION"; @@ -133,9 +134,12 @@ aliases = { LAST = "LASTLOG"; LEAVE = "PART"; M = "MSG"; + MS = "QUOTE MS"; MUB = "UNBAN *"; N = "NAMES"; NMSG = "^MSG"; + NS = "QUOTE NS"; + OS = "QUOTE OS"; P = "PART"; Q = "QUERY"; RESET = "SET -default"; From 1ba48840a112dfacf13cbbf6b77c1e3489fefcf8 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 19 May 2021 21:51:39 +0200 Subject: [PATCH 0803/1198] update default network --- README.md | 2 +- docs/help/in/admin.in | 2 +- docs/help/in/channel.in | 8 ++++---- docs/help/in/connect.in | 6 +++--- docs/help/in/disconnect.in | 2 +- docs/help/in/info.in | 2 +- docs/help/in/join.in | 2 +- docs/help/in/knock.in | 2 +- docs/help/in/log.in | 8 ++++---- docs/help/in/motd.in | 2 +- docs/help/in/names.in | 2 +- docs/help/in/nctcp.in | 2 +- docs/help/in/network.in | 6 +++--- docs/help/in/part.in | 2 +- docs/help/in/query.in | 4 ++-- docs/help/in/recode.in | 2 +- docs/help/in/reconnect.in | 2 +- docs/help/in/server.in | 16 ++++++++-------- docs/manual.txt | 2 +- docs/proxy.txt | 2 +- docs/startup-HOWTO.html | 4 ++-- docs/startup-HOWTO.txt | 4 ++-- irssi.conf | 8 ++++---- 23 files changed, 46 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 08be65b4..d1232764 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on freenode. +[#irssi](https://irssi.org/support/irc/) on irc.libera.chat. diff --git a/docs/help/in/admin.in b/docs/help/in/admin.in index 2b6f8b73..acb6e1ae 100644 --- a/docs/help/in/admin.in +++ b/docs/help/in/admin.in @@ -15,7 +15,7 @@ %9Examples:%9 /ADMIN - /ADMIN orwell.freenode.net + /ADMIN irc.libera.chat /ADMIN mike %9See also:%9 INFO diff --git a/docs/help/in/channel.in b/docs/help/in/channel.in index 86e824c2..d9be8cf5 100644 --- a/docs/help/in/channel.in +++ b/docs/help/in/channel.in @@ -33,12 +33,12 @@ /CHANNEL /CHANNEL LIST - /CHANNEL ADD -auto #irssi Freenode + /CHANNEL ADD -auto #irssi liberachat /CHANNEL ADD -auto #basementcat Quakenet secret_lair - /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout Freenode + /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout liberachat /CHANNEL ADD -auto -bots 'Q!TheQBot@CServe.quakenet.org' -botcmd '^MSG Q op #irssi' #irssi Quakenet - /CHANNEL MODIFY -noauto #irssi Freenode - /CHANNEL REMOVE #hideout Freenode + /CHANNEL MODIFY -noauto #irssi liberachat + /CHANNEL REMOVE #hideout liberachat %9Special Example:%9 diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index e861ad74..d4375eec 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -34,9 +34,9 @@ %9Examples:%9 - /CONNECT Freenode - /CONNECT -6 Freenode - /CONNECT -4 -! -host staff.irssi.org -network Freenode orwell.freenode.net + /CONNECT liberachat + /CONNECT -6 liberachat + /CONNECT -4 -! -host staff.irssi.org -network liberachat irc.libera.chat /CONNECT irc.irssi.org 6667 WzerT8zq mike %9See also:%9 DISCONNECT, RMRECONNS, SERVER diff --git a/docs/help/in/disconnect.in b/docs/help/in/disconnect.in index bd4a4e17..c53b1e60 100644 --- a/docs/help/in/disconnect.in +++ b/docs/help/in/disconnect.in @@ -18,7 +18,7 @@ %9Examples:%9 - /DISCONNECT Freenode I'm off for today, take care! + /DISCONNECT liberachat I'm off for today, take care! /DISCONNECT * Vacation time :D /DISCONNECT diff --git a/docs/help/in/info.in b/docs/help/in/info.in index 275f349d..d8d8cfc9 100644 --- a/docs/help/in/info.in +++ b/docs/help/in/info.in @@ -15,7 +15,7 @@ %9Examples:%9 /INFO - /INFO orwell.freenode.net + /INFO irc.libera.chat %9See also:%9 ADMIN diff --git a/docs/help/in/join.in b/docs/help/in/join.in index 39fa23f8..adf7158e 100644 --- a/docs/help/in/join.in +++ b/docs/help/in/join.in @@ -20,7 +20,7 @@ /JOIN #irssi /JOIN #basementcat secret_lair /JOIN -invite - /JOIN -freenode #github,#freenode,#irssi + /JOIN -liberachat #github,#libera,#irssi %9See also:%9 KICK, PART diff --git a/docs/help/in/knock.in b/docs/help/in/knock.in index bb554d55..ce8f9aa0 100644 --- a/docs/help/in/knock.in +++ b/docs/help/in/knock.in @@ -23,7 +23,7 @@ %9Examples:%9 /KNOCK #irssi - /KNOCK #freenode + /KNOCK #libera /KNOCK #github %9See also:%9 INVITE, JOIN diff --git a/docs/help/in/log.in b/docs/help/in/log.in index e4743d46..3ca8782c 100644 --- a/docs/help/in/log.in +++ b/docs/help/in/log.in @@ -33,10 +33,10 @@ %9Examples:%9 /LOG OPEN -targets mike ~/irclogs/mike.log MSGS - /LOG OPEN -targets #irssi-freenode ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG CLOSE ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG STOP ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG START ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG OPEN -targets #irssi ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG CLOSE ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG STOP ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG START ~/irclogs/liberachat/irssi-%%Y-%%m-%%d /SET autolog ON diff --git a/docs/help/in/motd.in b/docs/help/in/motd.in index e33a1c75..6e86681e 100644 --- a/docs/help/in/motd.in +++ b/docs/help/in/motd.in @@ -15,7 +15,7 @@ %9Examples:%9 /MOTD - /MOTD orwel.freenode.org + /MOTD irc.libera.chat /MOTD bob %9See also:%9 ADMIN, INFO, LINKS, MAP diff --git a/docs/help/in/names.in b/docs/help/in/names.in index 8fd8cf91..974b845f 100644 --- a/docs/help/in/names.in +++ b/docs/help/in/names.in @@ -21,7 +21,7 @@ %9Examples:%9 /NAMES -ops - /NAMES -voices #irssi,#freenode + /NAMES -voices #irssi,#libera %9See also:%9 JOIN, PART, WHO, WHOIS diff --git a/docs/help/in/nctcp.in b/docs/help/in/nctcp.in index 93c3f3ec..9f516730 100644 --- a/docs/help/in/nctcp.in +++ b/docs/help/in/nctcp.in @@ -15,7 +15,7 @@ %9Examples:%9 /NCTCP #irssi VERSION King of the Jungle v1.0 - /NCTCP bob,#freenode USERINFO I am bob :p + /NCTCP bob,#libera USERINFO I am bob :p %9See also:%9 CTCP diff --git a/docs/help/in/network.in b/docs/help/in/network.in index fbdaa0b4..0542bd7d 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -59,11 +59,11 @@ %9Examples:%9 /NETWORK ADD -usermode +giw EFnet - /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org Freenode - /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' Freenode + /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org liberachat + /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' liberachat /NETWORK ADD -autosendcmd '^MSG Q@CServe.quakenet.org AUTH mike WzerT8zq; WAIT 2000; OPER mike WzerT8zq; WAIT 2000; MODE mike +kXP' Quakenet /NETWORK MODIFY -usermode +gi EFnet - /NETWORK REMOVE Freenode + /NETWORK REMOVE liberachat %9See also:%9 CHANNEL, CONNECT, SERVER diff --git a/docs/help/in/part.in b/docs/help/in/part.in index e96abfbb..f89769cc 100644 --- a/docs/help/in/part.in +++ b/docs/help/in/part.in @@ -14,7 +14,7 @@ %9Examples:%9 /PART #irssi - /PART #freenode,#irssi + /PART #libera,#irssi %9See also:%9 JOIN, KICK diff --git a/docs/help/in/query.in b/docs/help/in/query.in index 1c0ba5b9..a34f85e8 100644 --- a/docs/help/in/query.in +++ b/docs/help/in/query.in @@ -17,8 +17,8 @@ %9Examples:%9 /QUERY mike - /QUERY -freenode bob - /QUERY -freenode -window sarah + /QUERY -liberachat bob + /QUERY -liberachat -window sarah %9See also:%9 MSG, UNQUERY, WINDOW diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in index 63f52339..760c66cd 100644 --- a/docs/help/in/recode.in +++ b/docs/help/in/recode.in @@ -22,7 +22,7 @@ %9Examples:%9 /RECODE - /RECODE ADD Freenode/mike utf-8 + /RECODE ADD liberachat/mike utf-8 /RECODE ADD #korea euc-kr /RECODE REMOVE #korea diff --git a/docs/help/in/reconnect.in b/docs/help/in/reconnect.in index aa1dc946..87beb95a 100644 --- a/docs/help/in/reconnect.in +++ b/docs/help/in/reconnect.in @@ -15,7 +15,7 @@ %9Examples:%9 /RECONNECT - /RECONNECT Freenode + /RECONNECT liberachat /RECONNECT EFnet BRB :) %9See also:%9 CONNECT, DISCONNECT, NETWORK, RMRECONNS, SERVER diff --git a/docs/help/in/server.in b/docs/help/in/server.in index beb75114..f7d907f3 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -61,15 +61,15 @@ %9Examples:%9 /SERVER - /SERVER CONNECT chat.freenode.net - /SERVER CONNECT +chat.freenode.net - /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 - /SERVER MODIFY -network Freenode -noauto orwell.freenode.net - /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - - /SERVER REMOVE orwell.freenode.net 6667 Freenode + /SERVER CONNECT irc.libera.chat + /SERVER CONNECT +irc.libera.chat + /SERVER ADD -network liberachat -noautosendcmd irc.libera.chat + /SERVER ADD -! -auto -host staff.irssi.org -4 -network liberachat -noproxy irc.libera.chat 6667 + /SERVER MODIFY -network liberachat -noauto irc.libera.chat + /SERVER MODIFY -network liberachat irc.libera.chat 6697 - + /SERVER REMOVE irc.libera.chat 6667 liberachat /SERVER PURGE - /SERVER PURGE orwell.freenode.net + /SERVER PURGE irc.libera.chat %9See also:%9 CHANNEL, CONNECT, DISCONNECT, NETWORK, RECONNECT, RMRECONNS diff --git a/docs/manual.txt b/docs/manual.txt index 0f24ffe3..5f0eac51 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -349,7 +349,7 @@ after connecting to the network. This is useful for automatically identifying yourself to NickServ, for example - /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" freenode + /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" liberachat /NETWORK REMOVE diff --git a/docs/proxy.txt b/docs/proxy.txt index 224d24e3..172770e8 100644 --- a/docs/proxy.txt +++ b/docs/proxy.txt @@ -24,7 +24,7 @@ You really should set some password for the proxy with: Then you'll need to configure the ports/ircnets the proxy listens in, something like: - /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779 + /SET irssiproxy_ports IRCnet=2777 EFNet=2778 liberachat=2779 There we have 3 different irc networks answering in 3 ports. Note that you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 48f6e6df..b0c68f1f 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -68,7 +68,7 @@

And to connect to one of those networks and join a channel:

-
/CONNECT Freenode
+
/CONNECT liberachat
 /JOIN #irssi
 
@@ -94,7 +94,7 @@

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat
 

These commands have many more options, see their help for details:

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 61de27e3..bff33108 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -43,7 +43,7 @@ has a few predefined networks, to list them: And to connect to one of those networks and join a channel: -/CONNECT Freenode +/CONNECT liberachat /JOIN #irssi To add more networks: @@ -67,7 +67,7 @@ wait for 2 seconds before joining channels: If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable: -/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat These commands have many more options, see their help for details: diff --git a/irssi.conf b/irssi.conf index 80c2b9c3..7a471b73 100644 --- a/irssi.conf +++ b/irssi.conf @@ -2,7 +2,7 @@ servers = ( { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.libera.chat"; chatnet = "liberachat";port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, @@ -34,7 +34,7 @@ chatnets = { max_msgs = "4"; max_whois = "1"; }; - Freenode = { + liberachat = { type = "IRC"; max_kicks = "1"; max_msgs = "4"; @@ -95,8 +95,8 @@ chatnets = { channels = ( { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, - { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#libera"; chatnet = "liberachat";autojoin = "No"; }, + { name = "#irssi"; chatnet = "liberachat";autojoin = "No"; }, { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, From 700ec4c472dd415536a29ffe1509473d6cc588e9 Mon Sep 17 00:00:00 2001 From: ffrogman Date: Tue, 25 May 2021 23:37:36 -0400 Subject: [PATCH 0804/1198] Fix cursor getting stuck for auto completions that exclusively change the case of letters --- src/fe-common/core/completion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 06ac124c..e2c4d2a9 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -104,7 +104,7 @@ char *auto_word_complete(const char *line, int *pos) /* check for words in autocompletion list */ replace = completion_find(word, TRUE); - if (replace == NULL) { + if (replace == NULL || (!g_strcmp0(replace, word))) { ret = NULL; g_string_free(result, TRUE); } else { From a4486c236a3bf15192d0500b3a1892f7465826c7 Mon Sep 17 00:00:00 2001 From: Geert Hauwaerts Date: Wed, 26 May 2021 09:24:32 +0300 Subject: [PATCH 0805/1198] Irssi does not take a political stance. --- README.md | 2 +- docs/help/in/admin.in | 2 +- docs/help/in/channel.in | 8 ++++---- docs/help/in/connect.in | 6 +++--- docs/help/in/disconnect.in | 2 +- docs/help/in/info.in | 2 +- docs/help/in/join.in | 2 +- docs/help/in/knock.in | 2 +- docs/help/in/log.in | 8 ++++---- docs/help/in/motd.in | 2 +- docs/help/in/names.in | 2 +- docs/help/in/nctcp.in | 2 +- docs/help/in/network.in | 6 +++--- docs/help/in/part.in | 2 +- docs/help/in/query.in | 4 ++-- docs/help/in/recode.in | 2 +- docs/help/in/reconnect.in | 2 +- docs/help/in/server.in | 16 ++++++++-------- docs/manual.txt | 2 +- docs/proxy.txt | 2 +- docs/startup-HOWTO.html | 4 ++-- docs/startup-HOWTO.txt | 4 ++-- irssi.conf | 8 ++++---- 23 files changed, 46 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index d1232764..08be65b4 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on irc.libera.chat. +[#irssi](https://irssi.org/support/irc/) on freenode. diff --git a/docs/help/in/admin.in b/docs/help/in/admin.in index acb6e1ae..2b6f8b73 100644 --- a/docs/help/in/admin.in +++ b/docs/help/in/admin.in @@ -15,7 +15,7 @@ %9Examples:%9 /ADMIN - /ADMIN irc.libera.chat + /ADMIN orwell.freenode.net /ADMIN mike %9See also:%9 INFO diff --git a/docs/help/in/channel.in b/docs/help/in/channel.in index d9be8cf5..86e824c2 100644 --- a/docs/help/in/channel.in +++ b/docs/help/in/channel.in @@ -33,12 +33,12 @@ /CHANNEL /CHANNEL LIST - /CHANNEL ADD -auto #irssi liberachat + /CHANNEL ADD -auto #irssi Freenode /CHANNEL ADD -auto #basementcat Quakenet secret_lair - /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout liberachat + /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout Freenode /CHANNEL ADD -auto -bots 'Q!TheQBot@CServe.quakenet.org' -botcmd '^MSG Q op #irssi' #irssi Quakenet - /CHANNEL MODIFY -noauto #irssi liberachat - /CHANNEL REMOVE #hideout liberachat + /CHANNEL MODIFY -noauto #irssi Freenode + /CHANNEL REMOVE #hideout Freenode %9Special Example:%9 diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index d4375eec..e861ad74 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -34,9 +34,9 @@ %9Examples:%9 - /CONNECT liberachat - /CONNECT -6 liberachat - /CONNECT -4 -! -host staff.irssi.org -network liberachat irc.libera.chat + /CONNECT Freenode + /CONNECT -6 Freenode + /CONNECT -4 -! -host staff.irssi.org -network Freenode orwell.freenode.net /CONNECT irc.irssi.org 6667 WzerT8zq mike %9See also:%9 DISCONNECT, RMRECONNS, SERVER diff --git a/docs/help/in/disconnect.in b/docs/help/in/disconnect.in index c53b1e60..bd4a4e17 100644 --- a/docs/help/in/disconnect.in +++ b/docs/help/in/disconnect.in @@ -18,7 +18,7 @@ %9Examples:%9 - /DISCONNECT liberachat I'm off for today, take care! + /DISCONNECT Freenode I'm off for today, take care! /DISCONNECT * Vacation time :D /DISCONNECT diff --git a/docs/help/in/info.in b/docs/help/in/info.in index d8d8cfc9..275f349d 100644 --- a/docs/help/in/info.in +++ b/docs/help/in/info.in @@ -15,7 +15,7 @@ %9Examples:%9 /INFO - /INFO irc.libera.chat + /INFO orwell.freenode.net %9See also:%9 ADMIN diff --git a/docs/help/in/join.in b/docs/help/in/join.in index adf7158e..39fa23f8 100644 --- a/docs/help/in/join.in +++ b/docs/help/in/join.in @@ -20,7 +20,7 @@ /JOIN #irssi /JOIN #basementcat secret_lair /JOIN -invite - /JOIN -liberachat #github,#libera,#irssi + /JOIN -freenode #github,#freenode,#irssi %9See also:%9 KICK, PART diff --git a/docs/help/in/knock.in b/docs/help/in/knock.in index ce8f9aa0..bb554d55 100644 --- a/docs/help/in/knock.in +++ b/docs/help/in/knock.in @@ -23,7 +23,7 @@ %9Examples:%9 /KNOCK #irssi - /KNOCK #libera + /KNOCK #freenode /KNOCK #github %9See also:%9 INVITE, JOIN diff --git a/docs/help/in/log.in b/docs/help/in/log.in index 3ca8782c..e4743d46 100644 --- a/docs/help/in/log.in +++ b/docs/help/in/log.in @@ -33,10 +33,10 @@ %9Examples:%9 /LOG OPEN -targets mike ~/irclogs/mike.log MSGS - /LOG OPEN -targets #irssi ~/irclogs/liberachat/irssi-%%Y-%%m-%%d - /LOG CLOSE ~/irclogs/liberachat/irssi-%%Y-%%m-%%d - /LOG STOP ~/irclogs/liberachat/irssi-%%Y-%%m-%%d - /LOG START ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG OPEN -targets #irssi-freenode ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG CLOSE ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG STOP ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG START ~/irclogs/freenode/irssi-%%Y-%%m-%%d /SET autolog ON diff --git a/docs/help/in/motd.in b/docs/help/in/motd.in index 6e86681e..e33a1c75 100644 --- a/docs/help/in/motd.in +++ b/docs/help/in/motd.in @@ -15,7 +15,7 @@ %9Examples:%9 /MOTD - /MOTD irc.libera.chat + /MOTD orwel.freenode.org /MOTD bob %9See also:%9 ADMIN, INFO, LINKS, MAP diff --git a/docs/help/in/names.in b/docs/help/in/names.in index 974b845f..8fd8cf91 100644 --- a/docs/help/in/names.in +++ b/docs/help/in/names.in @@ -21,7 +21,7 @@ %9Examples:%9 /NAMES -ops - /NAMES -voices #irssi,#libera + /NAMES -voices #irssi,#freenode %9See also:%9 JOIN, PART, WHO, WHOIS diff --git a/docs/help/in/nctcp.in b/docs/help/in/nctcp.in index 9f516730..93c3f3ec 100644 --- a/docs/help/in/nctcp.in +++ b/docs/help/in/nctcp.in @@ -15,7 +15,7 @@ %9Examples:%9 /NCTCP #irssi VERSION King of the Jungle v1.0 - /NCTCP bob,#libera USERINFO I am bob :p + /NCTCP bob,#freenode USERINFO I am bob :p %9See also:%9 CTCP diff --git a/docs/help/in/network.in b/docs/help/in/network.in index 0542bd7d..fbdaa0b4 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -59,11 +59,11 @@ %9Examples:%9 /NETWORK ADD -usermode +giw EFnet - /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org liberachat - /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' liberachat + /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org Freenode + /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' Freenode /NETWORK ADD -autosendcmd '^MSG Q@CServe.quakenet.org AUTH mike WzerT8zq; WAIT 2000; OPER mike WzerT8zq; WAIT 2000; MODE mike +kXP' Quakenet /NETWORK MODIFY -usermode +gi EFnet - /NETWORK REMOVE liberachat + /NETWORK REMOVE Freenode %9See also:%9 CHANNEL, CONNECT, SERVER diff --git a/docs/help/in/part.in b/docs/help/in/part.in index f89769cc..e96abfbb 100644 --- a/docs/help/in/part.in +++ b/docs/help/in/part.in @@ -14,7 +14,7 @@ %9Examples:%9 /PART #irssi - /PART #libera,#irssi + /PART #freenode,#irssi %9See also:%9 JOIN, KICK diff --git a/docs/help/in/query.in b/docs/help/in/query.in index a34f85e8..1c0ba5b9 100644 --- a/docs/help/in/query.in +++ b/docs/help/in/query.in @@ -17,8 +17,8 @@ %9Examples:%9 /QUERY mike - /QUERY -liberachat bob - /QUERY -liberachat -window sarah + /QUERY -freenode bob + /QUERY -freenode -window sarah %9See also:%9 MSG, UNQUERY, WINDOW diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in index 760c66cd..63f52339 100644 --- a/docs/help/in/recode.in +++ b/docs/help/in/recode.in @@ -22,7 +22,7 @@ %9Examples:%9 /RECODE - /RECODE ADD liberachat/mike utf-8 + /RECODE ADD Freenode/mike utf-8 /RECODE ADD #korea euc-kr /RECODE REMOVE #korea diff --git a/docs/help/in/reconnect.in b/docs/help/in/reconnect.in index 87beb95a..aa1dc946 100644 --- a/docs/help/in/reconnect.in +++ b/docs/help/in/reconnect.in @@ -15,7 +15,7 @@ %9Examples:%9 /RECONNECT - /RECONNECT liberachat + /RECONNECT Freenode /RECONNECT EFnet BRB :) %9See also:%9 CONNECT, DISCONNECT, NETWORK, RMRECONNS, SERVER diff --git a/docs/help/in/server.in b/docs/help/in/server.in index f7d907f3..beb75114 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -61,15 +61,15 @@ %9Examples:%9 /SERVER - /SERVER CONNECT irc.libera.chat - /SERVER CONNECT +irc.libera.chat - /SERVER ADD -network liberachat -noautosendcmd irc.libera.chat - /SERVER ADD -! -auto -host staff.irssi.org -4 -network liberachat -noproxy irc.libera.chat 6667 - /SERVER MODIFY -network liberachat -noauto irc.libera.chat - /SERVER MODIFY -network liberachat irc.libera.chat 6697 - - /SERVER REMOVE irc.libera.chat 6667 liberachat + /SERVER CONNECT chat.freenode.net + /SERVER CONNECT +chat.freenode.net + /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net + /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 + /SERVER MODIFY -network Freenode -noauto orwell.freenode.net + /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - + /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE - /SERVER PURGE irc.libera.chat + /SERVER PURGE orwell.freenode.net %9See also:%9 CHANNEL, CONNECT, DISCONNECT, NETWORK, RECONNECT, RMRECONNS diff --git a/docs/manual.txt b/docs/manual.txt index 5f0eac51..0f24ffe3 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -349,7 +349,7 @@ after connecting to the network. This is useful for automatically identifying yourself to NickServ, for example - /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" liberachat + /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" freenode /NETWORK REMOVE diff --git a/docs/proxy.txt b/docs/proxy.txt index 172770e8..224d24e3 100644 --- a/docs/proxy.txt +++ b/docs/proxy.txt @@ -24,7 +24,7 @@ You really should set some password for the proxy with: Then you'll need to configure the ports/ircnets the proxy listens in, something like: - /SET irssiproxy_ports IRCnet=2777 EFNet=2778 liberachat=2779 + /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779 There we have 3 different irc networks answering in 3 ports. Note that you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index b0c68f1f..48f6e6df 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -68,7 +68,7 @@

And to connect to one of those networks and join a channel:

-
/CONNECT liberachat
+
/CONNECT Freenode
 /JOIN #irssi
 
@@ -94,7 +94,7 @@

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat
+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
 

These commands have many more options, see their help for details:

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index bff33108..61de27e3 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -43,7 +43,7 @@ has a few predefined networks, to list them: And to connect to one of those networks and join a channel: -/CONNECT liberachat +/CONNECT Freenode /JOIN #irssi To add more networks: @@ -67,7 +67,7 @@ wait for 2 seconds before joining channels: If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable: -/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode These commands have many more options, see their help for details: diff --git a/irssi.conf b/irssi.conf index 21c3ba4c..edaeb3f5 100644 --- a/irssi.conf +++ b/irssi.conf @@ -2,7 +2,7 @@ servers = ( { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.libera.chat"; chatnet = "liberachat";port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, @@ -34,7 +34,7 @@ chatnets = { max_msgs = "4"; max_whois = "1"; }; - liberachat = { + Freenode = { type = "IRC"; max_kicks = "1"; max_msgs = "4"; @@ -95,8 +95,8 @@ chatnets = { channels = ( { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, - { name = "#libera"; chatnet = "liberachat";autojoin = "No"; }, - { name = "#irssi"; chatnet = "liberachat";autojoin = "No"; }, + { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, From 1773fa8d191c9f1dcc7c1e59dbcdf31c1263c918 Mon Sep 17 00:00:00 2001 From: Geert Hauwaerts Date: Thu, 27 May 2021 20:47:09 +0300 Subject: [PATCH 0806/1198] Applied the updated docs changes in line with the upcoming blog post. --- README.md | 2 +- docs/help/in/admin.in | 2 +- docs/help/in/channel.in | 8 +++--- docs/help/in/connect.in | 6 ++--- docs/help/in/disconnect.in | 2 +- docs/help/in/info.in | 2 +- docs/help/in/join.in | 2 +- docs/help/in/knock.in | 2 +- docs/help/in/log.in | 8 +++--- docs/help/in/motd.in | 2 +- docs/help/in/names.in | 2 +- docs/help/in/nctcp.in | 2 +- docs/help/in/network.in | 6 ++--- docs/help/in/part.in | 2 +- docs/help/in/query.in | 4 +-- docs/help/in/recode.in | 2 +- docs/help/in/reconnect.in | 2 +- docs/help/in/server.in | 16 +++++------ docs/manual.txt | 2 +- docs/proxy.txt | 2 +- docs/startup-HOWTO.html | 4 +-- docs/startup-HOWTO.txt | 4 +-- irssi.conf | 54 ++++++++++++++++++++++---------------- 23 files changed, 73 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 08be65b4..d229391a 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on freenode. +[#irssi](https://irssi.org/support/irc/) on irc.example.com. diff --git a/docs/help/in/admin.in b/docs/help/in/admin.in index 2b6f8b73..cfe66eba 100644 --- a/docs/help/in/admin.in +++ b/docs/help/in/admin.in @@ -15,7 +15,7 @@ %9Examples:%9 /ADMIN - /ADMIN orwell.freenode.net + /ADMIN irc.example.com /ADMIN mike %9See also:%9 INFO diff --git a/docs/help/in/channel.in b/docs/help/in/channel.in index 86e824c2..0e15b6d5 100644 --- a/docs/help/in/channel.in +++ b/docs/help/in/channel.in @@ -33,12 +33,12 @@ /CHANNEL /CHANNEL LIST - /CHANNEL ADD -auto #irssi Freenode + /CHANNEL ADD -auto #irssi ExampleNet /CHANNEL ADD -auto #basementcat Quakenet secret_lair - /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout Freenode + /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout ExampleNet /CHANNEL ADD -auto -bots 'Q!TheQBot@CServe.quakenet.org' -botcmd '^MSG Q op #irssi' #irssi Quakenet - /CHANNEL MODIFY -noauto #irssi Freenode - /CHANNEL REMOVE #hideout Freenode + /CHANNEL MODIFY -noauto #irssi ExampleNet + /CHANNEL REMOVE #hideout ExampleNet %9Special Example:%9 diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index e861ad74..4d59dde1 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -34,9 +34,9 @@ %9Examples:%9 - /CONNECT Freenode - /CONNECT -6 Freenode - /CONNECT -4 -! -host staff.irssi.org -network Freenode orwell.freenode.net + /CONNECT ExampleNet + /CONNECT -6 ExampleNet + /CONNECT -4 -! -host staff.irssi.org -network ExampleNet irc.example.com /CONNECT irc.irssi.org 6667 WzerT8zq mike %9See also:%9 DISCONNECT, RMRECONNS, SERVER diff --git a/docs/help/in/disconnect.in b/docs/help/in/disconnect.in index bd4a4e17..88772e1e 100644 --- a/docs/help/in/disconnect.in +++ b/docs/help/in/disconnect.in @@ -18,7 +18,7 @@ %9Examples:%9 - /DISCONNECT Freenode I'm off for today, take care! + /DISCONNECT ExampleNet I'm off for today, take care! /DISCONNECT * Vacation time :D /DISCONNECT diff --git a/docs/help/in/info.in b/docs/help/in/info.in index 275f349d..41578501 100644 --- a/docs/help/in/info.in +++ b/docs/help/in/info.in @@ -15,7 +15,7 @@ %9Examples:%9 /INFO - /INFO orwell.freenode.net + /INFO irc.example.com %9See also:%9 ADMIN diff --git a/docs/help/in/join.in b/docs/help/in/join.in index 39fa23f8..55190267 100644 --- a/docs/help/in/join.in +++ b/docs/help/in/join.in @@ -20,7 +20,7 @@ /JOIN #irssi /JOIN #basementcat secret_lair /JOIN -invite - /JOIN -freenode #github,#freenode,#irssi + /JOIN -ExampleNet #github,#example,#irssi %9See also:%9 KICK, PART diff --git a/docs/help/in/knock.in b/docs/help/in/knock.in index bb554d55..3e2fdbdb 100644 --- a/docs/help/in/knock.in +++ b/docs/help/in/knock.in @@ -23,7 +23,7 @@ %9Examples:%9 /KNOCK #irssi - /KNOCK #freenode + /KNOCK #example /KNOCK #github %9See also:%9 INVITE, JOIN diff --git a/docs/help/in/log.in b/docs/help/in/log.in index e4743d46..dfe26e30 100644 --- a/docs/help/in/log.in +++ b/docs/help/in/log.in @@ -33,10 +33,10 @@ %9Examples:%9 /LOG OPEN -targets mike ~/irclogs/mike.log MSGS - /LOG OPEN -targets #irssi-freenode ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG CLOSE ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG STOP ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG START ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG OPEN -targets #irssi ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d + /LOG CLOSE ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d + /LOG STOP ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d + /LOG START ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d /SET autolog ON diff --git a/docs/help/in/motd.in b/docs/help/in/motd.in index e33a1c75..ee1233b2 100644 --- a/docs/help/in/motd.in +++ b/docs/help/in/motd.in @@ -15,7 +15,7 @@ %9Examples:%9 /MOTD - /MOTD orwel.freenode.org + /MOTD irc.example.com /MOTD bob %9See also:%9 ADMIN, INFO, LINKS, MAP diff --git a/docs/help/in/names.in b/docs/help/in/names.in index 8fd8cf91..deccea40 100644 --- a/docs/help/in/names.in +++ b/docs/help/in/names.in @@ -21,7 +21,7 @@ %9Examples:%9 /NAMES -ops - /NAMES -voices #irssi,#freenode + /NAMES -voices #irssi,#example %9See also:%9 JOIN, PART, WHO, WHOIS diff --git a/docs/help/in/nctcp.in b/docs/help/in/nctcp.in index 93c3f3ec..68d789d6 100644 --- a/docs/help/in/nctcp.in +++ b/docs/help/in/nctcp.in @@ -15,7 +15,7 @@ %9Examples:%9 /NCTCP #irssi VERSION King of the Jungle v1.0 - /NCTCP bob,#freenode USERINFO I am bob :p + /NCTCP bob,#example USERINFO I am bob :p %9See also:%9 CTCP diff --git a/docs/help/in/network.in b/docs/help/in/network.in index fbdaa0b4..183fd5b5 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -59,11 +59,11 @@ %9Examples:%9 /NETWORK ADD -usermode +giw EFnet - /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org Freenode - /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' Freenode + /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org ExampleNet + /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' ExampleNet /NETWORK ADD -autosendcmd '^MSG Q@CServe.quakenet.org AUTH mike WzerT8zq; WAIT 2000; OPER mike WzerT8zq; WAIT 2000; MODE mike +kXP' Quakenet /NETWORK MODIFY -usermode +gi EFnet - /NETWORK REMOVE Freenode + /NETWORK REMOVE ExampleNet %9See also:%9 CHANNEL, CONNECT, SERVER diff --git a/docs/help/in/part.in b/docs/help/in/part.in index e96abfbb..51be59bd 100644 --- a/docs/help/in/part.in +++ b/docs/help/in/part.in @@ -14,7 +14,7 @@ %9Examples:%9 /PART #irssi - /PART #freenode,#irssi + /PART #example,#irssi %9See also:%9 JOIN, KICK diff --git a/docs/help/in/query.in b/docs/help/in/query.in index 1c0ba5b9..85f2556e 100644 --- a/docs/help/in/query.in +++ b/docs/help/in/query.in @@ -17,8 +17,8 @@ %9Examples:%9 /QUERY mike - /QUERY -freenode bob - /QUERY -freenode -window sarah + /QUERY -ExampleNet bob + /QUERY -ExampleNet -window sarah %9See also:%9 MSG, UNQUERY, WINDOW diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in index 63f52339..c34822de 100644 --- a/docs/help/in/recode.in +++ b/docs/help/in/recode.in @@ -22,7 +22,7 @@ %9Examples:%9 /RECODE - /RECODE ADD Freenode/mike utf-8 + /RECODE ADD ExampleNet/mike utf-8 /RECODE ADD #korea euc-kr /RECODE REMOVE #korea diff --git a/docs/help/in/reconnect.in b/docs/help/in/reconnect.in index aa1dc946..f2148c90 100644 --- a/docs/help/in/reconnect.in +++ b/docs/help/in/reconnect.in @@ -15,7 +15,7 @@ %9Examples:%9 /RECONNECT - /RECONNECT Freenode + /RECONNECT ExampleNet /RECONNECT EFnet BRB :) %9See also:%9 CONNECT, DISCONNECT, NETWORK, RMRECONNS, SERVER diff --git a/docs/help/in/server.in b/docs/help/in/server.in index beb75114..8a4d8887 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -61,15 +61,15 @@ %9Examples:%9 /SERVER - /SERVER CONNECT chat.freenode.net - /SERVER CONNECT +chat.freenode.net - /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 - /SERVER MODIFY -network Freenode -noauto orwell.freenode.net - /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - - /SERVER REMOVE orwell.freenode.net 6667 Freenode + /SERVER CONNECT irc.example.com + /SERVER CONNECT +irc.example.com + /SERVER ADD -network ExampleNet -noautosendcmd irc.example.com + /SERVER ADD -! -auto -host staff.irssi.org -4 -network ExampleNet -noproxy irc.example.com 6667 + /SERVER MODIFY -network ExampleNet -noauto irc.example.com + /SERVER MODIFY -network ExampleNet irc.example.com 6697 - + /SERVER REMOVE irc.example.com 6667 ExampleNet /SERVER PURGE - /SERVER PURGE orwell.freenode.net + /SERVER PURGE irc.example.com %9See also:%9 CHANNEL, CONNECT, DISCONNECT, NETWORK, RECONNECT, RMRECONNS diff --git a/docs/manual.txt b/docs/manual.txt index 0f24ffe3..29065feb 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -349,7 +349,7 @@ after connecting to the network. This is useful for automatically identifying yourself to NickServ, for example - /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" freenode + /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" ExampleNet /NETWORK REMOVE diff --git a/docs/proxy.txt b/docs/proxy.txt index 224d24e3..9ed7ecdb 100644 --- a/docs/proxy.txt +++ b/docs/proxy.txt @@ -24,7 +24,7 @@ You really should set some password for the proxy with: Then you'll need to configure the ports/ircnets the proxy listens in, something like: - /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779 + /SET irssiproxy_ports IRCnet=2777 EFNet=2778 ExampleNet=2779 There we have 3 different irc networks answering in 3 ports. Note that you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 48f6e6df..ecbeb467 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -68,7 +68,7 @@

And to connect to one of those networks and join a channel:

-
/CONNECT Freenode
+
/CONNECT ExampleNet
 /JOIN #irssi
 
@@ -94,7 +94,7 @@

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN ExampleNet
 

These commands have many more options, see their help for details:

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 61de27e3..84397f33 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -43,7 +43,7 @@ has a few predefined networks, to list them: And to connect to one of those networks and join a channel: -/CONNECT Freenode +/CONNECT LiberaChat /JOIN #irssi To add more networks: @@ -67,7 +67,7 @@ wait for 2 seconds before joining channels: If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable: -/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN ExampleNet These commands have many more options, see their help for details: diff --git a/irssi.conf b/irssi.conf index edaeb3f5..9faa8973 100644 --- a/irssi.conf +++ b/irssi.conf @@ -1,18 +1,19 @@ servers = ( - { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, - { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, - { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, - { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, - { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, - { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, - { address = "irc.oftc.net"; chatnet = "OFTC"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.quakenet.org"; chatnet = "QuakeNet"; port = "6667"; }, - { address = "irc.rizon.net"; chatnet = "Rizon"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; }, - { address = "irc.undernet.org"; chatnet = "Undernet"; port = "6667"; } + { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, + { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, + { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, + { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, + { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, + { address = "irc.libera.chat"; chatnet = "LiberaChat"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, + { address = "irc.oftc.net"; chatnet = "OFTC"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.quakenet.org"; chatnet = "QuakeNet"; port = "6667"; }, + { address = "irc.rizon.net"; chatnet = "Rizon"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; }, + { address = "irc.undernet.org"; chatnet = "Undernet"; port = "6667"; } ); chatnets = { @@ -58,6 +59,12 @@ chatnets = { max_msgs = "4"; max_whois = "1"; }; + LiberaChat = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "4"; + max_whois = "1"; + }; NetFuze = { type = "IRC"; max_kicks = "1"; @@ -94,15 +101,16 @@ chatnets = { }; channels = ( - { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, - { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, - { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, - { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, - { name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; }, - { name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; }, - { name = "silc"; chatnet = "SILC"; autojoin = "No"; } + { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, + { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, + { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, + { name = "#libera"; chatnet = "LiberaChat"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "LiberaChat"; autojoin = "No"; }, + { name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; }, + { name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; }, + { name = "silc"; chatnet = "SILC"; autojoin = "No"; } ); aliases = { From a5d4fd5aa7ad1d57c0b8e11e382944a3654cfa00 Mon Sep 17 00:00:00 2001 From: Geert Hauwaerts Date: Thu, 27 May 2021 20:50:38 +0300 Subject: [PATCH 0807/1198] Changed the support channel to LiberaChat. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d229391a..d1232764 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on irc.example.com. +[#irssi](https://irssi.org/support/irc/) on irc.libera.chat. From f147589e528722859d604446b6496a992602f3a9 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 28 Jul 2021 11:05:30 +0200 Subject: [PATCH 0808/1198] can do /server add -matrix -network my_matrix_network By Andrej Kacian --- src/fe-common/core/fe-server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index e0100618..468ac4e7 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -91,7 +91,9 @@ static SERVER_SETUP_REC *create_server_setup(GHashTable *optlist) if (rec == NULL) rec = chat_protocol_get_default(); else { - chatnet = g_hash_table_lookup(optlist, rec->chatnet); + chatnet = g_hash_table_lookup(optlist, "network"); + if (chatnet == NULL && g_hash_table_lookup(optlist, rec->chatnet) != NULL) + chatnet = rec->chatnet; if (chatnet_find(chatnet) == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_UNKNOWN_CHATNET, chatnet); From 6591c94635e4da69693cbe55dae747d970e6a52b Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 14 Jan 2021 14:27:57 +0100 Subject: [PATCH 0809/1198] add a limit to showing /NAMES on join only show the counts if too many nicks --- src/fe-common/core/fe-channels.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/fe-channels.c b/src/fe-common/core/fe-channels.c index 8c914cb8..2d4e9ece 100644 --- a/src/fe-common/core/fe-channels.c +++ b/src/fe-common/core/fe-channels.c @@ -107,9 +107,14 @@ static void signal_window_item_changed(WINDOW_REC *window, WI_ITEM_REC *item) static void sig_channel_joined(CHANNEL_REC *channel) { - if (settings_get_bool("show_names_on_join") && - !channel->session_rejoin) - fe_channels_nicklist(channel, CHANNEL_NICKLIST_FLAG_ALL); + if (settings_get_bool("show_names_on_join") && !channel->session_rejoin) { + int limit = settings_get_int("show_names_on_join_limit"); + int flags = CHANNEL_NICKLIST_FLAG_ALL; + if (limit > 0 && g_hash_table_size(channel->nicks) > limit) { + flags |= CHANNEL_NICKLIST_FLAG_COUNT; + } + fe_channels_nicklist(channel, flags); + } } /* SYNTAX: JOIN [-window] [-invite] [-] [] */ @@ -625,6 +630,7 @@ void fe_channels_init(void) { settings_add_bool("lookandfeel", "autoclose_windows", TRUE); settings_add_bool("lookandfeel", "show_names_on_join", TRUE); + settings_add_int("lookandfeel", "show_names_on_join_limit", 18); settings_add_int("lookandfeel", "names_max_columns", 6); settings_add_int("lookandfeel", "names_max_width", 0); From aecf0870143d9dc3530a9e6cc8b64928178d7794 Mon Sep 17 00:00:00 2001 From: Guntbert Reiter Date: Sun, 30 May 2021 21:11:10 +0200 Subject: [PATCH 0810/1198] Add documentation for escaping some characters this is especially important when using `sendcmd` to send a password for autologin --- docs/help/in/eval.in | 6 ++++++ docs/help/in/network.in | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/help/in/eval.in b/docs/help/in/eval.in index b2d4b625..b0c904b4 100644 --- a/docs/help/in/eval.in +++ b/docs/help/in/eval.in @@ -11,11 +11,17 @@ Evaluates the given commands and executes them; you can use internal variables and separate multiple commands by using the ';' character. + If the command contains a string with '$', '\' or ';' those characters + need to be escaped: + '$' -> '$$' + '\' -> '\\' (or even '\\\\', depending on where they are used) + ';' -> '\;' %9Examples:%9 /EVAL echo I am connected to ${S} on ${chatnet} as ${N} /EVAL echo My user privileges are +${usermode}; echo Let's party! + to print '1;2$3\4': /EVAL echo 1\;2$$3\\4 %9References:%9 diff --git a/docs/help/in/network.in b/docs/help/in/network.in index 0542bd7d..788c1c65 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -18,7 +18,8 @@ -usermode: Specifies the user modes to set on yourself. -autosendcmd: Specifies the commands, separated by the ';' character, and enclosed within two "'" characters, to perform after - connecting. + connecting. + (Some characters need to be escaped - see /help eval) -querychans: Specifies the maximum number of channels to put in one MODE or WHO command when synchronizing. -whois: Specifies the maximum number of nicknames in one WHOIS From 77741b187ca72ffef747eff3f36903bb1afbba21 Mon Sep 17 00:00:00 2001 From: Francis M Date: Tue, 22 Jun 2021 16:10:55 +0100 Subject: [PATCH 0811/1198] Fix minor typos in help text --- docs/help/in/otr.in | 2 +- docs/help/in/window.in | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/help/in/otr.in b/docs/help/in/otr.in index f76a2d53..fcfcd875 100644 --- a/docs/help/in/otr.in +++ b/docs/help/in/otr.in @@ -51,7 +51,7 @@ GENKEY This process is done in a background worker and can take an arbitrary amount of time. The completion is checked when another irssi event is - catched. + caught. HELP Print this help. diff --git a/docs/help/in/window.in b/docs/help/in/window.in index aa133766..9a7a7b10 100644 --- a/docs/help/in/window.in +++ b/docs/help/in/window.in @@ -33,12 +33,12 @@ THEME: %|Applies or removes a per-window theme. GROW: %|Increase the size of the active split window by the specified number of lines. SHRINK: %|Decrease the size of the active split window by the specified number of lines. - SIZE: %|Set the current split window size to the specified numer of lines. + SIZE: %|Set the current split window size to the specified number of lines. BALANCE: %|Balance the heights of all split windows. HIDE: %|Hides the current split window, or the split window specified by number or item name. SHOW: %|Show the window specified by number or item name as a new split windows. It is made sticky when autostick_split_windows is turned on. UP: %|Set the split window left or above the current one active. At the top, wraps to the bottom. - DOWN: %|Set the split window right or below the current one active. At the bottom, wraps teft. + DOWN: %|Set the split window right or below the current one active. At the bottom, wraps left. LEFT: %|Go to the previous window numerically that is part of the current sticky group (or not part of any sticky group). RIGHT: %|Go to the next window numerically that is part of the current sticky group (or not part of any sticky group). STICK: %|Make the currently active window sticky, or stick the window specified by number to the currently visible split window. Or turn off stickyness of the currently active window or the window specified by number. From d2062e34cf0e74faffb725928809837807ca67b9 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Wed, 23 Jun 2021 20:56:05 +0200 Subject: [PATCH 0812/1198] Update fe-common-core.c --- src/fe-common/core/fe-common-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 63df1698..e981db33 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -500,7 +500,8 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) str += server_tag_len + 1; } - if (g_strcmp0(str, "") == 0 || g_strcmp0(str, "::all") == 0) { + if (g_strcmp0(str, "") == 0 || g_strcmp0(str, "*") == 0 || + g_strcmp0(str, "::all") == 0) { return TRUE; } else if (g_ascii_strcasecmp(str, dest->target) == 0) { return TRUE; From 3aeebd310db1c026d90bb05c4f8e7d1ae9ffe544 Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Wed, 23 Jun 2021 21:07:31 +0200 Subject: [PATCH 0813/1198] Update fe-common-core.c --- src/fe-common/core/fe-common-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index e981db33..1fcd5df1 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -500,8 +500,7 @@ gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) str += server_tag_len + 1; } - if (g_strcmp0(str, "") == 0 || g_strcmp0(str, "*") == 0 || - g_strcmp0(str, "::all") == 0) { + if (g_strcmp0(str, "*") == 0 || g_strcmp0(str, "::all") == 0) { return TRUE; } else if (g_ascii_strcasecmp(str, dest->target) == 0) { return TRUE; From 554a8556d27c66917ed274a76d8ba47bdc7ba13a Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:46:31 +0200 Subject: [PATCH 0814/1198] fix use of wrong "equal" function in meta hash tables --- src/core/servers.c | 2 +- src/fe-text/textbuffer-formats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/servers.c b/src/core/servers.c index 159af0e1..30fc6844 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -369,7 +369,7 @@ void server_connect_init(SERVER_REC *server) server->type = module_get_uniq_id("SERVER", 0); server_ref(server); server->current_incoming_meta = - g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); server->nick = g_strdup(server->connrec->nick); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 2aa06cb2..2cd0d4a3 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -116,7 +116,7 @@ void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) { if (meta->hash == NULL) { - meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_strcmp0, + meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); } From 7d13cfba074b7dc849f095a3281952ee38518a92 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:48:37 +0200 Subject: [PATCH 0815/1198] add a meta table to all lines --- src/fe-common/core/formats.c | 32 +++++++++++++++++++++++++++++++- src/fe-common/core/formats.h | 12 ++++++++---- src/perl/ui/Formats.xs | 19 +++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 51588afb..b660b616 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -34,6 +34,7 @@ #include #include #include +#include static const char *format_backs = "04261537"; static const char *format_fores = "kbgcrmyw"; @@ -46,6 +47,8 @@ static int hide_text_style, hide_server_tags, hide_colors; static int timestamp_level; static int timestamp_timeout; +static GHashTable *global_meta; + int format_find_tag(const char *module, const char *tag) { FORMAT_REC *formats; @@ -453,6 +456,27 @@ void format_read_arglist(va_list va, FORMAT_REC *format, } } +void format_dest_meta_stash(TEXT_DEST_REC *dest, const char *meta_key, const char *meta_value) +{ + g_hash_table_replace(dest->meta, i_refstr_intern(meta_key), g_strdup(meta_value)); +} + +const char *format_dest_meta_stash_find(TEXT_DEST_REC *dest, const char *meta_key) +{ + return g_hash_table_lookup(dest->meta, meta_key); +} + +void format_dest_meta_clear_all(TEXT_DEST_REC *dest) +{ + g_hash_table_remove_all(dest->meta); +} + +static void clear_global_meta(WINDOW_REC *window, TEXT_DEST_REC *dest) +{ + if (dest != NULL && dest->meta == global_meta) + g_hash_table_remove_all(global_meta); +} + void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char *server_tag, const char *target, int level, WINDOW_REC *window, GHashTable *meta) @@ -465,7 +489,7 @@ void format_create_dest_tag_meta(TEXT_DEST_REC *dest, void *server, const char * dest->level = level; dest->window = window != NULL ? window : window_find_closest(server, target, level); - dest->meta = meta; + dest->meta = meta != NULL ? meta : global_meta; } void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, @@ -1705,12 +1729,18 @@ static void read_settings(void) void formats_init(void) { signal_gui_print_text = signal_get_uniq_id("gui print text"); + global_meta = + g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, + (GDestroyNotify) i_refstr_release, (GDestroyNotify) g_free); read_settings(); signal_add("setup changed", (SIGNAL_FUNC) read_settings); + signal_add_last("gui print text finished", (SIGNAL_FUNC) clear_global_meta); } void formats_deinit(void) { + g_hash_table_destroy(global_meta); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); + signal_remove("gui print text finished", (SIGNAL_FUNC) clear_global_meta); } diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 12274638..c17bcc75 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -63,7 +63,7 @@ typedef struct _TEXT_DEST_REC { int hilight_priority; char *hilight_color; - int flags; + int flags; /* PRINT_FLAG */ GHashTable *meta; } TEXT_DEST_REC; @@ -116,12 +116,16 @@ char *format_get_line_start(THEME_REC *theme, TEXT_DEST_REC *dest, time_t t); void format_create_dest(TEXT_DEST_REC *dest, void *server, const char *target, int level, WINDOW_REC *window); -void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, - const char *server_tag, const char *target, - int level, WINDOW_REC *window); +void format_create_dest_tag(TEXT_DEST_REC *dest, void *server, const char *server_tag, + const char *target, int level, WINDOW_REC *window); void format_newline(TEXT_DEST_REC *dest); +/* manipulate the meta table of a dest */ +void format_dest_meta_stash(TEXT_DEST_REC *dest, const char *meta_key, const char *meta_value); +const char *format_dest_meta_stash_find(TEXT_DEST_REC *dest, const char *meta_key); +void format_dest_meta_clear_all(TEXT_DEST_REC *dest); + /* Return how many characters in `str' must be skipped before `len' characters of text is skipped. */ int strip_real_length(const char *str, int len, diff --git a/src/perl/ui/Formats.xs b/src/perl/ui/Formats.xs index c03e6bb5..0f8b59b7 100644 --- a/src/perl/ui/Formats.xs +++ b/src/perl/ui/Formats.xs @@ -156,3 +156,22 @@ print(dest, str) char *str CODE: printtext_dest(dest, "%s", str); + +#******************************* +MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::TextDest PREFIX = format_dest_ +#******************************* + +void +format_dest_meta_stash(dest, meta_key, meta_value) + Irssi::UI::TextDest dest + char *meta_key + char *meta_value + +char * +format_dest_meta_stash_find(dest, meta_key) + Irssi::UI::TextDest dest + char *meta_key +CODE: + RETVAL = (char *) format_dest_meta_stash_find(dest, meta_key); +OUTPUT: + RETVAL From 9677b07488b6b7b4ee7a425d8f2826669404d058 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:49:40 +0200 Subject: [PATCH 0816/1198] fix wrong server_time in $line->get_meta --- src/perl/textui/TextBuffer.xs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 6695eae0..301e2d4a 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -123,6 +123,8 @@ PPCODE: (void) hv_store(hv, key, strlen(key), new_pv(val), 0); } } - (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); + if (m->server_time) { + (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); + } } XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); From 8d314eadf1350619d481cc5729c7bd74eec85693 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:51:18 +0200 Subject: [PATCH 0817/1198] move TEXT_BUFFER_META_REC -> LINE_INFO_META_REC --- src/fe-common/core/formats.h | 5 +++++ src/fe-text/textbuffer-formats.c | 12 ++++++------ src/fe-text/textbuffer-formats.h | 8 ++------ src/fe-text/textbuffer.h | 2 +- src/perl/textui/TextBuffer.xs | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index c17bcc75..5666c73b 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -67,6 +67,11 @@ typedef struct _TEXT_DEST_REC { GHashTable *meta; } TEXT_DEST_REC; +typedef struct _LINE_INFO_META_REC { + gint64 server_time; + GHashTable *hash; +} LINE_INFO_META_REC; + #define window_get_theme(window) \ (window != NULL && (window)->theme != NULL ? \ (window)->theme : current_theme) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 2cd0d4a3..b194a18a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -102,7 +102,7 @@ static void format_rec_set_dest(TEXT_BUFFER_FORMAT_REC *rec, const TEXT_DEST_REC rec->flags = dest->flags & ~PRINT_FLAG_FORMAT; } -void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) +void textbuffer_meta_rec_free(LINE_INFO_META_REC *rec) { if (rec == NULL) return; @@ -113,7 +113,7 @@ void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec) g_free(rec); } -static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) +static void meta_hash_create(struct _LINE_INFO_META_REC *meta) { if (meta->hash == NULL) { meta->hash = g_hash_table_new_full(g_str_hash, (GEqualFunc) g_str_equal, @@ -122,9 +122,9 @@ static void meta_hash_create(struct _TEXT_BUFFER_META_REC *meta) } } -static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash) +static LINE_INFO_META_REC *line_meta_create(GHashTable *meta_hash) { - struct _TEXT_BUFFER_META_REC *meta; + struct _LINE_INFO_META_REC *meta; GHashTableIter iter; const char *key; const char *val; @@ -132,7 +132,7 @@ static TEXT_BUFFER_META_REC *line_meta_create(GHashTable *meta_hash) if (meta_hash == NULL || g_hash_table_size(meta_hash) == 0) return NULL; - meta = g_new0(struct _TEXT_BUFFER_META_REC, 1); + meta = g_new0(struct _LINE_INFO_META_REC, 1); g_hash_table_iter_init(&iter, meta_hash); while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { @@ -362,7 +362,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean THEME_REC *theme; int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; - TEXT_BUFFER_META_REC *meta; + LINE_INFO_META_REC *meta; char *str; curr = line; diff --git a/src/fe-text/textbuffer-formats.h b/src/fe-text/textbuffer-formats.h index 17a907c1..86587563 100644 --- a/src/fe-text/textbuffer-formats.h +++ b/src/fe-text/textbuffer-formats.h @@ -2,11 +2,7 @@ #define IRSSI_FE_TEXT_TEXTBUFFER_FORMATS_H #include - -typedef struct _TEXT_BUFFER_META_REC { - gint64 server_time; - GHashTable *hash; -} TEXT_BUFFER_META_REC; +#include typedef struct _TEXT_BUFFER_FORMAT_REC { char *module; @@ -22,7 +18,7 @@ typedef struct _TEXT_BUFFER_FORMAT_REC { } TEXT_BUFFER_FORMAT_REC; void textbuffer_format_rec_free(TEXT_BUFFER_FORMAT_REC *rec); -void textbuffer_meta_rec_free(TEXT_BUFFER_META_REC *rec); +void textbuffer_meta_rec_free(LINE_INFO_META_REC *rec); char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean raw); void textbuffer_formats_init(void); void textbuffer_formats_deinit(void); diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 5f5f9a27..6c72a569 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -24,7 +24,7 @@ typedef struct { int level; time_t time; char *text; - struct _TEXT_BUFFER_META_REC *meta; + struct _LINE_INFO_META_REC *meta; struct _TEXT_BUFFER_FORMAT_REC *format; } LINE_INFO_REC; diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index 301e2d4a..be83cc59 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -107,7 +107,7 @@ textbuffer_line_get_meta(line) PREINIT: HV *hv; LINE_REC *l; - TEXT_BUFFER_META_REC *m; + LINE_INFO_META_REC *m; GHashTableIter iter; char *key; char *val; From 5953b675b9411a87d111ea82ecd7c0876de3f186 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 12 Aug 2021 23:53:44 +0200 Subject: [PATCH 0818/1198] store the hilight result in the meta table and apply it during the "gui render line text" signal --- src/fe-common/core/hilight-text.c | 98 +++++++++++++++++++++++++++---- src/fe-text/textbuffer-formats.c | 28 ++++++--- 2 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 153a7a15..4b5e4edd 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -323,6 +323,71 @@ void hilight_update_text_dest(TEXT_DEST_REC *dest, HILIGHT_REC *rec) static void hilight_print(int index, HILIGHT_REC *rec); +static void sig_render_line_text(TEXT_DEST_REC *dest, GString *str, LINE_INFO_META_REC *meta) +{ + char *color, *tmp, *tmp2; + + if (meta == NULL || meta->hash == NULL) + return; + + color = g_hash_table_lookup(meta->hash, "hilight-color"); + + if ((tmp = g_hash_table_lookup(meta->hash, "hilight-line")) != NULL) { + /* hilight whole line */ + + tmp = strip_codes(str->str); + + color = format_string_expand( + color != NULL ? color : settings_get_str("hilight_color"), NULL); + + g_string_truncate(str, 0); + g_string_append(str, color); + g_string_append(str, tmp); + + g_free(color); + g_free(tmp); + } else if ((tmp = g_hash_table_lookup(meta->hash, "hilight-start")) != NULL && + (tmp2 = g_hash_table_lookup(meta->hash, "hilight-end")) != NULL) { + /* hilight part of the line */ + int hilight_start, hilight_end; + int pos, color_pos, color_len; + char *middle; + GString *str2; + + hilight_start = atoi(tmp); + hilight_end = atoi(tmp2); + + /* start of the line */ + pos = strip_real_length(str->str, hilight_start, NULL, NULL); + + str2 = g_string_new_len(str->str, pos); + + /* color */ + color = format_string_expand( + color != NULL ? color : settings_get_str("hilight_color"), NULL); + g_string_append(str2, color); + g_free(color); + + /* middle of the line, stripped */ + middle = strip_codes(str->str + pos); + g_string_append_len(str2, middle, hilight_end - hilight_start); + g_free(middle); + + /* end of the line */ + pos = strip_real_length(str->str, hilight_end, &color_pos, &color_len); + if (color_pos > 0) { + g_string_append_len(str2, str->str + color_pos, color_len); + } else { + /* no colors in line, change back to default */ + g_string_append_c(str2, 4); + g_string_append_c(str2, FORMAT_STYLE_DEFAULTS); + } + g_string_append(str2, str->str + pos); + + g_string_assign(str, g_string_free(str2, FALSE)); + } +} + static void sig_print_text(TEXT_DEST_REC *dest, const char *text, const char *stripped) { @@ -372,38 +437,47 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, char *tmp = strip_codes(text); newstr = g_strconcat(color, tmp, NULL); g_free(tmp); + + format_dest_meta_stash(dest, "hilight-line", "\001"); } else { /* hilight part of the line */ - GString *tmp; - char *middle; + GString *str; + char *middle, *tmp; int pos, color_pos, color_len; /* start of the line */ pos = strip_real_length(text, hilight_start, NULL, NULL); - tmp = g_string_new_len(text, pos); + str = g_string_new_len(text, pos); /* color */ - g_string_append(tmp, color); + g_string_append(str, color); /* middle of the line, stripped */ middle = strip_codes(text + pos); - g_string_append_len(tmp, middle, hilight_len); + g_string_append_len(str, middle, hilight_len); g_free(middle); /* end of the line */ pos = strip_real_length(text, hilight_end, &color_pos, &color_len); if (color_pos > 0) { - g_string_append_len(tmp, text + color_pos, color_len); + g_string_append_len(str, text + color_pos, color_len); } else { /* no colors in line, change back to default */ - g_string_append_c(tmp, 4); - g_string_append_c(tmp, FORMAT_STYLE_DEFAULTS); + g_string_append_c(str, 4); + g_string_append_c(str, FORMAT_STYLE_DEFAULTS); } - g_string_append(tmp, text + pos); + g_string_append(str, text + pos); - newstr = tmp->str; - g_string_free(tmp, FALSE); + newstr = str->str; + g_string_free(str, FALSE); + + format_dest_meta_stash(dest, "hilight-start", + tmp = g_strdup_printf("%d", hilight_start)); + g_free(tmp); + format_dest_meta_stash(dest, "hilight-end", + tmp = g_strdup_printf("%d", hilight_end)); + g_free(tmp); } signal_emit("print text", 3, dest, newstr, stripped); @@ -721,6 +795,7 @@ void hilight_text_init(void) read_hilight_config(); signal_add_first("print text", (SIGNAL_FUNC) sig_print_text); + signal_add("gui render line text", (SIGNAL_FUNC) sig_render_line_text); signal_add("setup reread", (SIGNAL_FUNC) read_hilight_config); signal_add("setup changed", (SIGNAL_FUNC) read_settings); @@ -735,6 +810,7 @@ void hilight_text_deinit(void) nickmatch_deinit(nickmatch); signal_remove("print text", (SIGNAL_FUNC) sig_print_text); + signal_remove("gui render line text", (SIGNAL_FUNC) sig_render_line_text); signal_remove("setup reread", (SIGNAL_FUNC) read_hilight_config); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index b194a18a..5b15313f 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -16,6 +16,7 @@ TEXT_BUFFER_REC *color_buf; gboolean scrollback_format; gboolean show_server_time; +int signal_gui_render_line_text; #if GLIB_CHECK_VERSION(2, 56, 0) /* nothing */ @@ -363,7 +364,7 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean int formatnum; TEXT_BUFFER_FORMAT_REC *format_rec; LINE_INFO_META_REC *meta; - char *str; + char *tmp2; curr = line; line = NULL; @@ -396,6 +397,8 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean } if (text != NULL && *text != '\0') { + GString *str; + reference_time = curr->info.time; if (show_server_time && meta != NULL && meta->server_time != 0) { current_time = meta->server_time; @@ -403,18 +406,27 @@ char *textbuffer_line_get_text(TEXT_BUFFER_REC *buffer, LINE_REC *line, gboolean current_time = curr->info.time; } + str = g_string_new(text); + signal_emit_id(signal_gui_render_line_text, 3, &dest, str, meta); + if (g_strcmp0(text, str->str) == 0) { + g_string_free(str, TRUE); + } else { + g_free(text); + text = g_string_free(str, FALSE); + } + tmp = format_get_level_tag(theme, &dest); - str = !theme->info_eol ? format_add_linestart(text, tmp) : - format_add_lineend(text, tmp); + tmp2 = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); g_free_not_null(tmp); g_free_not_null(text); - text = str; + text = tmp2; tmp = format_get_line_start(theme, &dest, current_time); - str = !theme->info_eol ? format_add_linestart(text, tmp) : - format_add_lineend(text, tmp); + tmp2 = !theme->info_eol ? format_add_linestart(text, tmp) : + format_add_lineend(text, tmp); g_free_not_null(tmp); g_free_not_null(text); - text = str; + text = tmp2; /* str = g_strconcat(text, "\n", NULL); */ /* g_free(text); */ @@ -447,6 +459,8 @@ static void read_settings(void) void textbuffer_formats_init(void) { + signal_gui_render_line_text = signal_get_uniq_id("gui render line text"); + settings_add_bool("lookandfeel", "scrollback_format", TRUE); settings_add_bool("lookandfeel", "show_server_time", FALSE); From 6a52b5ac07fe57ebd5973871db64b775e41a3f84 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 00:44:33 +0200 Subject: [PATCH 0819/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index bdbafca7..990cc0cf 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 36 +#define IRSSI_ABI_VERSION 37 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 1602b506a69d12f6d15014f1c6b246066e29e404 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 17:31:14 +0200 Subject: [PATCH 0820/1198] add LINE_INFO_META_REC to Perl --- src/perl/get-signals.pl | 13 +++++++------ src/perl/textui/TextBuffer.xs | 30 +++++------------------------- src/perl/ui/UI.xs | 21 +++++++++++++++++++++ src/perl/ui/module.h | 1 + src/perl/ui/typemap | 1 + 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index 12aebdba..a76d7ecf 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -52,12 +52,13 @@ while (<>) { CLIENT_REC => 'Irssi::Irc::Client', # fe-common - THEME_REC => 'Irssi::UI::Theme', - KEYINFO_REC => 'Irssi::UI::Keyinfo', - PROCESS_REC => 'Irssi::UI::Process', - TEXT_DEST_REC => 'Irssi::UI::TextDest', - WINDOW_REC => 'Irssi::UI::Window', - WI_ITEM_REC => 'iobject', + THEME_REC => 'Irssi::UI::Theme', + KEYINFO_REC => 'Irssi::UI::Keyinfo', + PROCESS_REC => 'Irssi::UI::Process', + TEXT_DEST_REC => 'Irssi::UI::TextDest', + LINE_INFO_META_REC => 'Irssi::UI::LineInfoMeta', + WINDOW_REC => 'Irssi::UI::Window', + WI_ITEM_REC => 'iobject', # fe-text TEXTBUFFER_VIEW_REC => 'Irssi::TextUI::TextBufferView', diff --git a/src/perl/textui/TextBuffer.xs b/src/perl/textui/TextBuffer.xs index be83cc59..655dbd3c 100644 --- a/src/perl/textui/TextBuffer.xs +++ b/src/perl/textui/TextBuffer.xs @@ -101,30 +101,10 @@ PPCODE: } XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); -void +Irssi::UI::LineInfoMeta textbuffer_line_get_meta(line) Irssi::TextUI::Line line -PREINIT: - HV *hv; - LINE_REC *l; - LINE_INFO_META_REC *m; - GHashTableIter iter; - char *key; - char *val; -PPCODE: - hv = newHV(); - l = line->line; - if (l->info.meta != NULL) { - m = l->info.meta; - if (m->hash != NULL) { - g_hash_table_iter_init(&iter, m->hash); - while ( - g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { - (void) hv_store(hv, key, strlen(key), new_pv(val), 0); - } - } - if (m->server_time) { - (void) hv_store(hv, "server_time", 11, newSViv(m->server_time), 0); - } - } - XPUSHs(sv_2mortal(newRV_noinc((SV *) hv))); +CODE: + RETVAL = line->line->info.meta; +OUTPUT: + RETVAL diff --git a/src/perl/ui/UI.xs b/src/perl/ui/UI.xs index 5ac3da4e..30b0f637 100644 --- a/src/perl/ui/UI.xs +++ b/src/perl/ui/UI.xs @@ -64,6 +64,26 @@ 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_line_info_meta_fill_hash(HV *hv, LINE_INFO_META_REC *meta) +{ + GHashTableIter iter; + char *key; + char *val; + + if (meta != NULL) { + if (meta->hash != NULL) { + g_hash_table_iter_init(&iter, meta->hash); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { + (void) hv_store(hv, key, strlen(key), new_pv(val), 0); + } + } + if (meta->server_time) { + (void) hv_store(hv, "server_time", 11, newSViv(meta->server_time), 0); + } + } +} + static void perl_exec_fill_hash(HV *hv, EXEC_WI_REC *item) { g_return_if_fail(hv != NULL); @@ -81,6 +101,7 @@ 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 }, { "Irssi::UI::TextDest", (PERL_OBJECT_FUNC) perl_text_dest_fill_hash }, + { "Irssi::UI::LineInfoMeta", (PERL_OBJECT_FUNC) perl_line_info_meta_fill_hash }, { NULL, NULL } }; diff --git a/src/perl/ui/module.h b/src/perl/ui/module.h index 4e19d4c0..4106aec4 100644 --- a/src/perl/ui/module.h +++ b/src/perl/ui/module.h @@ -12,3 +12,4 @@ typedef WINDOW_REC *Irssi__UI__Window; typedef TEXT_DEST_REC *Irssi__UI__TextDest; typedef THEME_REC *Irssi__UI__Theme; typedef KEYINFO_REC *Irssi__UI__Keyinfo; +typedef LINE_INFO_META_REC *Irssi__UI__LineInfoMeta; diff --git a/src/perl/ui/typemap b/src/perl/ui/typemap index 2a16fe44..4afb273d 100644 --- a/src/perl/ui/typemap +++ b/src/perl/ui/typemap @@ -3,6 +3,7 @@ Irssi::UI::Theme T_PlainObj Irssi::UI::Window T_PlainObj Irssi::UI::Keyinfo T_PlainObj Irssi::UI::TextDest T_PlainObj +Irssi::UI::LineInfoMeta T_PlainObj INPUT From 425178e793f03dfaa3b42f4999f3b04eaad48732 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 17:31:49 +0200 Subject: [PATCH 0821/1198] add GString to Perl --- src/perl/get-signals.pl | 2 ++ src/perl/perl-signals.c | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index a76d7ecf..f7675f1b 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -19,6 +19,8 @@ while (<>) { s/GList \* of ([^,]*)s/glistptr_\1/g; s/GSList of ([^,]*)s/gslist_\1/g; + s/GString \*[^,]*/gstring/g; + s/char \*[^,]*/string/g; s/ulong \*[^,]*/ulongptr/g; s/int \*[^,]*/intptr/g; diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 9f49fba8..897689e1 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -86,7 +86,8 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, unsigned long v_ulong; GSList *v_gslist; GList *v_glist; - } saved_args[SIGNAL_MAX_ARGUMENTS]; + GString *v_gstring; + } saved_args[SIGNAL_MAX_ARGUMENTS]; AV *aargs; void *p[SIGNAL_MAX_ARGUMENTS]; PERL_SIGNAL_ARGS_REC *rec; @@ -146,6 +147,12 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, } else if (g_strcmp0(rec->args[n], "intptr") == 0) { saved_args[n].v_int = SvIV(SvRV(arg)); c_arg = &saved_args[n].v_int; + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + char *pv; + size_t len; + + pv = SvPV(SvRV(arg), len); + c_arg = saved_args[n].v_gstring = g_string_new_len(pv, len); } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { GList *gl; int is_str; @@ -220,6 +227,16 @@ void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, SV *t = SvRV(arg); SvIOK_only(t); SvIV_set(t, saved_args[n].v_int); + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + GString *str; + SV *t; + + str = saved_args[n].v_gstring; + t = SvRV(arg); + SvPOK_only(t); + sv_setpvn(t, str->str, str->len); + + g_string_free(str, TRUE); } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { g_slist_free(saved_args[n].v_gslist); } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { @@ -306,7 +323,10 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, perlarg = newSViv(*(unsigned long *) arg); else if (g_strcmp0(rec->args[n], "intptr") == 0) saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg)); - else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { + else if (g_strcmp0(rec->args[n], "gstring") == 0) { + GString *str = arg; + saved_args[n] = perlarg = newRV_noinc(newSVpvn(str->str, str->len)); + } else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) { const THEME_REC *theme; const MODULE_THEME_REC *rec; const FORMAT_REC *formats; @@ -415,8 +435,21 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, if (g_strcmp0(rec->args[n], "intptr") == 0) { int *val = arg; *val = SvIV(SvRV(saved_args[n])); + } else if (g_strcmp0(rec->args[n], "gstring") == 0) { + SV *os, *ns; + GString *str = arg; + + os = sv_2mortal(newSVpvn(str->str, str->len)); + ns = SvRV(saved_args[n]); + if (sv_cmp(os, ns) != 0) { + size_t len; + char *pv = SvPV(ns, len); + + g_string_truncate(str, 0); + g_string_append_len(str, pv, len); + } } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { - GList **ret = arg; + GList **ret = arg; GList *out = NULL; void *val; int count; From ed23d89a5a69b324ed05b5f9bd8115c34ad4b7a9 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 17:32:09 +0200 Subject: [PATCH 0822/1198] fix recursive crash in Perl scripts --- src/perl/perl-signals.c | 1 + src/perl/perl-sources.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 897689e1..683b4c3f 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -419,6 +419,7 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func, if (SvTRUE(ERRSV)) { char *error = g_strdup(SvPV_nolen(ERRSV)); + perl_signal_remove_script(script); signal_emit("script error", 2, script, error); g_free(error); rec = NULL; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 9f5773f1..9f9ec6b5 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -83,6 +83,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) if (SvTRUE(ERRSV)) { char *error = g_strdup(SvPV_nolen(ERRSV)); + perl_source_remove_script(rec->script); signal_emit("script error", 2, rec->script, error); g_free(error); } From 96e9ab41e9f353fc9612c27e3d61bc8ab978564d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 17:32:25 +0200 Subject: [PATCH 0823/1198] add "gui render line text" to signals.txt --- docs/signals.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/signals.txt b/docs/signals.txt index 1eefc7e0..4e5f85b4 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -358,6 +358,9 @@ gui-printtext.c: textbuffer-view.c "gui textbuffer line removed", TEXTBUFFER_VIEW_REC *view, LINE_REC *line, LINE_REC *prev_line +textbuffer-formats.c + "gui render line text", TEXT_DEST_REC, GString *str, LINE_INFO_META_REC + Perl ---- From 5a8b23cab0f758f78c0dc495ce788d0c58b8a661 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 17:38:57 +0200 Subject: [PATCH 0824/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 990cc0cf..cc334476 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 37 +#define IRSSI_ABI_VERSION 38 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 0c82a3adfd48df33c971a74ff862d69e23e6909e Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 15 Aug 2021 00:08:44 +0200 Subject: [PATCH 0825/1198] Workaround for google/oss-fuzz#3731 Run CIFuzz docker manually --- .github/workflows/cifuzz.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index a32e335d..6325d671 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -19,13 +19,23 @@ jobs: matrix: sanitizer: [address, undefined, memory] steps: + - uses: actions/checkout@main + with: + path: irssi + - name: Docker build build_fuzzers container + run: | + # google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + docker build -t build_fuzzers:actions -f "/home/runner/work/_actions/google/oss-fuzz/master/infra/build_fuzzers.Dockerfile" "/home/runner/work/_actions/google/oss-fuzz/master/infra" - name: Build Fuzzers (${{ matrix.sanitizer }}) id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'irssi' - dry-run: false - sanitizer: ${{ matrix.sanitizer }} + env: + OSS_FUZZ_PROJECT_NAME: 'irssi' + DRY_RUN: false + SANITIZER: ${{ matrix.sanitizer }} + PROJECT_SRC_PATH: /github/workspace/irssi + REPOSITORY: 'irssi' + run: | + docker run --workdir /github/workspace --rm -e OSS_FUZZ_PROJECT_NAME -e DRY_RUN -e SANITIZER -e PROJECT_SRC_PATH -e REPOSITORY -e WORKSPACE=/github/workspace -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "$GITHUB_WORKSPACE":"/github/workspace" build_fuzzers:actions - name: Run Fuzzers (${{ matrix.sanitizer }}) uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: From fdd61f5898c8a97b6a1088db717c16691d601d60 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 21:11:22 +0200 Subject: [PATCH 0826/1198] add a log_server_time setting --- src/core/log.c | 14 +++++++------- src/core/log.h | 6 +++--- src/fe-common/core/fe-log.c | 33 ++++++++++++++++++++++++++------- src/perl/common/Log.xs | 3 ++- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/core/log.c b/src/core/log.c index cb6f1edd..5bc953a1 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -204,11 +204,10 @@ static void log_rotate_check(LOG_REC *log) g_free(new_fname); } -void log_write_rec(LOG_REC *log, const char *str, int level) +void log_write_rec(LOG_REC *log, const char *str, int level, time_t now) { char *colorstr; struct tm *tm; - time_t now; int hour, day; g_return_if_fail(log != NULL); @@ -217,7 +216,8 @@ void log_write_rec(LOG_REC *log, const char *str, int level) if (log->handle == -1) return; - now = time(NULL); + if (now == (time_t) -1) + now = time(NULL); tm = localtime(&now); hour = tm->tm_hour; day = tm->tm_mday; @@ -282,8 +282,8 @@ LOG_ITEM_REC *log_item_find(LOG_REC *log, int type, const char *item, return NULL; } -void log_file_write(const char *server_tag, const char *item, int level, - const char *str, int no_fallbacks) +void log_file_write(const char *server_tag, const char *item, int level, time_t t, const char *str, + int no_fallbacks) { GSList *tmp, *fallbacks; char *tmpstr; @@ -309,7 +309,7 @@ void log_file_write(const char *server_tag, const char *item, int level, fallbacks = g_slist_append(fallbacks, rec); else if (log_item_find(rec, LOG_ITEM_TARGET, item, server_tag) != NULL) - log_write_rec(rec, str, level); + log_write_rec(rec, str, level, t); } if (!found && !no_fallbacks && fallbacks != NULL) { @@ -319,7 +319,7 @@ void log_file_write(const char *server_tag, const char *item, int level, g_strdup(str); for (tmp = fallbacks; tmp != NULL; tmp = tmp->next) - log_write_rec(tmp->data, tmpstr, level); + log_write_rec(tmp->data, tmpstr, level, t); g_free(tmpstr); } diff --git a/src/core/log.h b/src/core/log.h index 1c529670..19bca4f3 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -51,9 +51,9 @@ void log_item_destroy(LOG_REC *log, LOG_ITEM_REC *item); LOG_ITEM_REC *log_item_find(LOG_REC *log, int type, const char *item, const char *servertag); -void log_file_write(const char *server_tag, const char *item, int level, - const char *str, int no_fallbacks); -void log_write_rec(LOG_REC *log, const char *str, int level); +void log_file_write(const char *server_tag, const char *item, int level, time_t t, const char *str, + int no_fallbacks); +void log_write_rec(LOG_REC *log, const char *str, int level, time_t now); int log_start_logging(LOG_REC *log); void log_stop_logging(LOG_REC *log); diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index b5222059..984b3548 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -48,6 +48,7 @@ #define AUTOLOG_INACTIVITY_CLOSE (60*5) static int autolog_level; +static int log_server_time; static int autoremove_tag; static char *autolog_path; @@ -502,8 +503,8 @@ static void autolog_open_check(TEXT_DEST_REC *dest) autolog_open(server, server_tag, g_strcmp0(target, "*") ? target : deftarget); } -static void log_single_line(WINDOW_REC *window, const char *server_tag, - const char *target, int level, const char *text) +static void log_single_line(WINDOW_REC *window, const char *server_tag, const char *target, + int level, time_t t, const char *text) { char windownum[MAX_INT_STRLEN]; LOG_REC *log; @@ -514,15 +515,16 @@ static void log_single_line(WINDOW_REC *window, const char *server_tag, log = logs_find_item(LOG_ITEM_WINDOW_REFNUM, windownum, NULL, NULL); if (log != NULL) - log_write_rec(log, text, level); + log_write_rec(log, text, level, t); } - log_file_write(server_tag, target, level, text, FALSE); + log_file_write(server_tag, target, level, t, text, FALSE); } static void log_line(TEXT_DEST_REC *dest, const char *text) { char **lines, **tmp; + time_t t = (time_t) -1; if (dest->level == MSGLEVEL_NEVER) return; @@ -536,9 +538,18 @@ static void log_line(TEXT_DEST_REC *dest, const char *text) /* text may contain one or more lines, log wants to eat them one line at a time */ lines = g_strsplit(text, "\n", -1); + if (log_server_time && dest->meta != NULL) { + char *val; + if ((val = g_hash_table_lookup(dest->meta, "time")) != NULL) { + GDateTime *time; + if ((time = g_date_time_new_from_iso8601(val, NULL)) != NULL) { + t = g_date_time_to_unix(time); + g_date_time_unref(time); + } + } + } for (tmp = lines; *tmp != NULL; tmp++) - log_single_line(dest->window, dest->server_tag, - dest->target, dest->level, *tmp); + log_single_line(dest->window, dest->server_tag, dest->target, dest->level, t, *tmp); g_strfreev(lines); } @@ -720,6 +731,13 @@ static void read_settings(void) g_strfreev(autolog_ignore_targets); autolog_ignore_targets = g_strsplit(settings_get_str("autolog_ignore_targets"), " ", -1); + + log_server_time = settings_get_choice("log_server_time"); + if (log_server_time == 2) { + SETTINGS_REC *rec = settings_get_record("show_server_time"); + if (rec != NULL) + log_server_time = settings_get_bool("show_server_time"); + } } void fe_log_init(void) @@ -731,7 +749,8 @@ void fe_log_init(void) settings_add_bool("log", "autolog", FALSE); settings_add_bool("log", "autolog_colors", FALSE); settings_add_bool("log", "autolog_only_saved_channels", FALSE); - settings_add_str("log", "autolog_path", "~/irclogs/$tag/$0.log"); + settings_add_choice("log", "log_server_time", 2, "off;on;auto"); + settings_add_str("log", "autolog_path", "~/irclogs/$tag/$0.log"); settings_add_level("log", "autolog_level", "all -crap -clientcrap -ctcps"); settings_add_str("log", "log_theme", ""); settings_add_str("log", "autolog_ignore_targets", ""); diff --git a/src/perl/common/Log.xs b/src/perl/common/Log.xs index cdcdbd90..532095fb 100644 --- a/src/perl/common/Log.xs +++ b/src/perl/common/Log.xs @@ -54,10 +54,11 @@ log_close(log) Irssi::Log log void -log_write_rec(log, str, level) +log_write_rec(log, str, level, now = -1) Irssi::Log log char *str int level + time_t now void log_start_logging(log) From 6a331399399dc9b91d75fbe6b065e31a2db49fe0 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 14 Aug 2021 22:43:50 +0200 Subject: [PATCH 0827/1198] compat for glib 2.55 --- src/core/misc.c | 20 ++++++++++++++++---- src/core/misc.h | 7 +++++++ src/fe-text/textbuffer-formats.c | 16 +--------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index c66bbd6d..f0bbf4e0 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -95,7 +95,6 @@ int i_input_add_poll(int fd, int priority, int condition, GInputFunction functio #pragma GCC diagnostic ignored "-Wdeprecated-declarations" int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) { -#pragma GCC diagnostic pop if (tv1->tv_sec < tv2->tv_sec) return -1; if (tv1->tv_sec > tv2->tv_sec) @@ -105,11 +104,8 @@ int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) tv1->tv_usec > tv2->tv_usec ? 1 : 0; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) { -#pragma GCC diagnostic pop long secs, usecs; secs = tv1->tv_sec - tv2->tv_sec; @@ -122,6 +118,22 @@ long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) return usecs; } +#pragma GCC diagnostic pop + +#if GLIB_CHECK_VERSION(2, 56, 0) +/* nothing */ +#else +/* compatibility code for old GLib */ +GDateTime *g_date_time_new_from_iso8601(const gchar *iso_date, GTimeZone *default_tz) +{ + GTimeVal time; + if (g_time_val_from_iso8601(iso_date, &time)) { + return g_date_time_new_from_timeval_utc(&time); + } else { + return NULL; + } +} +#endif int find_substr(const char *list, const char *item) { diff --git a/src/core/misc.h b/src/core/misc.h index 76f5644b..622470f7 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -19,6 +19,13 @@ int g_timeval_cmp(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; long get_timeval_diff(const GTimeVal *tv1, const GTimeVal *tv2) G_GNUC_DEPRECATED; #pragma GCC diagnostic pop +#if GLIB_CHECK_VERSION(2, 56, 0) +/* nothing */ +#else +/* compatibility code for old GLib */ +GDateTime *g_date_time_new_from_iso8601(const gchar *iso_date, GTimeZone *default_tz); +#endif + GSList *i_slist_find_string(GSList *list, const char *key); GSList *i_slist_find_icase_string(GSList *list, const char *key); GList *i_list_find_string(GList *list, const char *key); diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 5b15313f..20abc0df 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -1,6 +1,7 @@ #include "module.h" #include #include +#include #include #include #include @@ -18,21 +19,6 @@ gboolean scrollback_format; gboolean show_server_time; int signal_gui_render_line_text; -#if GLIB_CHECK_VERSION(2, 56, 0) -/* nothing */ -#else -/* compatibility code for old GLib */ -static GDateTime *g_date_time_new_from_iso8601(const gchar *iso_date, GTimeZone *default_tz) -{ - GTimeVal time; - if (g_time_val_from_iso8601(iso_date, &time)) { - return g_date_time_new_from_timeval_utc(&time); - } else { - return NULL; - } -} -#endif - static void collector_free(GSList **collector) { while (*collector) { From b3f74fe0ab1fd8dc145dab662e74eeaaeeb6fffe Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 15 Aug 2021 15:58:10 +0200 Subject: [PATCH 0828/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index cc334476..a89b4964 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 38 +#define IRSSI_ABI_VERSION 39 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From a07a4c1ea886e35a17847ff004495e2f18b8b489 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 20:27:35 +0200 Subject: [PATCH 0829/1198] use an internal build of openssl when fuzzer is enabled --- meson.build | 7 ++++++- subprojects/openssl.wrap | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 subprojects/openssl.wrap diff --git a/meson.build b/meson.build index 1a5182af..fe5aa99f 100644 --- a/meson.build +++ b/meson.build @@ -273,7 +273,12 @@ endif dep += glib_dep dep += gmodule_dep -openssl_dep = dependency('openssl', static : want_static_dependency) +if glib_internal and want_static_dependency and want_fuzzer + openssl_proj = subproject('openssl', default_options : ['default_library=static', 'asm=disabled']) + openssl_dep = openssl_proj.get_variable('openssl_dep') +else + openssl_dep = dependency('openssl', static : want_static_dependency) +endif dep += openssl_dep ############ diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap new file mode 100644 index 00000000..4aaaba38 --- /dev/null +++ b/subprojects/openssl.wrap @@ -0,0 +1,14 @@ +[wrap-file] +directory = openssl-1.1.1l +source_url = https://www.openssl.org/source/openssl-1.1.1l.tar.gz +source_filename = openssl-1.1.1l.tar.gz +source_hash = 0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 +patch_filename = openssl_1.1.1l-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/openssl_1.1.1l-1/get_patch +patch_hash = 670db31580039e06c17f48bcd31e489f453fe72c22006de6d693b9b033f1003a + +[provide] +libcrypto = libcrypto_dep +libssl = libssl_dep +openssl = openssl_dep + From 49903f41854114aec37a74a907135e17931b43c8 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 21:59:38 +0200 Subject: [PATCH 0830/1198] mess with server ports --- src/core/servers-setup.c | 31 ++++++++++++++------- src/core/servers-setup.h | 1 + src/fe-common/core/fe-server.c | 51 +++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 357e8ebe..fd719c38 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -457,7 +457,7 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) port = config_node_get_int(node, "port", 0); chatnet = config_node_get_str(node, "chatnet", NULL); - if (server_setup_find(server, port, chatnet) != NULL) { + if ((rec = server_setup_find(server, port, chatnet)) != NULL && rec->port == port) { return NULL; } @@ -548,7 +548,7 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) return -1; address = config_node_get_str(node, "address", NULL); - chatnet = config_node_get_str(node, "chatnet", NULL); + chatnet = config_node_get_str(node, "chatnet", ""); port = config_node_get_int(node, "port", 0); if (address == NULL || chatnet == NULL) { @@ -556,7 +556,7 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) } if (g_ascii_strcasecmp(address, server->address) != 0 || - g_ascii_strcasecmp(chatnet, server->chatnet) != 0 || + g_ascii_strcasecmp(chatnet, server->chatnet != NULL ? server->chatnet : "") != 0 || port != server->port) { return 1; } @@ -564,16 +564,20 @@ static int compare_server_setup (CONFIG_NODE *node, SERVER_SETUP_REC *server) return 0; } -static void server_setup_save(SERVER_SETUP_REC *rec) +static void server_setup_save(SERVER_SETUP_REC *rec, int old_port, const char *old_chatnet) { CONFIG_NODE *parent_node, *node; + SERVER_SETUP_REC search_rec = { 0 }; GSList *config_node; parent_node = iconfig_node_traverse("(servers", TRUE); /* Try to find this channel in the configuration */ - config_node = g_slist_find_custom(parent_node->value, rec, - (GCompareFunc)compare_server_setup); + search_rec.address = rec->address; + search_rec.chatnet = old_chatnet != NULL ? (char *) old_chatnet : rec->chatnet; + search_rec.port = old_port; + config_node = g_slist_find_custom(parent_node->value, &search_rec, + (GCompareFunc) compare_server_setup); if (config_node != NULL) /* Let's update this server record */ node = config_node->data; @@ -654,16 +658,23 @@ static void server_setup_destroy(SERVER_SETUP_REC *rec) g_free(rec); } -void server_setup_add(SERVER_SETUP_REC *rec) +void server_setup_modify(SERVER_SETUP_REC *rec, int old_port, const char *old_chatnet) { + g_return_if_fail(g_slist_find(setupservers, rec) != NULL); + rec->type = module_get_uniq_id("SERVER SETUP", 0); - if (g_slist_find(setupservers, rec) == NULL) - setupservers = g_slist_append(setupservers, rec); - server_setup_save(rec); + server_setup_save(rec, old_port, old_chatnet); signal_emit("server setup updated", 1, rec); } +void server_setup_add(SERVER_SETUP_REC *rec) +{ + if (g_slist_find(setupservers, rec) == NULL) + setupservers = g_slist_append(setupservers, rec); + server_setup_modify(rec, -1, NULL); +} + void server_setup_remove_chatnet(const char *chatnet) { GSList *tmp, *next; diff --git a/src/core/servers-setup.h b/src/core/servers-setup.h index f35c3873..742ed4dd 100644 --- a/src/core/servers-setup.h +++ b/src/core/servers-setup.h @@ -41,6 +41,7 @@ SERVER_SETUP_REC *server_setup_find(const char *address, int port, const char *chatnet); void server_setup_add(SERVER_SETUP_REC *rec); +void server_setup_modify(SERVER_SETUP_REC *rec, int old_port, const char *old_chatnet); void server_setup_remove(SERVER_SETUP_REC *rec); /* Remove servers attached to chatne */ diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index 468ac4e7..de45f8e9 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -110,11 +110,11 @@ static SERVER_SETUP_REC *create_server_setup(GHashTable *optlist) static void cmd_server_add_modify(const char *data, gboolean add) { GHashTable *optlist; - SERVER_SETUP_REC *rec; - char *addr, *portstr, *password, *value, *chatnet; + SERVER_SETUP_REC *rec, *tmp; + char *addr, *portstr, *password, *value, *chatnet, *old_chatnet; void *free_arg; gboolean newrec; - int port; + int port, old_port, add_port; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, "server add", &optlist, &addr, &portstr, &password)) @@ -122,27 +122,39 @@ static void cmd_server_add_modify(const char *data, gboolean add) if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - value = g_hash_table_lookup(optlist, "port"); + port = old_port = -1; if (*portstr != '\0') - port = atoi(portstr); - else if (value != NULL && *value != '\0') - port = atoi(value); + port = add_port = atoi(portstr); else if (g_hash_table_lookup(optlist, "tls") || g_hash_table_lookup(optlist, "ssl")) - port = DEFAULT_SERVER_ADD_TLS_PORT; + add_port = DEFAULT_SERVER_ADD_TLS_PORT; else - port = DEFAULT_SERVER_ADD_PORT; + add_port = DEFAULT_SERVER_ADD_PORT; + + value = g_hash_table_lookup(optlist, "port"); + if (value != NULL && *value != '\0') + old_port = atoi(value); chatnet = g_hash_table_lookup(optlist, "network"); - rec = server_setup_find(addr, port, chatnet); + rec = server_setup_find(addr, old_port != -1 ? old_port : add_port, chatnet); + if (old_port == -1 && rec != NULL) + old_port = rec->port; - if (rec == NULL) { + if (port == -1) + port = old_port != -1 ? old_port : add_port; + + /* make sure the new port doesn't exist */ + tmp = server_setup_find(addr, port, chatnet); + if (tmp != NULL && tmp->port == port) + rec = tmp; + + if (rec == NULL || (rec->port != old_port && rec->port != port)) { newrec = TRUE; if (add == FALSE) { - printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, - TXT_SETUPSERVER_NOT_FOUND, addr, port); + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_NOT_FOUND, + addr, old_port == -1 ? port : old_port); cmd_params_free(free_arg); return; } @@ -156,8 +168,9 @@ static void cmd_server_add_modify(const char *data, gboolean add) rec->port = port; } else { newrec = FALSE; - if (*portstr != '\0' || g_hash_table_lookup(optlist, "port")) - rec->port = port; + old_chatnet = g_strdup(rec->chatnet); + old_port = rec->port; + rec->port = port; if (*password != '\0') g_free_and_null(rec->password); if (g_hash_table_lookup(optlist, "host")) { @@ -261,7 +274,13 @@ static void cmd_server_add_modify(const char *data, gboolean add) signal_emit("server add fill", 3, rec, optlist, GINT_TO_POINTER(add)); - server_setup_add(rec); + if (newrec) { + server_setup_add(rec); + } else { + server_setup_modify(rec, old_port, old_chatnet); + g_free(old_chatnet); + } + printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_ADDED, addr, port); From c4fd417ccef8f2af6b3efbc4afa72997949a79c9 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 31 Aug 2021 11:09:42 +0200 Subject: [PATCH 0831/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index a89b4964..245f2223 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 39 +#define IRSSI_ABI_VERSION 40 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 4b506fc45c518619f968377b925492a96c7041d5 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 31 Aug 2021 14:49:56 +0200 Subject: [PATCH 0832/1198] remove duplicated servers on load --- src/core/servers-setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index fd719c38..59ca6997 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -458,7 +458,8 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) chatnet = config_node_get_str(node, "chatnet", NULL); if ((rec = server_setup_find(server, port, chatnet)) != NULL && rec->port == port) { - return NULL; + /* duplicate server setup */ + server_setup_remove(rec); } rec = NULL; From 63a5b80ba7c1df88544ee10fa66ca6202d7ed077 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 20:36:24 +0200 Subject: [PATCH 0833/1198] only enable sasl plain when username and password are set may fix #1325 --- src/irc/core/irc-servers-setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 5299ef04..e0982550 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -121,9 +121,9 @@ static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn, if (ircnet->sasl_mechanism != NULL) { if (!g_ascii_strcasecmp(ircnet->sasl_mechanism, "plain")) { /* The PLAIN method needs both the username and the password */ - conn->sasl_mechanism = SASL_MECHANISM_PLAIN; if (ircnet->sasl_username != NULL && *ircnet->sasl_username && ircnet->sasl_password != NULL && *ircnet->sasl_password) { + conn->sasl_mechanism = SASL_MECHANISM_PLAIN; conn->sasl_username = g_strdup(ircnet->sasl_username); conn->sasl_password = g_strdup(ircnet->sasl_password); } else From 6710b357369e561138b2ee18da6acca1be3f97ed Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 19:31:56 +0200 Subject: [PATCH 0834/1198] fix reading of starttls = "no" in config --- src/irc/core/irc-servers-setup.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index 7b11a2fe..d55507d8 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -12,8 +12,8 @@ (IRC_SERVER_SETUP(server) ? TRUE : FALSE) enum { - STARTTLS_DISALLOW = -1, /* */ - STARTTLS_NOTSET = 0, + STARTTLS_NOTSET = -1, /* */ + STARTTLS_DISALLOW = 0, STARTTLS_ENABLED = 1 }; From 92ade2f591475f310e83b4557012aa5480449fcb Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 19:40:41 +0200 Subject: [PATCH 0835/1198] fuzz server ssl init --- src/fe-fuzz/server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 83ce7bfa..b74a29b9 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -152,6 +152,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { args_execute(0, NULL); core_preinit((*argv)[0]); core_init(); + irssi_ssl_init(); irc_init(); fe_common_core_init(); fe_common_irc_init(); From e10e1c2da73a4af4ffc9acb3dd91b65feb93e6c7 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 18:43:50 +0200 Subject: [PATCH 0836/1198] fix reading of old config ssl_verify key --- src/core/servers-setup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 357e8ebe..0664aa38 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -484,8 +484,9 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node) rec->password = g_strdup(config_node_get_str(node, "password", NULL)); rec->use_tls = config_node_get_bool(node, "use_tls", FALSE) || config_node_get_bool(node, "use_ssl", FALSE); - rec->tls_verify = config_node_get_bool(node, "tls_verify", TRUE) || - config_node_get_bool(node, "ssl_verify", FALSE); + rec->tls_verify = config_node_find(node, "tls_verify") != NULL ? + config_node_get_bool(node, "tls_verify", TRUE) : + config_node_get_bool(node, "ssl_verify", TRUE); value = config_node_get_str(node, "tls_cert", NULL); if (value == NULL) From 215cf08828d14e5e307e0f334e51f7ac41e83329 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 30 Aug 2021 19:40:41 +0200 Subject: [PATCH 0837/1198] fuzz server ssl init --- src/fe-fuzz/server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-fuzz/server.c b/src/fe-fuzz/server.c index 83ce7bfa..b74a29b9 100644 --- a/src/fe-fuzz/server.c +++ b/src/fe-fuzz/server.c @@ -152,6 +152,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { args_execute(0, NULL); core_preinit((*argv)[0]); core_init(); + irssi_ssl_init(); irc_init(); fe_common_core_init(); fe_common_irc_init(); From 21701a1299cd6b64db5b2fb3765f578ff1f9fc6b Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 31 Aug 2021 17:29:43 +0200 Subject: [PATCH 0838/1198] do not unconditionally enable tls on /connect -! --- src/core/servers-setup.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index b1f57a99..82e5f6be 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -191,8 +191,10 @@ static void server_setup_fill_optlist(SERVER_CONNECT_REC *conn, GHashTable *optl /* ad-hoc TLS settings from command optlist */ if ((tmp = g_hash_table_lookup(optlist, "tls_cert")) != NULL || - (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) + (tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) { conn->tls_cert = g_strdup(tmp); + conn->use_tls = TRUE; + } if ((tmp = g_hash_table_lookup(optlist, "tls_pkey")) != NULL || (tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) conn->tls_pkey = g_strdup(tmp); @@ -220,10 +222,10 @@ static void server_setup_fill_optlist(SERVER_CONNECT_REC *conn, GHashTable *optl if (g_hash_table_lookup(optlist, "notls_verify") != NULL) conn->tls_verify = FALSE; if (g_hash_table_lookup(optlist, "tls_verify") != NULL || - g_hash_table_lookup(optlist, "ssl_verify") != NULL) + g_hash_table_lookup(optlist, "ssl_verify") != NULL) { conn->tls_verify = TRUE; - if ((conn->tls_cert != NULL && conn->tls_cert[0] != '\0') || conn->tls_verify) conn->use_tls = TRUE; + } if (g_hash_table_lookup(optlist, "notls") != NULL) conn->use_tls = FALSE; if (g_hash_table_lookup(optlist, "tls") != NULL || From 6c47fcf10d5a4b7718a3351ea0571da4d9f3c536 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 31 Aug 2021 21:49:29 +0200 Subject: [PATCH 0839/1198] Revert "Merge pull request #19 from ailin-nemui/starttls-no" This reverts commit 3324c5da89c694ce5bbd20ecb313da870d1bb914, reversing changes made to d3115f38550f26b935d4e22201d09287ce44e5ac. --- src/irc/core/irc-servers-setup.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/irc/core/irc-servers-setup.h b/src/irc/core/irc-servers-setup.h index d55507d8..7b11a2fe 100644 --- a/src/irc/core/irc-servers-setup.h +++ b/src/irc/core/irc-servers-setup.h @@ -12,8 +12,8 @@ (IRC_SERVER_SETUP(server) ? TRUE : FALSE) enum { - STARTTLS_NOTSET = -1, /* */ - STARTTLS_DISALLOW = 0, + STARTTLS_DISALLOW = -1, /* */ + STARTTLS_NOTSET = 0, STARTTLS_ENABLED = 1 }; From 1a6d74ac2645cf4f1c980604894f60dbf29a2d95 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 31 Aug 2021 21:54:41 +0200 Subject: [PATCH 0840/1198] fix reading of starttls = "no" in config, attempt 2 --- src/irc/core/irc-servers-setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-servers-setup.c b/src/irc/core/irc-servers-setup.c index 5299ef04..2cc80946 100644 --- a/src/irc/core/irc-servers-setup.c +++ b/src/irc/core/irc-servers-setup.c @@ -188,6 +188,7 @@ static void init_userinfo(void) static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) { + int starttls; g_return_if_fail(rec != NULL); g_return_if_fail(node != NULL); @@ -197,7 +198,10 @@ static void sig_server_setup_read(IRC_SERVER_SETUP_REC *rec, CONFIG_NODE *node) rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0); rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0); rec->max_query_chans = config_node_get_int(node, "max_query_chans", 0); - rec->starttls = config_node_get_bool(node, "starttls", STARTTLS_NOTSET); + starttls = config_node_get_bool(node, "starttls", -1); + rec->starttls = starttls == -1 ? STARTTLS_NOTSET : + starttls == 0 ? STARTTLS_DISALLOW : + STARTTLS_ENABLED; if (rec->starttls == STARTTLS_ENABLED) { rec->use_tls = 0; } From 939b773b8bea76dcf4ab33bb53d9899c84c218fb Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 13:37:07 +0200 Subject: [PATCH 0841/1198] Revert "Changed the support channel to LiberaChat." This reverts commit a5d4fd5aa7ad1d57c0b8e11e382944a3654cfa00. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1232764..d229391a 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on irc.libera.chat. +[#irssi](https://irssi.org/support/irc/) on irc.example.com. From 1a30e646d9a450b19582bdf306d7aad66730a632 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 13:37:17 +0200 Subject: [PATCH 0842/1198] Revert "Applied the updated docs changes in line with the upcoming blog post." This reverts commit 1773fa8d191c9f1dcc7c1e59dbcdf31c1263c918. --- README.md | 2 +- docs/help/in/admin.in | 2 +- docs/help/in/channel.in | 8 +++--- docs/help/in/connect.in | 6 ++--- docs/help/in/disconnect.in | 2 +- docs/help/in/info.in | 2 +- docs/help/in/join.in | 2 +- docs/help/in/knock.in | 2 +- docs/help/in/log.in | 8 +++--- docs/help/in/motd.in | 2 +- docs/help/in/names.in | 2 +- docs/help/in/nctcp.in | 2 +- docs/help/in/network.in | 6 ++--- docs/help/in/part.in | 2 +- docs/help/in/query.in | 4 +-- docs/help/in/recode.in | 2 +- docs/help/in/reconnect.in | 2 +- docs/help/in/server.in | 16 +++++------ docs/manual.txt | 2 +- docs/proxy.txt | 2 +- docs/startup-HOWTO.html | 4 +-- docs/startup-HOWTO.txt | 4 +-- irssi.conf | 54 ++++++++++++++++---------------------- 23 files changed, 65 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index d229391a..08be65b4 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on irc.example.com. +[#irssi](https://irssi.org/support/irc/) on freenode. diff --git a/docs/help/in/admin.in b/docs/help/in/admin.in index cfe66eba..2b6f8b73 100644 --- a/docs/help/in/admin.in +++ b/docs/help/in/admin.in @@ -15,7 +15,7 @@ %9Examples:%9 /ADMIN - /ADMIN irc.example.com + /ADMIN orwell.freenode.net /ADMIN mike %9See also:%9 INFO diff --git a/docs/help/in/channel.in b/docs/help/in/channel.in index 0e15b6d5..86e824c2 100644 --- a/docs/help/in/channel.in +++ b/docs/help/in/channel.in @@ -33,12 +33,12 @@ /CHANNEL /CHANNEL LIST - /CHANNEL ADD -auto #irssi ExampleNet + /CHANNEL ADD -auto #irssi Freenode /CHANNEL ADD -auto #basementcat Quakenet secret_lair - /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout ExampleNet + /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout Freenode /CHANNEL ADD -auto -bots 'Q!TheQBot@CServe.quakenet.org' -botcmd '^MSG Q op #irssi' #irssi Quakenet - /CHANNEL MODIFY -noauto #irssi ExampleNet - /CHANNEL REMOVE #hideout ExampleNet + /CHANNEL MODIFY -noauto #irssi Freenode + /CHANNEL REMOVE #hideout Freenode %9Special Example:%9 diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index 4d59dde1..e861ad74 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -34,9 +34,9 @@ %9Examples:%9 - /CONNECT ExampleNet - /CONNECT -6 ExampleNet - /CONNECT -4 -! -host staff.irssi.org -network ExampleNet irc.example.com + /CONNECT Freenode + /CONNECT -6 Freenode + /CONNECT -4 -! -host staff.irssi.org -network Freenode orwell.freenode.net /CONNECT irc.irssi.org 6667 WzerT8zq mike %9See also:%9 DISCONNECT, RMRECONNS, SERVER diff --git a/docs/help/in/disconnect.in b/docs/help/in/disconnect.in index 88772e1e..bd4a4e17 100644 --- a/docs/help/in/disconnect.in +++ b/docs/help/in/disconnect.in @@ -18,7 +18,7 @@ %9Examples:%9 - /DISCONNECT ExampleNet I'm off for today, take care! + /DISCONNECT Freenode I'm off for today, take care! /DISCONNECT * Vacation time :D /DISCONNECT diff --git a/docs/help/in/info.in b/docs/help/in/info.in index 41578501..275f349d 100644 --- a/docs/help/in/info.in +++ b/docs/help/in/info.in @@ -15,7 +15,7 @@ %9Examples:%9 /INFO - /INFO irc.example.com + /INFO orwell.freenode.net %9See also:%9 ADMIN diff --git a/docs/help/in/join.in b/docs/help/in/join.in index 55190267..39fa23f8 100644 --- a/docs/help/in/join.in +++ b/docs/help/in/join.in @@ -20,7 +20,7 @@ /JOIN #irssi /JOIN #basementcat secret_lair /JOIN -invite - /JOIN -ExampleNet #github,#example,#irssi + /JOIN -freenode #github,#freenode,#irssi %9See also:%9 KICK, PART diff --git a/docs/help/in/knock.in b/docs/help/in/knock.in index 3e2fdbdb..bb554d55 100644 --- a/docs/help/in/knock.in +++ b/docs/help/in/knock.in @@ -23,7 +23,7 @@ %9Examples:%9 /KNOCK #irssi - /KNOCK #example + /KNOCK #freenode /KNOCK #github %9See also:%9 INVITE, JOIN diff --git a/docs/help/in/log.in b/docs/help/in/log.in index dfe26e30..e4743d46 100644 --- a/docs/help/in/log.in +++ b/docs/help/in/log.in @@ -33,10 +33,10 @@ %9Examples:%9 /LOG OPEN -targets mike ~/irclogs/mike.log MSGS - /LOG OPEN -targets #irssi ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d - /LOG CLOSE ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d - /LOG STOP ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d - /LOG START ~/irclogs/ExampleNet/irssi-%%Y-%%m-%%d + /LOG OPEN -targets #irssi-freenode ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG CLOSE ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG STOP ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG START ~/irclogs/freenode/irssi-%%Y-%%m-%%d /SET autolog ON diff --git a/docs/help/in/motd.in b/docs/help/in/motd.in index ee1233b2..e33a1c75 100644 --- a/docs/help/in/motd.in +++ b/docs/help/in/motd.in @@ -15,7 +15,7 @@ %9Examples:%9 /MOTD - /MOTD irc.example.com + /MOTD orwel.freenode.org /MOTD bob %9See also:%9 ADMIN, INFO, LINKS, MAP diff --git a/docs/help/in/names.in b/docs/help/in/names.in index deccea40..8fd8cf91 100644 --- a/docs/help/in/names.in +++ b/docs/help/in/names.in @@ -21,7 +21,7 @@ %9Examples:%9 /NAMES -ops - /NAMES -voices #irssi,#example + /NAMES -voices #irssi,#freenode %9See also:%9 JOIN, PART, WHO, WHOIS diff --git a/docs/help/in/nctcp.in b/docs/help/in/nctcp.in index 68d789d6..93c3f3ec 100644 --- a/docs/help/in/nctcp.in +++ b/docs/help/in/nctcp.in @@ -15,7 +15,7 @@ %9Examples:%9 /NCTCP #irssi VERSION King of the Jungle v1.0 - /NCTCP bob,#example USERINFO I am bob :p + /NCTCP bob,#freenode USERINFO I am bob :p %9See also:%9 CTCP diff --git a/docs/help/in/network.in b/docs/help/in/network.in index 183fd5b5..fbdaa0b4 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -59,11 +59,11 @@ %9Examples:%9 /NETWORK ADD -usermode +giw EFnet - /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org ExampleNet - /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' ExampleNet + /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org Freenode + /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' Freenode /NETWORK ADD -autosendcmd '^MSG Q@CServe.quakenet.org AUTH mike WzerT8zq; WAIT 2000; OPER mike WzerT8zq; WAIT 2000; MODE mike +kXP' Quakenet /NETWORK MODIFY -usermode +gi EFnet - /NETWORK REMOVE ExampleNet + /NETWORK REMOVE Freenode %9See also:%9 CHANNEL, CONNECT, SERVER diff --git a/docs/help/in/part.in b/docs/help/in/part.in index 51be59bd..e96abfbb 100644 --- a/docs/help/in/part.in +++ b/docs/help/in/part.in @@ -14,7 +14,7 @@ %9Examples:%9 /PART #irssi - /PART #example,#irssi + /PART #freenode,#irssi %9See also:%9 JOIN, KICK diff --git a/docs/help/in/query.in b/docs/help/in/query.in index 85f2556e..1c0ba5b9 100644 --- a/docs/help/in/query.in +++ b/docs/help/in/query.in @@ -17,8 +17,8 @@ %9Examples:%9 /QUERY mike - /QUERY -ExampleNet bob - /QUERY -ExampleNet -window sarah + /QUERY -freenode bob + /QUERY -freenode -window sarah %9See also:%9 MSG, UNQUERY, WINDOW diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in index c34822de..63f52339 100644 --- a/docs/help/in/recode.in +++ b/docs/help/in/recode.in @@ -22,7 +22,7 @@ %9Examples:%9 /RECODE - /RECODE ADD ExampleNet/mike utf-8 + /RECODE ADD Freenode/mike utf-8 /RECODE ADD #korea euc-kr /RECODE REMOVE #korea diff --git a/docs/help/in/reconnect.in b/docs/help/in/reconnect.in index f2148c90..aa1dc946 100644 --- a/docs/help/in/reconnect.in +++ b/docs/help/in/reconnect.in @@ -15,7 +15,7 @@ %9Examples:%9 /RECONNECT - /RECONNECT ExampleNet + /RECONNECT Freenode /RECONNECT EFnet BRB :) %9See also:%9 CONNECT, DISCONNECT, NETWORK, RMRECONNS, SERVER diff --git a/docs/help/in/server.in b/docs/help/in/server.in index 8a4d8887..beb75114 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -61,15 +61,15 @@ %9Examples:%9 /SERVER - /SERVER CONNECT irc.example.com - /SERVER CONNECT +irc.example.com - /SERVER ADD -network ExampleNet -noautosendcmd irc.example.com - /SERVER ADD -! -auto -host staff.irssi.org -4 -network ExampleNet -noproxy irc.example.com 6667 - /SERVER MODIFY -network ExampleNet -noauto irc.example.com - /SERVER MODIFY -network ExampleNet irc.example.com 6697 - - /SERVER REMOVE irc.example.com 6667 ExampleNet + /SERVER CONNECT chat.freenode.net + /SERVER CONNECT +chat.freenode.net + /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net + /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 + /SERVER MODIFY -network Freenode -noauto orwell.freenode.net + /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - + /SERVER REMOVE orwell.freenode.net 6667 Freenode /SERVER PURGE - /SERVER PURGE irc.example.com + /SERVER PURGE orwell.freenode.net %9See also:%9 CHANNEL, CONNECT, DISCONNECT, NETWORK, RECONNECT, RMRECONNS diff --git a/docs/manual.txt b/docs/manual.txt index 29065feb..0f24ffe3 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -349,7 +349,7 @@ after connecting to the network. This is useful for automatically identifying yourself to NickServ, for example - /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" ExampleNet + /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" freenode /NETWORK REMOVE diff --git a/docs/proxy.txt b/docs/proxy.txt index 9ed7ecdb..224d24e3 100644 --- a/docs/proxy.txt +++ b/docs/proxy.txt @@ -24,7 +24,7 @@ You really should set some password for the proxy with: Then you'll need to configure the ports/ircnets the proxy listens in, something like: - /SET irssiproxy_ports IRCnet=2777 EFNet=2778 ExampleNet=2779 + /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779 There we have 3 different irc networks answering in 3 ports. Note that you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index ecbeb467..48f6e6df 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -68,7 +68,7 @@

And to connect to one of those networks and join a channel:

-
/CONNECT ExampleNet
+
/CONNECT Freenode
 /JOIN #irssi
 
@@ -94,7 +94,7 @@

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN ExampleNet
+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
 

These commands have many more options, see their help for details:

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 84397f33..61de27e3 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -43,7 +43,7 @@ has a few predefined networks, to list them: And to connect to one of those networks and join a channel: -/CONNECT LiberaChat +/CONNECT Freenode /JOIN #irssi To add more networks: @@ -67,7 +67,7 @@ wait for 2 seconds before joining channels: If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable: -/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN ExampleNet +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode These commands have many more options, see their help for details: diff --git a/irssi.conf b/irssi.conf index 9faa8973..edaeb3f5 100644 --- a/irssi.conf +++ b/irssi.conf @@ -1,19 +1,18 @@ servers = ( - { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, - { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, - { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, - { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, - { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, - { address = "irc.libera.chat"; chatnet = "LiberaChat"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, - { address = "irc.oftc.net"; chatnet = "OFTC"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "irc.quakenet.org"; chatnet = "QuakeNet"; port = "6667"; }, - { address = "irc.rizon.net"; chatnet = "Rizon"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; }, - { address = "irc.undernet.org"; chatnet = "Undernet"; port = "6667"; } + { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, + { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, + { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, + { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, + { address = "irc.ircsource.net"; chatnet = "IRCSource"; port = "6667"; }, + { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, + { address = "irc.oftc.net"; chatnet = "OFTC"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.quakenet.org"; chatnet = "QuakeNet"; port = "6667"; }, + { address = "irc.rizon.net"; chatnet = "Rizon"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; }, + { address = "irc.undernet.org"; chatnet = "Undernet"; port = "6667"; } ); chatnets = { @@ -59,12 +58,6 @@ chatnets = { max_msgs = "4"; max_whois = "1"; }; - LiberaChat = { - type = "IRC"; - max_kicks = "1"; - max_msgs = "4"; - max_whois = "1"; - }; NetFuze = { type = "IRC"; max_kicks = "1"; @@ -101,16 +94,15 @@ chatnets = { }; channels = ( - { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, - { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, - { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, - { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, - { name = "#libera"; chatnet = "LiberaChat"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "LiberaChat"; autojoin = "No"; }, - { name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; }, - { name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; }, - { name = "silc"; chatnet = "SILC"; autojoin = "No"; } + { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, + { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, + { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, + { name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; }, + { name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; }, + { name = "silc"; chatnet = "SILC"; autojoin = "No"; } ); aliases = { From 82d2cd88e78b4bffe0c710dd940d1771506eced6 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 13:37:37 +0200 Subject: [PATCH 0843/1198] Revert "Irssi does not take a political stance." This reverts commit a4486c236a3bf15192d0500b3a1892f7465826c7. --- README.md | 2 +- docs/help/in/admin.in | 2 +- docs/help/in/channel.in | 8 ++++---- docs/help/in/connect.in | 6 +++--- docs/help/in/disconnect.in | 2 +- docs/help/in/info.in | 2 +- docs/help/in/join.in | 2 +- docs/help/in/knock.in | 2 +- docs/help/in/log.in | 8 ++++---- docs/help/in/motd.in | 2 +- docs/help/in/names.in | 2 +- docs/help/in/nctcp.in | 2 +- docs/help/in/network.in | 6 +++--- docs/help/in/part.in | 2 +- docs/help/in/query.in | 4 ++-- docs/help/in/recode.in | 2 +- docs/help/in/reconnect.in | 2 +- docs/help/in/server.in | 16 ++++++++-------- docs/manual.txt | 2 +- docs/proxy.txt | 2 +- docs/startup-HOWTO.html | 4 ++-- docs/startup-HOWTO.txt | 4 ++-- irssi.conf | 8 ++++---- 23 files changed, 46 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 08be65b4..d1232764 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ Irssi is always looking for developers. Feel free to submit patches through GitHub pull requests. You can also contact the Irssi developers in -[#irssi](https://irssi.org/support/irc/) on freenode. +[#irssi](https://irssi.org/support/irc/) on irc.libera.chat. diff --git a/docs/help/in/admin.in b/docs/help/in/admin.in index 2b6f8b73..acb6e1ae 100644 --- a/docs/help/in/admin.in +++ b/docs/help/in/admin.in @@ -15,7 +15,7 @@ %9Examples:%9 /ADMIN - /ADMIN orwell.freenode.net + /ADMIN irc.libera.chat /ADMIN mike %9See also:%9 INFO diff --git a/docs/help/in/channel.in b/docs/help/in/channel.in index 86e824c2..d9be8cf5 100644 --- a/docs/help/in/channel.in +++ b/docs/help/in/channel.in @@ -33,12 +33,12 @@ /CHANNEL /CHANNEL LIST - /CHANNEL ADD -auto #irssi Freenode + /CHANNEL ADD -auto #irssi liberachat /CHANNEL ADD -auto #basementcat Quakenet secret_lair - /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout Freenode + /CHANNEL ADD -auto -bots '*!@*.irssi.org *!bot@irssi.org' -botcmd 'msg $0 op WzerTrzq' #hideout liberachat /CHANNEL ADD -auto -bots 'Q!TheQBot@CServe.quakenet.org' -botcmd '^MSG Q op #irssi' #irssi Quakenet - /CHANNEL MODIFY -noauto #irssi Freenode - /CHANNEL REMOVE #hideout Freenode + /CHANNEL MODIFY -noauto #irssi liberachat + /CHANNEL REMOVE #hideout liberachat %9Special Example:%9 diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in index e861ad74..d4375eec 100644 --- a/docs/help/in/connect.in +++ b/docs/help/in/connect.in @@ -34,9 +34,9 @@ %9Examples:%9 - /CONNECT Freenode - /CONNECT -6 Freenode - /CONNECT -4 -! -host staff.irssi.org -network Freenode orwell.freenode.net + /CONNECT liberachat + /CONNECT -6 liberachat + /CONNECT -4 -! -host staff.irssi.org -network liberachat irc.libera.chat /CONNECT irc.irssi.org 6667 WzerT8zq mike %9See also:%9 DISCONNECT, RMRECONNS, SERVER diff --git a/docs/help/in/disconnect.in b/docs/help/in/disconnect.in index bd4a4e17..c53b1e60 100644 --- a/docs/help/in/disconnect.in +++ b/docs/help/in/disconnect.in @@ -18,7 +18,7 @@ %9Examples:%9 - /DISCONNECT Freenode I'm off for today, take care! + /DISCONNECT liberachat I'm off for today, take care! /DISCONNECT * Vacation time :D /DISCONNECT diff --git a/docs/help/in/info.in b/docs/help/in/info.in index 275f349d..d8d8cfc9 100644 --- a/docs/help/in/info.in +++ b/docs/help/in/info.in @@ -15,7 +15,7 @@ %9Examples:%9 /INFO - /INFO orwell.freenode.net + /INFO irc.libera.chat %9See also:%9 ADMIN diff --git a/docs/help/in/join.in b/docs/help/in/join.in index 39fa23f8..adf7158e 100644 --- a/docs/help/in/join.in +++ b/docs/help/in/join.in @@ -20,7 +20,7 @@ /JOIN #irssi /JOIN #basementcat secret_lair /JOIN -invite - /JOIN -freenode #github,#freenode,#irssi + /JOIN -liberachat #github,#libera,#irssi %9See also:%9 KICK, PART diff --git a/docs/help/in/knock.in b/docs/help/in/knock.in index bb554d55..ce8f9aa0 100644 --- a/docs/help/in/knock.in +++ b/docs/help/in/knock.in @@ -23,7 +23,7 @@ %9Examples:%9 /KNOCK #irssi - /KNOCK #freenode + /KNOCK #libera /KNOCK #github %9See also:%9 INVITE, JOIN diff --git a/docs/help/in/log.in b/docs/help/in/log.in index e4743d46..3ca8782c 100644 --- a/docs/help/in/log.in +++ b/docs/help/in/log.in @@ -33,10 +33,10 @@ %9Examples:%9 /LOG OPEN -targets mike ~/irclogs/mike.log MSGS - /LOG OPEN -targets #irssi-freenode ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG CLOSE ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG STOP ~/irclogs/freenode/irssi-%%Y-%%m-%%d - /LOG START ~/irclogs/freenode/irssi-%%Y-%%m-%%d + /LOG OPEN -targets #irssi ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG CLOSE ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG STOP ~/irclogs/liberachat/irssi-%%Y-%%m-%%d + /LOG START ~/irclogs/liberachat/irssi-%%Y-%%m-%%d /SET autolog ON diff --git a/docs/help/in/motd.in b/docs/help/in/motd.in index e33a1c75..6e86681e 100644 --- a/docs/help/in/motd.in +++ b/docs/help/in/motd.in @@ -15,7 +15,7 @@ %9Examples:%9 /MOTD - /MOTD orwel.freenode.org + /MOTD irc.libera.chat /MOTD bob %9See also:%9 ADMIN, INFO, LINKS, MAP diff --git a/docs/help/in/names.in b/docs/help/in/names.in index 8fd8cf91..974b845f 100644 --- a/docs/help/in/names.in +++ b/docs/help/in/names.in @@ -21,7 +21,7 @@ %9Examples:%9 /NAMES -ops - /NAMES -voices #irssi,#freenode + /NAMES -voices #irssi,#libera %9See also:%9 JOIN, PART, WHO, WHOIS diff --git a/docs/help/in/nctcp.in b/docs/help/in/nctcp.in index 93c3f3ec..9f516730 100644 --- a/docs/help/in/nctcp.in +++ b/docs/help/in/nctcp.in @@ -15,7 +15,7 @@ %9Examples:%9 /NCTCP #irssi VERSION King of the Jungle v1.0 - /NCTCP bob,#freenode USERINFO I am bob :p + /NCTCP bob,#libera USERINFO I am bob :p %9See also:%9 CTCP diff --git a/docs/help/in/network.in b/docs/help/in/network.in index fbdaa0b4..0542bd7d 100644 --- a/docs/help/in/network.in +++ b/docs/help/in/network.in @@ -59,11 +59,11 @@ %9Examples:%9 /NETWORK ADD -usermode +giw EFnet - /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org Freenode - /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' Freenode + /NETWORK ADD -usermode +iw -nick mike -realname 'The one and only mike!' -host staff.irssi.org liberachat + /NETWORK ADD -autosendcmd '^MSG NickServ identify WzerT8zq' liberachat /NETWORK ADD -autosendcmd '^MSG Q@CServe.quakenet.org AUTH mike WzerT8zq; WAIT 2000; OPER mike WzerT8zq; WAIT 2000; MODE mike +kXP' Quakenet /NETWORK MODIFY -usermode +gi EFnet - /NETWORK REMOVE Freenode + /NETWORK REMOVE liberachat %9See also:%9 CHANNEL, CONNECT, SERVER diff --git a/docs/help/in/part.in b/docs/help/in/part.in index e96abfbb..f89769cc 100644 --- a/docs/help/in/part.in +++ b/docs/help/in/part.in @@ -14,7 +14,7 @@ %9Examples:%9 /PART #irssi - /PART #freenode,#irssi + /PART #libera,#irssi %9See also:%9 JOIN, KICK diff --git a/docs/help/in/query.in b/docs/help/in/query.in index 1c0ba5b9..a34f85e8 100644 --- a/docs/help/in/query.in +++ b/docs/help/in/query.in @@ -17,8 +17,8 @@ %9Examples:%9 /QUERY mike - /QUERY -freenode bob - /QUERY -freenode -window sarah + /QUERY -liberachat bob + /QUERY -liberachat -window sarah %9See also:%9 MSG, UNQUERY, WINDOW diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in index 63f52339..760c66cd 100644 --- a/docs/help/in/recode.in +++ b/docs/help/in/recode.in @@ -22,7 +22,7 @@ %9Examples:%9 /RECODE - /RECODE ADD Freenode/mike utf-8 + /RECODE ADD liberachat/mike utf-8 /RECODE ADD #korea euc-kr /RECODE REMOVE #korea diff --git a/docs/help/in/reconnect.in b/docs/help/in/reconnect.in index aa1dc946..87beb95a 100644 --- a/docs/help/in/reconnect.in +++ b/docs/help/in/reconnect.in @@ -15,7 +15,7 @@ %9Examples:%9 /RECONNECT - /RECONNECT Freenode + /RECONNECT liberachat /RECONNECT EFnet BRB :) %9See also:%9 CONNECT, DISCONNECT, NETWORK, RMRECONNS, SERVER diff --git a/docs/help/in/server.in b/docs/help/in/server.in index beb75114..f7d907f3 100644 --- a/docs/help/in/server.in +++ b/docs/help/in/server.in @@ -61,15 +61,15 @@ %9Examples:%9 /SERVER - /SERVER CONNECT chat.freenode.net - /SERVER CONNECT +chat.freenode.net - /SERVER ADD -network Freenode -noautosendcmd orwell.freenode.net - /SERVER ADD -! -auto -host staff.irssi.org -4 -network Freenode -noproxy orwell.freenode.net 6667 - /SERVER MODIFY -network Freenode -noauto orwell.freenode.net - /SERVER MODIFY -network Freenode orwell.freenode.net 6697 - - /SERVER REMOVE orwell.freenode.net 6667 Freenode + /SERVER CONNECT irc.libera.chat + /SERVER CONNECT +irc.libera.chat + /SERVER ADD -network liberachat -noautosendcmd irc.libera.chat + /SERVER ADD -! -auto -host staff.irssi.org -4 -network liberachat -noproxy irc.libera.chat 6667 + /SERVER MODIFY -network liberachat -noauto irc.libera.chat + /SERVER MODIFY -network liberachat irc.libera.chat 6697 - + /SERVER REMOVE irc.libera.chat 6667 liberachat /SERVER PURGE - /SERVER PURGE orwell.freenode.net + /SERVER PURGE irc.libera.chat %9See also:%9 CHANNEL, CONNECT, DISCONNECT, NETWORK, RECONNECT, RMRECONNS diff --git a/docs/manual.txt b/docs/manual.txt index 0f24ffe3..5f0eac51 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -349,7 +349,7 @@ after connecting to the network. This is useful for automatically identifying yourself to NickServ, for example - /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" freenode + /NETWORK ADD -autosendcmd "/^msg NickServ identify secret" liberachat /NETWORK REMOVE diff --git a/docs/proxy.txt b/docs/proxy.txt index 224d24e3..172770e8 100644 --- a/docs/proxy.txt +++ b/docs/proxy.txt @@ -24,7 +24,7 @@ You really should set some password for the proxy with: Then you'll need to configure the ports/ircnets the proxy listens in, something like: - /SET irssiproxy_ports ircnet=2777 efnet=2778 freenode=2779 + /SET irssiproxy_ports IRCnet=2777 EFNet=2778 liberachat=2779 There we have 3 different irc networks answering in 3 ports. Note that you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index 48f6e6df..b0c68f1f 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -68,7 +68,7 @@

And to connect to one of those networks and join a channel:

-
/CONNECT Freenode
+
/CONNECT liberachat
 /JOIN #irssi
 
@@ -94,7 +94,7 @@

If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable:

-
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode
+
/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat
 

These commands have many more options, see their help for details:

diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index 61de27e3..bff33108 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -43,7 +43,7 @@ has a few predefined networks, to list them: And to connect to one of those networks and join a channel: -/CONNECT Freenode +/CONNECT liberachat /JOIN #irssi To add more networks: @@ -67,7 +67,7 @@ wait for 2 seconds before joining channels: If you have irssi 0.8.18 or higher and the irc network supports it, you can use SASL instead of nickserv, which is more reliable: -/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN Freenode +/NETWORK ADD -sasl_username yourname -sasl_password yourpassword -sasl_mechanism PLAIN liberachat These commands have many more options, see their help for details: diff --git a/irssi.conf b/irssi.conf index edaeb3f5..21c3ba4c 100644 --- a/irssi.conf +++ b/irssi.conf @@ -2,7 +2,7 @@ servers = ( { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, { address = "ssl.efnet.org"; chatnet = "EFNet"; port = "9999"; use_tls = "yes"; tls_verify = "no"; }, { address = "irc.esper.net"; chatnet = "EsperNet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, - { address = "chat.freenode.net"; chatnet = "Freenode"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, + { address = "irc.libera.chat"; chatnet = "liberachat";port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "irc.gamesurge.net"; chatnet = "GameSurge"; port = "6667"; }, { address = "ssl.ircnet.ovh"; chatnet = "IRCnet"; port = "6697"; use_tls = "yes"; tls_verify = "yes"; }, { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, @@ -34,7 +34,7 @@ chatnets = { max_msgs = "4"; max_whois = "1"; }; - Freenode = { + liberachat = { type = "IRC"; max_kicks = "1"; max_msgs = "4"; @@ -95,8 +95,8 @@ chatnets = { channels = ( { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, - { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, - { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#libera"; chatnet = "liberachat";autojoin = "No"; }, + { name = "#irssi"; chatnet = "liberachat";autojoin = "No"; }, { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, From 240b79aa2677c5f21ec3350123eb573502bea85d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 22:56:06 +0200 Subject: [PATCH 0844/1198] send channel sync requests "later" in the command queue --- src/irc/core/channels-query.c | 16 +++++---- src/irc/core/irc-servers.h | 1 + src/irc/core/irc.c | 59 ++++++++++++++++++++------------ src/irc/core/irc.h | 12 +++++-- src/irc/notifylist/notify-ison.c | 6 ++-- src/perl/irc/Server.xs | 7 ++++ 6 files changed, 69 insertions(+), 32 deletions(-) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 6cf3dd2b..37fcb2d2 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -53,9 +53,9 @@ loop: /* here are the WHOX commands we send. the full spec can be found on [1]. (1) WHOX_CHANNEL_FULL_CMD for getting the user list when we join a channel. we request the fields - c (channel), u (user), h (host), n (nick), f (flags), d (hops), a (important, account!), and - r (the real name goes last because it os the only that can contain spaces.) we request all - those fields as they are also included in the "regular" WHO reply we would get without WHOX. + c (channel), u (user), h (host), n (nick), f (flags), d (hops), a (account), and r (the real + name goes last because it is the only that can contain spaces.) we request all those fields + as they are also included in the "regular" WHO reply we would get without WHOX. (2) WHOX_USERACCOUNT_CMD for getting the account names of people that joined. this code is obviously only used when we don't have extended-joins. we request n (nick) and a (account) @@ -265,7 +265,7 @@ static void query_send(IRC_SERVER_REC *server, int query) cmd = NULL; } - irc_send_cmd(server, cmd); + irc_send_cmd_later(server, cmd); g_free(chanstr); g_free(chanstr_commas); @@ -440,6 +440,7 @@ void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *n g_free(cmd); server->cmdcount--; + server->cmdlater--; } else { prev = tmp->next; } @@ -528,7 +529,9 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char } if (g_hash_table_size(chanrec->nicks) < settings_get_int("channel_max_who_sync") && - server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL) { + server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL && + g_hash_table_size(server->chanqueries->accountqueries) < + settings_get_int("account_max_chase")) { char *cmd; server_redirect_event(server, "who user", 1, nick, -1, "chanquery useraccount abort", /* failure signal */ @@ -538,7 +541,7 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char cmd = g_strdup_printf(WHOX_USERACCOUNT_CMD, nick); g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick)); /* queue the command */ - irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE); + irc_send_cmd_later(server, cmd); g_free(cmd); } } @@ -635,6 +638,7 @@ void channels_query_init(void) { settings_add_bool("misc", "channel_sync", TRUE); settings_add_int("misc", "channel_max_who_sync", 1000); + settings_add_int("misc", "account_max_chase", 10); signal_add("server connected", (SIGNAL_FUNC) sig_connected); signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 544baba9..93fa02a4 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -119,6 +119,7 @@ struct _IRC_SERVER_REC { there actually is, to make flood control remember how many messages can be sent before starting the flood control */ + int cmdlater; /* number of commands in queue to be sent later */ GSList *cmdqueue; /* command, redirection, ... */ gint64 wait_cmd; /* don't send anything to server before this */ gint64 last_cmd; /* last time command was sent to server */ diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 628d7130..e712c9bf 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -47,8 +47,7 @@ static void strip_params_colon(char *const); /* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd' won't be checked at all if it's 512 bytes or not, or if it contains line feeds or not. Use with extreme caution! */ -void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, - int send_now, int immediate, int raw) +void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_when, int raw) { GString *str; int len; @@ -65,6 +64,8 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, if (server->cmdcount == 0) irc_servers_start_cmd_timeout(); + if (server->cmdlater > server->cmdcount) + server->cmdlater = server->cmdcount; server->cmdcount++; if (!raw) { @@ -105,7 +106,7 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, g_string_append(str, cmd); } - if (send_now) { + if (irc_send_when == IRC_SEND_NOW) { rawlog_output(server->rawlog, str->str); server_redirect_command(server, str->str, server->redirect_next); server->redirect_next = NULL; @@ -117,25 +118,31 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, g_string_append_c(str, 10); } - if (send_now) { - irc_server_send_data(server, str->str, str->len); + if (irc_send_when == IRC_SEND_NOW) { + irc_server_send_data(server, str->str, str->len); g_string_free(str, TRUE); - } else { - + } else if (irc_send_when == IRC_SEND_NEXT) { /* add to queue */ - if (immediate) { - server->cmdqueue = g_slist_prepend(server->cmdqueue, - server->redirect_next); - server->cmdqueue = g_slist_prepend(server->cmdqueue, - g_string_free(str, FALSE)); - } else { - server->cmdqueue = g_slist_append(server->cmdqueue, - g_string_free(str, FALSE)); - server->cmdqueue = g_slist_append(server->cmdqueue, - server->redirect_next); - } + server->cmdqueue = g_slist_prepend(server->cmdqueue, server->redirect_next); + server->cmdqueue = g_slist_prepend(server->cmdqueue, g_string_free(str, FALSE)); + } else if (irc_send_when == IRC_SEND_NORMAL) { + guint pos = g_slist_length(server->cmdqueue); + if (pos > 2 * server->cmdlater) + pos -= 2 * server->cmdlater; + else + pos = 0; + + server->cmdqueue = g_slist_insert(server->cmdqueue, server->redirect_next, pos); + server->cmdqueue = g_slist_insert(server->cmdqueue, g_string_free(str, FALSE), pos); + } else if (irc_send_when == IRC_SEND_LATER) { + server->cmdqueue = g_slist_append(server->cmdqueue, g_string_free(str, FALSE)); + server->cmdqueue = g_slist_append(server->cmdqueue, server->redirect_next); + server->cmdlater++; + } else { + g_warn_if_reached(); } - server->redirect_next = NULL; + + server->redirect_next = NULL; } /* Send command to IRC server */ @@ -149,7 +156,7 @@ void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd) (server->cmdcount < server->max_cmds_at_once || server->cmd_queue_speed <= 0); - irc_send_cmd_full(server, cmd, send_now, FALSE, FALSE); + irc_send_cmd_full(server, cmd, send_now ? IRC_SEND_NOW : IRC_SEND_NORMAL, FALSE); } /* Send command to IRC server */ @@ -173,7 +180,7 @@ void irc_send_cmd_now(IRC_SERVER_REC *server, const char *cmd) { g_return_if_fail(cmd != NULL); - irc_send_cmd_full(server, cmd, TRUE, TRUE, FALSE); + irc_send_cmd_full(server, cmd, IRC_SEND_NOW, FALSE); } /* Send command to server putting it at the beginning of the queue of @@ -183,7 +190,15 @@ void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd) { g_return_if_fail(cmd != NULL); - irc_send_cmd_full(server, cmd, FALSE, TRUE, FALSE); + irc_send_cmd_full(server, cmd, IRC_SEND_NEXT, FALSE); +} + +/* Send command to server putting it at the end of the queue. */ +void irc_send_cmd_later(IRC_SERVER_REC *server, const char *cmd) +{ + g_return_if_fail(cmd != NULL); + + irc_send_cmd_full(server, cmd, IRC_SEND_LATER, FALSE); } static char *split_nicks(const char *cmd, char **pre, char **nicks, char **post, int arg) diff --git a/src/irc/core/irc.h b/src/irc/core/irc.h index 8803f662..92fb4ccb 100644 --- a/src/irc/core/irc.h +++ b/src/irc/core/irc.h @@ -27,6 +27,13 @@ typedef struct _REDIRECT_REC REDIRECT_REC; extern char *current_server_event; /* current server event being processed */ +enum { + IRC_SEND_NOW, /* */ + IRC_SEND_NEXT, + IRC_SEND_NORMAL, + IRC_SEND_LATER +}; + /* Send command to IRC server */ void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd); void irc_send_cmdv(IRC_SERVER_REC *server, const char *cmd, ...) G_GNUC_PRINTF (2, 3); @@ -42,11 +49,12 @@ void irc_send_cmd_now(IRC_SERVER_REC *server, const char *cmd); commands to send -- it will go out as soon as possible in accordance to the flood protection settings. */ void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd); +/* Send command to server putting it at the end of the queue. */ +void irc_send_cmd_later(IRC_SERVER_REC *server, const char *cmd); /* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd' won't be checked at all if it's 512 bytes or not, or if it contains line feeds or not. Use with extreme caution! */ -void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, - int send_now, int immediate, int raw); +void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_when, int raw); /* Extract a tag value from tags */ GHashTable *irc_parse_message_tags(const char *tags); diff --git a/src/irc/notifylist/notify-ison.c b/src/irc/notifylist/notify-ison.c index 32316038..809394c4 100644 --- a/src/irc/notifylist/notify-ison.c +++ b/src/irc/notifylist/notify-ison.c @@ -92,7 +92,7 @@ static void ison_send(IRC_SERVER_REC *server, GString *cmd) server_redirect_event(server, "ison", 1, NULL, -1, NULL, "event 303", "notifylist event", NULL); - irc_send_cmd(server, cmd->str); + irc_send_cmd_later(server, cmd->str); g_string_truncate(cmd, 0); } @@ -183,7 +183,9 @@ static void whois_send(IRC_SERVER_REC *server, const char *nicks, "", "event empty", NULL); g_free(str); - irc_send_cmdv(server, "WHOIS %s", whois_request); + str = g_strdup_printf("WHOIS %s", whois_request); + irc_send_cmd_later(server, str); + g_free(str); } static void whois_send_server(IRC_SERVER_REC *server, char *nick) diff --git a/src/perl/irc/Server.xs b/src/perl/irc/Server.xs index fef3698f..63e3111a 100644 --- a/src/perl/irc/Server.xs +++ b/src/perl/irc/Server.xs @@ -86,6 +86,13 @@ send_raw_first(server, cmd) CODE: irc_send_cmd_first(server, cmd); +void +send_raw_later(server, cmd) + Irssi::Irc::Server server + char *cmd +CODE: + irc_send_cmd_later(server, cmd); + void send_raw_split(server, cmd, nickarg, max_nicks) Irssi::Irc::Server server From 157913bd98f1f95eb7eb58b2c73a8e6685f0c8cc Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 23:26:35 +0200 Subject: [PATCH 0845/1198] do not chase during netsplit --- src/irc/core/channels-query.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/irc/core/channels-query.c b/src/irc/core/channels-query.c index 37fcb2d2..05c9768c 100644 --- a/src/irc/core/channels-query.c +++ b/src/irc/core/channels-query.c @@ -530,6 +530,7 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char if (g_hash_table_size(chanrec->nicks) < settings_get_int("channel_max_who_sync") && server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL && + server->split_servers == NULL && g_hash_table_size(server->chanqueries->accountqueries) < settings_get_int("account_max_chase")) { char *cmd; From 2de9c25376c18776011a42dc9f2e3ff4370bb700 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 23:01:58 +0200 Subject: [PATCH 0846/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 245f2223..d2dd2f7c 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 40 +#define IRSSI_ABI_VERSION 41 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From 37237f377e639650a4eb92168661fe4d53989400 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Thu, 2 Sep 2021 22:38:53 +0200 Subject: [PATCH 0847/1198] actually remember the hilight -color --- src/fe-common/core/hilight-text.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 4b5e4edd..d308bd04 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -479,6 +479,8 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, tmp = g_strdup_printf("%d", hilight_end)); g_free(tmp); } + if (hilight->color != NULL) + format_dest_meta_stash(dest, "hilight-color", hilight->color); signal_emit("print text", 3, dest, newstr, stripped); From cf903840233904de85858aa180f1a6b2e339a45d Mon Sep 17 00:00:00 2001 From: Jari Matilainen Date: Thu, 2 Sep 2021 23:10:37 +0200 Subject: [PATCH 0848/1198] Allow -tls_ca{file,path} '' to unset an argument --- src/fe-common/core/fe-server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c index de45f8e9..78e7202c 100644 --- a/src/fe-common/core/fe-server.c +++ b/src/fe-common/core/fe-server.c @@ -213,12 +213,16 @@ static void cmd_server_add_modify(const char *data, gboolean add) value = g_hash_table_lookup(optlist, "ssl_cafile"); if (value != NULL && *value != '\0') rec->tls_cafile = g_strdup(value); + else if (value != NULL && *value == '\0') + g_free_and_null(rec->tls_cafile); value = g_hash_table_lookup(optlist, "tls_capath"); if (value == NULL) value = g_hash_table_lookup(optlist, "ssl_capath"); if (value != NULL && *value != '\0') rec->tls_capath = g_strdup(value); + else if (value != NULL && *value == '\0') + g_free_and_null(rec->tls_capath); value = g_hash_table_lookup(optlist, "tls_ciphers"); if (value == NULL) From cb11fd9cf76a368d8672925d02272c8a24992017 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 3 Sep 2021 16:18:21 +0200 Subject: [PATCH 0849/1198] add a PACKAGE_VERSION override for meson --- meson.build | 10 ++++++++-- meson_options.txt | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index fe5aa99f..bd192a92 100644 --- a/meson.build +++ b/meson.build @@ -53,6 +53,8 @@ require_glib_internal = get_option('install-glib') == 'force' want_static_dependency = get_option('static-dependency') == 'yes' +package_version = get_option('PACKAGE_VERSION') != '' ? get_option('PACKAGE_VERSION') : meson.project_version() + chat_modules = ['irc'] run_command('mkdir', meson.current_build_dir() / incdir) @@ -540,7 +542,7 @@ foreach h : headers endforeach conf.set('HAVE_LIBUTF8PROC', have_libutf8proc) -conf.set_quoted('PACKAGE_VERSION', meson.project_version()) +conf.set_quoted('PACKAGE_VERSION', package_version) conf.set_quoted('PACKAGE_TARNAME', meson.project_name()) configure_file(output : 'irssi-config.h', @@ -581,7 +583,11 @@ pc_requires = [] if not glib_internal pc_requires += glib_dep endif -pc.generate(filebase : 'irssi-1', name : 'Irssi', description : 'Irssi chat client', requires : pc_requires) +pc.generate(filebase : 'irssi-1', + name : 'Irssi', + description : 'Irssi chat client', + version : package_version, + requires : pc_requires) ########### # irssi.1 # diff --git a/meson_options.txt b/meson_options.txt index 5dc9c514..1013166d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -15,3 +15,4 @@ option('static-dependency', type : 'combo', description : 'Request static depen option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes', 'force']) option('docdir', type : 'string', description : 'Documentation directory') option('fhs-prefix', type : 'string', description : 'System prefix for Termux') +option('PACKAGE_VERSION', type : 'string', description : 'Override PACKAGE_VERSION in tarballs') From 37eb6c351cd46af6b5827a4f6cd58dbe493067ca Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 3 Sep 2021 19:34:11 +0200 Subject: [PATCH 0850/1198] fix queue bug --- src/irc/core/irc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index e712c9bf..51b55a2b 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -51,6 +51,7 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_whe { GString *str; int len; + guint pos; gboolean server_supports_tag; g_return_if_fail(server != NULL); @@ -64,10 +65,16 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_whe if (server->cmdcount == 0) irc_servers_start_cmd_timeout(); - if (server->cmdlater > server->cmdcount) - server->cmdlater = server->cmdcount; server->cmdcount++; + pos = g_slist_length(server->cmdqueue); + if (server->cmdlater > pos / 2) { + server->cmdlater = pos / 2; + pos = 0; + } else { + pos -= 2 * server->cmdlater; + } + if (!raw) { const char *tmp = cmd; @@ -126,12 +133,6 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_whe server->cmdqueue = g_slist_prepend(server->cmdqueue, server->redirect_next); server->cmdqueue = g_slist_prepend(server->cmdqueue, g_string_free(str, FALSE)); } else if (irc_send_when == IRC_SEND_NORMAL) { - guint pos = g_slist_length(server->cmdqueue); - if (pos > 2 * server->cmdlater) - pos -= 2 * server->cmdlater; - else - pos = 0; - server->cmdqueue = g_slist_insert(server->cmdqueue, server->redirect_next, pos); server->cmdqueue = g_slist_insert(server->cmdqueue, g_string_free(str, FALSE), pos); } else if (irc_send_when == IRC_SEND_LATER) { From 9e128901104afb61ca29926e4421aadda031f38d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Fri, 13 Aug 2021 18:32:49 +0200 Subject: [PATCH 0851/1198] add a "server outgoing modify" signal to intercept outgoing messages --- docs/signals.txt | 1 + src/irc/core/irc-servers.c | 24 ++++++++++++++---------- src/irc/core/irc.c | 21 +++++++++++++-------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/docs/signals.txt b/docs/signals.txt index 4e5f85b4..6128084b 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -151,6 +151,7 @@ irc.c: "whois default event", SERVER_REC, char *args, char *sender_nick, char *sender_address "server incoming", SERVER_REC, char *data + "server outgoing modify", SERVER_REC, GString *data (for perl parser..) "redir ", SERVER_REC, char *args, char *sender_nick, char *sender_address diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 676e8cb9..1c9f0cec 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -734,9 +734,9 @@ static int server_cmd_timeout(IRC_SERVER_REC *server, gint64 now) { REDIRECT_REC *redirect; GSList *link; + GString *str; long usecs; char *cmd; - int len; if (!IS_IRC_SERVER(server)) return 0; @@ -759,16 +759,20 @@ static int server_cmd_timeout(IRC_SERVER_REC *server, gint64 now) redirect = server->cmdqueue->next->data; /* send command */ - len = strlen(cmd); - irc_server_send_data(server, cmd, len); + str = g_string_new(cmd); + signal_emit("server outgoing modify", 2, server, str); + if (str->len) { + irc_server_send_data(server, str->str, str->len); - /* add to rawlog without [CR+]LF */ - if (len > 2 && cmd[len-2] == '\r') - cmd[len-2] = '\0'; - else if (cmd[len-1] == '\n') - cmd[len-1] = '\0'; - rawlog_output(server->rawlog, cmd); - server_redirect_command(server, cmd, redirect); + /* add to rawlog without [CR+]LF */ + if (str->len > 2 && str->str[str->len - 2] == '\r') + str->str[str->len - 2] = '\0'; + else if (str->str[str->len - 1] == '\n') + str->str[str->len - 1] = '\0'; + rawlog_output(server->rawlog, str->str); + server_redirect_command(server, str->str, redirect); + } + g_string_free(str, TRUE); /* remove from queue */ server->cmdqueue = g_slist_remove(server->cmdqueue, cmd); diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 51b55a2b..c17e2470 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -113,20 +113,25 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_whe g_string_append(str, cmd); } - if (irc_send_when == IRC_SEND_NOW) { - rawlog_output(server->rawlog, str->str); - server_redirect_command(server, str->str, server->redirect_next); - server->redirect_next = NULL; - } - if (!raw) { - /* Add CR+LF to command */ + /* Add CR+LF to command */ g_string_append_c(str, 13); g_string_append_c(str, 10); } if (irc_send_when == IRC_SEND_NOW) { - irc_server_send_data(server, str->str, str->len); + signal_emit("server outgoing modify", 2, server, str); + if (str->len) { + irc_server_send_data(server, str->str, str->len); + + /* add to rawlog without [CR+]LF */ + if (str->len > 2 && str->str[str->len - 2] == '\r') + str->str[str->len - 2] = '\0'; + else if (str->str[str->len - 1] == '\n') + str->str[str->len - 1] = '\0'; + rawlog_output(server->rawlog, str->str); + server_redirect_command(server, str->str, server->redirect_next); + } g_string_free(str, TRUE); } else if (irc_send_when == IRC_SEND_NEXT) { /* add to queue */ From 2cdcf86174b420091372edd295dc81cda8b46d8f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 1 Sep 2021 23:37:11 +0200 Subject: [PATCH 0852/1198] branding --- .github/workflows/check.yml | 2 +- NEWS | 274 ++++++++++++++++++++++++++++++++++- README.md | 33 ++--- src/core/expandos.c | 2 +- src/fe-text/module-formats.c | 6 +- 5 files changed, 291 insertions(+), 26 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index aeaf6c27..61de72ff 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -118,5 +118,5 @@ jobs: echo load perl >> irssi-test/startup echo load proxy >> irssi-test/startup echo ^quit >> irssi-test/startup - irssi-build/bin/irssi --home irssi-test | ~/render.pl + irssi-build/bin/irssi --home irssi-test | perl -Mutf8 -C ~/render.pl cat irc.log.* diff --git a/NEWS b/NEWS index 1bdffd82..b3282761 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,274 @@ -v1.3-head 2021-xx-xx The Irssi team +v1.3.0-an 2021-09-05 Ailin Nemui + * /SET resolve_reverse_lookup setting was removed (#1135) + * Irssi will try to connect on IPv4 if IPv6 connection failed + (#1146). By Shivaram Lingamneni + * The display system now renders formats on the fly (#1079, + #1188, #1191, #1192, #1204, #1205, #1209, an#13, an#14, an#28, + an#29) + + This major change will break scripts that try to modify + printed text during "print text" signal (#1189). They need + to be ported to modify the text during "print format" + instead. It also breaks the usage of using /FORMAT to add + different colours to a line. Such usage needs to be ported + to using $expando variables instead. Affected scripts + include format_identify.pl, friends_peder.pl, nickcolor.pl, + nm.pl, people.pl + + The "gui print text finished" and "gui print text after + finished" signals gained a TEXT_DEST_REC *parameter in the + process. + + A new "gui render line text" signal is available to change + the rendering of a line + + * made the $Z expando (time) dynamic (#1087, #1207, #1208) + + This change breaks the usage of /SET timestamp_format to + supply a custom displayed time stamp. Affected scripts + include binary_time.pl + + * /HILIGHT -priority now affects which hilight rule gets + applied (#1228, #1232) + * The NAMES list is now hidden by default if there are more + than 18 users on the channel (an#7) + + To revert to the previous behaviour + + /SET show_names_on_join_limit -1 + + * -tls_verify is now enabled by default (#1170, an#18, #1309, + an#23) + + This may cause an ugly display of notls_verify in the output + of /SERVER LIST, even on plain-text connection, on old + configs. Kindly remove the "tls_verify = "no";" entries from + your config file manually. + + * Irssi will now attempt STARTTLS if advertised (#1170, #1312, + an#19) + + Use -disallow_starttls if you absolutely do not want this + + In order to check for a STARTTLS advertisement, Irssi will + now wait for a response (even an error) to CAP LS 302. If + your bouncer/server does not want to communicate before + receiving USER/PASS at all, use -nocap to disable the CAP + check. + + * Channel sync requests (WHO, MODE) are now sent "later" than + user commands. This should improve responsiveness to user + commands in the autojoin phase (an#26, an#32, an#33) + * Irssi is now using full paths in #include directives and + consequently does not add all directories to the include + path anymore (#1040) + * The Build System was ported to Meson (#1064, #1065, #1068, + #1071, #1072, #1073, #1074, #1075, #1084, #1085, #1118, #1166, + #1223, #1224, #1245, #1313, #1314, an#31) + * Scriptassist was changed to use a YAML database (#1163) + + It will tell you when you need to update your setting + + * /BIND shows all partial matches (#1155) + * Cleanup of unused functions (#1017, #1132, #1145, #1182, + #1246, #1264) + + Functions removed: + + NET_CALLBACK + NET_HOST_CALLBACK + RESOLVED_NAME_REC + net_gethostbyaddr_nonblock + net_connect_nonblock + [ SIMPLE_THREAD_REC, simple_init, simple_readpipe ] + hash_save_key + + Functions deprecated: + + dec2octal + g_timeval_cmp + get_timeval_diff + + Function names corrected: + + g_input -> i_input + g_istr -> i_istr + g_io_channel -> i_io_channel + g_hash_free_value -> i_hash_free_value + remove g_free_true + gslist -> i_slist + glog_func -> i_log_func + glist -> i_list + + If multi-version compatibility is desired, module authors + can find an example of backwards compatible code in + cdidier/irssi-xmpp#55 + + + Add MSGLEVEL_HIDDEN to Perl (#1044) + + Add $view->set_hidden_level and $view->remove_lines_by_level + to Perl (#1026) + + Add a /SET scrollback_max_age setting (#1022). By Heikki + Orsila + + Add /SET actlist_prefer_window_name (#1025) + + Add -window option to /CAT (#1023, #1159) + + Add an option to list specific sections with + + /SET -section lookandfeel + + (#1048) + + + Add support for IRCv3 CAP LS 302 (#1091) + + Add a new "print noformat" signal that goes together with + "print format" (#1088, #1192) + + Add support for IRCv3 extended-join. /SET show_extended_join + to enable (#1097, #1107, #1124) + + There are two new /FORMATs, join_extended and + join_extended_account, that theme writers need to take into + account if desired. + + + Add support for IRCv3 setname (#1093, #1104, #1254, GL#33, + #1104, #1254) + + Add support for IRCv3 account-notify (#1100, #1098, GL#33, + #1105, #1131). Credit to oss-fuzz + /SET show_account_notify to enable + + Add support for IRCv3 invite-notify (#1094) + + Add support for receiving IRCv3 message-tags (#576, #1090) + + Add support for sending IRCv3 message-tags (#1092) + + Add support for the oragono.io/maxline-2 CAP to increase IRC + protocol line length (#1092) + + Enable the znc.in/self-message CAP by default (#1123) + + Add support for IRCv3 away-notify. /SET away_notify_public + to enable (#1099, GL#33, #1105) + + Add support for IRCv3 chghost (#1096, GL#33, #1105) + + Add support for IRCv3 account-notify. + + Add support for IRCv3 server-time. /SET show_server_time to + enable (#1108) + + Add support for logging IRCv3 server-time. + /SET log_server_time to disable (#1318, an#16) + + Add IRCv3 features to signals.txt (#1111) + + In particular, "message join" now takes 2 additional + arguments, script and module authors must beware of this + change. + + + Show the unignore time in /IGNORE output (#1158, #1161) + + Add /SET quit_on_hup to make the behaviour of SIGHUP + configurable (#828, #1169). By Pinguin1234 + + Support numeric 489 as ERR_SECUREONLYCHAN (#1193, #1196). By + Michael Hansen + + Improve support for building Irssi in Termux-Android with + Meson (#1199) + + Add usermode key to Irssi::Irc::Chatnet in Perl (#1288). By + Jessica Sophie Porter + + Add format_string_expand and format_string_unexpand + functions to Perl (#1286) + + Add ...->format_create_dest(...)->printformat("format", + args...) and ...->printformat_module("module", "format", + args...) methods to Perl (#1284) + + You can avoid any CORE::GLOBAL::caller hacks using the + printformat_module method, especially sind that hack was not + safe during signal emissions + + + Add tracking of user accounts in the channel nicklist using + WHOX on join (#1250) + + Add auto-loading of the Perl and otr module from /SET + autoload_modules (#1295) + + Add /IGNORE ... NOHILIGHT to ignore some hilights (#1260) + + Do not beep on hidden lines with /SET beep_msg_level + ... -HIDDEN (#1259) + + Added /CS, /MS, /NS, and /OS aliases to the default config + (#1316). By Mathis Beer + + Allow -tls_ca{file,path} '' to unset an argument (#730, + #1060, an#30) + + Add a "server outgoing modify" signal to intercept outgoing + messages (#1148, #1151, an#15). Original by + JustAnotherArchivist + - remove some hard-coded 510 byte assumptions (#1086) + - Several fixes for error checks in SSL (#944, #1037, #943, + #1036). Reported by Chi Li + - Wrong variable tested in mask_match (#902, #1035) + - Fix bug where irssi-proxy with `?'-port would not reconnect + (#1041) + - Allow shrinking of /SET rawlog_lines (#957, #1020). By + Marcus "Teschi" Prinz + - Fix /WINDOW BALANCE warning (#1054) + - fix overflow when first command history entry expires + (#1070) + - begin modularising IRC module (#1067, #1112, #1113) + - fix some memory leaks in /DCC RESUME and settings_add + (#1077). By Zero King + - fix cut-off text with theme_indent module and /SET + indent_always OFF (#1078) + - fix the cap_queue order (#1095) + - add reference counted strings (#1089) + - Fix irc_op_public messages not triggering hilights (#354, + #891, #1129). By Dan Collins + - Fix /IGNORE not setting the right level in irc_op_public + messages (#1280). Credit to oss-fuzz + - Fix GTimeVal deprecation (#1141, #1144, #1145) + + If multi-version compatibility is desired, module authors + can find an example of backwards compatible code in + cdidier/irssi-xmpp#53 + + - Fix /IGNORE ... MODES NO_ACT not working (#1164) + - Deprecated -ssl* options are hidden from tab completion + (#1171) + - Make /SET actlist_sort a choice type (#1198) + - Fix crash from self-unloading script (#1206). By Thomas + Stagner + - Fix crash during Perl signal emission (#1233, #1234) + - Fix a case where empty lines or comments inside channels or + servers in the config would confuse Irssi (#1062, #1242, + #1243) + - Fix reported freezing in DCC GET on slow disks (#159, #1271) + - Fix message-tags parsing (#1274, #1275). Credit to oss-fuzz + - Fail redirects when receiving numeric 263 (RPL_TRYAGAIN) in + response to /WHO (#1283) + - Some updates to .gitignore (#1302). By Rene Kita + - Fix build on operating systems with X/Open Curses, version 2 + (#1305, #1308). By Nia Alarie (Regression introduced with + #1290, alternative fix for Irssi 1.2.3 no-term.h.patch) + - Fix otr module not using g_strndup, e.g. on Solaris 10 + (#1315). By Claes Nästén + - Fix cursor getting stuck for auto completions that changes + case (#1176, #1322, an#8). By ffrogman + - Restore operation of tag/* in /SET activity_hide_targets + (#1337, an#11) nb. the ::all syntax was working in Irssi 1.1 + and 1.2 (and continues to work) + - Fix /SERVER ADD -matrix -network my_matrix_network + (an#12). By Andrej Kacian + - Fix /SERVER ADD creating duplicated entries in the config + file (#1317, an#22) + - Fix critical when SASL user is set and SASL password is + empty (#1325, an#21) + - Misc fixes (#1106, #1141, #1272, #1297) + - Fuzz fixes (#1116, #1117, #1119, #1125, #1126, an#20) + - Build system fixes (#1101, #1102, #1069, #1140, #1181, #1253) + - Text and Help updates + - add -tls_* options to manual (#1029, #1030). By Jacob + V. Rasmussen + - missing targets in /MSG (#1032) + - wrong parameter in /ECHO (#1024) + - Spelling in OTR (#1047). By David Gall + - Clarify statusbar priority (#1049). By Marius Gedminas + - Document get_irssi_dir in Perl (#1051, #1052). By Alex + Shafer + - typo in /HILIGHT help (#1081). By DFrostByte + - improved clarity of your_nick_owned (#1138). By Mike Quin + - Update some URLs to https (#1163) + - Add documentation for escaping some characters (#1329, + #1330, an#9). By Guntbert Reiter + - Fix some typos (#1336, an#10). By Francis Mteo + - Infrastructure updates: + - Support for Github Actions (#1039, #1103, #1160, #1212, + #1231, #1252, #1261) + - Run clang-format on pull requests (#1172, #1173, #1184, + #1230, #1247, #1287) + - Run abidiff on pull requests (#1179, #1195) + - Test CI-Fuzz (#1279, #1304, an#17) v1.2.3 2021-04-11 The Irssi team - Fix the compilation of utf8proc (#1021) @@ -40,7 +310,7 @@ v1.2.3 2021-04-11 The Irssi team v1.2.2 2019-08-29 The Irssi team - Fix a use after free issue when receiving IRCv3 CAP - information from the server (GL#34) + information from the server (GL#34, GL!35) - Fix a crash during startup when windows weren't fully initialised yet (#1114, bdo#935813) diff --git a/README.md b/README.md index d1232764..21fa14e8 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ -# [Irssi](https://irssi.org/) +# Neırssi -![Build Status](https://github.com/irssi/irssi/workflows/Check%20Irssi/badge.svg?branch=master) +![Build Status](https://github.com/ailin-nemui/irssi/workflows/Check%20Irssi/badge.svg?branch=master) -Irssi is a modular chat client that is most commonly known for its -text mode user interface, but 80% of the code isn't text mode -specific. Irssi comes with IRC support built in, and there are -third party [ICB](https://github.com/jperkin/irssi-icb), +Neırssi is a modular text mode chat client mostly compatible with +[Irssi](https://irssi.org). It comes with IRC support built in, and +there are third party [ICB](https://github.com/jperkin/irssi-icb), [SILC](http://www.silcnet.org/), [XMPP](http://cybione.org/~irssi-xmpp/) (Jabber), [PSYC](http://about.psyc.eu/Irssyc) and @@ -14,14 +13,14 @@ available. ![irssi](https://user-images.githubusercontent.com/5665186/32180643-cf127f60-bd92-11e7-8aa2-882313ce1d8e.png) -## [Download information](https://irssi.org/download/) +## [Download information](https://ailin-nemui.github.io/irssi/Getting.html) #### Development source installation [Ninja](https://ninja-build.org/) 1.5 and [Meson](https://mesonbuild.com/) 0.49 ``` -git clone https://github.com/irssi/irssi +git clone https://github.com/ailin-nemui/irssi cd irssi meson Build ninja -C Build && sudo ninja -C Build install @@ -29,13 +28,13 @@ ninja -C Build && sudo ninja -C Build install #### Release source installation -* Download [release](https://github.com/irssi/irssi/releases) -* [Verify](https://irssi.org/download/#release-sources) signature +* Download [release](https://github.com/ailin-nemui/irssi/releases) +* Verify signature ``` tar xJf irssi-*.tar.xz cd irssi-* -./configure -make && sudo make install +meson Build +ninja -C Build && sudo ninja -C Build install ``` ### Requirements @@ -47,23 +46,23 @@ make && sudo make install #### See the [INSTALL](INSTALL) file for details -## [Documentation](https://irssi.org/documentation/) +## Documentation -* [Frequently Asked Questions](https://irssi.org/documentation/faq) -* [Startup How-To](https://irssi.org/documentation/startup) +* [New users guide](https://ailin-nemui.github.io/irssi/New-users.html) * Check the built-in `/HELP`, it has all the details on command syntax +* Other random Irssi documentation on https://irssi.org/documentation/ ## [Themes](https://irssi-import.github.io/themes/) ## [Scripts](https://scripts.irssi.org/) -## [Modules](https://irssi.org/modules/) +## [Modules](https://ailin-nemui.github.io/irssi/Modules.html) ## [Security information](https://irssi.org/security/) Please report security issues to staff@irssi.org. Thanks! -## [Bugs](https://github.com/irssi/irssi/issues) / Suggestions / [Contributing](https://irssi.org/development/) +## [Bugs](https://github.com/irssi/irssi/issues) / Suggestions / Contributing Check the GitHub issues if it is already listed in there; if not, open an issue on GitHub or send a mail to [staff@irssi.org](mailto:staff@irssi.org). diff --git a/src/core/expandos.c b/src/core/expandos.c index 0f317e51..da84b568 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -322,7 +322,7 @@ static char *expando_last_invite(SERVER_REC *server, void *item, int *free_ret) /* client version text string */ static char *expando_version(SERVER_REC *server, void *item, int *free_ret) { - return PACKAGE_VERSION; + return PACKAGE_VERSION "-an"; } /* current value of CMDCHARS */ diff --git a/src/fe-text/module-formats.c b/src/fe-text/module-formats.c index 7cdc5654..e9d4fab9 100644 --- a/src/fe-text/module-formats.c +++ b/src/fe-text/module-formats.c @@ -84,11 +84,7 @@ FORMAT_REC gui_text_formats[] = { NULL, "Welcome", 0 }, { "irssi_banner", - " ___ _%:" - "|_ _|_ _ _____(_)%:" - " | || '_(_-<_-< |%:" - "|___|_| /__/__/_|%:" - "Irssi v$J - https://irssi.org", 0 }, + "Neırssi v$J", 0 }, { "welcome_firsttime", "- - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" "Hi there! If this is your first time using Irssi, you%:" From 2003446e988280d86aebd2bc2492670f3329a9b7 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 7 Sep 2021 01:21:35 +0200 Subject: [PATCH 0853/1198] continue head --- NEWS | 2 ++ configure.ac | 2 +- meson.build | 2 +- src/core/expandos.c | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index b3282761..87cd3cfd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +v1.4-head-an 2022-xx-xx Ailin Nemui + v1.3.0-an 2021-09-05 Ailin Nemui * /SET resolve_reverse_lookup setting was removed (#1135) * Irssi will try to connect on IPv4 if IPv6 connection failed diff --git a/configure.ac b/configure.ac index 3a9e7bd6..a51edf3c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(irssi, 1.3-head) +AC_INIT(irssi, 1.4-head-an) AC_CONFIG_SRCDIR([src]) AC_CONFIG_AUX_DIR(build-aux) AC_PREREQ(2.50) diff --git a/meson.build b/meson.build index bd192a92..31bdfa9f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('irssi', 'c', - version : '1.3-head', + version : '1.4-head-an', meson_version : '>=0.49', default_options : ['warning_level=1']) diff --git a/src/core/expandos.c b/src/core/expandos.c index da84b568..0f317e51 100644 --- a/src/core/expandos.c +++ b/src/core/expandos.c @@ -322,7 +322,7 @@ static char *expando_last_invite(SERVER_REC *server, void *item, int *free_ret) /* client version text string */ static char *expando_version(SERVER_REC *server, void *item, int *free_ret) { - return PACKAGE_VERSION "-an"; + return PACKAGE_VERSION; } /* current value of CMDCHARS */ From 521c0d4e6fb906f65855f13e70c063ec7eb13552 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 8 Sep 2021 11:57:25 +0200 Subject: [PATCH 0854/1198] remove oragono.io/maxline-2 --- src/irc/core/irc-servers.c | 21 --------------------- src/irc/core/irc-servers.h | 1 - 2 files changed, 22 deletions(-) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 1c9f0cec..664ca9a4 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -282,7 +282,6 @@ static void server_init_1(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SASL, TRUE); } - irc_cap_toggle(server, CAP_MAXLINE, TRUE); irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE); @@ -647,24 +646,6 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) g_free(recoded); } -static void cap_maxline(IRC_SERVER_REC *server) -{ - unsigned int maxline = 0; - gboolean parse_successful = FALSE; - const char *maxline_str; - - maxline_str = g_hash_table_lookup(server->cap_supported, CAP_MAXLINE); - if (maxline_str != NULL) { - parse_successful = parse_uint(maxline_str, NULL, 10, &maxline); - - } - - if (parse_successful && - maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { - server->max_message_len = maxline - 2; - } -} - void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data) { char *recoded; @@ -1226,7 +1207,6 @@ void irc_servers_init(void) signal_add_first("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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_add("event 670", (SIGNAL_FUNC) event_starttls); signal_add("event 451", (SIGNAL_FUNC) event_registerfirst); signal_add("server cap end", (SIGNAL_FUNC) event_capend); @@ -1258,7 +1238,6 @@ void irc_servers_deinit(void) 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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_remove("event 670", (SIGNAL_FUNC) event_starttls); signal_remove("event 451", (SIGNAL_FUNC) event_registerfirst); signal_remove("server cap end", (SIGNAL_FUNC) event_capend); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 93fa02a4..903de773 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -15,7 +15,6 @@ #define MAX_IRC_USER_TAGS_LEN 4094 #define CAP_LS_VERSION "302" -#define CAP_MAXLINE "oragono.io/maxline-2" #define CAP_MESSAGE_TAGS "message-tags" #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" From 85eb4f118fca71daaf67c0c1440f169c164bd87f Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 8 Sep 2021 12:03:05 +0200 Subject: [PATCH 0855/1198] also remove from NEWS --- NEWS | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 87cd3cfd..7ed44195 100644 --- a/NEWS +++ b/NEWS @@ -136,9 +136,7 @@ v1.3.0-an 2021-09-05 Ailin Nemui /SET show_account_notify to enable + Add support for IRCv3 invite-notify (#1094) + Add support for receiving IRCv3 message-tags (#576, #1090) - + Add support for sending IRCv3 message-tags (#1092) - + Add support for the oragono.io/maxline-2 CAP to increase IRC - protocol line length (#1092) + + Add support for sending IRCv3 message-tags (#1092, an#34) + Enable the znc.in/self-message CAP by default (#1123) + Add support for IRCv3 away-notify. /SET away_notify_public to enable (#1099, GL#33, #1105) From 27a73e253b66240d02d0738e38c6162765e27726 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 8 Sep 2021 12:04:18 +0200 Subject: [PATCH 0856/1198] duplicate issue in NEWS reported by @tobbez --- NEWS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 87cd3cfd..0515314f 100644 --- a/NEWS +++ b/NEWS @@ -129,8 +129,7 @@ v1.3.0-an 2021-09-05 Ailin Nemui join_extended_account, that theme writers need to take into account if desired. - + Add support for IRCv3 setname (#1093, #1104, #1254, GL#33, - #1104, #1254) + + Add support for IRCv3 setname (#1093, #1104, #1254, GL#33) + Add support for IRCv3 account-notify (#1100, #1098, GL#33, #1105, #1131). Credit to oss-fuzz /SET show_account_notify to enable From 42f749346b375ccd5e46527a21ff2e7192273f5f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 8 Sep 2021 13:03:03 +0200 Subject: [PATCH 0857/1198] Merge pull request #34 from ailin-nemui/no-maxline remove oragono.io/maxline-2 (cherry picked from commit 7e1401140412361b813accd99aa367658435c12f) --- NEWS | 4 +--- src/irc/core/irc-servers.c | 21 --------------------- src/irc/core/irc-servers.h | 1 - 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/NEWS b/NEWS index b3282761..8be7531e 100644 --- a/NEWS +++ b/NEWS @@ -134,9 +134,7 @@ v1.3.0-an 2021-09-05 Ailin Nemui /SET show_account_notify to enable + Add support for IRCv3 invite-notify (#1094) + Add support for receiving IRCv3 message-tags (#576, #1090) - + Add support for sending IRCv3 message-tags (#1092) - + Add support for the oragono.io/maxline-2 CAP to increase IRC - protocol line length (#1092) + + Add support for sending IRCv3 message-tags (#1092, an#34) + Enable the znc.in/self-message CAP by default (#1123) + Add support for IRCv3 away-notify. /SET away_notify_public to enable (#1099, GL#33, #1105) diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index 1c9f0cec..664ca9a4 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -282,7 +282,6 @@ static void server_init_1(IRC_SERVER_REC *server) irc_cap_toggle(server, CAP_SASL, TRUE); } - irc_cap_toggle(server, CAP_MAXLINE, TRUE); irc_cap_toggle(server, CAP_MULTI_PREFIX, TRUE); irc_cap_toggle(server, CAP_EXTENDED_JOIN, TRUE); irc_cap_toggle(server, CAP_SETNAME, TRUE); @@ -647,24 +646,6 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) g_free(recoded); } -static void cap_maxline(IRC_SERVER_REC *server) -{ - unsigned int maxline = 0; - gboolean parse_successful = FALSE; - const char *maxline_str; - - maxline_str = g_hash_table_lookup(server->cap_supported, CAP_MAXLINE); - if (maxline_str != NULL) { - parse_successful = parse_uint(maxline_str, NULL, 10, &maxline); - - } - - if (parse_successful && - maxline >= MAX_IRC_MESSAGE_LEN + 2 /* 2 bytes for CR+LF */) { - server->max_message_len = maxline - 2; - } -} - void irc_server_send_action(IRC_SERVER_REC *server, const char *target, const char *data) { char *recoded; @@ -1226,7 +1207,6 @@ void irc_servers_init(void) signal_add_first("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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_add("event 670", (SIGNAL_FUNC) event_starttls); signal_add("event 451", (SIGNAL_FUNC) event_registerfirst); signal_add("server cap end", (SIGNAL_FUNC) event_capend); @@ -1258,7 +1238,6 @@ void irc_servers_deinit(void) 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("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline); signal_remove("event 670", (SIGNAL_FUNC) event_starttls); signal_remove("event 451", (SIGNAL_FUNC) event_registerfirst); signal_remove("server cap end", (SIGNAL_FUNC) event_capend); diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index 93fa02a4..903de773 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -15,7 +15,6 @@ #define MAX_IRC_USER_TAGS_LEN 4094 #define CAP_LS_VERSION "302" -#define CAP_MAXLINE "oragono.io/maxline-2" #define CAP_MESSAGE_TAGS "message-tags" #define CAP_SASL "sasl" #define CAP_MULTI_PREFIX "multi-prefix" From 0f3e95892de7e7a360336fcc9739e770916a9156 Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 8 Sep 2021 13:03:14 +0200 Subject: [PATCH 0858/1198] Merge pull request #35 from ailin-nemui/fixes duplicate issue in NEWS (cherry picked from commit d3e105a3963cbc693ac316ae884b000902999828) --- NEWS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 8be7531e..ced7bcd5 100644 --- a/NEWS +++ b/NEWS @@ -127,8 +127,7 @@ v1.3.0-an 2021-09-05 Ailin Nemui join_extended_account, that theme writers need to take into account if desired. - + Add support for IRCv3 setname (#1093, #1104, #1254, GL#33, - #1104, #1254) + + Add support for IRCv3 setname (#1093, #1104, #1254, GL#33) + Add support for IRCv3 account-notify (#1100, #1098, GL#33, #1105, #1131). Credit to oss-fuzz /SET show_account_notify to enable From 949dc06af3a023436712ba5e2a1f90641fd56d23 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 15 Sep 2021 17:48:27 +0200 Subject: [PATCH 0859/1198] correctly store updated message levels e.g. from /hilight --- src/fe-text/textbuffer-formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 20abc0df..50d6250a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -265,7 +265,7 @@ static void sig_gui_print_text_finished(WINDOW_REC *window, TEXT_DEST_REC *dest) info->meta = line_meta_create(dest->meta); - info->level |= MSGLEVEL_FORMAT; + info->level = dest->level | MSGLEVEL_FORMAT; /* the line will be inserted into the view with textbuffer_view_insert_line by gui-printtext.c:view_add_eol */ From 515e493db392a9e6944551a156e1780d653cd208 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 15 Sep 2021 17:52:44 +0200 Subject: [PATCH 0860/1198] update news --- NEWS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index f4a7a199..1934dfbf 100644 --- a/NEWS +++ b/NEWS @@ -4,9 +4,10 @@ v1.3.0-an 2021-09-05 Ailin Nemui * /SET resolve_reverse_lookup setting was removed (#1135) * Irssi will try to connect on IPv4 if IPv6 connection failed (#1146). By Shivaram Lingamneni + * The display system now renders formats on the fly (#1079, - #1188, #1191, #1192, #1204, #1205, #1209, an#13, an#14, an#28, - an#29) + #1188, #1191, #1192, #1204, #1205, #1209, #1349, an#13, + an#14, an#28, an#29, an#36) This major change will break scripts that try to modify printed text during "print text" signal (#1189). They need From 8b49cd012dc4af4040eb4ef03939e80072d40a5f Mon Sep 17 00:00:00 2001 From: ailin-nemui Date: Wed, 15 Sep 2021 17:56:45 +0200 Subject: [PATCH 0861/1198] Merge pull request #36 from ailin-nemui/missing-hilights correctly store updated message levels e.g. from /hilight (cherry picked from commit ad8221835c90969a6ba87807b072ba9f4d63bd48) --- NEWS | 5 +++-- src/fe-text/textbuffer-formats.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index ced7bcd5..b7c62b93 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,10 @@ v1.3.0-an 2021-09-05 Ailin Nemui * /SET resolve_reverse_lookup setting was removed (#1135) * Irssi will try to connect on IPv4 if IPv6 connection failed (#1146). By Shivaram Lingamneni + * The display system now renders formats on the fly (#1079, - #1188, #1191, #1192, #1204, #1205, #1209, an#13, an#14, an#28, - an#29) + #1188, #1191, #1192, #1204, #1205, #1209, #1349, an#13, + an#14, an#28, an#29, an#36) This major change will break scripts that try to modify printed text during "print text" signal (#1189). They need diff --git a/src/fe-text/textbuffer-formats.c b/src/fe-text/textbuffer-formats.c index 20abc0df..50d6250a 100644 --- a/src/fe-text/textbuffer-formats.c +++ b/src/fe-text/textbuffer-formats.c @@ -265,7 +265,7 @@ static void sig_gui_print_text_finished(WINDOW_REC *window, TEXT_DEST_REC *dest) info->meta = line_meta_create(dest->meta); - info->level |= MSGLEVEL_FORMAT; + info->level = dest->level | MSGLEVEL_FORMAT; /* the line will be inserted into the view with textbuffer_view_insert_line by gui-printtext.c:view_add_eol */ From bcea697e7c3eba1df2affdfd68f6c54f2bb0da06 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 19 Sep 2021 20:59:14 +0200 Subject: [PATCH 0862/1198] fix pedantic error in MSGLEVEL enum reported by horgh --- src/core/levels.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/levels.h b/src/core/levels.h index 04893b34..7f1aa931 100644 --- a/src/core/levels.h +++ b/src/core/levels.h @@ -42,7 +42,7 @@ enum { MSGLEVEL_HIDDEN = 0x10000000, /* Hidden from view */ MSGLEVEL_RESERVED1 = 0x20000000, MSGLEVEL_RESERVED2 = 0x40000000, - MSGLEVEL_FORMAT = 0x80000000 /* Format data */ + MSGLEVEL_FORMAT = (int)0x80000000 /* Format data */ }; /* clang-format on */ From df227eb0946aa4967613a26bba74fcaf96880a95 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Wed, 22 Sep 2021 10:50:20 +0200 Subject: [PATCH 0863/1198] update github actions ubuntu version to 18.04 and meson to <0.60.0 --- .github/workflows/check.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 61de72ff..97cb3feb 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -18,7 +18,7 @@ jobs: steps: - name: prepare required software run: | - sudo apt install $apt_build_deps $apt_build_deps_autotools + sudo apt update && sudo apt install $apt_build_deps $apt_build_deps_autotools - uses: actions/checkout@main - name: make dist run: | @@ -38,18 +38,18 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-16.04, ubuntu-latest] + os: [ubuntu-18.04, ubuntu-latest] builder: [meson, configure] compiler: [clang, gcc] flags: [regular] include: - - os: ubuntu-16.04 + - os: ubuntu-18.04 builder: meson meson_ver: ==0.49.2 setuptools_ver: <51 - os: ubuntu-latest builder: meson - meson_ver: <0.59.0 + meson_ver: <0.60.0 - os: ubuntu-latest builder: meson flags: meson-latest FAILURE-OK @@ -64,7 +64,7 @@ jobs: meson_ver: ${{ matrix.meson_ver }} setuptools_ver: ${{ matrix.setuptools_ver }} run: | - sudo apt install $apt_build_deps $apt_build_deps_${{ matrix.builder }} + sudo apt update && sudo apt install $apt_build_deps $apt_build_deps_${{ matrix.builder }} eval "$get_pip_build_deps_${{ matrix.builder }}" curl -SLf https://github.com/irssi-import/actions-irssi/raw/master/check-irssi/render.pl -o ~/render.pl && chmod +x ~/render.pl - name: unpack archive From 32a3f4463c435304717883f810d222c0f79492a9 Mon Sep 17 00:00:00 2001 From: bw1 Date: Sun, 19 Sep 2021 19:56:14 +0200 Subject: [PATCH 0864/1198] update docs + version() + $abiversion + parse_special() --- docs/perl.txt | 6 ++++++ docs/special_vars.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/docs/perl.txt b/docs/perl.txt index 761b2f4d..964f4f72 100644 --- a/docs/perl.txt +++ b/docs/perl.txt @@ -205,6 +205,12 @@ Window::command(cmd) Windowitem::command(cmd) Send a command `cmd' (in current channel). The '/' char isn't needed. +version() - return client release date and time (format YYYYMMDD.hhmm) + +parse_special(cmd, data="", flags=0) +Server::parse_special(cmd, data="", flags=0) +Windowitem::parse_special(cmd, data="", flags=0) + evaluate a string with special vars *** Themes diff --git a/docs/special_vars.txt b/docs/special_vars.txt index 36517f78..1101c8a6 100644 --- a/docs/special_vars.txt +++ b/docs/special_vars.txt @@ -94,6 +94,8 @@ $A .. $Z is important. $winname window name $itemname like $T, but use item's visible_name which may be different (eg. $T = !12345chan, $itemname = !chan) + $abiversion IRSSI_ABI_VERSION + https://github.com/irssi/irssi/wiki/irssi_abi_version For example, assume you have the following alias: From 6a83eddf84573acd0d489dc2eb18796699494a23 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 21 Sep 2021 22:40:14 +0200 Subject: [PATCH 0865/1198] run syncdocs.sh and syncscripts.sh --- docs/faq.html | 4 +- docs/faq.txt | 6 +- docs/startup-HOWTO.html | 4 +- docs/startup-HOWTO.txt | 4 +- scripts/quitmsg.pl | 27 +++----- scripts/scriptassist.pl | 139 +++++++++++++++++++++++++--------------- 6 files changed, 104 insertions(+), 80 deletions(-) diff --git a/docs/faq.html b/docs/faq.html index 7c17f45d..50b404a0 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -2,7 +2,7 @@

Frequently Asked Questions

Q: Why doesn’t irssi display colors even when ircii etc. displays them?

-

A: They force ANSI colors even if terminal doesn’t support them. By default, irssi uses colors only if terminfo/termcap so says. The correct way to fix this would be to change your TERM environment to a value where colors work, like xterm-color or color_xterm (eg. TERM=xterm-color irssi). If this doesn’t help, then use the evil way of /SET term_force_colors ON.

+

A: They force ANSI colors even if terminal doesn’t support them. By default, irssi uses colors only if terminfo/termcap so says. The correct way to fix this would be to change your TERM environment to a value where colors work, like xterm-256color or color_xterm (eg. TERM=xterm-256color irssi). If this doesn’t help, then use the evil way of /SET term_force_colors ON.

Q: How do I easily write text to channel that starts with ‘/’ character?

@@ -54,7 +54,7 @@

Q: Will there be /DETACH-like feature?

-

A: tmux, screen and dtach can be used to do it just fine.

+

A: tmux, screen and dtach can be used to do it just fine.

Q: How do I run scripts automatically at startup?

diff --git a/docs/faq.txt b/docs/faq.txt index 0d0b5f46..0fcc156a 100644 --- a/docs/faq.txt +++ b/docs/faq.txt @@ -4,8 +4,8 @@ Q: Why doesn’t irssi display colors even when ircii etc. displays them? A: They force ANSI colors even if terminal doesn’t support them. By default, irssi uses colors only if terminfo/termcap so says. The correct way to fix this would be to change your TERM environment to a value where colors work, like - xterm-color or color_xterm (eg. TERM=xterm-color irssi). If this doesn’t help, - then use the evil way of /SET term_force_colors ON. + xterm-256color or color_xterm (eg. TERM=xterm-256color irssi). If this doesn’t + help, then use the evil way of /SET term_force_colors ON. Q: How do I easily write text to channel that starts with ‘/’ character? A: / /text @@ -119,6 +119,6 @@ A: Check [6]here [1] https://github.com/irssi-import/xirssi [2] https://tmux.github.io/ [3] https://www.gnu.org/software/screen/screen.html - [4] http://dtach.sf.net/ + [4] https://sourceforge.net/projects/dtach/ [5] https://dgl.cx/irssi/hack-whois-in-current-window.pl [6] https://irssi.org/assets/irssi.wav diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html index b0c68f1f..696dea4d 100644 --- a/docs/startup-HOWTO.html +++ b/docs/startup-HOWTO.html @@ -226,7 +226,7 @@ Ctrl-P, Ctrl-N - Jump to previous / next window

And finally channels:

-
/CHANNEL ADD -auto -bots *!*user@host -botcmd "/^msg $0 op pass" #irssi efnet
+
/CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet
 /CHANNEL ADD -auto #secret IRCnet password
 
@@ -395,7 +395,7 @@ Ctrl-X - set the next server in list active

/HELP bind tells pretty much everything there is to know about keyboard bindings. However, there’s the problem of how to bind some non-standard keys. They might differ a bit with each terminal, so you’ll need to find out what exactly the keypress produces. Easiest way to check that would be to see what it prints in cat. Here’s an example for pressing F1 key:

-
 [user@host] ~% cat
+
 [cras@hurina] ~% cat
  ^[OP
 
diff --git a/docs/startup-HOWTO.txt b/docs/startup-HOWTO.txt index bff33108..90d278de 100644 --- a/docs/startup-HOWTO.txt +++ b/docs/startup-HOWTO.txt @@ -218,7 +218,7 @@ IRC network, other servers are automatically connected in same network if the And finally channels: -/CHANNEL ADD -auto -bots *!*user@host -botcmd "/^msg $0 op pass" #irssi efnet +/CHANNEL ADD -auto -bots *!*bot@host.org -botcmd "/^msg $0 op pass" #irssi efnet /CHANNEL ADD -auto #secret IRCnet password -bots and -botcmd should be the only ones needing a bit of explaining. They’re @@ -442,7 +442,7 @@ They might differ a bit with each terminal, so you’ll need to find out what exactly the keypress produces. Easiest way to check that would be to see what it prints in cat. Here’s an example for pressing F1 key: - [user@host] ~% cat + [cras@hurina] ~% cat ^[OP So in irssi you would use /BIND ^[OP /ECHO F1 pressed. If you use multiple diff --git a/scripts/quitmsg.pl b/scripts/quitmsg.pl index e289468c..102d9aa5 100644 --- a/scripts/quitmsg.pl +++ b/scripts/quitmsg.pl @@ -6,36 +6,27 @@ use Irssi::Irc; use strict; use vars qw($VERSION %IRSSI); -$VERSION = "1.00"; +$VERSION = "1.01"; %IRSSI = ( authors => 'Timo Sirainen', name => 'quitmsg', description => 'Random quit messages', license => 'Public Domain', - changed => 'Sun Mar 10 23:18 EET 2002' + changed => 'Mon Jul 22 20:00 EET 2020' ); -my $quitfile = glob "~/.irssi/irssi.quit"; +my $quitfile = Irssi::get_irssi_dir() . "/irssi.quit"; sub cmd_quit { my ($data, $server, $channel) = @_; return if ($data ne ""); + + open (my $fh, "<", $quitfile) || return; + my @lines = <$fh>; - open (f, "<", $quitfile) || return; - my $lines = 0; while() { $lines++; }; - - my $line = int(rand($lines))+1; - - my $quitmsg; - seek(f, 0, 0); $. = 0; - while() { - next if ($. != $line); - - chomp; - $quitmsg = $_; - last; - } - close(f); + my $quitmsg = $lines[int(rand(@lines))]; + chomp($quitmsg); + close($fh); foreach my $server (Irssi::servers) { $server->command("/disconnect ".$server->{tag}." $quitmsg"); diff --git a/scripts/scriptassist.pl b/scripts/scriptassist.pl index 536ef33a..cf02d57e 100644 --- a/scripts/scriptassist.pl +++ b/scripts/scriptassist.pl @@ -5,7 +5,7 @@ use strict; -our $VERSION = '2003020807'; +our $VERSION = '2020042700'; our %IRSSI = ( authors => 'Stefan \'tommie\' Tomanek', contact => 'stefan@pico.ruhr.de', @@ -23,12 +23,15 @@ use Irssi 20020324; use CPAN::Meta::YAML; use LWP::UserAgent; use POSIX; +use version; # GnuPG is not always needed $have_gpg = 0; eval "use GnuPG qw(:algo :trust);"; $have_gpg = 1 if not ($@); +my $irssi_version = qv(Irssi::parse_special('v$J') =~ s/-.*//r); + sub show_help { my $help = "scriptassist $VERSION /scriptassist check @@ -39,15 +42,15 @@ sub show_help { Search the script database /scriptassist info Display information about -".#/scriptassist ratings -# Retrieve the average ratings of the the scripts -#/scriptassist top -# Retrieve the first top rated scripts -"/scriptassist new +/scriptassist ratings + Retrieve the average ratings of the the scripts +/scriptassist top + Retrieve the first top rated scripts +/scriptassist new Display the newest scripts -".#/scriptassist rate )?\s*(
\s*){0,3})}{\1\2}g;' +s{(\s*)?\s*((\r?\n)*\s*\s*)?(
\s*){0,3})}{\1\2}g; +s{}{}g; +s{(.*?)}{\1}g;' srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. @@ -45,6 +48,7 @@ else any=false fi +addheadermark="perl -p -e s{\\K}{(q:#:x\$1).q: :}ge;s{(?=)}{q: :.(q:#:x\$1)}ge" if type w3m >/dev/null 2>&1 ; then converter="w3m -o display_link_number=1 -dump -T text/html" any=true @@ -83,25 +87,33 @@ download_it() { mv "$3".tmp "$3" } -download_it "FAQ" "$faq" "$srcdir"/docs/faq.html -download_it "Startup How-To" "$howto" "$srcdir"/docs/startup-HOWTO.html -download_it "Design" "$design" "$srcdir"/docs/design.html +download_it_nested() { + name=$1; shift + src=$1; shift + dest=$1; shift + download_it "$name" "$src" "$dest".nest + echo > "$dest" + eval $(perl -n -0777 -e 'print qq{download_it "\$name ($2)" "\${src}$1/" "\${dest}.$1"; +cat "\${dest}.$1" >> "\${dest}.tmp"; +rm "\${dest}.$1";\n} + while(m{(.*?)}g)' "$dest".nest) + rm "$dest".nest + perl -i -0777 -p -e 's{}{}g;s{\A}{\n}' "$dest".tmp + mv "$dest".tmp "$dest" +} + +download_it_nested "QNA" "$qna" "$srcdir"/docs/qna.html +download_it "New users guide" "$howto" "$srcdir"/docs/New-users.html +#download_it "Design" "$design" "$srcdir"/docs/design.html # .html -> .txt with lynx or elinks -echo "Documentation: html -> txt..." +echo "Documentation: html -> txt... [converter: $converter]" -cat "$srcdir"/docs/faq.html \ - | LC_ALL=en_IE.utf8 $converter \ - | perl -pe ' - s/^ *//; - if ($_ eq "\n" && $state eq "Q") { $_ = ""; } - elsif (/^([QA]):/) { $state = $1 } - elsif ($_ ne "\n") { $_ = " $_"; }; -' > "$srcdir"/docs/faq.txt +cat "$srcdir"/docs/qna.html \ + | $addheadermark | $converter > "$srcdir"/docs/qna.txt -cat "$srcdir"/docs/startup-HOWTO.html \ - | perl -pe "s/\\bhref=([\"\'])#.*?\\1//" \ - | LC_ALL=en_IE.utf8 $converter > "$srcdir"/docs/startup-HOWTO.txt +cat "$srcdir"/docs/New-users.html \ + | $addheadermark | $converter > "$srcdir"/docs/New-users.txt -cat "$srcdir"/docs/design.html \ - | LC_ALL=en_IE.utf8 $converter > "$srcdir"/docs/design.txt +#cat "$srcdir"/docs/design.html \ +# | $addheadermark | $converter > "$srcdir"/docs/design.txt From d30cdafcffeb5c14a4afc2028a93d93d825fd0db Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 27 Dec 2025 22:41:02 +0100 Subject: [PATCH 1184/1198] github actions: update package lists --- .github/workflows/abicheck.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/abicheck.yml b/.github/workflows/abicheck.yml index d1387b82..254c64f9 100644 --- a/.github/workflows/abicheck.yml +++ b/.github/workflows/abicheck.yml @@ -17,7 +17,7 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: prepare required software run: | - sudo apt install $apt_build_deps + sudo apt update; sudo apt install $apt_build_deps eval "$get_pip_build_deps" - name: checkout base ref uses: actions/checkout@main @@ -52,7 +52,7 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: prepare required software run: | - sudo apt install $apt_build_deps + sudo apt update; sudo apt install $apt_build_deps eval "$get_pip_build_deps" - name: checkout merge ref uses: actions/checkout@main @@ -87,7 +87,7 @@ jobs: steps: - name: prepare required software run: | - sudo apt install abigail-tools + sudo apt update; sudo apt install abigail-tools - name: fetch base build uses: actions/download-artifact@v4 with: From 51f2a4f7fb51f57fe32ce5bccdbb5ed6cd9013c3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 27 Jul 2025 20:06:10 +0200 Subject: [PATCH 1185/1198] use GIO resolver change: rename resolve_prefer_ipv6 -> irssiproxy_prefer_ipv6 --- docs/help/in/toggle.in | 1 - docs/manual.txt | 3 - meson.build | 35 ++++- src/common.h | 3 +- src/core/chat-commands.c | 9 +- src/core/net-nonblock.c | 120 +++++++----------- src/core/net-nonblock.h | 18 +-- src/core/network.c | 182 ++++++++++---------------- src/core/network.h | 30 ++--- src/core/server-connect-rec.h | 4 +- src/core/server-rec.h | 4 +- src/core/servers-reconnect.c | 11 +- src/core/servers-setup.c | 14 +- src/core/servers.c | 190 +++++++++++++++------------- src/core/servers.h | 1 + src/fe-common/core/fe-common-core.c | 23 +++- src/irc/proxy/listen.c | 11 +- src/irc/proxy/proxy.c | 1 + 18 files changed, 317 insertions(+), 343 deletions(-) diff --git a/docs/help/in/toggle.in b/docs/help/in/toggle.in index f87a6462..9469ba5c 100644 --- a/docs/help/in/toggle.in +++ b/docs/help/in/toggle.in @@ -15,7 +15,6 @@ %9Examples:%9 - /TOGGLE resolve_prefer_ipv6 /TOGGLE channels_rejoin_unavailable ON %9See also:%9 SET diff --git a/docs/manual.txt b/docs/manual.txt index d55e362e..073abe18 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -373,9 +373,6 @@ After connected to server, Irssi can automatically change your user mode. You can set it with /SET usermode , default is +i. - /SET resolve_prefer_ipv6 - If ON, prefer IPv6 for hosts that - have both v4 and v6 addresses. - 5.5 Automatic reconnecting If you get disconnected from server, Irssi will try to reconnect diff --git a/meson.build b/meson.build index 9499a126..4f78600e 100644 --- a/meson.build +++ b/meson.build @@ -8,6 +8,7 @@ project('irssi', 'c', glib_internal_version = 'glib-2.74.3' # keep this in sync with subprojects/glib.wrap glib_pcre2_internal_version = 'pcre2-10.40' +glib_libffi_internal_version = 'libffi' cc = meson.get_compiler('c') rootinc = include_directories('.') dep = [] @@ -217,11 +218,6 @@ if not glib_dep.found() prov_lib = cc.find_library('iconv', dirs : '/usr/local/lib') glib_internal_usr_local = true endif - if cc.has_function('libiconv_open', dependencies : prov_lib) - glib_internal_configure_args += '-Diconv=gnu' - else - glib_internal_configure_args += '-Diconv=native' - endif glib_internal_dependencies += prov_lib endif @@ -254,7 +250,7 @@ if not glib_dep.found() glib_internal_configure_t = custom_target('glib-internal-configure', command : [ meson_cmd, 'setup', '--prefix=/irssi-glib-internal', '--buildtype=' + get_option('buildtype'), - '-Dlibmount=disabled', '-Dselinux=disabled', '-Ddefault_library=static', '-Dforce_fallback_for=pcre2', + '-Dlibmount=disabled', '-Dselinux=disabled', '-Ddefault_library=static', '-Dforce_fallback_for=pcre2,libffi', glib_internal_configure_args, (meson.current_build_dir() / 'build-subprojects' / 'glib'), (meson.current_source_dir() / 'subprojects' / glib_internal_version) ], @@ -263,9 +259,13 @@ if not glib_dep.found() depends : glib_internal_download_t,) glib_internal_build_t = custom_target('glib-internal-build', command : [ ninja, '-C', meson.current_build_dir() / 'build-subprojects' / 'glib', + 'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a', 'subprojects' / glib_pcre2_internal_version / 'libpcre2-8.a', 'glib' / 'libglib-2.0.a', - 'gmodule' / 'libgmodule-2.0.a'], + 'gmodule' / 'libgmodule-2.0.a', + 'gobject' / 'libgobject-2.0.a', + 'gio' / 'libgio-2.0.a', + ], console : true, output : ['glib-internal-build'], depends : glib_internal_configure_t,) @@ -295,11 +295,32 @@ if not glib_dep.found() ], link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gmodule' / 'libgmodule-2.0.a' ], ) + gobject_dep = declare_dependency(sources : glib_internal_build_t, + compile_args : [ + '-isystem' + (meson.current_build_dir() / 'build-subprojects' / 'glib'), + ], + link_args : [ + meson.current_build_dir() / 'build-subprojects' / 'glib' / 'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a', + meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gobject' / 'libgobject-2.0.a' + ], + ) + gio_dep = declare_dependency(sources : glib_internal_build_t, + dependencies : cc.find_library('z'), + compile_args : [ + '-isystem' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'gio'), + '-isystem' + (meson.current_build_dir() / 'build-subprojects' / 'glib'), + ], + link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gio' / 'libgio-2.0.a' ], + ) else gmodule_dep = dependency('gmodule-2.0', static : want_static_dependency, include_type : 'system') + gobject_dep = dependency('gobject-2.0', static : want_static_dependency, include_type : 'system') + gio_dep = dependency('gio-2.0', static : want_static_dependency, include_type : 'system') endif dep += glib_dep dep += gmodule_dep +dep += gobject_dep +dep += gio_dep if glib_internal and want_static_dependency and want_fuzzer openssl_proj = subproject('openssl', default_options : ['default_library=static', 'asm=disabled']) diff --git a/src/common.h b/src/common.h index e514f279..06b63a15 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 56 +#define IRSSI_ABI_VERSION 57 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 @@ -38,6 +38,7 @@ #include #include +#include typedef guint64 uoff_t; #define PRIuUOFF_T G_GUINT64_FORMAT diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c index 10da0d2c..9e2b80e8 100644 --- a/src/core/chat-commands.c +++ b/src/core/chat-commands.c @@ -101,10 +101,11 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, host = g_hash_table_lookup(optlist, "host"); if (host != NULL && *host != '\0') { - IPADDR ip4, ip6; - - if (net_gethostbyname(host, &ip4, &ip6) == 0) - server_connect_own_ip_save(conn, &ip4, &ip6); + IPADDR ip4 = { 0 }; + IPADDR ip6 = { 0 }; + if (net_gethostbyname_first_ips(host, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, &ip4, + &ip6) == 0) + server_connect_own_ip_save(conn, &ip4, &ip6); } cmd_params_free(free_arg); diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 643884ee..494d9894 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -22,86 +22,54 @@ #include -#include +#include #include -/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is - written to pipe when found PID of the resolver child is returned */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup) -{ - RESOLVED_IP_REC rec; - const char *errorstr; - int pid; +typedef struct { + NetGethostbynameContinuationFunc cont; + void *cont_data; +} NET_GETHOSTBYNAME_CALLBACK_DATA; - (void) reverse_lookup; /* Kept for API backward compatibility */ +static void net_gethostbyname_callback(GResolver *resolver, GAsyncResult *result, + NET_GETHOSTBYNAME_CALLBACK_DATA *data) +{ + /* GList */ + GList *ailist; + GError *error; + RESOLVED_IP_REC *iprec; + + error = NULL; + ailist = g_resolver_lookup_by_name_with_flags_finish(resolver, result, &error); + iprec = g_new0(RESOLVED_IP_REC, 1); + if (error != NULL) { + iprec->error = error; + } else { + iprec->ailist = ailist; + } + g_object_unref(resolver); + resolved_ip_ref(iprec); + + data->cont(iprec, data->cont_data); + g_free(data); +} + +/* nonblocking gethostbyname() */ +GCancellable *net_gethostbyname_nonblock(const char *addr, GResolverNameLookupFlags flags, + NetGethostbynameContinuationFunc cont, void *cont_data) +{ + GResolver *resolver; + GCancellable *cancellable; + NET_GETHOSTBYNAME_CALLBACK_DATA *data; g_return_val_if_fail(addr != NULL, FALSE); - pid = fork(); - if (pid > 0) { - /* parent */ - pidwait_add(pid); - return pid; - } - - if (pid != 0) { - /* failed! */ - g_warning("net_connect_thread(): fork() failed! " - "Using blocking resolving"); - } - - /* child */ - srand(time(NULL)); - - memset(&rec, 0, sizeof(rec)); - rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6); - if (rec.error == 0) { - errorstr = NULL; - } else { - errorstr = net_gethosterror(rec.error); - rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; - } - - i_io_channel_write_block(pipe, &rec, sizeof(rec)); - if (rec.errlen != 0) - i_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); - - if (pid == 0) - _exit(99); - - /* we used blocking lookup */ - return 0; -} - -/* get the resolved IP address */ -int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) -{ - rec->error = -1; - rec->errorstr = NULL; - - fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); - - /* get ip+error */ - if (i_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) { - rec->errorstr = g_strdup_printf("Host name lookup: %s", - g_strerror(errno)); - return -1; - } - - if (rec->error) { - /* read error string, if we can't read everything for some - reason, just ignore it. */ - rec->errorstr = g_malloc0(rec->errlen+1); - i_io_channel_read_block(pipe, rec->errorstr, rec->errlen); - } - - return 0; -} - -/* Kill the resolver child */ -void net_disconnect_nonblock(int pid) -{ - g_return_if_fail(pid > 0); - - kill(pid, SIGKILL); + resolver = g_resolver_get_default(); + cancellable = g_cancellable_new(); + data = g_new0(NET_GETHOSTBYNAME_CALLBACK_DATA, 1); + data->cont = cont; + data->cont_data = cont_data; + g_resolver_lookup_by_name_with_flags_async(resolver, addr, flags, cancellable, + (GAsyncReadyCallback) net_gethostbyname_callback, + data); + return cancellable; } diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index c93dd9e3..c4cb7824 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -3,20 +3,10 @@ #include -typedef struct { - IPADDR ip4, ip6; /* resolved ip addresses */ - int error; /* error, 0 = no error, -1 = error: */ - int errlen; /* error text length */ - char *errorstr; /* error string - dynamically allocated, you'll - need to free() it yourself unless it's NULL */ -} RESOLVED_IP_REC; +typedef void (*NetGethostbynameContinuationFunc)(RESOLVED_IP_REC *, void *); -/* nonblocking gethostbyname(), PID of the resolver child is returned. */ -int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup); -/* get the resolved IP address. returns -1 if some error occurred with read() */ -int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec); - -/* Kill the resolver child */ -void net_disconnect_nonblock(int pid); +/* nonblocking gethostbyname(), Cancellable of the resolver child is returned. */ +GCancellable *net_gethostbyname_nonblock(const char *addr, GResolverNameLookupFlags flags, + NetGethostbynameContinuationFunc cont, void *cont_data); #endif diff --git a/src/core/network.c b/src/core/network.c index fa70d62a..c763a7c6 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -81,27 +81,6 @@ int i_io_channel_read_block(GIOChannel *channel, void *data, int len) return received < len ? -1 : 0; } -IPADDR ip4_any = { - AF_INET, -#if defined(IN6ADDR_ANY_INIT) - IN6ADDR_ANY_INIT -#else - { INADDR_ANY } -#endif -}; - -int net_ip_compare(IPADDR *ip1, IPADDR *ip2) -{ - if (ip1->family != ip2->family) - return 0; - - if (ip1->family == AF_INET6) - return memcmp(&ip1->ip, &ip2->ip, sizeof(ip1->ip)) == 0; - - return memcmp(&ip1->ip, &ip2->ip, 4) == 0; -} - - static void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) { if (ip == NULL) { @@ -392,95 +371,87 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port) return 0; } -/* Get IP addresses for host, both IPv4 and IPv6 if possible. - If ip->family is 0, the address wasn't found. - Returns 0 = ok, others = error code for net_gethosterror() */ -int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) +void resolved_ip_ref(RESOLVED_IP_REC *iprec) { - union sockaddr_union *so; - struct addrinfo hints, *ai, *ailist; - int ret, count_v4, count_v6, use_v4, use_v6; + iprec->refcount++; +} + +int resolved_ip_unref(RESOLVED_IP_REC *iprec) +{ + if (--iprec->refcount > 0) { + return TRUE; + } + + g_resolver_free_addresses(iprec->ailist); + if (iprec->error != NULL) { + g_error_free(iprec->error); + } + g_free(iprec); + + return FALSE; +} + +/* Get IP addresses for host, both IPv4 and IPv6 if possible. */ +static RESOLVED_IP_REC *net_gethostbyname(const char *addr, GResolverNameLookupFlags flags) +{ + /* GList */ + GList *ailist; + GError *error; + GResolver *resolver; + RESOLVED_IP_REC *iprec; #ifdef HAVE_CAPSICUM if (capsicum_enabled()) - return (capsicum_net_gethostbyname(addr, ip4, ip6)); + return (capsicum_net_gethostbyname(addr, flags)); #endif - g_return_val_if_fail(addr != NULL, -1); + g_return_val_if_fail(addr != NULL, NULL); - memset(ip4, 0, sizeof(IPADDR)); - memset(ip6, 0, sizeof(IPADDR)); - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG; - - /* save error to host_error for later use */ - ret = getaddrinfo(addr, NULL, &hints, &ailist); - if (ret != 0) - return ret; - - /* count IPs */ - count_v4 = count_v6 = 0; - for (ai = ailist; ai != NULL; ai = ai->ai_next) { - if (ai->ai_family == AF_INET) - count_v4++; - else if (ai->ai_family == AF_INET6) - count_v6++; + error = NULL; + resolver = g_resolver_get_default(); + ailist = g_resolver_lookup_by_name_with_flags(resolver, addr, flags, NULL, &error); + iprec = g_new0(RESOLVED_IP_REC, 1); + if (error != NULL) { + iprec->error = error; + } else { + iprec->ailist = ailist; } + g_object_unref(resolver); + resolved_ip_ref(iprec); - if (count_v4 == 0 && count_v6 == 0) - return EAI_NONAME; /* shouldn't happen? */ - - /* if there are multiple addresses, return random one */ - use_v4 = count_v4 <= 1 ? 0 : rand() % count_v4; - use_v6 = count_v6 <= 1 ? 0 : rand() % count_v6; - - count_v4 = count_v6 = 0; - for (ai = ailist; ai != NULL; ai = ai->ai_next) { - so = (union sockaddr_union *) ai->ai_addr; - - if (ai->ai_family == AF_INET) { - if (use_v4 == count_v4) - sin_get_ip(so, ip4); - count_v4++; - } else if (ai->ai_family == AF_INET6) { - if (use_v6 == count_v6) - sin_get_ip(so, ip6); - count_v6++; - } - } - freeaddrinfo(ailist); - return 0; + return iprec; } -/* Get name for host, *name should be g_free()'d unless it's NULL. - Return values are the same as with net_gethostbyname() */ -int net_gethostbyaddr(IPADDR *ip, char **name) +int net_gethostbyname_first_ips(const char *addr, GResolverNameLookupFlags flags, IPADDR *ip4, + IPADDR *ip6) { - union sockaddr_union so; - int host_error; - char hostname[NI_MAXHOST]; + RESOLVED_IP_REC *iprec; - g_return_val_if_fail(ip != NULL, -1); - g_return_val_if_fail(name != NULL, -1); + iprec = net_gethostbyname(addr, flags); + if (iprec->error == NULL) { + GList *curr; - *name = NULL; + for (curr = iprec->ailist; curr->next; curr = curr->next) { + unsigned short family; + GInetAddress *addr; - memset(&so, 0, sizeof(so)); - sin_set_ip(&so, ip); + addr = curr->data; + family = g_inet_address_get_family(addr); + if (ip4->family == 0 && family == AF_INET) { + ip4->family = AF_INET; + memcpy(&ip4->ip, g_inet_address_to_bytes(addr), sizeof(ip4->ip)); + } else if (ip6->family == 0 && family == AF_INET6) { + ip6->family = AF_INET6; + memcpy(&ip6->ip, g_inet_address_to_bytes(addr), sizeof(ip6->ip)); + } + } - /* save error to host_error for later use */ - host_error = getnameinfo((struct sockaddr *)&so, sizeof(so), - hostname, sizeof(hostname), - NULL, 0, - NI_NAMEREQD); - if (host_error != 0) - return host_error; - - *name = g_strdup(hostname); - - return 0; + resolved_ip_unref(iprec); + return 0; + } else { + resolved_ip_unref(iprec); + return -1; + } } int net_ip2host(IPADDR *ip, char *host) @@ -519,29 +490,6 @@ int net_geterror(GIOChannel *handle) return data; } -/* get error of net_gethostname() */ -const char *net_gethosterror(int error) -{ - g_return_val_if_fail(error != 0, NULL); - - if (error == EAI_SYSTEM) { - return strerror(errno); - } else { - return gai_strerror(error); - } -} - -/* return TRUE if host lookup failed because it didn't exist (ie. not - some error with name server) */ -int net_hosterror_notfound(int error) -{ -#ifdef EAI_NODATA /* NODATA is deprecated */ - return error != 1 && (error == EAI_NONAME || error == EAI_NODATA); -#else - return error != 1 && (error == EAI_NONAME); -#endif -} - /* Get name of TCP service */ char *net_getservbyport(int port) { diff --git a/src/core/network.h b/src/core/network.h index 5cd85ccc..647cd8c7 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -6,6 +6,7 @@ #include #include #include +#include #ifndef AF_INET6 # ifdef PF_INET6 @@ -20,6 +21,13 @@ struct _IPADDR { struct in6_addr ip; }; +typedef struct { + int refcount; + /* GList */ + GList *ailist; /* needs to be freed */ + GError *error; /* needs to be freed */ +} RESOLVED_IP_REC; + /* maxmimum string length of IP address */ #define MAX_IP_LEN INET6_ADDRSTRLEN @@ -29,9 +37,7 @@ extern IPADDR ip4_any; GIOChannel *i_io_channel_new(int handle); -/* Returns 1 if IPADDRs are the same. */ -/* Deprecated since it is unused. It will be deleted in a later release. */ -int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED; +/* OTR */ int i_io_channel_write_block(GIOChannel *channel, void *data, int len); int i_io_channel_read_block(GIOChannel *channel, void *data, int len); @@ -60,18 +66,9 @@ int net_receive(GIOChannel *handle, char *buf, int len); /* Transmit data, return number of bytes sent, -1 = error */ int net_transmit(GIOChannel *handle, const char *data, int len); -/* Get IP addresses for host, both IPv4 and IPv6 if possible. - If ip->family is 0, the address wasn't found. - Returns 0 = ok, others = error code for net_gethosterror() */ -int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6); -/* Get name for host, *name should be g_free()'d unless it's NULL. - Return values are the same as with net_gethostbyname() */ -int net_gethostbyaddr(IPADDR *ip, char **name); -/* get error of net_gethostname() */ -const char *net_gethosterror(int error); -/* return TRUE if host lookup failed because it didn't exist (ie. not - some error with name server) */ -int net_hosterror_notfound(int error); +/* Get the first IP address for host, both IPv4 and IPv6 if possible. */ +int net_gethostbyname_first_ips(const char *addr, GResolverNameLookupFlags flags, IPADDR *ip4, + IPADDR *ip6); /* Get socket address/port */ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port); @@ -90,4 +87,7 @@ char *net_getservbyport(int port); int is_ipv4_address(const char *host); int is_ipv6_address(const char *host); +void resolved_ip_ref(RESOLVED_IP_REC *iprec); +int resolved_ip_unref(RESOLVED_IP_REC *iprec); + #endif diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h index 16513109..de1f06df 100644 --- a/src/core/server-connect-rec.h +++ b/src/core/server-connect-rec.h @@ -45,6 +45,8 @@ unsigned int unix_socket:1; /* Connect using named unix socket */ unsigned int use_tls:1; /* this connection uses TLS */ unsigned int tls_verify:1; unsigned int no_connect:1; /* don't connect() at all, it's done by plugin */ -unsigned short last_failed_family; /* #641: if we failed to connect to ipv6, try ipv4 and vice versa */ +int last_connected; +int last_failed; +RESOLVED_IP_REC *resolved_host; char *channels; char *away_reason; diff --git a/src/core/server-rec.h b/src/core/server-rec.h index 6c7c63e3..e43245a7 100644 --- a/src/core/server-rec.h +++ b/src/core/server-rec.h @@ -21,10 +21,8 @@ unsigned int no_reconnect:1; /* Don't reconnect to server */ NET_SENDBUF_REC *handle; int readtag; /* input tag */ -/* for net_gethostbyname_return() */ -GIOChannel *connect_pipe[2]; +GCancellable *connect_cancellable; int connect_tag; -int connect_pid; RAWLOG_REC *rawlog; GHashTable *module_data; diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c index a9d9422b..64af6287 100644 --- a/src/core/servers-reconnect.c +++ b/src/core/servers-reconnect.c @@ -120,6 +120,10 @@ static int server_reconnect_timeout(void) if (server->connect_tag != -1) { g_source_remove(server->connect_tag); server->connect_tag = -1; + } else if (server->connect_cancellable != NULL) { + g_cancellable_cancel(server->connect_cancellable); + g_object_unref(server->connect_cancellable); + server->connect_cancellable = NULL; } server->connection_lost = TRUE; server_connect_failed(server, "Timeout"); @@ -168,7 +172,8 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) server_connect_ref(dest); dest->type = module_get_uniq_id("SERVER CONNECT", 0); dest->reconnection = src->reconnection; - dest->last_failed_family = src->last_failed_family; + dest->last_connected = src->last_connected; + dest->last_failed = src->last_failed; dest->proxy = g_strdup(src->proxy); dest->proxy_port = src->proxy_port; dest->proxy_string = g_strdup(src->proxy_string); @@ -207,6 +212,10 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info) dest->own_ip6 = g_new(IPADDR, 1); memcpy(dest->own_ip6, src->own_ip6, sizeof(IPADDR)); } + dest->resolved_host = src->resolved_host; + if (dest->resolved_host != NULL) { + resolved_ip_ref(dest->resolved_host); + } dest->channels = g_strdup(src->channels); dest->away_reason = g_strdup(src->away_reason); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index ff3d6584..97206328 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -58,7 +58,8 @@ static void save_ips(IPADDR *ip4, IPADDR *ip6, static void get_source_host_ip(void) { const char *hostname; - IPADDR ip4, ip6; + IPADDR ip4 = { 0 }; + IPADDR ip6 = { 0 }; if (source_host_ok) return; @@ -66,7 +67,8 @@ static void get_source_host_ip(void) /* FIXME: This will block! */ hostname = settings_get_str("hostname"); source_host_ok = *hostname != '\0' && - net_gethostbyname(hostname, &ip4, &ip6) == 0; + net_gethostbyname_first_ips(hostname, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, + &ip4, &ip6) == 0; if (source_host_ok) save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6); @@ -79,12 +81,14 @@ static void get_source_host_ip(void) static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host, IPADDR **own_ip4, IPADDR **own_ip6) { - IPADDR ip4, ip6; + IPADDR ip4 = { 0 }; + IPADDR ip6 = { 0 }; if (*own_ip4 == NULL && *own_ip6 == NULL) { /* resolve the IP */ - if (net_gethostbyname(own_host, &ip4, &ip6) == 0) - save_ips(&ip4, &ip6, own_ip4, own_ip6); + if (net_gethostbyname_first_ips(own_host, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, + &ip4, &ip6) == 0) + save_ips(&ip4, &ip6, own_ip4, own_ip6); } server_connect_own_ip_save(conn, *own_ip4, *own_ip6); diff --git a/src/core/servers.c b/src/core/servers.c index 811081e8..e62f09ec 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -51,20 +51,16 @@ void server_connect_failed(SERVER_REC *server, const char *msg) g_source_remove(server->connect_tag); server->connect_tag = -1; } + if (server->connect_cancellable != NULL) { + g_cancellable_cancel(server->connect_cancellable); + g_object_unref(server->connect_cancellable); + server->connect_cancellable = NULL; + } if (server->handle != NULL) { net_sendbuffer_destroy(server->handle, TRUE); server->handle = NULL; } - if (server->connect_pipe[0] != NULL) { - g_io_channel_shutdown(server->connect_pipe[0], TRUE, NULL); - g_io_channel_unref(server->connect_pipe[0]); - g_io_channel_shutdown(server->connect_pipe[1], TRUE, NULL); - g_io_channel_unref(server->connect_pipe[1]); - server->connect_pipe[0] = NULL; - server->connect_pipe[1] = NULL; - } - server_unref(server); } @@ -156,7 +152,7 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle) error = net_geterror(handle); if (error != 0) { server->connection_lost = TRUE; - server->connrec->last_failed_family = server->connrec->chosen_family; + server->connrec->last_failed = server->connrec->last_connected; server_connect_failed(server, g_strerror(error)); return; } @@ -177,7 +173,7 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han error = irssi_ssl_handshake(handle); if (error == -1) { server->connection_lost = TRUE; - server->connrec->last_failed_family = server->connrec->chosen_family; + server->connrec->last_failed = server->connrec->last_connected; server_connect_failed(server, NULL); return; } @@ -259,12 +255,12 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, server->connection_lost = TRUE; if (ip != NULL) { - server->connrec->last_failed_family = ip->family; + server->connrec->last_failed = server->connrec->last_connected; } server_connect_failed(server, errmsg2 ? errmsg2 : errmsg); g_free(errmsg2); } else { - server->connrec->last_failed_family = 0; + server->connrec->last_failed = 0; if (!server->connrec->use_tls) server->handle = net_sendbuffer_create(handle, 0); if (server->connrec->use_tls) @@ -276,48 +272,47 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip, } } -static void server_connect_callback_readpipe(SERVER_REC *server) +static int server_start_connect_resolve(SERVER_REC *server); + +static void server_connect_use_resolved(SERVER_REC *server) { - RESOLVED_IP_REC iprec; - IPADDR *ip; + IPADDR *ip; const char *errormsg; + RESOLVED_IP_REC *iprec = server->connrec->resolved_host; - g_source_remove(server->connect_tag); - server->connect_tag = -1; - - net_gethostbyname_return(server->connect_pipe[0], &iprec); - - g_io_channel_shutdown(server->connect_pipe[0], TRUE, NULL); - g_io_channel_unref(server->connect_pipe[0]); - g_io_channel_shutdown(server->connect_pipe[1], TRUE, NULL); - g_io_channel_unref(server->connect_pipe[1]); - - server->connect_pipe[0] = NULL; - server->connect_pipe[1] = NULL; - - /* figure out if we should use IPv4 or v6 address */ - if (iprec.error != 0) { - /* error */ + if (iprec->error != NULL) { + /* error */ ip = NULL; - } else if (server->connrec->family == AF_INET) { - /* force IPv4 connection */ - ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4; - } else if (server->connrec->family == AF_INET6) { - /* force IPv6 connection */ - ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6; } else { - /* pick the one that was found. if both were found: - 1. disprefer the last one that failed - 2. prefer ipv4 over ipv6 unless resolve_prefer_ipv6 is set - */ - if (iprec.ip4.family == 0 || - (iprec.ip6.family != 0 && - (server->connrec->last_failed_family == AF_INET || - (settings_get_bool("resolve_prefer_ipv6") && - server->connrec->last_failed_family != AF_INET6)))) { - ip = &iprec.ip6; + GList *curr; + int i; + + curr = iprec->ailist; + i = 0; + while (i < server->connrec->last_failed) { + if (curr != NULL) { + curr = curr->next; + i++; + } + /* curr is different now */ + if (curr == NULL) { + resolved_ip_unref(server->connrec->resolved_host); + server->connrec->resolved_host = NULL; + server->connrec->last_failed = 0; + /* retry resolve */ + server_start_connect_resolve(server); + return; + } + } + if (curr != NULL) { + GInetAddress *addr; + addr = curr->data; + server->connrec->last_connected = i + 1; + ip = g_new0(IPADDR, 1); + ip->family = g_inet_address_get_family(addr); + memcpy(&ip->ip, g_inet_address_to_bytes(addr), sizeof(ip->ip)); } else { - ip = &iprec.ip4; + ip = NULL; } } @@ -326,28 +321,63 @@ static void server_connect_callback_readpipe(SERVER_REC *server) server_real_connect(server, ip, NULL); errormsg = NULL; } else { - if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) { + if (iprec->error->code == G_RESOLVER_ERROR_NOT_FOUND) { /* IP wasn't found for the host, don't try to reconnect back to this server */ server->dns_error = TRUE; } - if (iprec.error == 0) { - /* forced IPv4 or IPv6 address but it wasn't found */ - errormsg = server->connrec->family == AF_INET ? - "IPv4 address not found for host" : - "IPv6 address not found for host"; - } else { - /* gethostbyname() failed */ - errormsg = iprec.errorstr != NULL ? iprec.errorstr : - "Host lookup failed"; - } + errormsg = iprec->error->message; + if (errormsg == NULL) + errormsg = "Host lookup failed"; server->connection_lost = TRUE; + /* clear the error in resolved_host */ + server->connrec->resolved_host = NULL; server_connect_failed(server, errormsg); - } - g_free(iprec.errorstr); + resolved_ip_unref(iprec); + } +} + +static void server_connect_callback_resolved(RESOLVED_IP_REC *iprec, SERVER_REC *server) +{ + server->connect_cancellable = NULL; + + if (server->connrec->resolved_host != NULL) { + resolved_ip_unref(server->connrec->resolved_host); + } + server->connrec->resolved_host = iprec; + if (iprec->error == NULL && iprec->ailist == NULL) { + server->connection_lost = TRUE; + server->dns_error = TRUE; + server_connect_failed(server, "Host lookup failed"); + } else { + server_connect_use_resolved(server); + } +} + +static int server_start_connect_resolve(SERVER_REC *server) +{ + const char *connect_address; + GResolverNameLookupFlags net_gethostbyname_flags; + + connect_address = + server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->address; + net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT; + if (server->connrec->family == AF_INET) { + net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY; + } else if (server->connrec->family == AF_INET6) { + net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY; + } + if (server->connrec->resolved_host == NULL) { + server->connect_cancellable = net_gethostbyname_nonblock( + connect_address, net_gethostbyname_flags, + (NetGethostbynameContinuationFunc) server_connect_callback_resolved, server); + return FALSE; + } else { + return TRUE; + } } SERVER_REC *server_connect(SERVER_CONNECT_REC *conn) @@ -399,9 +429,6 @@ void server_connect_init(SERVER_REC *server) /* starts connecting to server */ int server_start_connect(SERVER_REC *server) { - const char *connect_address; - int fd[2]; - g_return_val_if_fail(server != NULL, FALSE); if (!server->connrec->unix_socket && server->connrec->port <= 0) return FALSE; @@ -419,30 +446,17 @@ int server_start_connect(SERVER_REC *server) /* connect with unix socket */ server_real_connect(server, NULL, server->connrec->address); } else { + int already_resolved; /* resolve host name */ - if (pipe(fd) != 0) { - g_warning("server_connect(): pipe() failed."); - g_free(server->tag); - g_free(server->nick); - return FALSE; - } - - server->connect_pipe[0] = i_io_channel_new(fd[0]); - server->connect_pipe[1] = i_io_channel_new(fd[1]); - - connect_address = server->connrec->proxy != NULL ? - server->connrec->proxy : server->connrec->address; - server->connect_pid = - net_gethostbyname_nonblock(connect_address, - server->connect_pipe[1], 0); - server->connect_tag = - i_input_add(server->connect_pipe[0], I_INPUT_READ, - (GInputFunction) server_connect_callback_readpipe, server); + already_resolved = server_start_connect_resolve(server); server->connect_time = time(NULL); lookup_servers = g_slist_append(lookup_servers, server); signal_emit("server looking", 1, server); + if (already_resolved) { + server_connect_use_resolved(server); + } } return TRUE; } @@ -481,8 +495,9 @@ void server_disconnect(SERVER_REC *server) if (server->connect_tag != -1) { /* still connecting to server.. */ - if (server->connect_pid != -1) - net_disconnect_nonblock(server->connect_pid); + server_connect_failed(server, NULL); + return; + } else if (server->connect_cancellable != NULL) { server_connect_failed(server, NULL); return; } @@ -649,6 +664,10 @@ void server_connect_unref(SERVER_CONNECT_REC *conn) g_free_not_null(conn->own_ip4); g_free_not_null(conn->own_ip6); + if (conn->resolved_host != NULL) { + resolved_ip_unref(conn->resolved_host); + } + g_free_not_null(conn->password); g_free_not_null(conn->nick); g_free_not_null(conn->username); @@ -769,7 +788,6 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto) void servers_init(void) { - settings_add_bool("server", "resolve_prefer_ipv6", TRUE); lookup_servers = servers = NULL; signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit); diff --git a/src/core/servers.h b/src/core/servers.h index d52603eb..5e5a7fd2 100644 --- a/src/core/servers.h +++ b/src/core/servers.h @@ -2,6 +2,7 @@ #define IRSSI_CORE_SERVERS_H #include +#include /* Returns SERVER_REC if it's server, NULL if it isn't. */ #define SERVER(server) \ diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index 9724354f..06240d5c 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -166,7 +166,7 @@ void fe_common_core_init(void) settings_add_bool("lookandfeel", "use_msgs_window", FALSE); g_get_charset(&str); settings_add_str("lookandfeel", "term_charset", str); - settings_add_str("lookandfeel", "glib_log_domains", "all"); + settings_add_str("lookandfeel", "glib_log_domains", "all -glib-gio:debug"); themes_init(); theme_register(fecommon_core_formats); @@ -258,13 +258,19 @@ void fe_common_core_deinit(void) g_log_set_default_handler(logger_old, NULL); } -static gboolean glib_domain_wanted(const char *domain) +static gboolean glib_domain_wanted(const char *domain, const char *level) { const char *domains; char *c, *cur; int len = 0; int print_it = 0; /* -1 for exclude, 0 for undecided, 1 for include */ int incl; + char *domainlevel, *alllevel, *starlevel, *domainstar; + + domainlevel = g_strdup_printf("%s:%s", domain, level); + alllevel = g_strdup_printf("all:%s", level); + starlevel = g_strdup_printf("*:%s", level); + domainstar = g_strdup_printf("%s:*", domain); /* Go through each item in glib_log_domains setting to determine whether * or not we want to print message from this domain */ @@ -287,8 +293,10 @@ static gboolean glib_domain_wanted(const char *domain) } /* If we got a valid item, process it */ - if (len > 0 && (!strncmp(domain, c, len) || !strncasecmp("all", c, len) || - !strncmp("*", c, len))) + if (len > 0 && (!strncasecmp(domain, c, len) || !strncasecmp("all", c, len) || + !strncmp("*", c, len) || !strncasecmp(domainstar, c, len) || + !strncasecmp(domainlevel, c, len) || + !strncasecmp(alllevel, c, len) || !strncasecmp(starlevel, c, len))) print_it = incl; /* Go past any spaces towards the next item */ @@ -300,6 +308,11 @@ static gboolean glib_domain_wanted(const char *domain) len = 0; } while (*c != '\0' && print_it != -1); + g_free(domainlevel); + g_free(alllevel); + g_free(starlevel); + g_free(domainstar); + return (print_it == 1); } @@ -333,7 +346,7 @@ static void i_log_func(const char *log_domain, GLogLevelFlags log_level, const c domain = (log_domain ? log_domain : "default"); /* Only print the message if we decided to */ - if (!glib_domain_wanted(domain)) + if (!glib_domain_wanted(domain, reason)) return; if (windows == NULL) diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index 19aba87d..1fed639e 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -711,16 +711,19 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path) /* bind to specific host/ip? */ my_ip = NULL; if (*settings_get_str("irssiproxy_bind") != '\0') { - if (net_gethostbyname(settings_get_str("irssiproxy_bind"), - &ip4, &ip6) != 0) { + if (net_gethostbyname_first_ips(settings_get_str("irssiproxy_bind"), + G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, &ip4, + &ip6) != 0) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Proxy: can not resolve '%s' - aborting", settings_get_str("irssiproxy_bind")); return; } - my_ip = ip6.family == 0 ? &ip4 : ip4.family == 0 || - settings_get_bool("resolve_prefer_ipv6") ? &ip6 : &ip4; + my_ip = ip6.family == 0 ? &ip4 : + ip4.family == 0 || settings_get_bool("irssiproxy_prefer_ipv6") ? + &ip6 : + &ip4; } handle = net_listen(my_ip, &port); } diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c index d32b6009..240df971 100644 --- a/src/irc/proxy/proxy.c +++ b/src/irc/proxy/proxy.c @@ -74,6 +74,7 @@ static void irc_proxy_setup_changed(void) void irc_proxy_init(void) { + settings_add_bool("irssiproxy", "irssiproxy_prefer_ipv6", TRUE); settings_add_str("irssiproxy", "irssiproxy_ports", ""); settings_add_str("irssiproxy", "irssiproxy_password", ""); settings_add_str("irssiproxy", "irssiproxy_bind", ""); From e64ed836a5a62ab1e398bd0ca7b6e7070df82939 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 27 Jul 2025 21:16:06 +0200 Subject: [PATCH 1186/1198] up glib wrap --- meson.build | 2 +- subprojects/glib.wrap | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 4f78600e..c7eed79d 100644 --- a/meson.build +++ b/meson.build @@ -6,7 +6,7 @@ project('irssi', 'c', ############################ ############################ -glib_internal_version = 'glib-2.74.3' # keep this in sync with subprojects/glib.wrap +glib_internal_version = 'glib-2.74.7' # keep this in sync with subprojects/glib.wrap glib_pcre2_internal_version = 'pcre2-10.40' glib_libffi_internal_version = 'libffi' cc = meson.get_compiler('c') diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap index 5e50e9a5..e6c649fc 100644 --- a/subprojects/glib.wrap +++ b/subprojects/glib.wrap @@ -1,6 +1,6 @@ [wrap-file] # make sure to update the glib_internal_version in meson.build -directory = glib-2.74.3 -source_url = https://download.gnome.org/sources/glib/2.74/glib-2.74.3.tar.xz -source_filename = glib-2.74.3.tar.xz -source_hash = e9bc41ecd9690d9bc6a970cc7380119b828e5b6a4b16c393c638b3dc2b87cbcb +directory = glib-2.74.7 +source_url = https://download.gnome.org/sources/glib/2.74/glib-2.74.7.tar.xz +source_filename = glib-2.74.7.tar.xz +source_hash = 196ab86c27127a61b7a70c3ba6af7b97bdc01c07cd3b21abd5e778b955eccb1b From c6d15ee461569ef821ea8b7cff85ddc83da6e42d Mon Sep 17 00:00:00 2001 From: nikolas Date: Thu, 12 Jun 2025 20:53:18 -0400 Subject: [PATCH 1187/1198] Add a few more compile dependencies to INSTALL document --- INSTALL | 3 +++ 1 file changed, 3 insertions(+) diff --git a/INSTALL b/INSTALL index ed5a14a3..ac7c419f 100644 --- a/INSTALL +++ b/INSTALL @@ -9,7 +9,10 @@ To compile Irssi you need: - glib-2.32 or greater - openssl (for ssl support) - perl-5.8 or greater (for building, and optionally Perl scripts) + (n.b a complete perl is needed, including ExtUtils::Embed and xsubpp) - terminfo or ncurses (for text frontend) +- utf8proc (optional, for additional char width calculation) +- libgcrypt (for OTR) For most people, this should work just fine: From 51322d6af121c0394becf96189244428302df7cd Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 13:53:23 +0100 Subject: [PATCH 1188/1198] restore ip4_any --- src/core/network.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/network.c b/src/core/network.c index c763a7c6..8dd5cf9d 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -81,6 +81,14 @@ int i_io_channel_read_block(GIOChannel *channel, void *data, int len) return received < len ? -1 : 0; } +IPADDR ip4_any = { AF_INET, +#if defined(IN6ADDR_ANY_INIT) + IN6ADDR_ANY_INIT +#else + { INADDR_ANY } +#endif +}; + static void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) { if (ip == NULL) { From 2012668beff7a275ad5ddb94d56adcf54b0d77be Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 13:54:57 +0100 Subject: [PATCH 1189/1198] make Irssi::Irc usable without dcc --- src/perl/irc/Dcc.xs | 102 +++++++++++++++++++++++++++++++++++++++ src/perl/irc/Irc.pm | 6 +++ src/perl/irc/Irc.xs | 83 ++----------------------------- src/perl/irc/Irc/Dcc.pm | 26 ++++++++++ src/perl/irc/meson.build | 34 ++++++++++++- 5 files changed, 169 insertions(+), 82 deletions(-) create mode 100644 src/perl/irc/Irc/Dcc.pm diff --git a/src/perl/irc/Dcc.xs b/src/perl/irc/Dcc.xs index c078a1b5..f96f4d33 100644 --- a/src/perl/irc/Dcc.xs +++ b/src/perl/irc/Dcc.xs @@ -1,7 +1,74 @@ #define PERL_NO_GET_CONTEXT #include "module.h" +static int initialized = FALSE; + +static void perl_dcc_fill_hash(HV *hv, DCC_REC *dcc) +{ + (void) hv_store(hv, "type", 4, new_pv(dcc_type2str(dcc->type)), 0); + (void) hv_store(hv, "orig_type", 9, new_pv(dcc_type2str(dcc->orig_type)), 0); + (void) hv_store(hv, "created", 7, newSViv(dcc->created), 0); + + (void) hv_store(hv, "server", 6, iobject_bless(dcc->server), 0); + (void) hv_store(hv, "servertag", 9, new_pv(dcc->servertag), 0); + (void) hv_store(hv, "mynick", 6, new_pv(dcc->mynick), 0); + (void) hv_store(hv, "nick", 4, new_pv(dcc->nick), 0); + + (void) hv_store(hv, "chat", 4, simple_iobject_bless(dcc->chat), 0); + (void) hv_store(hv, "target", 6, new_pv(dcc->target), 0); + (void) hv_store(hv, "arg", 3, new_pv(dcc->arg), 0); + + (void) hv_store(hv, "addr", 4, new_pv(dcc->addrstr), 0); + (void) hv_store(hv, "port", 4, newSViv(dcc->port), 0); + + (void) hv_store(hv, "starttime", 9, newSViv(dcc->starttime), 0); + (void) hv_store(hv, "transfd", 7, newSViv(dcc->transfd), 0); +} + +static void perl_dcc_chat_fill_hash(HV *hv, CHAT_DCC_REC *dcc) +{ + perl_dcc_fill_hash(hv, (DCC_REC *) dcc); + + (void) hv_store(hv, "id", 2, new_pv(dcc->id), 0); + (void) hv_store(hv, "mirc_ctcp", 9, newSViv(dcc->mirc_ctcp), 0); + (void) hv_store(hv, "connection_lost", 15, newSViv(dcc->connection_lost), 0); +} + +static void perl_dcc_file_fill_hash(HV *hv, FILE_DCC_REC *dcc) +{ + perl_dcc_fill_hash(hv, (DCC_REC *) dcc); + + (void) hv_store(hv, "size", 4, newSViv(dcc->size), 0); + (void) hv_store(hv, "skipped", 7, newSViv(dcc->skipped), 0); +} + +static void perl_dcc_get_fill_hash(HV *hv, GET_DCC_REC *dcc) +{ + perl_dcc_file_fill_hash(hv, (FILE_DCC_REC *) dcc); + + (void) hv_store(hv, "get_type", 8, newSViv(dcc->get_type), 0); + (void) hv_store(hv, "file", 4, new_pv(dcc->file), 0); + (void) hv_store(hv, "file_quoted", 11, newSViv(dcc->file_quoted), 0); +} + +static void perl_dcc_send_fill_hash(HV *hv, SEND_DCC_REC *dcc) +{ + perl_dcc_file_fill_hash(hv, (FILE_DCC_REC *) dcc); + + (void) hv_store(hv, "file_quoted", 11, newSViv(dcc->file_quoted), 0); + (void) hv_store(hv, "waitforend", 10, newSViv(dcc->waitforend), 0); + (void) hv_store(hv, "gotalldata", 10, newSViv(dcc->gotalldata), 0); +} + +static PLAIN_OBJECT_INIT_REC irc_dcc_plains[] = { { "Irssi::Irc::Dcc", + (PERL_OBJECT_FUNC) perl_dcc_fill_hash }, + + { NULL, NULL } }; + +/********************************/ + MODULE = Irssi::Irc::Dcc PACKAGE = Irssi::Irc + PROTOTYPES: ENABLE void @@ -101,3 +168,38 @@ MODULE = Irssi::Irc::Dcc PACKAGE = Irssi::Windowitem PREFIX = item_ Irssi::Irc::Dcc::Chat item_get_dcc(item) Irssi::Windowitem item + +#******************************* +MODULE = Irssi::Irc::Dcc PACKAGE = Irssi::Irc::Dcc +#******************************* + +void +init() +CODE: + if (initialized) + return; + perl_api_version_check("Irssi::Irc::Dcc"); + initialized = TRUE; + + irssi_add_object(module_get_uniq_id_str("DCC", "CHAT"), 0, "Irssi::Irc::Dcc::Chat", + (PERL_OBJECT_FUNC) perl_dcc_chat_fill_hash); + irssi_add_object(module_get_uniq_id_str("DCC", "GET"), 0, "Irssi::Irc::Dcc::Get", + (PERL_OBJECT_FUNC) perl_dcc_get_fill_hash); + irssi_add_object(module_get_uniq_id_str("DCC", "SEND"), 0, "Irssi::Irc::Dcc::Send", + (PERL_OBJECT_FUNC) perl_dcc_send_fill_hash); + irssi_add_object(module_get_uniq_id_str("DCC", "SERVER"), 0, "Irssi::Irc::Dcc::Server", + (PERL_OBJECT_FUNC) perl_dcc_send_fill_hash); + irssi_add_plains(irc_dcc_plains); + perl_eval_pv("@Irssi::Irc::Dcc::Chat::ISA = qw(Irssi::Irc::Dcc);\n" + "@Irssi::Irc::Dcc::Get::ISA = qw(Irssi::Irc::Dcc);\n" + "@Irssi::Irc::Dcc::Send::ISA = qw(Irssi::Irc::Dcc);\n" + "@Irssi::Irc::Dcc::Server::ISA = qw(Irssi::Irc::Dcc);\n", + TRUE); + +void +deinit() +CODE: + initialized = FALSE; + +BOOT: + /* nothing * / diff --git a/src/perl/irc/Irc.pm b/src/perl/irc/Irc.pm index 1d95462d..b5ace267 100644 --- a/src/perl/irc/Irc.pm +++ b/src/perl/irc/Irc.pm @@ -22,5 +22,11 @@ Irssi::Irc::init(); Irssi::EXPORT_ALL(); +eval { + local $@; + require Irssi::Irc::Dcc; + 1; +}; + 1; diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs index 33be93d5..80033fba 100644 --- a/src/perl/irc/Irc.xs +++ b/src/perl/irc/Irc.xs @@ -69,63 +69,6 @@ static void perl_ban_fill_hash(HV *hv, BAN_REC *ban) (void) hv_store(hv, "time", 4, newSViv(ban->time), 0); } -static void perl_dcc_fill_hash(HV *hv, DCC_REC *dcc) -{ - (void) hv_store(hv, "type", 4, new_pv(dcc_type2str(dcc->type)), 0); - (void) hv_store(hv, "orig_type", 9, new_pv(dcc_type2str(dcc->orig_type)), 0); - (void) hv_store(hv, "created", 7, newSViv(dcc->created), 0); - - (void) hv_store(hv, "server", 6, iobject_bless(dcc->server), 0); - (void) hv_store(hv, "servertag", 9, new_pv(dcc->servertag), 0); - (void) hv_store(hv, "mynick", 6, new_pv(dcc->mynick), 0); - (void) hv_store(hv, "nick", 4, new_pv(dcc->nick), 0); - - (void) hv_store(hv, "chat", 4, simple_iobject_bless(dcc->chat), 0); - (void) hv_store(hv, "target", 6, new_pv(dcc->target), 0); - (void) hv_store(hv, "arg", 3, new_pv(dcc->arg), 0); - - (void) hv_store(hv, "addr", 4, new_pv(dcc->addrstr), 0); - (void) hv_store(hv, "port", 4, newSViv(dcc->port), 0); - - (void) hv_store(hv, "starttime", 9, newSViv(dcc->starttime), 0); - (void) hv_store(hv, "transfd", 7, newSViv(dcc->transfd), 0); -} - -static void perl_dcc_chat_fill_hash(HV *hv, CHAT_DCC_REC *dcc) -{ - perl_dcc_fill_hash(hv, (DCC_REC *) dcc); - - (void) hv_store(hv, "id", 2, new_pv(dcc->id), 0); - (void) hv_store(hv, "mirc_ctcp", 9, newSViv(dcc->mirc_ctcp), 0); - (void) hv_store(hv, "connection_lost", 15, newSViv(dcc->connection_lost), 0); -} - -static void perl_dcc_file_fill_hash(HV *hv, FILE_DCC_REC *dcc) -{ - perl_dcc_fill_hash(hv, (DCC_REC *) dcc); - - (void) hv_store(hv, "size", 4, newSViv(dcc->size), 0); - (void) hv_store(hv, "skipped", 7, newSViv(dcc->skipped), 0); -} - -static void perl_dcc_get_fill_hash(HV *hv, GET_DCC_REC *dcc) -{ - perl_dcc_file_fill_hash(hv, (FILE_DCC_REC *) dcc); - - (void) hv_store(hv, "get_type", 8, newSViv(dcc->get_type), 0); - (void) hv_store(hv, "file", 4, new_pv(dcc->file), 0); - (void) hv_store(hv, "file_quoted", 11, newSViv(dcc->file_quoted), 0); -} - -static void perl_dcc_send_fill_hash(HV *hv, SEND_DCC_REC *dcc) -{ - perl_dcc_file_fill_hash(hv, (FILE_DCC_REC *) dcc); - - (void) hv_store(hv, "file_quoted", 11, newSViv(dcc->file_quoted), 0); - (void) hv_store(hv, "waitforend", 10, newSViv(dcc->waitforend), 0); - (void) hv_store(hv, "gotalldata", 10, newSViv(dcc->gotalldata), 0); -} - static void perl_netsplit_fill_hash(HV *hv, NETSPLIT_REC *netsplit) { AV *av; @@ -195,7 +138,6 @@ static void perl_client_fill_hash(HV *hv, CLIENT_REC *client) static PLAIN_OBJECT_INIT_REC irc_plains[] = { { "Irssi::Irc::Ban", (PERL_OBJECT_FUNC) perl_ban_fill_hash }, - { "Irssi::Irc::Dcc", (PERL_OBJECT_FUNC) perl_dcc_fill_hash }, { "Irssi::Irc::Netsplit", (PERL_OBJECT_FUNC) perl_netsplit_fill_hash }, { "Irssi::Irc::Netsplitserver", (PERL_OBJECT_FUNC) perl_netsplit_server_fill_hash }, { "Irssi::Irc::Netsplitchannel", (PERL_OBJECT_FUNC) perl_netsplit_channel_fill_hash }, @@ -244,27 +186,9 @@ CODE: irssi_add_object(module_get_uniq_id("SERVER CONNECT", 0), chat_type, "Irssi::Irc::Connect", (PERL_OBJECT_FUNC) perl_irc_connect_fill_hash); - irssi_add_object(module_get_uniq_id("SERVER", 0), - chat_type, "Irssi::Irc::Server", - (PERL_OBJECT_FUNC) perl_irc_server_fill_hash); - irssi_add_object(module_get_uniq_id_str("DCC", "CHAT"), - 0, "Irssi::Irc::Dcc::Chat", - (PERL_OBJECT_FUNC) perl_dcc_chat_fill_hash); - irssi_add_object(module_get_uniq_id_str("DCC", "GET"), - 0, "Irssi::Irc::Dcc::Get", - (PERL_OBJECT_FUNC) perl_dcc_get_fill_hash); - irssi_add_object(module_get_uniq_id_str("DCC", "SEND"), - 0, "Irssi::Irc::Dcc::Send", - (PERL_OBJECT_FUNC) perl_dcc_send_fill_hash); - irssi_add_object(module_get_uniq_id_str("DCC", "SERVER"), - 0, "Irssi::Irc::Dcc::Server", - (PERL_OBJECT_FUNC) perl_dcc_send_fill_hash); - irssi_add_plains(irc_plains); - perl_eval_pv("@Irssi::Irc::Dcc::Chat::ISA = qw(Irssi::Irc::Dcc);\n" - "@Irssi::Irc::Dcc::Get::ISA = qw(Irssi::Irc::Dcc);\n" - "@Irssi::Irc::Dcc::Send::ISA = qw(Irssi::Irc::Dcc);\n" - "@Irssi::Irc::Dcc::Server::ISA = qw(Irssi::Irc::Dcc);\n", - TRUE); + irssi_add_object(module_get_uniq_id("SERVER", 0), chat_type, "Irssi::Irc::Server", + (PERL_OBJECT_FUNC) perl_irc_server_fill_hash); + irssi_add_plains(irc_plains); void deinit() @@ -274,7 +198,6 @@ CODE: BOOT: irssi_boot(Irc__Channel); irssi_boot(Irc__Ctcp); - irssi_boot(Irc__Dcc); irssi_boot(Irc__Modes); irssi_boot(Irc__Netsplit); irssi_boot(Irc__Notifylist); diff --git a/src/perl/irc/Irc/Dcc.pm b/src/perl/irc/Irc/Dcc.pm new file mode 100644 index 00000000..65a30c44 --- /dev/null +++ b/src/perl/irc/Irc/Dcc.pm @@ -0,0 +1,26 @@ +# +# Perl interface to irssi functions. +# + +package Irssi::Irc::Dcc; + +use strict; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); + +$VERSION = "0.9"; + +require Exporter; +require DynaLoader; + +@ISA = qw(Exporter DynaLoader); +@EXPORT = qw(); +@EXPORT_OK = qw(); + +bootstrap Irssi::Irc::Dcc $VERSION if (!Irssi::Core::is_static()); + +Irssi::Irc::Dcc::init(); + +Irssi::EXPORT_ALL(); + +1; + diff --git a/src/perl/irc/meson.build b/src/perl/irc/meson.build index e033c260..af68ce7f 100644 --- a/src/perl/irc/meson.build +++ b/src/perl/irc/meson.build @@ -4,7 +4,6 @@ shared_library('Irc', 'Channel.xs', 'Client.xs', 'Ctcp.xs', - 'Dcc.xs', 'Irc.xs', 'Modes.xs', 'Netsplit.xs', @@ -27,7 +26,7 @@ shared_library('Irc', include_directories : rootinc, implicit_include_directories : true, dependencies : dep + [ perl_dep ], - link_with : dl_cross_perl_core + dl_cross_irc_dcc + dl_cross_irc_notifylist + dl_cross_irc_core + dl_cross_irssi_main, + link_with : dl_cross_perl_core + dl_cross_irc_notifylist + dl_cross_irc_core + dl_cross_irssi_main, override_options : ['b_lundef=false'], ) @@ -37,6 +36,37 @@ install_headers( ), install_dir : perlmoddir / 'Irssi', ) + +shared_library('Dcc', + [ xsubpp.process( + files( + 'Dcc.xs', + ), + extra_args : [ + '-typemap', + '../common/typemap', + ], + ) ] + + files( + 'module.h', + ), + name_prefix : '', + name_suffix : perl_module_suffix, + install : true, + install_dir : perlmoddir / 'auto' / 'Irssi' / 'Irc' / 'Dcc', + include_directories : rootinc, + implicit_include_directories : true, + dependencies : dep + [ perl_dep ], + link_with : dl_cross_perl_core + dl_cross_irc_dcc + dl_cross_irc_core + dl_cross_irssi_main, + override_options : ['b_lundef=false'], +) + +install_headers( + files( + 'Irc/Dcc.pm', + ), + install_dir : perlmoddir / 'Irssi' / 'Irc', +) # 'Makefile.PL.in', # 'typemap', From a54677ce99413e4c5f7ac7e5061ac83f5a4af85d Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 14:08:28 +0100 Subject: [PATCH 1190/1198] up perl api --- 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 0a4d78f6..398eb1c7 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 + IRSSI_ABI_VERSION) +#define IRSSI_PERL_API_VERSION (20160124 + IRSSI_ABI_VERSION) From 45d3013f9e490626f0cf8ba11b1db7569239e0e3 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 14:11:42 +0100 Subject: [PATCH 1191/1198] up abi --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 06b63a15..4e9b5c79 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #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 57 +#define IRSSI_ABI_VERSION 58 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 From e9281b2f1147eb25dd811f4cd2a870eae3c22a62 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 18:05:05 +0100 Subject: [PATCH 1192/1198] add compatibility code for older GResolver --- src/core/net-nonblock.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/core/network.h | 13 +++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index 494d9894..1a06a662 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -26,6 +26,7 @@ #include typedef struct { + GResolverNameLookupFlags flags; NetGethostbynameContinuationFunc cont; void *cont_data; } NET_GETHOSTBYNAME_CALLBACK_DATA; @@ -39,7 +40,39 @@ static void net_gethostbyname_callback(GResolver *resolver, GAsyncResult *result RESOLVED_IP_REC *iprec; error = NULL; +#if GLIB_CHECK_VERSION(2, 59, 0) ailist = g_resolver_lookup_by_name_with_flags_finish(resolver, result, &error); +#else + /* compatibility code for old GLib */ + ailist = g_resolver_lookup_by_name_finish(resolver, result, &error); + if (error == NULL && data->flags) { + GList *ll, *lll; + + for (ll = ailist; ll != NULL; ll = lll) { + GInetAddress *address; + GSocketFamily family; + + address = G_INET_ADDRESS(ll->data); + family = g_inet_address_get_family(address); + lll = ll->next; + + if ((data->flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && + family == G_SOCKET_FAMILY_IPV6) || + (data->flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY && + family == G_SOCKET_FAMILY_IPV4)) { + g_object_unref(address); + ailist = g_list_delete_link(ailist, ll); + } + } + + if (ailist == NULL) { + g_set_error(&error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + data->flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY ? + "IPv4 address not found for host" : + "IPv6 address not found for host"); + } + } +#endif iprec = g_new0(RESOLVED_IP_REC, 1); if (error != NULL) { iprec->error = error; @@ -66,10 +99,17 @@ GCancellable *net_gethostbyname_nonblock(const char *addr, GResolverNameLookupFl resolver = g_resolver_get_default(); cancellable = g_cancellable_new(); data = g_new0(NET_GETHOSTBYNAME_CALLBACK_DATA, 1); + data->flags = flags; data->cont = cont; data->cont_data = cont_data; +#if GLIB_CHECK_VERSION(2, 59, 0) g_resolver_lookup_by_name_with_flags_async(resolver, addr, flags, cancellable, (GAsyncReadyCallback) net_gethostbyname_callback, data); +#else + /* compatibility code for old GLib */ + g_resolver_lookup_by_name_async(resolver, addr, cancellable, + (GAsyncReadyCallback) net_gethostbyname_callback, data); +#endif return cancellable; } diff --git a/src/core/network.h b/src/core/network.h index 647cd8c7..78092375 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -16,6 +16,19 @@ # endif #endif +#if GLIB_CHECK_VERSION(2, 59, 0) +/* nothing */ +#else +/* compatibility code for old GLib */ + +typedef enum { + G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT = 0, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY = 1 << 0, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY = 1 << 1, +} GResolverNameLookupFlags; + +#endif + struct _IPADDR { unsigned short family; struct in6_addr ip; From 00146211d08ddc0ba0e1907f25fd08a0624f0eea Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 18:06:21 +0100 Subject: [PATCH 1193/1198] fix space in end comment --- src/perl/irc/Dcc.xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perl/irc/Dcc.xs b/src/perl/irc/Dcc.xs index f96f4d33..a6d2c473 100644 --- a/src/perl/irc/Dcc.xs +++ b/src/perl/irc/Dcc.xs @@ -202,4 +202,4 @@ CODE: initialized = FALSE; BOOT: - /* nothing * / + /* nothing */ From 0157a4424bce0715b09799af64a86f8e956e6a64 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sat, 24 Jan 2026 20:53:29 +0100 Subject: [PATCH 1194/1198] fix clang-format-xs boot code --- utils/clang-format-xs/clang-format-xs | 29 ++++++++++++++++++++++++--- utils/clang-format-xs/format-xs-1.pl | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/utils/clang-format-xs/clang-format-xs b/utils/clang-format-xs/clang-format-xs index 3216210b..39493c53 100755 --- a/utils/clang-format-xs/clang-format-xs +++ b/utils/clang-format-xs/clang-format-xs @@ -6,14 +6,22 @@ srcdir=$(dirname "$(readlink -f "$0")") test -z "$srcdir" && srcdir=. CLANG_FORMAT=${CLANG_FORMAT:-clang-format} +if [[ "$CLANG_FORMAT" = *-xs\ * ]]; then + CLANG_FORMAT=${CLANG_FORMAT/-xs / } +elif [[ "$CLANG_FORMAT" = *-xs ]]; then + CLANG_FORMAT=${CLANG_FORMAT%-xs} +fi + +clang_format_version=$($CLANG_FORMAT --version 2>/dev/null | perl -ne '/(\d+)/ && print $1 or print 0') + options=() files=() lines=() -inplace=0;xml=0; +inplace=0;xml=0;list_ignored=0; filename=tmp.1.c offsets= off_opts=() -opts=$(getopt -n clang-format-xs -s bash -a -o in -l Werror,assume-filename:,cursor:,dry-run,dump-config,fallback-style:,ferror-limit:,help,length:,lines:,offset:,output-replacement-xmls,sort-includes,style:,verbose,version -- "$@") +opts=$(getopt -n clang-format-xs -s bash -a -o in -l Werror,assume-filename:,cursor:,dry-run,dump-config,fallback-style:,ferror-limit:,help,length:,lines:,offset:,output-replacement-xmls,sort-includes,list-ignored,style:,verbose,version -- "$@") if [ $? -ne 0 ]; then exit 1; fi eval set -- "$opts"; unset opts while :; do @@ -47,6 +55,11 @@ while :; do shift continue ;; + --list-ignored) + list_ignored=1 + shift + continue + ;; -i) inplace=1 shift @@ -75,6 +88,10 @@ fi if [[ $xml = 1 ]]; then options_o=("-output-replacements-xml" "${options[@]}") fi +if [[ $list_ignored = 1 ]]; then + options_o=("-list-ignored" "${options[@]}") +fi + options_o+=("${off_opts[@]}") do_xs() { @@ -92,7 +109,13 @@ do_xs() { rm "$1".1.c } -if [[ ${#files[@]} -eq 0 ]]; then +if [[ $list_ignored = 1 ]]; then + if [[ $clang_format_version -lt 19 ]]; then + : # true + else + $CLANG_FORMAT "${options_o[@]}" -- "${files[@]}" + fi +elif [[ ${#files[@]} -eq 0 ]]; then case "$filename" in *.xs) cat > "$filename".1.xs diff --git a/utils/clang-format-xs/format-xs-1.pl b/utils/clang-format-xs/format-xs-1.pl index 1d15316e..fab1e90a 100644 --- a/utils/clang-format-xs/format-xs-1.pl +++ b/utils/clang-format-xs/format-xs-1.pl @@ -30,7 +30,7 @@ while (<>) { $prot = 2; $in_code = 0; } - elsif (/^((PP)?CODE|PREINIT):/) { + elsif (/^((PP)?CODE|PREINIT|BOOT):/) { $prot = 1; $in_code = 3; } From 88afc78aacc3e89b49745cac6c61be662fe9cefa Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 25 Jan 2026 00:25:14 +0100 Subject: [PATCH 1195/1198] GResolver fixes fix issues brought up by @horgh in #1580 --- src/core/network.c | 44 ++++++++++++++++++++++++++++++++++------ src/core/servers-setup.c | 8 ++++---- src/core/servers.c | 8 +++++++- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/core/network.c b/src/core/network.c index 8dd5cf9d..c641b203 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -408,16 +408,43 @@ static RESOLVED_IP_REC *net_gethostbyname(const char *addr, GResolverNameLookupF GResolver *resolver; RESOLVED_IP_REC *iprec; -#ifdef HAVE_CAPSICUM - if (capsicum_enabled()) - return (capsicum_net_gethostbyname(addr, flags)); -#endif - g_return_val_if_fail(addr != NULL, NULL); error = NULL; resolver = g_resolver_get_default(); +#if GLIB_CHECK_VERSION(2, 59, 0) ailist = g_resolver_lookup_by_name_with_flags(resolver, addr, flags, NULL, &error); +#else + /* compatibility code for old GLib */ + ailist = g_resolver_lookup_by_name(resolver, addr, NULL, &error); + if (error == NULL && flags) { + GList *ll, *lll; + + for (ll = ailist; ll != NULL; ll = lll) { + GInetAddress *address; + GSocketFamily family; + + address = G_INET_ADDRESS(ll->data); + family = g_inet_address_get_family(address); + lll = ll->next; + + if ((flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && + family == G_SOCKET_FAMILY_IPV6) || + (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY && + family == G_SOCKET_FAMILY_IPV4)) { + g_object_unref(address); + ailist = g_list_delete_link(ailist, ll); + } + } + + if (ailist == NULL) { + g_set_error(&error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY ? + "IPv4 address not found for host" : + "IPv6 address not found for host"); + } + } +#endif iprec = g_new0(RESOLVED_IP_REC, 1); if (error != NULL) { iprec->error = error; @@ -435,11 +462,16 @@ int net_gethostbyname_first_ips(const char *addr, GResolverNameLookupFlags flags { RESOLVED_IP_REC *iprec; +#ifdef HAVE_CAPSICUM + if (capsicum_enabled()) + return (capsicum_net_gethostbyname(addr, ip4, ip6)); +#endif + iprec = net_gethostbyname(addr, flags); if (iprec->error == NULL) { GList *curr; - for (curr = iprec->ailist; curr->next; curr = curr->next) { + for (curr = iprec->ailist; curr; curr = curr->next) { unsigned short family; GInetAddress *addr; diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 97206328..8747eea3 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -70,11 +70,11 @@ static void get_source_host_ip(void) net_gethostbyname_first_ips(hostname, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, &ip4, &ip6) == 0; - if (source_host_ok) + if (source_host_ok) { save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6); - else { - g_free_and_null(source_host_ip4); - g_free_and_null(source_host_ip6); + } else { + g_free_and_null(source_host_ip4); + g_free_and_null(source_host_ip6); } } diff --git a/src/core/servers.c b/src/core/servers.c index e62f09ec..04852104 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -338,16 +338,22 @@ static void server_connect_use_resolved(SERVER_REC *server) resolved_ip_unref(iprec); } + + g_free(ip); } static void server_connect_callback_resolved(RESOLVED_IP_REC *iprec, SERVER_REC *server) { - server->connect_cancellable = NULL; + if (server->connect_cancellable != NULL) { + g_object_unref(server->connect_cancellable); + server->connect_cancellable = NULL; + } if (server->connrec->resolved_host != NULL) { resolved_ip_unref(server->connrec->resolved_host); } server->connrec->resolved_host = iprec; + if (iprec->error == NULL && iprec->ailist == NULL) { server->connection_lost = TRUE; server->dns_error = TRUE; From 221d520c370d5dedfe2f7ab97d76459fc20c7dc1 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Sun, 25 Jan 2026 22:07:44 +0100 Subject: [PATCH 1196/1198] run meson formatter --- .muon_fmt.ini | 14 + docs/help/meson.build | 3 +- docs/meson.build | 3 +- meson.build | 494 +++++++++++++++++------ scripts/meson.build | 3 +- src/core/meson.build | 11 +- src/fe-common/core/meson.build | 19 +- src/fe-common/irc/dcc/meson.build | 15 +- src/fe-common/irc/meson.build | 15 +- src/fe-common/irc/notifylist/meson.build | 15 +- src/fe-fuzz/fe-common/core/meson.build | 7 +- src/fe-fuzz/irc/core/meson.build | 7 +- src/fe-fuzz/meson.build | 14 +- src/fe-none/meson.build | 5 +- src/fe-text/meson.build | 11 +- src/irc/core/meson.build | 17 +- src/irc/dcc/meson.build | 11 +- src/irc/flood/meson.build | 15 +- src/irc/notifylist/meson.build | 11 +- src/irc/proxy/meson.build | 5 +- src/lib-config/meson.build | 9 +- src/meson.build | 7 +- src/otr/meson.build | 5 +- src/perl/common/meson.build | 40 +- src/perl/irc/meson.build | 62 +-- src/perl/meson.build | 29 +- src/perl/textui/meson.build | 33 +- src/perl/ui/meson.build | 30 +- tests/fe-common/core/meson.build | 14 +- tests/fe-text/meson.build | 13 +- tests/irc/core/meson.build | 24 +- tests/irc/flood/meson.build | 12 +- themes/meson.build | 3 +- 33 files changed, 661 insertions(+), 315 deletions(-) create mode 100644 .muon_fmt.ini diff --git a/.muon_fmt.ini b/.muon_fmt.ini new file mode 100644 index 00000000..47fce5d2 --- /dev/null +++ b/.muon_fmt.ini @@ -0,0 +1,14 @@ +# Irssi configuration for muon fmt +max_line_len = 108 +indent_style = space +indent_size = 2 +#indent_by = ' ' +space_array = true +kwargs_force_multiline = true +wide_colon = true +no_single_comma_function = true +insert_final_newline = true +sort_files = false +group_arg_value = true +sticky_parens = true +continuation_indent = true diff --git a/docs/help/meson.build b/docs/help/meson.build index 7fe95d43..6eaa3025 100644 --- a/docs/help/meson.build +++ b/docs/help/meson.build @@ -116,6 +116,7 @@ install_data( 'whowas', 'window', ), - install_dir : helpdir) + install_dir : helpdir, +) # subdir('in') diff --git a/docs/meson.build b/docs/meson.build index a58faed3..f6761200 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -13,6 +13,7 @@ install_data( 'startup-HOWTO.html', 'startup-HOWTO.txt', ), - install_dir : docdir) + install_dir : docdir, +) subdir('help') diff --git a/meson.build b/meson.build index c7eed79d..d6c582b5 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,10 @@ -project('irssi', 'c', +project( + 'irssi', + 'c', version : '1.5-head', meson_version : '>=0.53', - default_options : ['warning_level=1']) + default_options : [ 'warning_level=1' ], +) ############################ ############################ @@ -11,11 +14,11 @@ glib_pcre2_internal_version = 'pcre2-10.40' glib_libffi_internal_version = 'libffi' cc = meson.get_compiler('c') rootinc = include_directories('.') -dep = [] -textui_dep = [] +dep = [ ] +textui_dep = [ ] need_dl_cross_link = false need_dl_cross_link_main = false -dl_cross_irssi_main = [] +dl_cross_irssi_main = [ ] # The Android environment requires that all modules are linked to each other. # See https://github.com/android/ndk/issues/201 if host_machine.system() == 'android' @@ -66,14 +69,33 @@ if fs.exists('config.status') or fs.exists('irssi-version.h') or fs.exists('defa endif UNSET = '=INVALID=' -UNSET_ARR = [UNSET] +UNSET_ARR = [ UNSET ] -chat_modules = ['irc'] +chat_modules = [ 'irc' ] -run_command('mkdir', meson.current_build_dir() / incdir, check : false) -run_command('ln', '-s', meson.current_source_dir() / 'src', meson.current_build_dir() / incdir, check : false) -run_command('ln', '-s', meson.current_build_dir() / 'irssi-config.h', meson.current_build_dir() / incdir, check : false) -run_command('ln', '-s', meson.current_build_dir() / 'irssi-version.h', meson.current_build_dir() / incdir, check : false) +run_command( + 'mkdir', + meson.current_build_dir() / incdir, + check : false, +) +run_command( + 'ln', + '-s', meson.current_source_dir() / 'src', + meson.current_build_dir() / incdir, + check : false, +) +run_command( + 'ln', + '-s', meson.current_build_dir() / 'irssi-config.h', + meson.current_build_dir() / incdir, + check : false, +) +run_command( + 'ln', + '-s', meson.current_build_dir() / 'irssi-version.h', + meson.current_build_dir() / incdir, + check : false, +) def_moduledir = '-D' + 'MODULEDIR' + '="' + (get_option('prefix') / moduledir) + '"' def_sysconfdir = '-D' + 'SYSCONFDIR' + '="' + (get_option('prefix') / get_option('sysconfdir')) + '"' @@ -83,12 +105,11 @@ def_scriptdir = '-D' + 'SCRIPTDIR' + '="' + (get_option('prefix') / scriptdir) def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK' - -module_suffix = [] -perl_module_suffix = [] +module_suffix = [ ] +perl_module_suffix = [ ] # Meson uses the wrong module extensions on Mac. # https://gitlab.gnome.org/GNOME/glib/issues/520 -if ['darwin', 'ios'].contains(host_machine.system()) +if [ 'darwin', 'ios' ].contains(host_machine.system()) module_suffix = 'so' perl_module_suffix = 'bundle' endif @@ -97,13 +118,20 @@ endif # Help files # ############## -build_perl = find_program('perl', native : true) +build_perl = find_program( + 'perl', + native : true, +) if meson.is_cross_build() cross_perl = find_program('perl') else cross_perl = build_perl endif -run_command(build_perl, files('utils/syntax.pl'), check : true) +run_command( + build_perl, + files('utils/syntax.pl'), + check : true, +) ################### # irssi-version.h # @@ -111,12 +139,12 @@ run_command(build_perl, files('utils/syntax.pl'), check : true) env = find_program('env') irssi_version_sh = find_program('utils/irssi-version.sh') -irssi_version_h = custom_target('irssi-version.h', +irssi_version_h = custom_target( + 'irssi-version.h', build_by_default : true, build_always_stale : true, capture : true, - command : [env, 'VERSION=' + meson.project_version(), - irssi_version_sh, meson.current_source_dir()], + command : [ env, 'VERSION=' + meson.project_version(), irssi_version_sh, meson.current_source_dir() ], output : 'irssi-version.h', install : true, install_dir : includedir / incdir, @@ -127,22 +155,24 @@ irssi_version_h = custom_target('irssi-version.h', #################### file2header = find_program('utils/file2header.sh') -default_config_h = custom_target('default-config.h', +default_config_h = custom_target( + 'default-config.h', input : files('irssi.conf'), output : 'default-config.h', capture : true, - command : [file2header, '@INPUT@', 'default_config'], + command : [ file2header, '@INPUT@', 'default_config' ], ) ################### # default-theme.h # ################### -default_theme_h = custom_target('default-theme.h', +default_theme_h = custom_target( + 'default-theme.h', input : files('themes/default.theme'), output : 'default-theme.h', capture : true, - command : [file2header, '@INPUT@', 'default_theme'], + command : [ file2header, '@INPUT@', 'default_theme' ], ) ################ @@ -151,12 +181,18 @@ default_theme_h = custom_target('default-theme.h', #### inet_addr #### inet_addr_found = false -foreach inet_addr_provider : ['', 'nsl'] - prov_lib = [] +foreach inet_addr_provider : [ '', 'nsl' ] + prov_lib = [ ] if inet_addr_provider != '' - prov_lib += cc.find_library(inet_addr_provider, required : false) + prov_lib += cc.find_library( + inet_addr_provider, + required : false, + ) endif - if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('inet_addr', dependencies : prov_lib) + if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function( + 'inet_addr', + dependencies : prov_lib, + ) dep += prov_lib inet_addr_found = true break @@ -168,12 +204,18 @@ endif #### socket #### socket_found = false -foreach socket_provider : ['', 'socket', 'network'] - prov_lib = [] +foreach socket_provider : [ '', 'socket', 'network' ] + prov_lib = [ ] if socket_provider != '' - prov_lib += cc.find_library(socket_provider, required : false) + prov_lib += cc.find_library( + socket_provider, + required : false, + ) endif - if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function('socket', dependencies : prov_lib) + if (prov_lib.length() == 0 or prov_lib[0].found()) and cc.has_function( + 'socket', + dependencies : prov_lib, + ) dep += prov_lib socket_found = true break @@ -183,7 +225,7 @@ if not socket_found error('socket not found') endif -built_src = [] +built_src = [ ] glib_internal = false message('*** If you don\'t have GLib, you can run meson ... -Dinstall-glib=yes') message('*** to download and build it automatically') @@ -191,54 +233,82 @@ message('*** Or alternatively install your distribution\'s package') message('*** On Debian: sudo apt-get install libglib2.0-dev') message('*** On Redhat: dnf install glib2-devel') if not require_glib_internal - glib_dep = dependency('glib-2.0', version : '>=2.32', required : not want_glib_internal, static : want_static_dependency, include_type : 'system') + glib_dep = dependency( + 'glib-2.0', + version : '>=2.32', + required : not want_glib_internal, + static : want_static_dependency, + include_type : 'system', + ) else - glib_dep = dependency('', required : false) + glib_dep = dependency( + '', + required : false, + ) endif if not glib_dep.found() glib_internal = true meson_cmd = find_program('meson') ninja = find_program('ninja') - glib_internal_download_t = custom_target('glib-internal-download', + glib_internal_download_t = custom_target( + 'glib-internal-download', command : [ meson_cmd, 'subprojects', 'download', 'glib', '--sourcedir', meson.current_source_dir() ], console : true, - output : ['glib-internal-download'], + output : [ 'glib-internal-download' ], ) glib_internal_dependencies = [ dependency('threads'), ] - glib_internal_configure_args = [] + glib_internal_configure_args = [ ] glib_internal_usr_local = false if not cc.has_function('iconv_open') - prov_lib = cc.find_library('iconv', required : false) + prov_lib = cc.find_library( + 'iconv', + required : false, + ) if not prov_lib.found() - prov_lib = cc.find_library('iconv', dirs : '/usr/local/lib') + prov_lib = cc.find_library( + 'iconv', + dirs : '/usr/local/lib', + ) glib_internal_usr_local = true endif glib_internal_dependencies += prov_lib endif if not cc.has_function('ngettext') - prov_lib = cc.find_library('intl', required : false) + prov_lib = cc.find_library( + 'intl', + required : false, + ) if not prov_lib.found() - prov_lib = cc.find_library('intl', dirs : '/usr/local/lib') + prov_lib = cc.find_library( + 'intl', + dirs : '/usr/local/lib', + ) glib_internal_usr_local = true endif glib_internal_dependencies += prov_lib endif if glib_internal_usr_local - glib_internal_configure_args += ['-Dc_args=-I/usr/local/include', '-Dc_link_args=-L/usr/local/lib'] + glib_internal_configure_args += [ '-Dc_args=-I/usr/local/include', '-Dc_link_args=-L/usr/local/lib' ] endif if not cc.has_function('getxattr') or not cc.has_header('sys/xattr.h') if cc.has_header_symbol('attr/xattr.h', 'getxattr') - prov_lib = cc.find_library('xattr', required : false) + prov_lib = cc.find_library( + 'xattr', + required : false, + ) else - prov_lib = dependency('', required : false) + prov_lib = dependency( + '', + required : false, + ) endif if prov_lib.found() glib_internal_dependencies += prov_lib @@ -247,28 +317,41 @@ if not glib_dep.found() endif endif - glib_internal_configure_t = custom_target('glib-internal-configure', - command : [ meson_cmd, 'setup', '--prefix=/irssi-glib-internal', + glib_internal_configure_t = custom_target( + 'glib-internal-configure', + command : [ + meson_cmd, + 'setup', + '--prefix=/irssi-glib-internal', '--buildtype=' + get_option('buildtype'), - '-Dlibmount=disabled', '-Dselinux=disabled', '-Ddefault_library=static', '-Dforce_fallback_for=pcre2,libffi', + '-Dlibmount=disabled', + '-Dselinux=disabled', + '-Ddefault_library=static', + '-Dforce_fallback_for=pcre2,libffi', glib_internal_configure_args, (meson.current_build_dir() / 'build-subprojects' / 'glib'), - (meson.current_source_dir() / 'subprojects' / glib_internal_version) ], + (meson.current_source_dir() / 'subprojects' / glib_internal_version), + ], console : true, - output : ['glib-internal-configure'], - depends : glib_internal_download_t,) - glib_internal_build_t = custom_target('glib-internal-build', - command : [ ninja, '-C', meson.current_build_dir() / 'build-subprojects' / 'glib', + output : [ 'glib-internal-configure' ], + depends : glib_internal_download_t, + ) + glib_internal_build_t = custom_target( + 'glib-internal-build', + command : [ + ninja, + '-C', meson.current_build_dir() / 'build-subprojects' / 'glib', 'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a', 'subprojects' / glib_pcre2_internal_version / 'libpcre2-8.a', 'glib' / 'libglib-2.0.a', 'gmodule' / 'libgmodule-2.0.a', 'gobject' / 'libgobject-2.0.a', 'gio' / 'libgio-2.0.a', - ], + ], console : true, - output : ['glib-internal-build'], - depends : glib_internal_configure_t,) + output : [ 'glib-internal-build' ], + depends : glib_internal_configure_t, + ) glib_dep = declare_dependency( dependencies : glib_internal_dependencies, sources : glib_internal_build_t, @@ -283,28 +366,37 @@ if not glib_dep.found() ], ) built_src += glib_internal_build_t - libdl_dep = [] - prov_lib = cc.find_library('dl', required : false) - if prov_lib.found() and cc.has_function('dlopen', dependencies : prov_lib) + libdl_dep = [ ] + prov_lib = cc.find_library( + 'dl', + required : false, + ) + if prov_lib.found() and cc.has_function( + 'dlopen', + dependencies : prov_lib, + ) libdl_dep += prov_lib endif - gmodule_dep = declare_dependency(sources : glib_internal_build_t, + gmodule_dep = declare_dependency( + sources : glib_internal_build_t, dependencies : libdl_dep, compile_args : [ '-isystem' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'gmodule'), ], link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gmodule' / 'libgmodule-2.0.a' ], ) - gobject_dep = declare_dependency(sources : glib_internal_build_t, + gobject_dep = declare_dependency( + sources : glib_internal_build_t, compile_args : [ '-isystem' + (meson.current_build_dir() / 'build-subprojects' / 'glib'), ], link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a', - meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gobject' / 'libgobject-2.0.a' + meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gobject' / 'libgobject-2.0.a', ], ) - gio_dep = declare_dependency(sources : glib_internal_build_t, + gio_dep = declare_dependency( + sources : glib_internal_build_t, dependencies : cc.find_library('z'), compile_args : [ '-isystem' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'gio'), @@ -313,9 +405,21 @@ if not glib_dep.found() link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gio' / 'libgio-2.0.a' ], ) else - gmodule_dep = dependency('gmodule-2.0', static : want_static_dependency, include_type : 'system') - gobject_dep = dependency('gobject-2.0', static : want_static_dependency, include_type : 'system') - gio_dep = dependency('gio-2.0', static : want_static_dependency, include_type : 'system') + gmodule_dep = dependency( + 'gmodule-2.0', + static : want_static_dependency, + include_type : 'system', + ) + gobject_dep = dependency( + 'gobject-2.0', + static : want_static_dependency, + include_type : 'system', + ) + gio_dep = dependency( + 'gio-2.0', + static : want_static_dependency, + include_type : 'system', + ) endif dep += glib_dep dep += gmodule_dep @@ -323,10 +427,17 @@ dep += gobject_dep dep += gio_dep if glib_internal and want_static_dependency and want_fuzzer - openssl_proj = subproject('openssl', default_options : ['default_library=static', 'asm=disabled']) + openssl_proj = subproject( + 'openssl', + default_options : [ 'default_library=static', 'asm=disabled' ], + ) openssl_dep = openssl_proj.get_variable('openssl_dep') else - openssl_dep = dependency('openssl', static : want_static_dependency, include_type : 'system') + openssl_dep = dependency( + 'openssl', + static : want_static_dependency, + include_type : 'system', + ) endif dep += openssl_dep @@ -335,10 +446,16 @@ dep += openssl_dep ############ have_libutf8proc = false -libutf8proc = [] +libutf8proc = [ ] if want_libutf8proc - libutf8proc = cc.find_library('utf8proc', required : require_libutf8proc) - have_libutf8proc = cc.has_function('utf8proc_version', dependencies : libutf8proc) + libutf8proc = cc.find_library( + 'utf8proc', + required : require_libutf8proc, + ) + have_libutf8proc = cc.has_function( + 'utf8proc_version', + dependencies : libutf8proc, + ) if have_libutf8proc dep += libutf8proc endif @@ -353,9 +470,15 @@ endif if want_textui setupterm_found = false - foreach setupterm_provider : ['tinfo', 'ncursesw', 'ncurses', 'terminfo'] - prov_lib = cc.find_library(setupterm_provider, required : false) - if prov_lib.found() and cc.has_function('setupterm', dependencies : prov_lib) + foreach setupterm_provider : [ 'tinfo', 'ncursesw', 'ncurses', 'terminfo' ] + prov_lib = cc.find_library( + setupterm_provider, + required : false, + ) + if prov_lib.found() and cc.has_function( + 'setupterm', + dependencies : prov_lib, + ) textui_dep += prov_lib setupterm_found = true break @@ -372,15 +495,20 @@ endif have_perl = false if want_perl - perl_cflags = [] - perl_ldflags = [] - perl_rpath_flags = [] + perl_cflags = [ ] + perl_ldflags = [ ] + perl_rpath_flags = [ ] perl_rpath = '' #### ccopts #### perl_ccopts = meson.get_cross_property('perl_ccopts', UNSET_ARR) if perl_ccopts == UNSET_ARR - res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ccopts', check : true) + res = run_command( + cross_perl, + '-MExtUtils::Embed', + '-e', 'ccopts', + check : true, + ) perl_ccopts = res.stdout().strip().split() endif foreach fl : perl_ccopts @@ -397,10 +525,15 @@ if want_perl #### ldopts #### perl_ldopts = meson.get_cross_property('perl_ldopts', UNSET_ARR) if perl_ldopts == UNSET_ARR - res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ldopts', check : true) + res = run_command( + cross_perl, + '-MExtUtils::Embed', + '-e', 'ldopts', + check : true, + ) perl_ldopts = res.stdout().strip().split() endif - skip_libs = ['-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic'] + skip_libs = [ '-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic' ] foreach fl : perl_ldopts if not fl.startswith('-A') and not skip_libs.contains(fl) if fl.startswith('-Wl,-rpath,') @@ -414,18 +547,26 @@ if want_perl perl_version = meson.get_cross_property('perl_version', UNSET) if perl_version == UNSET - perl_version = run_command(cross_perl, '-V::version:', check : true).stdout().split('\'')[1] + perl_version = run_command( + cross_perl, + '-V::version:', + check : true, + ).stdout().split('\'')[1] endif # disable clang warning if perl_version.version_compare('<5.35.2') perl_cflags += cc.get_supported_arguments('-Wno-compound-token-split-by-macro') endif - perl_dep = declare_dependency(compile_args : perl_cflags, link_args : perl_ldflags, - version : perl_version) + perl_dep = declare_dependency( + compile_args : perl_cflags, + link_args : perl_ldflags, + version : perl_version, + ) #### - if not cc.links(''' + if not cc.links( + ''' #include #include int main() @@ -433,8 +574,10 @@ int main() perl_alloc(); return 0; } -''', args : perl_cflags + perl_ldflags + perl_rpath_flags, - name : 'working Perl support') +''', + args : perl_cflags + perl_ldflags + perl_rpath_flags, + name : 'working Perl support', + ) if require_perl error('error linking with perl libraries') else @@ -443,9 +586,15 @@ int main() else xsubpp_file_c = meson.get_cross_property('perl_xsubpp', UNSET) if xsubpp_file_c == UNSET - xsubpp_file_c = run_command(build_perl, '-MExtUtils::ParseXS', '-e($r = $INC{"ExtUtils/ParseXS.pm"}) =~ s{ParseXS\\.pm$}{xsubpp}; print $r', check : true).stdout() + xsubpp_file_c = run_command( + build_perl, + '-MExtUtils::ParseXS', + '-e($r = $INC{"ExtUtils/ParseXS.pm"}) =~ s{ParseXS\\.pm$}{xsubpp}; print $r', + check : true, + ).stdout() endif - xsubpp = generator(build_perl, + xsubpp = generator( + build_perl, output : '@BASENAME@.c', capture : true, arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ], @@ -453,31 +602,44 @@ int main() xsubpp_file = files(xsubpp_file_c) if with_perl_lib == 'module' - perl_install_base = run_command(build_perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}', check : true).stdout() + perl_install_base = run_command( + build_perl, + '-MText::ParseWords=shellwords', + '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}', + check : true, + ).stdout() if perl_install_base == '' with_perl_lib = '' endif endif if with_perl_lib == '' - if get_option('prefix') in ['/usr/local', 'C:/'] + if get_option('prefix') in [ '/usr/local', 'C:/' ] with_perl_lib = 'site' - elif get_option('prefix') in ['/usr'] + elif get_option('prefix') in [ '/usr' ] with_perl_lib = 'vendor' endif endif perlmoddir = '' - if with_perl_lib in ['site', 'vendor', 'module'] + if with_perl_lib in [ 'site', 'vendor', 'module' ] set_perl_use_lib = false perl_library_dir = with_perl_lib + ' default' - if with_perl_lib in ['site', 'vendor'] + if with_perl_lib in [ 'site', 'vendor' ] perlmoddir = meson.get_cross_property('perl_install' + with_perl_lib + 'arch', UNSET) if perlmoddir == UNSET - perlmoddir = run_command(cross_perl, '-V::install' + with_perl_lib + 'arch:', check : true).stdout().split('\'')[1] + perlmoddir = run_command( + cross_perl, + '-V::install' + with_perl_lib + 'arch:', + check : true, + ).stdout().split('\'')[1] endif elif with_perl_lib == 'module' perl_archname = meson.get_cross_property('perl_archname', UNSET) if perl_archname == UNSET - perl_archname = run_command(cross_perl, '-V::archname:', check : true).stdout().split('\'')[1] + perl_archname = run_command( + cross_perl, + '-V::archname:', + check : true, + ).stdout().split('\'')[1] endif perlmoddir = perl_install_base / 'lib' / 'perl5' / perl_archname endif @@ -498,7 +660,12 @@ int main() if set_perl_use_lib perl_inc = meson.get_cross_property('perl_inc', UNSET_ARR) if perl_inc == UNSET_ARR - set_perl_use_lib = run_command(cross_perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib, check : false).returncode() != 0 + set_perl_use_lib = run_command( + cross_perl, + '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', + perl_use_lib, + check : false, + ).returncode() != 0 else set_perl_use_lib = not perl_inc.contains(perl_use_lib) endif @@ -524,8 +691,20 @@ endif have_otr = false if want_otr - libgcrypt = dependency('libgcrypt', version : '>=1.2.0', required : require_otr, static : want_static_dependency, include_type : 'system') - libotr = dependency('libotr', version : '>=4.1.0', required : require_otr, static : want_static_dependency, include_type : 'system') + libgcrypt = dependency( + 'libgcrypt', + version : '>=1.2.0', + required : require_otr, + static : want_static_dependency, + include_type : 'system', + ) + libotr = dependency( + 'libotr', + version : '>=4.1.0', + required : require_otr, + static : want_static_dependency, + include_type : 'system', + ) if libgcrypt.found() and libotr.found() dep += libgcrypt dep += libotr @@ -539,9 +718,19 @@ endif have_capsicum = false if want_capsicum - if cc.has_function('cap_enter', dependencies : cc.find_library('c')) - libnv = cc.find_library('nv', required : require_capsicum) - nvlist_create_found = libnv.found() and cc.has_function('nvlist_create', dependencies : libnv, prefix : '#include ') + if cc.has_function( + 'cap_enter', + dependencies : cc.find_library('c'), + ) + libnv = cc.find_library( + 'nv', + required : require_capsicum, + ) + nvlist_create_found = libnv.found() and cc.has_function( + 'nvlist_create', + dependencies : libnv, + prefix : '#include ', + ) if nvlist_create_found dep += libnv have_capsicum = true @@ -558,11 +747,14 @@ if want_capsicum endif # dependency helper sets -dep_cflagsonly = [] +dep_cflagsonly = [ ] foreach d : dep - dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true) + dep_cflagsonly += d.partial_dependency( + includes : true, + compile_args : true, + ) endforeach -dl_cross_dep = [] +dl_cross_dep = [ ] if need_dl_cross_link dl_cross_dep = dep endif @@ -573,11 +765,19 @@ endif conf = configuration_data() -conf.set('HAVE_CAPSICUM', have_capsicum, description : 'Build with Capsicum support') +conf.set( + 'HAVE_CAPSICUM', + have_capsicum, + description : 'Build with Capsicum support', +) conf.set('HAVE_GMODULE', true) conf.set('TERM_TRUECOLOR', true) conf.set('USE_GREGEX', true) -conf.set10('_DARWIN_USE_64_BIT_INODE', true, description : 'Enable large inode numbers on Mac OS X 10.5.') +conf.set10( + '_DARWIN_USE_64_BIT_INODE', + true, + description : 'Enable large inode numbers on Mac OS X 10.5.', +) conf.set_quoted('FHS_PREFIX', get_option('fhs-prefix')) headers = [ @@ -591,31 +791,50 @@ headers = [ ] foreach h : headers if cc.has_header(h) - conf.set('HAVE_' + h.underscorify().to_upper(), 1, description : 'Define to 1 if you have the <' + h + '> header file.') + conf.set( + 'HAVE_' + h.underscorify().to_upper(), + 1, + description : 'Define to 1 if you have the <' + h + '> header file.', + ) endif endforeach if want_textui and conf.get('HAVE_TERM_H', 0) == 1 - if cc.links(''' + if cc.links( + ''' #include #include int main (void) { return tputs("x", 1, putchar); } -''', args : '-pedantic-errors', dependencies : textui_dep, name : 'Curses working') +''', + args : '-pedantic-errors', + dependencies : textui_dep, + name : 'Curses working', + ) # ok else has_curses_h = cc.has_header('curses.h') - if has_curses_h and cc.links(''' + if has_curses_h and cc.links( + ''' #include #include int main (void) { return tputs("x", 1, putchar); } -''', args : '-pedantic-errors', dependencies : textui_dep, name : 'Curses working with curses.h') - conf.set('NEED_CURSES_H', 1, description : 'tputs needs curses.h') +''', + args : '-pedantic-errors', + dependencies : textui_dep, + name : 'Curses working with curses.h', + ) + conf.set( + 'NEED_CURSES_H', + 1, + description : 'tputs needs curses.h', + ) else - if has_curses_h and cc.links(''' + if has_curses_h and cc.links( + ''' #include #include int char_putchar (char c) { @@ -624,9 +843,21 @@ int char_putchar (char c) { int main (void) { return tputs("x", 1, char_putchar); } -''', args : '-pedantic-errors', dependencies : textui_dep, name : 'Curses with tputs third argument arg char') - conf.set('NEED_CURSES_H', 1, description : 'tputs needs curses.h') - conf.set('TPUTS_SVR4', 1, description : 'third argument of tputs has the type int (*)(char)') +''', + args : '-pedantic-errors', + dependencies : textui_dep, + name : 'Curses with tputs third argument arg char', + ) + conf.set( + 'NEED_CURSES_H', + 1, + description : 'tputs needs curses.h', + ) + conf.set( + 'TPUTS_SVR4', + 1, + description : 'third argument of tputs has the type int (*)(char)', + ) else error('could not link terminfo') endif @@ -638,21 +869,32 @@ conf.set('HAVE_LIBUTF8PROC', have_libutf8proc) conf.set_quoted('PACKAGE_VERSION', package_version) conf.set_quoted('PACKAGE_TARNAME', meson.project_name()) -configure_file(output : 'irssi-config.h', +configure_file( + output : 'irssi-config.h', configuration : conf, - install_dir : includedir / incdir) + install_dir : includedir / incdir, +) ########## # CFLAGS # ########## #### warnings #### -add_project_arguments(cc.get_supported_arguments('-Werror=declaration-after-statement'), language : 'c') +add_project_arguments( + cc.get_supported_arguments('-Werror=declaration-after-statement'), + language : 'c', +) #### personality #### -add_project_arguments(cc.get_supported_arguments('-fno-strict-aliasing'), language : 'c') +add_project_arguments( + cc.get_supported_arguments('-fno-strict-aliasing'), + language : 'c', +) if get_option('buildtype').contains('debug') - add_project_arguments(cc.get_supported_arguments('-fno-omit-frame-pointer'), language : 'c') + add_project_arguments( + cc.get_supported_arguments('-fno-omit-frame-pointer'), + language : 'c', + ) endif if want_fuzzer @@ -660,7 +902,10 @@ if want_fuzzer if not cc.has_argument('-fsanitize=fuzzer-no-link') error('compiler does not support -fsanitize=fuzzer-no-link, try clang?') endif - add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c') + add_project_arguments( + '-fsanitize=fuzzer-no-link', + language : 'c', + ) endif if fuzzer_link_language != 'c' add_languages(fuzzer_link_language) @@ -672,7 +917,7 @@ endif ############## pc = import('pkgconfig') -pc_requires = [] +pc_requires = [ ] if not glib_internal pc_requires += glib_dep endif @@ -687,7 +932,8 @@ if signalsfile.startswith('/') else signalsfile = '${prefix}' / signalsfile endif -pc.generate(filebase : 'irssi-1', +pc.generate( + filebase : 'irssi-1', name : 'Irssi', description : 'Irssi chat client', version : package_version, diff --git a/scripts/meson.build b/scripts/meson.build index 072ac3ea..10fdc34b 100644 --- a/scripts/meson.build +++ b/scripts/meson.build @@ -11,4 +11,5 @@ install_data( 'scriptassist.pl', 'usercount.pl', ), - install_dir : scriptdir) + install_dir : scriptdir, +) diff --git a/src/core/meson.build b/src/core/meson.build index 56b6ec77..521015d4 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -3,10 +3,11 @@ if have_capsicum core_capsicum_source = files('capsicum.c') else - core_capsicum_source = [] + core_capsicum_source = [ ] endif -libcore_a = static_library('core', +libcore_a = static_library( + 'core', files( 'args.c', 'channels-setup.c', @@ -63,7 +64,8 @@ libcore_a = static_library('core', def_moduledir, def_sysconfdir, ], - dependencies : dep) + dependencies : dep, +) install_headers( files( @@ -122,4 +124,5 @@ install_headers( 'window-item-def.h', 'write-buffer.h', ), - subdir : incdir / 'src' / 'core') + subdir : incdir / 'src' / 'core', +) diff --git a/src/fe-common/core/meson.build b/src/fe-common/core/meson.build index 73cb156a..a84f12eb 100644 --- a/src/fe-common/core/meson.build +++ b/src/fe-common/core/meson.build @@ -3,7 +3,7 @@ if have_capsicum fe_common_core_capsicum_source = files('fe-capsicum.c') else - fe_common_core_capsicum_source = [] + fe_common_core_capsicum_source = [ ] endif fe_common_core_sources = [ @@ -43,10 +43,11 @@ fe_common_core_sources = [ + [ default_theme_h, irssi_version_h, - ] + ], ] -libfe_common_core_a = static_library('fe_common_core', +libfe_common_core_a = static_library( + 'fe_common_core', fe_common_core_sources, include_directories : rootinc, implicit_include_directories : false, @@ -54,10 +55,12 @@ libfe_common_core_a = static_library('fe_common_core', def_helpdir, def_themesdir, ], - dependencies : dep) + dependencies : dep, +) if want_fuzzer - libfuzzer_fe_common_core_a = static_library('fuzzer_fe_common_core', + libfuzzer_fe_common_core_a = static_library( + 'fuzzer_fe_common_core', fe_common_core_sources, include_directories : rootinc, implicit_include_directories : false, @@ -66,7 +69,8 @@ if want_fuzzer def_themesdir, def_suppress_printf_fallback, ], - dependencies : dep) + dependencies : dep, + ) endif install_headers( @@ -96,4 +100,5 @@ install_headers( 'window-items.h', 'windows-layout.h', ), - subdir : incdir / 'src' / 'fe-common' / 'core') + subdir : incdir / 'src' / 'fe-common' / 'core', +) diff --git a/src/fe-common/irc/dcc/meson.build b/src/fe-common/irc/dcc/meson.build index 5edf2477..b347cd00 100644 --- a/src/fe-common/irc/dcc/meson.build +++ b/src/fe-common/irc/dcc/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libfe_irc_dcc_a = static_library('fe_irc_dcc', +libfe_irc_dcc_a = static_library( + 'fe_irc_dcc', files( 'fe-dcc-chat-messages.c', 'fe-dcc-chat.c', @@ -16,14 +17,17 @@ libfe_irc_dcc_a = static_library('fe_irc_dcc', def_helpdir, def_sysconfdir, ], - dependencies : dep) -shared_library('fe_irc_dcc', + dependencies : dep, +) +shared_library( + 'fe_irc_dcc', name_suffix : module_suffix, install : true, install_dir : moduledir, link_with : dl_cross_irc_dcc + dl_cross_irc_core + dl_cross_irssi_main, link_whole : libfe_irc_dcc_a, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) install_headers( files( @@ -31,4 +35,5 @@ install_headers( 'module-formats.h', 'module.h', ), - subdir : incdir / 'src' / 'fe-common' / 'irc' / 'dcc') + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'dcc', +) diff --git a/src/fe-common/irc/meson.build b/src/fe-common/irc/meson.build index 518dfbfa..b4d78032 100644 --- a/src/fe-common/irc/meson.build +++ b/src/fe-common/irc/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libfe_common_irc_a = static_library('fe_common_irc', +libfe_common_irc_a = static_library( + 'fe_common_irc', files( 'fe-cap.c', 'fe-common-irc.c', @@ -27,14 +28,17 @@ libfe_common_irc_a = static_library('fe_common_irc', def_helpdir, def_themesdir, ], - dependencies : dep) -shared_library('fe_common_irc', + dependencies : dep, +) +shared_library( + 'fe_common_irc', name_suffix : module_suffix, install : true, install_dir : moduledir, link_with : dl_cross_irc_core + dl_cross_irssi_main, link_whole : libfe_common_irc_a, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) install_headers( files( @@ -43,7 +47,8 @@ install_headers( 'module-formats.h', 'module.h', ), - subdir : incdir / 'src' / 'fe-common' / 'irc') + subdir : incdir / 'src' / 'fe-common' / 'irc', +) subdir('dcc') subdir('notifylist') diff --git a/src/fe-common/irc/notifylist/meson.build b/src/fe-common/irc/notifylist/meson.build index cdb5168b..894c1d89 100644 --- a/src/fe-common/irc/notifylist/meson.build +++ b/src/fe-common/irc/notifylist/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libfe_irc_notifylist_a = static_library('fe_irc_notifylist', +libfe_irc_notifylist_a = static_library( + 'fe_irc_notifylist', files( 'fe-notifylist.c', 'module-formats.c', @@ -11,18 +12,22 @@ libfe_irc_notifylist_a = static_library('fe_irc_notifylist', def_helpdir, def_sysconfdir, ], - dependencies : dep) -shared_library('fe_irc_notifylist', + dependencies : dep, +) +shared_library( + 'fe_irc_notifylist', name_suffix : module_suffix, install : true, install_dir : moduledir, link_with : dl_cross_irc_notifylist + dl_cross_irssi_main, link_whole : libfe_irc_notifylist_a, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) install_headers( files( 'module-formats.h', 'module.h', ), - subdir : incdir / 'src' / 'fe-common' / 'irc' / 'notifylist') + subdir : incdir / 'src' / 'fe-common' / 'irc' / 'notifylist', +) diff --git a/src/fe-fuzz/fe-common/core/meson.build b/src/fe-fuzz/fe-common/core/meson.build index 893f5937..af9dea6e 100644 --- a/src/fe-fuzz/fe-common/core/meson.build +++ b/src/fe-fuzz/fe-common/core/meson.build @@ -1,5 +1,6 @@ # this file is part of irssi -executable('theme-load-fuzz', +executable( + 'theme-load-fuzz', files( '../../null-logger.c', 'theme-load.c', @@ -10,12 +11,12 @@ executable('theme-load-fuzz', libcore_a, libfuzzer_fe_common_core_a, ], - link_args : [fuzzer_lib], + link_args : [ fuzzer_lib ], link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, - dependencies : dep + dependencies : dep, ) # noinst_headers = files( diff --git a/src/fe-fuzz/irc/core/meson.build b/src/fe-fuzz/irc/core/meson.build index 730c9240..65d316d3 100644 --- a/src/fe-fuzz/irc/core/meson.build +++ b/src/fe-fuzz/irc/core/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -executable('event-get-params-fuzz', +executable( + 'event-get-params-fuzz', files( '../../null-logger.c', 'event-get-params.c', @@ -12,12 +13,12 @@ executable('event-get-params-fuzz', libirc_core_a, libfuzzer_fe_common_core_a, ], - link_args : [fuzzer_lib], + link_args : [ fuzzer_lib ], link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, - dependencies : dep + dependencies : dep, ) # noinst_headers = files( diff --git a/src/fe-fuzz/meson.build b/src/fe-fuzz/meson.build index 5ab19651..55071a30 100644 --- a/src/fe-fuzz/meson.build +++ b/src/fe-fuzz/meson.build @@ -3,7 +3,8 @@ subdir('irc') subdir('fe-common') -executable('irssi-fuzz', +executable( + 'irssi-fuzz', files( 'null-logger.c', 'irssi.c', @@ -14,15 +15,16 @@ executable('irssi-fuzz', libcore_a, libfuzzer_fe_common_core_a, ], - link_args : [fuzzer_lib], + link_args : [ fuzzer_lib ], link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, - dependencies : dep + dependencies : dep, ) -executable('server-fuzz', +executable( + 'server-fuzz', files( 'null-logger.c', 'server.c', @@ -37,12 +39,12 @@ executable('server-fuzz', libfe_irc_dcc_a, libfe_irc_notifylist_a, ], - link_args : [fuzzer_lib], + link_args : [ fuzzer_lib ], link_language : fuzzer_link_language, include_directories : rootinc, implicit_include_directories : false, install : true, - dependencies : dep + dependencies : dep, ) # noinst_headers = files( diff --git a/src/fe-none/meson.build b/src/fe-none/meson.build index 49cfe517..b6b91b57 100644 --- a/src/fe-none/meson.build +++ b/src/fe-none/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -fe_none_irssi = executable('botti', +fe_none_irssi = executable( + 'botti', files( 'irssi.c', ), @@ -13,7 +14,7 @@ fe_none_irssi = executable('botti', libcore_a, ], install : true, - dependencies : dep + dependencies : dep, ) if need_dl_cross_link_main dl_cross_irssi_main = [ fe_none_irssi ] diff --git a/src/fe-text/meson.build b/src/fe-text/meson.build index 1c885b89..6165b461 100644 --- a/src/fe-text/meson.build +++ b/src/fe-text/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -fe_text_irssi = executable('irssi', +fe_text_irssi = executable( + 'irssi', files( #### terminfo_sources #### 'term-terminfo.c', @@ -40,10 +41,9 @@ fe_text_irssi = executable('irssi', libconfig_a, libcore_a, libfe_common_core_a, - ], + ], install : true, - dependencies : dep - + textui_dep + dependencies : dep + textui_dep, ) if need_dl_cross_link_main dl_cross_irssi_main = [ fe_text_irssi ] @@ -61,7 +61,8 @@ install_headers( 'textbuffer-view.h', 'textbuffer.h', ), - subdir : incdir / 'src' / 'fe-text') + subdir : incdir / 'src' / 'fe-text', +) # noinst_headers = files( # 'gui-entry.h', diff --git a/src/irc/core/meson.build b/src/irc/core/meson.build index 94ed20a2..d1b7db78 100644 --- a/src/irc/core/meson.build +++ b/src/irc/core/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libirc_core_a = static_library('irc_core', +libirc_core_a = static_library( + 'irc_core', files( 'bans.c', 'channel-events.c', @@ -38,16 +39,19 @@ libirc_core_a = static_library('irc_core', def_moduledir, def_sysconfdir, ], - dependencies : dep) -libirc_core_sm = shared_library('irc_core', + dependencies : dep, +) +libirc_core_sm = shared_library( + 'irc_core', name_suffix : module_suffix, install : true, install_dir : moduledir, link_whole : libirc_core_a, link_with : dl_cross_irssi_main, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) -dl_cross_irc_core = [] +dl_cross_irc_core = [ ] if need_dl_cross_link dl_cross_irc_core += libirc_core_sm endif @@ -77,4 +81,5 @@ install_headers( 'servers-idle.h', 'servers-redirect.h', ), - subdir : incdir / 'src' / 'irc' / 'core') + subdir : incdir / 'src' / 'irc' / 'core', +) diff --git a/src/irc/dcc/meson.build b/src/irc/dcc/meson.build index 3ab1bace..c09f07b2 100644 --- a/src/irc/dcc/meson.build +++ b/src/irc/dcc/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libirc_dcc_sm = shared_library('irc_dcc', +libirc_dcc_sm = shared_library( + 'irc_dcc', files( 'dcc-autoget.c', 'dcc-chat.c', @@ -18,9 +19,10 @@ libirc_dcc_sm = shared_library('irc_dcc', install_dir : moduledir, link_with : dl_cross_irc_core + dl_cross_irssi_main, dependencies : dep, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) -dl_cross_irc_dcc = [] +dl_cross_irc_dcc = [ ] if need_dl_cross_link dl_cross_irc_dcc += libirc_dcc_sm endif @@ -38,4 +40,5 @@ install_headers( 'dcc.h', 'module.h', ), - subdir : incdir / 'src' / 'irc' / 'dcc') + subdir : incdir / 'src' / 'irc' / 'dcc', +) diff --git a/src/irc/flood/meson.build b/src/irc/flood/meson.build index 257e5c11..9df0ef84 100644 --- a/src/irc/flood/meson.build +++ b/src/irc/flood/meson.build @@ -1,21 +1,26 @@ # this file is part of irssi -libirc_flood_a = static_library('irc_flood', +libirc_flood_a = static_library( + 'irc_flood', files( 'autoignore.c', 'flood.c', ), include_directories : rootinc, implicit_include_directories : false, - dependencies : dep) -shared_library('irc_flood', + dependencies : dep, +) +shared_library( + 'irc_flood', name_suffix : module_suffix, install : true, install_dir : moduledir, link_with : dl_cross_irc_core + dl_cross_irssi_main, link_whole : libirc_flood_a, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) install_headers( files('module.h'), - subdir : incdir / 'src' / 'irc' / 'flood') + subdir : incdir / 'src' / 'irc' / 'flood', +) diff --git a/src/irc/notifylist/meson.build b/src/irc/notifylist/meson.build index 34517b34..75f92810 100644 --- a/src/irc/notifylist/meson.build +++ b/src/irc/notifylist/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libirc_notifylist_sm = shared_library('irc_notifylist', +libirc_notifylist_sm = shared_library( + 'irc_notifylist', files( 'notify-commands.c', 'notify-ison.c', @@ -15,9 +16,10 @@ libirc_notifylist_sm = shared_library('irc_notifylist', install_dir : moduledir, link_with : dl_cross_irc_core + dl_cross_irssi_main, dependencies : dep, - override_options : ['b_lundef=false']) + override_options : [ 'b_lundef=false' ], +) -dl_cross_irc_notifylist = [] +dl_cross_irc_notifylist = [ ] if need_dl_cross_link dl_cross_irc_notifylist += libirc_notifylist_sm endif @@ -28,4 +30,5 @@ install_headers( 'notify-setup.h', 'notifylist.h', ), - subdir : incdir / 'src' / 'irc' / 'notifylist') + subdir : incdir / 'src' / 'irc' / 'notifylist', +) diff --git a/src/irc/proxy/meson.build b/src/irc/proxy/meson.build index 4cc2b658..4d5ed554 100644 --- a/src/irc/proxy/meson.build +++ b/src/irc/proxy/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -shared_library('irc_proxy', +shared_library( + 'irc_proxy', files( 'dump.c', 'listen.c', @@ -13,7 +14,7 @@ shared_library('irc_proxy', install : true, install_dir : moduledir, dependencies : dep, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) # noinst_headers = files( diff --git a/src/lib-config/meson.build b/src/lib-config/meson.build index 2bc094dd..c4818dcd 100644 --- a/src/lib-config/meson.build +++ b/src/lib-config/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -libconfig_a = static_library('irssi_config', +libconfig_a = static_library( + 'irssi_config', files( 'get.c', 'parse.c', @@ -9,11 +10,13 @@ libconfig_a = static_library('irssi_config', ), include_directories : rootinc, implicit_include_directories : false, - dependencies : dep) + dependencies : dep, +) install_headers( files( 'iconfig.h', 'module.h', ), - subdir : incdir / 'src' / 'lib-config') + subdir : incdir / 'src' / 'lib-config', +) diff --git a/src/meson.build b/src/meson.build index cc30da1b..b1663d18 100644 --- a/src/meson.build +++ b/src/meson.build @@ -24,7 +24,6 @@ if want_fuzzer endif install_headers( - files( - 'common.h' - ), - subdir : incdir / 'src') + files('common.h'), + subdir : incdir / 'src', +) diff --git a/src/otr/meson.build b/src/otr/meson.build index 13b564ea..9611b428 100644 --- a/src/otr/meson.build +++ b/src/otr/meson.build @@ -1,6 +1,7 @@ # this file is part of irssi -shared_library('otr_core', +shared_library( + 'otr_core', files( 'key.c', 'otr-fe.c', @@ -15,7 +16,7 @@ shared_library('otr_core', install : true, install_dir : moduledir, dependencies : dep, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) # noinst_headers = files( diff --git a/src/perl/common/meson.build b/src/perl/common/meson.build index 0f3f3bb5..1d0ba953 100644 --- a/src/perl/common/meson.build +++ b/src/perl/common/meson.build @@ -1,20 +1,22 @@ - -shared_library('Irssi', - [ xsubpp.process( - files( - 'Channel.xs', - 'Core.xs', - 'Expando.xs', - 'Ignore.xs', - 'Irssi.xs', - 'Log.xs', - 'Masks.xs', - 'Query.xs', - 'Rawlog.xs', - 'Server.xs', - 'Settings.xs', - ) - ) ] +shared_library( + 'Irssi', + [ + xsubpp.process( + files( + 'Channel.xs', + 'Core.xs', + 'Expando.xs', + 'Ignore.xs', + 'Irssi.xs', + 'Log.xs', + 'Masks.xs', + 'Query.xs', + 'Rawlog.xs', + 'Server.xs', + 'Settings.xs', + ) + ), + ] + files( 'module.h', ) @@ -27,7 +29,7 @@ shared_library('Irssi', implicit_include_directories : true, dependencies : dep + [ perl_dep ], link_with : dl_cross_perl_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) install_headers( @@ -36,6 +38,6 @@ install_headers( ), install_dir : perlmoddir, ) - + # 'Makefile.PL.in', # 'typemap', diff --git a/src/perl/irc/meson.build b/src/perl/irc/meson.build index af68ce7f..4dd0f5e1 100644 --- a/src/perl/irc/meson.build +++ b/src/perl/irc/meson.build @@ -1,21 +1,23 @@ -shared_library('Irc', - [ xsubpp.process( - files( - 'Channel.xs', - 'Client.xs', - 'Ctcp.xs', - 'Irc.xs', - 'Modes.xs', - 'Netsplit.xs', - 'Notifylist.xs', - 'Query.xs', - 'Server.xs', +shared_library( + 'Irc', + [ + xsubpp.process( + files( + 'Channel.xs', + 'Client.xs', + 'Ctcp.xs', + 'Irc.xs', + 'Modes.xs', + 'Netsplit.xs', + 'Notifylist.xs', + 'Query.xs', + 'Server.xs', + ), + extra_args : [ + '-typemap', '../common/typemap', + ], ), - extra_args : [ - '-typemap', - '../common/typemap', - ], - ) ] + ] + files( 'module.h', ), @@ -27,7 +29,7 @@ shared_library('Irc', implicit_include_directories : true, dependencies : dep + [ perl_dep ], link_with : dl_cross_perl_core + dl_cross_irc_notifylist + dl_cross_irc_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) install_headers( @@ -37,16 +39,18 @@ install_headers( install_dir : perlmoddir / 'Irssi', ) -shared_library('Dcc', - [ xsubpp.process( - files( - 'Dcc.xs', +shared_library( + 'Dcc', + [ + xsubpp.process( + files( + 'Dcc.xs', + ), + extra_args : [ + '-typemap', '../common/typemap', + ], ), - extra_args : [ - '-typemap', - '../common/typemap', - ], - ) ] + ] + files( 'module.h', ), @@ -58,7 +62,7 @@ shared_library('Dcc', implicit_include_directories : true, dependencies : dep + [ perl_dep ], link_with : dl_cross_perl_core + dl_cross_irc_dcc + dl_cross_irc_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) install_headers( @@ -67,6 +71,6 @@ install_headers( ), install_dir : perlmoddir / 'Irssi' / 'Irc', ) - + # 'Makefile.PL.in', # 'typemap', diff --git a/src/perl/meson.build b/src/perl/meson.build index 1c6e2fbc..9e85ca06 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -1,32 +1,36 @@ - -perl_signals_list_h = custom_target('perl-signals-list.h', +perl_signals_list_h = custom_target( + 'perl-signals-list.h', input : files('../../docs/signals.txt'), output : 'perl-signals-list.h', capture : true, depend_files : files('get-signals.pl'), - command : [build_perl, files('get-signals.pl'), '@INPUT@'], + command : [ build_perl, files('get-signals.pl'), '@INPUT@' ], ) -irssi_core_pl_h = custom_target('irssi-core.pl.h', +irssi_core_pl_h = custom_target( + 'irssi-core.pl.h', input : files('irssi-core.pl'), output : 'irssi-core.pl.h', capture : true, - command : [file2header, '@INPUT@', 'irssi_core_code'], + command : [ file2header, '@INPUT@', 'irssi_core_code' ], ) # required as of Meson 0.58.0 generated_files_inc = include_directories('.') -libperl_core_sm = shared_library('perl_core', +libperl_core_sm = shared_library( + 'perl_core', files( 'perl-common.c', 'perl-core.c', 'perl-signals.c', 'perl-sources.c', - ) + [ + ) + + [ irssi_core_pl_h, perl_signals_list_h, - ] + built_src, + ] + + built_src, c_args : [ def_scriptdir, def_perl_use_lib, @@ -39,16 +43,17 @@ libperl_core_sm = shared_library('perl_core', install_rpath : perl_rpath, build_rpath : perl_rpath, dependencies : dep_cflagsonly + [ perl_dep ] + dl_cross_dep, - override_options : ['b_asneeded=false', 'b_lundef=false'], + override_options : [ 'b_asneeded=false', 'b_lundef=false' ], link_with : dl_cross_irssi_main, ) -dl_cross_perl_core = [] +dl_cross_perl_core = [ ] if need_dl_cross_link dl_cross_perl_core += libperl_core_sm endif -shared_library('fe_perl', +shared_library( + 'fe_perl', files( 'module-formats.c', 'perl-fe.c', @@ -63,7 +68,7 @@ shared_library('fe_perl', install_dir : moduledir, dependencies : dep, link_with : dl_cross_perl_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) subdir('common') diff --git a/src/perl/textui/meson.build b/src/perl/textui/meson.build index b7d769c5..9a5b08cf 100644 --- a/src/perl/textui/meson.build +++ b/src/perl/textui/meson.build @@ -1,18 +1,19 @@ -shared_library('TextUI', - [ xsubpp.process( - files( - 'Statusbar.xs', - 'TextBufferView.xs', - 'TextBuffer.xs', - 'TextUI.xs', +shared_library( + 'TextUI', + [ + xsubpp.process( + files( + 'Statusbar.xs', + 'TextBufferView.xs', + 'TextBuffer.xs', + 'TextUI.xs', + ), + extra_args : [ + '-typemap', '../common/typemap', + '-typemap', '../ui/typemap', + ], ), - extra_args : [ - '-typemap', - '../common/typemap', - '-typemap', - '../ui/typemap', - ], - ) ] + ] + files( 'module.h', ), @@ -24,7 +25,7 @@ shared_library('TextUI', implicit_include_directories : true, dependencies : dep + [ perl_dep ], link_with : dl_cross_perl_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) install_headers( @@ -33,6 +34,6 @@ install_headers( ), install_dir : perlmoddir / 'Irssi', ) - + # 'Makefile.PL.in', # 'typemap', diff --git a/src/perl/ui/meson.build b/src/perl/ui/meson.build index a6e5c93c..5a24d5d6 100644 --- a/src/perl/ui/meson.build +++ b/src/perl/ui/meson.build @@ -1,16 +1,18 @@ -shared_library('UI', - [ xsubpp.process( - files( - 'Formats.xs', - 'Themes.xs', - 'UI.xs', - 'Window.xs', +shared_library( + 'UI', + [ + xsubpp.process( + files( + 'Formats.xs', + 'Themes.xs', + 'UI.xs', + 'Window.xs', + ), + extra_args : [ + '-typemap', '../common/typemap', + ], ), - extra_args : [ - '-typemap', - '../common/typemap', - ], - ) ] + ] + files( 'module.h', ), @@ -22,7 +24,7 @@ shared_library('UI', implicit_include_directories : true, dependencies : dep + [ perl_dep ], link_with : dl_cross_perl_core + dl_cross_irssi_main, - override_options : ['b_lundef=false'], + override_options : [ 'b_lundef=false' ], ) install_headers( @@ -31,6 +33,6 @@ install_headers( ), install_dir : perlmoddir / 'Irssi', ) - + # 'Makefile.PL.in', # 'typemap', diff --git a/tests/fe-common/core/meson.build b/tests/fe-common/core/meson.build index 44b11222..a3181f7b 100644 --- a/tests/fe-common/core/meson.build +++ b/tests/fe-common/core/meson.build @@ -1,4 +1,5 @@ -test_test_formats = executable('test-formats', +test_test_formats = executable( + 'test-formats', files( 'test-formats.c', ), @@ -12,8 +13,11 @@ test_test_formats = executable('test-formats', ], include_directories : rootinc, implicit_include_directories : false, - dependencies : dep + dependencies : dep, +) +test( + 'test-formats test', + test_test_formats, + args : [ '--tap' ], + protocol : 'tap', ) -test('test-formats test', test_test_formats, - args : ['--tap'], - protocol : 'tap') diff --git a/tests/fe-text/meson.build b/tests/fe-text/meson.build index 397bd39f..68def5f8 100644 --- a/tests/fe-text/meson.build +++ b/tests/fe-text/meson.build @@ -1,4 +1,5 @@ -test_test_paste_join_multiline = executable('test-paste-join-multiline', +test_test_paste_join_multiline = executable( + 'test-paste-join-multiline', files( '../../src/fe-text/gui-entry.c', '../../src/fe-text/gui-printtext.c', @@ -25,7 +26,9 @@ test_test_paste_join_multiline = executable('test-paste-join-multiline', implicit_include_directories : false, dependencies : dep + textui_dep, ) -test('test-paste-join-multiline test', test_test_paste_join_multiline, - args : ['--tap'], - protocol : 'tap') - +test( + 'test-paste-join-multiline test', + test_test_paste_join_multiline, + args : [ '--tap' ], + protocol : 'tap', +) diff --git a/tests/irc/core/meson.build b/tests/irc/core/meson.build index f63f4fa8..d59b645d 100644 --- a/tests/irc/core/meson.build +++ b/tests/irc/core/meson.build @@ -1,4 +1,5 @@ -test_test_irc = executable('test-irc', +test_test_irc = executable( + 'test-irc', files( 'test-irc.c', ), @@ -13,15 +14,19 @@ test_test_irc = executable('test-irc', ], include_directories : rootinc, implicit_include_directories : false, - dependencies : dep + dependencies : dep, ) -test('test-irc test', test_test_irc, +test( + 'test-irc test', + test_test_irc, args : [ '--tap', ], - protocol : 'tap') + protocol : 'tap', +) -test_test_channel_events = executable('test-channel-events', +test_test_channel_events = executable( + 'test-channel-events', files( 'test-channel-events.c', ), @@ -36,10 +41,13 @@ test_test_channel_events = executable('test-channel-events', ], include_directories : rootinc, implicit_include_directories : false, - dependencies : dep + dependencies : dep, ) -test('test-channel-events test', test_test_channel_events, +test( + 'test-channel-events test', + test_test_channel_events, args : [ '--tap', ], - protocol : 'tap') + protocol : 'tap', +) diff --git a/tests/irc/flood/meson.build b/tests/irc/flood/meson.build index 78556331..9da3dda5 100644 --- a/tests/irc/flood/meson.build +++ b/tests/irc/flood/meson.build @@ -1,4 +1,5 @@ -test_test_796 = executable('test-796', +test_test_796 = executable( + 'test-796', files( 'test-796.c', ), @@ -17,10 +18,13 @@ test_test_796 = executable('test-796', ], include_directories : rootinc, implicit_include_directories : false, - dependencies : dep + dependencies : dep, ) -test('test-796 test', test_test_796, +test( + 'test-796 test', + test_test_796, args : [ '--tap', ], - protocol : 'tap') + protocol : 'tap', +) diff --git a/themes/meson.build b/themes/meson.build index d58dddf4..bdf2519e 100644 --- a/themes/meson.build +++ b/themes/meson.build @@ -3,4 +3,5 @@ install_data( 'default.theme', 'colorless.theme', ), - install_dir : themedir) + install_dir : themedir, +) From 7ca9fd5aee415ca50f0262a7382cb113732d5bfd Mon Sep 17 00:00:00 2001 From: William Storey Date: Mon, 26 Jan 2026 20:58:37 -0800 Subject: [PATCH 1197/1198] Format root meson.build --- meson.build | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/meson.build b/meson.build index d6c582b5..bb6d2829 100644 --- a/meson.build +++ b/meson.build @@ -28,40 +28,40 @@ elif host_machine.system() == 'cygwin' need_dl_cross_link_main = true endif -includedir = get_option('includedir') -incdir = 'irssi' -moduledir = get_option('libdir') / incdir / 'modules' -helpdir = get_option('datadir') / incdir / 'help' -themedir = get_option('datadir') / incdir / 'themes' -scriptdir = get_option('datadir') / incdir / 'scripts' -docdir = get_option('docdir') != '' ? get_option('docdir') : (get_option('datadir') / 'doc' / incdir) +includedir = get_option('includedir') +incdir = 'irssi' +moduledir = get_option('libdir') / incdir / 'modules' +helpdir = get_option('datadir') / incdir / 'help' +themedir = get_option('datadir') / incdir / 'themes' +scriptdir = get_option('datadir') / incdir / 'scripts' +docdir = get_option('docdir') != '' ? get_option('docdir') : (get_option('datadir') / 'doc' / incdir) -want_textui = get_option('without-textui') != 'yes' -want_bot = get_option('with-bot') == 'yes' -want_fuzzer = get_option('with-fuzzer') == 'yes' -fuzzer_lib = get_option('with-fuzzer-lib') +want_textui = get_option('without-textui') != 'yes' +want_bot = get_option('with-bot') == 'yes' +want_fuzzer = get_option('with-fuzzer') == 'yes' +fuzzer_lib = get_option('with-fuzzer-lib') fuzzer_link_language = get_option('fuzzer-link-language') -want_proxy = get_option('with-proxy') == 'yes' +want_proxy = get_option('with-proxy') == 'yes' -require_capsicum = get_option('with-capsicum') == 'yes' -want_capsicum = get_option('with-capsicum') != 'no' +require_capsicum = get_option('with-capsicum') == 'yes' +want_capsicum = get_option('with-capsicum') != 'no' require_libutf8proc = get_option('disable-utf8proc') == 'no' -want_libutf8proc = get_option('disable-utf8proc') != 'yes' +want_libutf8proc = get_option('disable-utf8proc') != 'yes' -require_perl = get_option('with-perl') == 'yes' -want_perl = get_option('with-perl') != 'no' -with_perl_lib = get_option('with-perl-lib') +require_perl = get_option('with-perl') == 'yes' +want_perl = get_option('with-perl') != 'no' +with_perl_lib = get_option('with-perl-lib') -require_otr = get_option('with-otr') == 'yes' -want_otr = get_option('with-otr') != 'no' +require_otr = get_option('with-otr') == 'yes' +want_otr = get_option('with-otr') != 'no' -want_glib_internal = get_option('install-glib') != 'no' +want_glib_internal = get_option('install-glib') != 'no' require_glib_internal = get_option('install-glib') == 'force' want_static_dependency = get_option('static-dependency') == 'yes' -package_version = get_option('PACKAGE_VERSION') != '' ? get_option('PACKAGE_VERSION') : meson.project_version() +package_version = get_option('PACKAGE_VERSION') != '' ? get_option('PACKAGE_VERSION') : meson.project_version() fs = import('fs') if fs.exists('config.status') or fs.exists('irssi-version.h') or fs.exists('default-config.h') or fs.exists('default-theme.h') or fs.exists('src/perl/irssi-core.pl.h') or fs.exists('src/perl/perl-signals-list.h') or fs.exists('irssi-config.h') @@ -97,11 +97,11 @@ run_command( check : false, ) -def_moduledir = '-D' + 'MODULEDIR' + '="' + (get_option('prefix') / moduledir) + '"' +def_moduledir = '-D' + 'MODULEDIR' + '="' + (get_option('prefix') / moduledir) + '"' def_sysconfdir = '-D' + 'SYSCONFDIR' + '="' + (get_option('prefix') / get_option('sysconfdir')) + '"' -def_helpdir = '-D' + 'HELPDIR' + '="' + (get_option('prefix') / helpdir) + '"' -def_themesdir = '-D' + 'THEMESDIR' + '="' + (get_option('prefix') / themedir) + '"' -def_scriptdir = '-D' + 'SCRIPTDIR' + '="' + (get_option('prefix') / scriptdir) + '"' +def_helpdir = '-D' + 'HELPDIR' + '="' + (get_option('prefix') / helpdir) + '"' +def_themesdir = '-D' + 'THEMESDIR' + '="' + (get_option('prefix') / themedir) + '"' +def_scriptdir = '-D' + 'SCRIPTDIR' + '="' + (get_option('prefix') / scriptdir) + '"' def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK' @@ -938,10 +938,8 @@ pc.generate( description : 'Irssi chat client', version : package_version, requires : pc_requires, - variables : [ - 'irssimoduledir=${libdir}' / incdir / 'modules', - 'signalsfile=' + signalsfile - ]) + variables : [ 'irssimoduledir=${libdir}' / incdir / 'modules', 'signalsfile=' + signalsfile ], +) ########### # irssi.1 # From 54bb34e14fa996ca2db543a7a62e1225ffe6c0f2 Mon Sep 17 00:00:00 2001 From: William Storey Date: Mon, 26 Jan 2026 20:42:05 -0800 Subject: [PATCH 1198/1198] Add muon fmt GitHub Actions workflow --- .github/workflows/muon-fmt.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/muon-fmt.yml diff --git a/.github/workflows/muon-fmt.yml b/.github/workflows/muon-fmt.yml new file mode 100644 index 00000000..6fa06d38 --- /dev/null +++ b/.github/workflows/muon-fmt.yml @@ -0,0 +1,32 @@ +name: Format meson files + +on: + push: + pull_request: + +permissions: {} + +jobs: + muon-meson-fmt: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + with: + persist-credentials: false + + # Build from source because Ubuntu 24.04 apt only has muon 0.2.0. + # Newer muons seem to format differently. + - name: Build muon from source + run: | + git clone --depth 1 --branch 0.5.0 https://github.com/muon-build/muon /tmp/muon + cd /tmp/muon + ./bootstrap.sh build + build/muon-bootstrap setup build + build/muon-bootstrap -C build samu + sudo build/muon -C build install + + - name: Run muon fmt + run: | + find . -name meson.build -print0 | xargs -0 muon fmt -c .muon_fmt.ini -i + git diff --exit-code