1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Redirection fixes.

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1983 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2001-11-11 20:20:43 +00:00 committed by cras
parent 24d51a694b
commit 5e1993346e
8 changed files with 132 additions and 104 deletions

View File

@ -167,7 +167,7 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
{ {
SERVER_QUERY_REC *rec; SERVER_QUERY_REC *rec;
IRC_CHANNEL_REC *chanrec; IRC_CHANNEL_REC *chanrec;
GSList *tmp, *chans, *newchans; GSList *chans, *newchans;
char *cmd, *chanstr_commas, *chanstr; char *cmd, *chanstr_commas, *chanstr;
int onlyone; int onlyone;
@ -206,71 +206,51 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
switch (query) { switch (query) {
case CHANNEL_QUERY_MODE: case CHANNEL_QUERY_MODE:
cmd = g_strdup_printf("MODE %s", chanstr_commas); cmd = g_strdup_printf("MODE %s", chanstr_commas);
for (tmp = chans; tmp != NULL; tmp = tmp->next) { server_redirect_event(server, "mode channel", chanstr, -1,
chanrec = tmp->data; "chanquery mode abort",
"event 324", "chanquery mode",
server_redirect_event(server, "mode channel", chanstr, -1, "", "chanquery mode abort", NULL);
"chanquery mode abort",
"event 324", "chanquery mode",
"", "chanquery mode abort", NULL);
}
break; break;
case CHANNEL_QUERY_WHO: case CHANNEL_QUERY_WHO:
cmd = g_strdup_printf("WHO %s", chanstr_commas); cmd = g_strdup_printf("WHO %s", chanstr_commas);
for (tmp = chans; tmp != NULL; tmp = tmp->next) { server_redirect_event(server, "who", chanstr, -1,
chanrec = tmp->data; "chanquery who abort",
"event 315", "chanquery who end",
server_redirect_event(server, "who", chanstr, -1, "event 352", "silent event who",
"chanquery who abort", "", "chanquery who abort", NULL);
"event 315", "chanquery who end",
"event 352", "silent event who",
"", "chanquery who abort", NULL);
}
break; break;
case CHANNEL_QUERY_BMODE: case CHANNEL_QUERY_BMODE:
cmd = g_strdup_printf("MODE %s b", chanstr_commas); cmd = g_strdup_printf("MODE %s b", chanstr_commas);
for (tmp = chans; tmp != NULL; tmp = tmp->next) { /* check all the multichannel problems with all
chanrec = tmp->data; mode requests - if channels are joined manually
irssi could ask modes separately but afterwards
/* check all the multichannel problems with all join the two b/e/I modes together */
mode requests - if channels are joined manually server_redirect_event(server, "mode b", chanstr, -1,
irssi could ask modes separately but afterwards "chanquery mode abort",
join the two b/e/I modes together */ "event 367", "chanquery ban",
server_redirect_event(server, "mode b", chanstr, -1, "event 368", "chanquery ban end",
"chanquery mode abort", "", "chanquery mode abort", NULL);
"event 367", "chanquery ban",
"event 368", "chanquery ban end",
"", "chanquery mode abort", NULL);
}
break; break;
case CHANNEL_QUERY_EMODE: case CHANNEL_QUERY_EMODE:
cmd = g_strdup_printf("MODE %s e", chanstr_commas); cmd = g_strdup_printf("MODE %s e", chanstr_commas);
for (tmp = chans; tmp != NULL; tmp = tmp->next) { server_redirect_event(server, "mode e", chanstr, -1,
chanrec = tmp->data; "chanquery mode abort",
"event 348", "chanquery eban",
server_redirect_event(server, "mode e", chanstr, -1, "event 349", "chanquery eban end",
"chanquery mode abort", "", "chanquery mode abort", NULL);
"event 348", "chanquery eban",
"event 349", "chanquery eban end",
"", "chanquery mode abort", NULL);
}
break; break;
case CHANNEL_QUERY_IMODE: case CHANNEL_QUERY_IMODE:
cmd = g_strdup_printf("MODE %s I", chanstr_commas); cmd = g_strdup_printf("MODE %s I", chanstr_commas);
for (tmp = chans; tmp != NULL; tmp = tmp->next) { server_redirect_event(server, "mode I", chanstr, -1,
chanrec = tmp->data; "chanquery mode abort",
"event 346", "chanquery ilist",
server_redirect_event(server, "mode I", chanstr, -1, "event 347", "chanquery ilist end",
"chanquery mode abort", "", "chanquery mode abort", NULL);
"event 346", "chanquery ilist",
"event 347", "chanquery ilist end",
"", "chanquery mode abort", NULL);
}
break; break;
default: default:

View File

@ -418,7 +418,6 @@ static void sig_whois_not_found(IRC_SERVER_REC *server, const char *data)
server_redirect_event(server, "whowas", nick, -1, NULL, server_redirect_event(server, "whowas", nick, -1, NULL,
"event 314", "whowas event", "event 314", "whowas event",
"event 369", "whowas event end", "event 369", "whowas event end",
"event 406", "event empty",
"", "event empty", NULL); "", "event empty", NULL);
irc_send_cmdv(server, "WHOWAS %s 1", nick); irc_send_cmdv(server, "WHOWAS %s 1", nick);

View File

@ -211,20 +211,33 @@ static int command_has_target(const char *cmd, const char *target)
/* Purge server output, either all or for specified target */ /* Purge server output, either all or for specified target */
void irc_server_purge_output(IRC_SERVER_REC *server, const char *target) void irc_server_purge_output(IRC_SERVER_REC *server, const char *target)
{ {
GSList *tmp, *next; GSList *tmp, *next, *link;
REDIRECT_REC *redirect;
char *cmd; char *cmd;
if (target != NULL && *target == '\0') if (target != NULL && *target == '\0')
target = NULL; target = NULL;
for (tmp = server->cmdqueue; tmp != NULL; tmp = next) { for (tmp = server->cmdqueue; tmp != NULL; tmp = next) {
next = tmp->next; next = tmp->next->next;
cmd = tmp->data; cmd = tmp->data;
redirect = tmp->next->data;
if ((target == NULL || command_has_target(cmd, target)) && if ((target == NULL || command_has_target(cmd, target)) &&
g_strncasecmp(cmd, "PONG ", 5) != 0) { g_strncasecmp(cmd, "PONG ", 5) != 0) {
/* remove the redirection */
link = tmp->next;
server->cmdqueue =
g_slist_remove_link(server->cmdqueue, link);
g_slist_free_1(link);
if (redirect != NULL)
server_redirect_destroy(redirect);
/* remove the command */
server->cmdqueue = server->cmdqueue =
g_slist_remove(server->cmdqueue, cmd); g_slist_remove(server->cmdqueue, cmd);
g_free(cmd);
server->cmdcount--; server->cmdcount--;
} }
} }
@ -241,10 +254,16 @@ static void sig_connected(IRC_SERVER_REC *server)
static void sig_disconnected(IRC_SERVER_REC *server) static void sig_disconnected(IRC_SERVER_REC *server)
{ {
GSList *tmp;
if (!IS_IRC_SERVER(server)) if (!IS_IRC_SERVER(server))
return; return;
g_slist_foreach(server->cmdqueue, (GFunc) g_free, NULL); for (tmp = server->cmdqueue; tmp != NULL; tmp = tmp->next->next) {
g_free(tmp->data);
if (tmp->next->data != NULL)
server_redirect_destroy(tmp->next->data);
}
g_slist_free(server->cmdqueue); g_slist_free(server->cmdqueue);
g_free_not_null(server->real_address); g_free_not_null(server->real_address);
@ -268,6 +287,8 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg)
static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
{ {
REDIRECT_REC *redirect;
GSList *link;
long usecs; long usecs;
char *cmd; char *cmd;
int len; int len;
@ -290,6 +311,7 @@ static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
/* send command */ /* send command */
cmd = server->cmdqueue->data; cmd = server->cmdqueue->data;
redirect = server->cmdqueue->next->data;
len = strlen(cmd); len = strlen(cmd);
if (net_sendbuffer_send(server->handle, cmd, len) == -1) { if (net_sendbuffer_send(server->handle, cmd, len) == -1) {
@ -305,11 +327,15 @@ static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
/* add to rawlog without CR+LF */ /* add to rawlog without CR+LF */
cmd[len-2] = '\0'; cmd[len-2] = '\0';
rawlog_output(server->rawlog, cmd); rawlog_output(server->rawlog, cmd);
server_redirect_command(server, cmd); server_redirect_command(server, cmd, redirect);
/* remove from queue */ /* remove from queue */
g_free(cmd); g_free(cmd);
server->cmdqueue = g_slist_remove(server->cmdqueue, cmd); server->cmdqueue = g_slist_remove(server->cmdqueue, cmd);
link = server->cmdqueue;
server->cmdqueue = g_slist_remove_link(server->cmdqueue, link);
g_slist_free_1(link);
} }
/* check every now and then if there's data to be sent in command buffer */ /* check every now and then if there's data to be sent in command buffer */

View File

@ -38,9 +38,10 @@ struct _IRC_SERVER_REC {
#include "server-rec.h" #include "server-rec.h"
/* For deciding if event should be redirected */ /* For deciding if event should be redirected */
GSList *redirects; GSList *redirects;
void *redirect_next; GSList *redirect_queue; /* should be updated from redirect_next each time cmdqueue is updated */
void *redirect_continue; REDIRECT_REC *redirect_next;
REDIRECT_REC *redirect_continue;
char *real_address; /* address the irc server gives */ char *real_address; /* address the irc server gives */
char *usermode; /* The whole mode string .. */ char *usermode; /* The whole mode string .. */
@ -66,7 +67,7 @@ struct _IRC_SERVER_REC {
there actually is, to make flood control remember there actually is, to make flood control remember
how many messages can be sent before starting the how many messages can be sent before starting the
flood control */ flood control */
GSList *cmdqueue; GSList *cmdqueue; /* command, redirection, ... */
GTimeVal wait_cmd; /* don't send anything to server before this */ GTimeVal wait_cmd; /* don't send anything to server before this */
GTimeVal last_cmd; /* last time command was sent to server */ GTimeVal last_cmd; /* last time command was sent to server */

View File

@ -64,7 +64,8 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
if (send_now) { if (send_now) {
rawlog_output(server->rawlog, cmd); rawlog_output(server->rawlog, cmd);
server_redirect_command(server, cmd); server_redirect_command(server, cmd, server->redirect_next);
server->redirect_next = NULL;
} }
if (!raw) { if (!raw) {
@ -87,9 +88,18 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
} }
/* add to queue */ /* add to queue */
server->cmdqueue = immediate ? if (immediate) {
g_slist_prepend(server->cmdqueue, g_strdup(cmd)) : server->cmdqueue = g_slist_prepend(server->cmdqueue,
g_slist_append(server->cmdqueue, g_strdup(cmd)); server->redirect_next);
server->cmdqueue = g_slist_prepend(server->cmdqueue,
g_strdup(cmd));
} else {
server->cmdqueue = g_slist_append(server->cmdqueue,
g_strdup(cmd));
server->cmdqueue = g_slist_append(server->cmdqueue,
server->redirect_next);
}
server->redirect_next = NULL;
} }
/* Send command to IRC server */ /* Send command to IRC server */

View File

@ -5,6 +5,7 @@ typedef struct _IRC_CHATNET_REC IRC_CHATNET_REC;
typedef struct _IRC_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC; typedef struct _IRC_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC;
typedef struct _IRC_SERVER_REC IRC_SERVER_REC; typedef struct _IRC_SERVER_REC IRC_SERVER_REC;
typedef struct _IRC_CHANNEL_REC IRC_CHANNEL_REC; typedef struct _IRC_CHANNEL_REC IRC_CHANNEL_REC;
typedef struct _REDIRECT_REC REDIRECT_REC;
/* From ircd 2.9.5: /* From ircd 2.9.5:
none I line with ident none I line with ident

View File

@ -33,7 +33,7 @@ typedef struct {
GSList *start, *stop; /* char *event, int argpos, ... */ GSList *start, *stop; /* char *event, int argpos, ... */
} REDIRECT_CMD_REC; } REDIRECT_CMD_REC;
typedef struct { struct _REDIRECT_REC {
REDIRECT_CMD_REC *cmd; REDIRECT_CMD_REC *cmd;
time_t created; time_t created;
int destroyed; int destroyed;
@ -42,7 +42,7 @@ typedef struct {
int remote; int remote;
char *failure_signal, *default_signal; char *failure_signal, *default_signal;
GSList *signals; /* event, signal, ... */ GSList *signals; /* event, signal, ... */
} REDIRECT_REC; };
static GHashTable *command_redirects; /* "command xxx" : REDIRECT_CMD_REC* */ static GHashTable *command_redirects; /* "command xxx" : REDIRECT_CMD_REC* */
@ -88,7 +88,7 @@ static void redirect_cmd_unref(REDIRECT_CMD_REC *rec)
redirect_cmd_destroy(rec); redirect_cmd_destroy(rec);
} }
static void redirect_destroy(REDIRECT_REC *rec) void server_redirect_destroy(REDIRECT_REC *rec)
{ {
redirect_cmd_unref(rec->cmd); redirect_cmd_unref(rec->cmd);
@ -199,7 +199,7 @@ void server_redirect_event_list(IRC_SERVER_REC *server, const char *command,
g_return_if_fail((g_slist_length(signals) & 1) == 0); g_return_if_fail((g_slist_length(signals) & 1) == 0);
if (server->redirect_next != NULL) { if (server->redirect_next != NULL) {
redirect_destroy(server->redirect_next); server_redirect_destroy(server->redirect_next);
server->redirect_next = NULL; server->redirect_next = NULL;
} }
@ -232,18 +232,15 @@ void server_redirect_event_list(IRC_SERVER_REC *server, const char *command,
server->redirect_next = rec; server->redirect_next = rec;
} }
void server_redirect_command(IRC_SERVER_REC *server, const char *command) void server_redirect_command(IRC_SERVER_REC *server, const char *command,
REDIRECT_REC *redirect)
{ {
REDIRECT_CMD_REC *cmdrec; REDIRECT_CMD_REC *cmdrec;
REDIRECT_REC *rec;
g_return_if_fail(IS_IRC_SERVER(server)); g_return_if_fail(IS_IRC_SERVER(server));
g_return_if_fail(command != NULL); g_return_if_fail(command != NULL);
if (server->redirect_next != NULL) { if (redirect == NULL) {
rec = server->redirect_next;
server->redirect_next = NULL;
} else {
cmdrec = redirect_cmd_find(command); cmdrec = redirect_cmd_find(command);
if (cmdrec == NULL) if (cmdrec == NULL)
return; return;
@ -252,13 +249,13 @@ void server_redirect_command(IRC_SERVER_REC *server, const char *command)
so future redirections wont get messed up. */ so future redirections wont get messed up. */
redirect_cmd_ref(cmdrec); redirect_cmd_ref(cmdrec);
rec = g_new0(REDIRECT_REC, 1); redirect = g_new0(REDIRECT_REC, 1);
rec->created = time(NULL); redirect->created = time(NULL);
rec->cmd = cmdrec; redirect->cmd = cmdrec;
rec->remote = cmdrec->remote; redirect->remote = cmdrec->remote;
} }
server->redirects = g_slist_append(server->redirects, rec); server->redirects = g_slist_append(server->redirects, redirect);
} }
static int redirect_args_match(const char *event_args, static int redirect_args_match(const char *event_args,
@ -316,35 +313,43 @@ static const char *redirect_match(REDIRECT_REC *redirect, const char *event,
const char *args, int *match_stop) const char *args, int *match_stop)
{ {
GSList *tmp, *cmdpos; GSList *tmp, *cmdpos;
const char *signal;
int stop_signal; int stop_signal;
/* get the signal for redirection event - if it's not found we'll
use the default signal */
signal = NULL;
for (tmp = redirect->signals; tmp != NULL; tmp = tmp->next->next) { for (tmp = redirect->signals; tmp != NULL; tmp = tmp->next->next) {
if (strcmp(tmp->data, event) != 0) if (strcmp(tmp->data, event) == 0) {
continue; signal = tmp->next->data;
break;
/* 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;
} }
/* check that arguments match */
if (args != NULL && redirect->arg != NULL && cmdpos != NULL &&
!redirect_args_match(args, redirect->arg,
GPOINTER_TO_INT(cmdpos->next->data)))
continue;
*match_stop = stop_signal;
return tmp->next->data;
} }
*match_stop = redirect_cmd_list_find(redirect->cmd->stop, /* find the argument position */
event) != NULL; cmdpos = redirect_cmd_list_find(redirect->cmd->start, event);
return NULL; 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) {
/* event not found from specified redirection events nor
registered command events */
return NULL;
}
/* check that arguments match */
if (args != NULL && redirect->arg != NULL && cmdpos != NULL &&
!redirect_args_match(args, redirect->arg,
GPOINTER_TO_INT(cmdpos->next->data)))
return NULL;
*match_stop = stop_signal;
return signal != NULL ? signal : redirect->default_signal;
} }
static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event, static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event,
@ -386,7 +391,7 @@ static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event,
/* emit the failure signal */ /* emit the failure signal */
signal_emit(rec->failure_signal, 1, server); signal_emit(rec->failure_signal, 1, server);
} }
redirect_destroy(rec); server_redirect_destroy(rec);
} }
} }
@ -404,6 +409,7 @@ const char *server_redirect_get_signal(IRC_SERVER_REC *server,
if (server->redirects == NULL) if (server->redirects == NULL)
return NULL; return NULL;
match_stop = FALSE;
if (server->redirect_continue == NULL) { if (server->redirect_continue == NULL) {
/* find the redirection */ /* find the redirection */
redirect = redirect_find(server, event, args, redirect = redirect_find(server, event, args,
@ -442,11 +448,12 @@ static void sig_disconnected(IRC_SERVER_REC *server)
if (!IS_IRC_SERVER(server)) if (!IS_IRC_SERVER(server))
return; return;
g_slist_foreach(server->redirects, (GFunc) redirect_destroy, NULL); g_slist_foreach(server->redirects,
(GFunc) server_redirect_destroy, NULL);
g_slist_free(server->redirects); g_slist_free(server->redirects);
if (server->redirect_next != NULL) if (server->redirect_next != NULL)
redirect_destroy(server->redirect_next); server_redirect_destroy(server->redirect_next);
} }
static void cmd_redirect_destroy(char *key, REDIRECT_CMD_REC *cmd) static void cmd_redirect_destroy(char *key, REDIRECT_CMD_REC *cmd)

View File

@ -53,13 +53,17 @@ void server_redirect_event_list(IRC_SERVER_REC *server, const char *command,
/* irc_send_cmd() calls this to make sure redirecting knows /* irc_send_cmd() calls this to make sure redirecting knows
what's sent to server */ what's sent to server */
void server_redirect_command(IRC_SERVER_REC *server, const char *command); void server_redirect_command(IRC_SERVER_REC *server, const char *command,
REDIRECT_REC *redirect);
/* Returns the redirection signal for specified event. /* Returns the redirection signal for specified event.
This is the function that contains the real redirecting logic. */ This is the function that contains the real redirecting logic. */
const char *server_redirect_get_signal(IRC_SERVER_REC *server, const char *server_redirect_get_signal(IRC_SERVER_REC *server,
const char *event, const char *event,
const char *args); const char *args);
/* Destroy redirection record */
void server_redirect_destroy(REDIRECT_REC *rec);
void servers_redirect_init(void); void servers_redirect_init(void);
void servers_redirect_deinit(void); void servers_redirect_deinit(void);