summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-11-17 00:07:24 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-11-17 00:07:24 +0000
commit1c29219d1cba8250d104af5367bcc4d5c585609c (patch)
treef332e3f5989bd58f41fc53f23fb4eb0aa4c6a2d5 /src
parent7545f463bd279359a56521ff6114634dc4d0ea6f (diff)
downloadirssi-1c29219d1cba8250d104af5367bcc4d5c585609c.zip
Added support for "optional events" in redirection. They're checked right
after stop-signal is received. This fixes /WHOIS non_existing_nick in OPN, and also hides the Channel created-event when joining to channel that's received in several networks after /MODE #channel. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2037 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src')
-rw-r--r--src/irc/core/servers-redirect.c74
-rw-r--r--src/perl/irc/Server.xs6
2 files changed, 56 insertions, 24 deletions
diff --git a/src/irc/core/servers-redirect.c b/src/irc/core/servers-redirect.c
index a6a1a38d..495423bc 100644
--- a/src/irc/core/servers-redirect.c
+++ b/src/irc/core/servers-redirect.c
@@ -39,7 +39,7 @@ typedef struct {
int remote;
int timeout;
- GSList *start, *stop; /* char *event, int argpos, ... */
+ GSList *start, *stop, *opt; /* char *event, int argpos, ... */
} REDIRECT_CMD_REC;
struct _REDIRECT_REC {
@@ -83,8 +83,11 @@ static void redirect_cmd_destroy(REDIRECT_CMD_REC *rec)
g_free(tmp->data);
for (tmp = rec->stop; tmp != NULL; tmp = tmp->next->next)
g_free(tmp->data);
+ for (tmp = rec->opt; tmp != NULL; tmp = tmp->next->next)
+ g_free(tmp->data);
g_slist_free(rec->start);
g_slist_free(rec->stop);
+ g_slist_free(rec->opt);
g_free(rec->name);
g_free(rec);
}
@@ -116,18 +119,21 @@ void server_redirect_register(const char *command,
int remote, int timeout, ...)
{
va_list va;
- GSList *start, *stop, **list;
+ GSList *start, *stop, *opt, **list;
const char *event;
int argpos;
va_start(va, timeout);
- start = stop = NULL; list = &start;
+ start = stop = opt = NULL; list = &start;
for (;;) {
event = va_arg(va, const char *);
if (event == NULL) {
- if (list == &stop)
- break;
- list = &stop;
+ if (list == &start)
+ list = &stop;
+ else if (list == &stop)
+ list = &opt;
+ else
+ break;
continue;
}
@@ -138,12 +144,13 @@ void server_redirect_register(const char *command,
va_end(va);
- server_redirect_register_list(command, remote, timeout, start, stop);
+ server_redirect_register_list(command, remote, timeout,
+ start, stop, opt);
}
void server_redirect_register_list(const char *command,
int remote, int timeout,
- GSList *start, GSList *stop)
+ GSList *start, GSList *stop, GSList *opt)
{
REDIRECT_CMD_REC *rec;
gpointer key, value;
@@ -166,6 +173,7 @@ void server_redirect_register_list(const char *command,
rec->timeout = timeout > 0 ? timeout : DEFAULT_REDIRECT_TIMEOUT;
rec->start = start;
rec->stop = stop;
+ rec->opt = opt;
g_hash_table_insert(command_redirects, rec->name, rec);
}
@@ -337,13 +345,24 @@ static const char *redirect_match(REDIRECT_REC *redirect, const char *event,
}
/* find the argument position */
- cmdpos = redirect_cmd_list_find(redirect->cmd->start, event);
- if (cmdpos != NULL)
- stop_signal = FALSE;
- else {
- cmdpos = redirect_cmd_list_find(redirect->cmd->stop,
- event);
- stop_signal = cmdpos != NULL;
+ if (redirect->destroyed) {
+ /* stop event is already found for this redirection, but
+ we'll still want to look for optional events */
+ cmdpos = redirect_cmd_list_find(redirect->cmd->opt, event);
+ if (cmdpos == NULL)
+ return NULL;
+
+ stop_signal = TRUE;
+ } else {
+ /* look from start/stop lists */
+ cmdpos = redirect_cmd_list_find(redirect->cmd->start, event);
+ if (cmdpos != NULL)
+ stop_signal = FALSE;
+ else {
+ cmdpos = redirect_cmd_list_find(redirect->cmd->stop,
+ event);
+ stop_signal = cmdpos != NULL;
+ }
}
if (signal == NULL && cmdpos == NULL) {
@@ -396,12 +415,10 @@ static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event,
for (tmp = server->redirects; tmp != NULL; tmp = tmp->next) {
REDIRECT_REC *rec = tmp->data;
- if (!rec->destroyed) {
- *signal = redirect_match(rec, event, args, match_stop);
- if (*signal != NULL) {
- redirect = rec;
- break;
- }
+ *signal = redirect_match(rec, event, args, match_stop);
+ if (*signal != NULL) {
+ redirect = rec;
+ break;
}
}
@@ -523,10 +540,12 @@ void servers_redirect_init(void)
with a default timeout */
server_redirect_register("whois", TRUE, 0,
"event 311", 1, /* Begins the WHOIS */
- "event 401", 1, /* No such nick */
NULL,
+ "event 401", 1, /* No such nick */
"event 318", 1, /* End of WHOIS */
"event 402", 1, /* No such server */
+ NULL,
+ "event 318", 1, /* After 401, we should get 318, but in OPN we don't.. */
NULL);
/* WHOWAS */
@@ -535,6 +554,7 @@ void servers_redirect_init(void)
"event 406", 1, /* There was no such nick */
NULL,
"event 369", 1, /* End of WHOWAS */
+ NULL,
NULL);
/* WHO */
@@ -544,6 +564,7 @@ void servers_redirect_init(void)
NULL,
"event 315", 1, /* End of WHO */
"event 403", 1, /* no such channel */
+ NULL,
NULL);
/* LIST */
@@ -551,12 +572,14 @@ void servers_redirect_init(void)
"event 321", 1, /* Begins the LIST */
NULL,
"event 323", 1, /* End of LIST */
+ NULL,
NULL);
/* ISON */
server_redirect_register("ison", FALSE, 0,
NULL,
"event 303", -1, /* ISON */
+ NULL,
NULL);
/* USERHOST */
@@ -565,6 +588,7 @@ void servers_redirect_init(void)
NULL,
"event 302", -1, /* Userhost */
"event 461", -1, /* Not enough parameters */
+ NULL,
NULL);
/* MODE #channel */
@@ -574,6 +598,8 @@ void servers_redirect_init(void)
"event 403", 1, /* no such channel */
"event 442", 1, /* "you're not on that channel" */
"event 479", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
+ NULL,
+ "event 329", 1, /* Channel create time */
NULL);
/* MODE #channel b */
@@ -584,6 +610,7 @@ void servers_redirect_init(void)
"event 403", 1, /* no such channel */
"event 442", 1, /* "you're not on that channel" */
"event 479", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
+ NULL,
NULL);
/* MODE #channel e */
@@ -596,6 +623,7 @@ void servers_redirect_init(void)
"event 442", 1, /* "you're not on that channel" */
"event 479", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
"event 472", -1, /* unknown mode (you should check e-mode's existance from 004 event instead of relying on this) */
+ NULL,
NULL);
/* MODE #channel I */
@@ -608,6 +636,7 @@ void servers_redirect_init(void)
"event 442", 1, /* "you're not on that channel" */
"event 479", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
"event 472", -1, /* unknown mode (you should check I-mode's existance from 004 event instead of relying on this) */
+ NULL,
NULL);
/* PING - use default timeout */
@@ -615,6 +644,7 @@ void servers_redirect_init(void)
NULL,
"event 402", -1, /* no such server */
"event pong", -1, /* PONG */
+ NULL,
NULL);
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
diff --git a/src/perl/irc/Server.xs b/src/perl/irc/Server.xs
index df04e181..db4f7ced 100644
--- a/src/perl/irc/Server.xs
+++ b/src/perl/irc/Server.xs
@@ -81,16 +81,18 @@ ctcp_send_reply(server, data)
MODULE = Irssi::Irc::Server PACKAGE = Irssi::Irc::Server PREFIX = server_
void
-server_redirect_register(command, remote, timeout, start, stop)
+server_redirect_register(command, remote, timeout, start, stop, opt)
char *command
int remote
int timeout
SV *start
SV *stop
+ SV *opt
CODE:
server_redirect_register_list(command, remote, timeout,
register_hash2list(hvref(start)),
- register_hash2list(hvref(stop)));
+ register_hash2list(hvref(stop)),
+ register_hash2list(hvref(opt)));
void
server_redirect_event(server, command, count, arg, remote, failure_signal, signals)