1
0
mirror of https://github.com/irssi/irssi.git synced 2025-02-02 15:08:01 -05:00

Merge branch 'master' into 'security'

Sync to master

See merge request !6
This commit is contained in:
Nei 2017-01-02 17:03:31 +00:00 committed by ailin-nemui
commit 7a112e0217
19 changed files with 350 additions and 118 deletions

View File

@ -13,6 +13,7 @@ Irssi staff (current maintainers) <staff@irssi.org>:
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:

View File

@ -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
@ -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 **
@ -237,7 +246,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)
@ -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."

View File

@ -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

View File

@ -67,11 +67,12 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text)
return FALSE;
if (rec->regexp) {
#ifdef HAVE_REGEX_H
#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;
#else
return FALSE;
#endif
}
@ -326,12 +327,27 @@ static void ignore_remove_config(IGNORE_REC *rec)
static void ignore_init_rec(IGNORE_REC *rec)
{
#ifdef HAVE_REGEX_H
#ifdef USE_GREGEX
if (rec->preg != NULL)
g_regex_unref(rec->preg);
if (rec->regexp && rec->pattern != NULL) {
GError *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);
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);
@ -365,7 +381,9 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal)
if (send_signal)
signal_emit("ignore destroyed", 1, rec);
#ifdef HAVE_REGEX_H
#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);

View File

@ -1,7 +1,7 @@
#ifndef __IGNORE_H
#define __IGNORE_H
#ifdef HAVE_REGEX_H
#ifndef USE_GREGEX
# include <regex.h>
#endif
@ -20,7 +20,9 @@ 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
#ifdef USE_GREGEX
GRegex *preg;
#else
unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */
regex_t preg;
#endif

View File

@ -22,7 +22,7 @@
#include "misc.h"
#include "commands.h"
#ifdef HAVE_REGEX_H
#ifndef USE_GREGEX
# include <regex.h>
#endif

View File

@ -58,7 +58,10 @@ 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
#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

View File

@ -35,30 +35,83 @@
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;
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);
}
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;
GSList *tmp;
GSequenceIter *iter, *end;
int refnum;
refnum = 1;
tmp = windows;
while (tmp != NULL) {
win = tmp->data;
iter = windows_seq_begin();
end = windows_seq_end();
if (refnum != win->refnum) {
tmp = tmp->next;
continue;
}
while (iter != end) {
win = g_sequence_get(iter);
if (refnum != win->refnum)
return refnum;
refnum++;
tmp = windows;
iter = g_sequence_iter_next(iter);
}
return refnum;
@ -73,6 +126,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);
windows_seq_insert(rec);
signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic));
if (item != NULL) window_item_add(rec, item, automatic);
@ -84,6 +138,19 @@ 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));
}
/* 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 +158,37 @@ 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 = windows_seq_end();
iter = windows_seq_refnum_lookup(refnum);
if (iter == NULL) return;
while (iter != end) {
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);
windows_seq_changed(iter);
refnum++;
iter = g_sequence_iter_next(iter);
}
}
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 = windows_seq_window_lookup(window);
if (iter != NULL) g_sequence_remove(iter);
if (active_win == window) {
active_win = NULL; /* it's corrupted */
@ -189,26 +270,32 @@ void window_change_server(WINDOW_REC *window, void *server)
void window_set_refnum(WINDOW_REC *window, int refnum)
{
GSList *tmp;
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;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
other_iter = windows_seq_refnum_lookup(refnum);
window_iter = windows_seq_refnum_lookup(window->refnum);
if (rec->refnum == refnum) {
rec->refnum = window->refnum;
signal_emit("window refnum changed", 2, rec, GINT_TO_POINTER(refnum));
break;
}
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));
}
old_refnum = window->refnum;
window->refnum = refnum;
signal_emit("window refnum changed", 2, window, GINT_TO_POINTER(old_refnum));
if (window_iter != NULL && other_iter != NULL) {
g_sequence_swap(other_iter, window_iter);
} else {
windows_seq_changed(window_iter);
}
}
void window_set_name(WINDOW_REC *window, const char *name)
@ -346,13 +433,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 = windows_seq_refnum_lookup(refnum);
if (iter != NULL) {
WINDOW_REC *rec = g_sequence_get(iter);
if (rec->refnum == refnum)
return rec;
return rec;
}
return NULL;
@ -400,71 +487,86 @@ WINDOW_REC *window_find_item(SERVER_REC *server, const char *name)
int window_refnum_prev(int refnum, int wrap)
{
GSList *tmp;
int prev, max;
WINDOW_REC *rec;
GSequenceIter *iter, *end;
max = prev = -1;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
iter = windows_seq_refnum_search_left(refnum);
end = windows_seq_end();
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) {
rec = g_sequence_get(iter);
return rec->refnum;
}
return prev != -1 ? prev : max;
if (wrap) {
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;
WINDOW_REC *rec;
GSequenceIter *iter, *end;
min = next = -1;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
iter = windows_seq_refnum_search_right(refnum);
end = windows_seq_end();
if (rec->refnum > refnum && (next == -1 || rec->refnum < next))
next = rec->refnum;
if (wrap && (min == -1 || rec->refnum < min))
min = rec->refnum;
if (iter != end) {
rec = g_sequence_get(iter);
return rec->refnum;
}
return next != -1 ? next : min;
if (wrap) {
iter = windows_seq_begin();
if (iter != end) {
rec = g_sequence_get(iter);
return rec->refnum;
}
}
return -1;
}
int windows_refnum_last(void)
{
GSList *tmp;
int max;
WINDOW_REC *rec;
GSequenceIter *end, *iter;
max = -1;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
if (rec->refnum > max)
max = rec->refnum;
end = windows_seq_end();
iter = g_sequence_iter_prev(end);
if (iter != end) {
rec = g_sequence_get(iter);
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;
iter = windows_seq_end();
begin = windows_seq_begin();
sorted = g_slist_insert_sorted(sorted, rec, (GCompareFunc)
window_refnum_cmp);
while (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 +811,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 +836,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;
}

View File

@ -101,7 +101,9 @@ static void hilight_destroy(HILIGHT_REC *rec)
{
g_return_if_fail(rec != NULL);
#ifdef HAVE_REGEX_H
#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);
@ -120,7 +122,12 @@ static void hilights_destroy_all(void)
static void hilight_init_rec(HILIGHT_REC *rec)
{
#ifdef HAVE_REGEX_H
#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;
@ -194,13 +201,24 @@ 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) {
#ifdef HAVE_REGEX_H
#ifdef USE_GREGEX
if (rec->preg != NULL) {
GMatchInfo *match;
g_regex_match (rec->preg, text, 0, &match);
if (g_match_info_matches(match))
ret = g_match_info_fetch_pos(match, 0, match_beg, match_end);
g_match_info_free(match);
}
#else
regmatch_t rmatch[1];
if (rec->regexp_compiled &&
@ -210,10 +228,12 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text,
*match_beg = rmatch[0].rm_so;
*match_end = rmatch[0].rm_eo;
}
return TRUE;
ret = TRUE;
}
#endif
} else {
char *match;
if (rec->case_sensitive) {
match = rec->fullword ?
strstr_full(text, rec->text) :
@ -228,11 +248,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) \
@ -509,7 +529,10 @@ 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
#ifdef USE_GREGEX
if (rec->preg == NULL)
g_string_append(options, "[INVALID!] ");
#else
if (!rec->regexp_compiled)
g_string_append(options, "[INVALID!] ");
#endif

View File

@ -1,7 +1,7 @@
#ifndef __HILIGHT_TEXT_H
#define __HILIGHT_TEXT_H
#ifdef HAVE_REGEX_H
#ifndef USE_GREGEX
# include <regex.h>
#endif
@ -24,7 +24,9 @@ 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
#ifdef USE_GREGEX
GRegex *preg;
#else
unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */
regex_t preg;
#endif

View File

@ -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);
}
}

View File

@ -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,11 @@
#include "module-formats.h"
#include "signals.h"
#include "levels.h"
#include "misc.h"
#include "sasl.h"
#include "irc-servers.h"
#include "settings.h"
#include "printtext.h"
@ -35,14 +40,36 @@ 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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -27,7 +27,7 @@
#include "textbuffer.h"
#ifdef HAVE_REGEX_H
#ifndef USE_GREGEX
# include <regex.h>
#endif
@ -537,7 +537,9 @@ 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
#ifdef USE_GREGEX
GRegex *preg;
#else
regex_t preg;
#endif
LINE_REC *line, *pre_line;
@ -549,16 +551,23 @@ 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);
if (preg == NULL)
return NULL;
}
#else
if (regexp) {
#ifdef HAVE_REGEX_H
int flags = REG_EXTENDED | REG_NOSUB |
(case_sensitive ? 0 : REG_ICASE);
if (regcomp(&preg, text, flags) != 0)
return NULL;
#else
return NULL;
#endif
}
#endif
matches = NULL; match_after = 0;
str = g_string_new(NULL);
@ -577,12 +586,15 @@ 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 :
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
match_func(str->str, text) != NULL;
: match_func(str->str, text) != NULL;
}
}
if (line_matched) {
@ -610,7 +622,11 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline,
matches = g_list_append(matches, NULL);
}
}
#ifdef HAVE_REGEX_H
#ifdef USE_GREGEX
if (preg != NULL)
g_regex_unref(preg);
#else
if (regexp) regfree(&preg);
#endif
g_string_free(str, TRUE);

View File

@ -81,20 +81,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)
@ -119,14 +105,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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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)