mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Moved rewritten server redirection code from core to irc. This new code
should be able to do the redirecting a lot more error-proof. Changed lag-checking to use PINGs instead of NOTIFYs. This breaks scripts using redirection. Hopefully this doesn't break too much things in irssi :) git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1980 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
712f3b383d
commit
850cf993eb
src
@ -44,7 +44,6 @@ libcore_a_SOURCES = \
|
|||||||
rawlog.c \
|
rawlog.c \
|
||||||
servers.c \
|
servers.c \
|
||||||
servers-reconnect.c \
|
servers-reconnect.c \
|
||||||
servers-redirect.c \
|
|
||||||
servers-setup.c \
|
servers-setup.c \
|
||||||
settings.c \
|
settings.c \
|
||||||
signals.c \
|
signals.c \
|
||||||
@ -92,7 +91,6 @@ noinst_HEADERS = \
|
|||||||
rawlog.h \
|
rawlog.h \
|
||||||
servers.h \
|
servers.h \
|
||||||
servers-reconnect.h \
|
servers-reconnect.h \
|
||||||
servers-redirect.h \
|
|
||||||
servers-setup.h \
|
servers-setup.h \
|
||||||
settings.h \
|
settings.h \
|
||||||
signals.h \
|
signals.h \
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "window-item-def.h"
|
#include "window-item-def.h"
|
||||||
|
|
||||||
#include "servers.h"
|
#include "servers.h"
|
||||||
#include "servers-redirect.h"
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
|
|
||||||
#include "lib-config/iconfig.h"
|
#include "lib-config/iconfig.h"
|
||||||
@ -853,10 +852,8 @@ static void parse_command(const char *command, int expand_aliases,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd = g_strconcat("command ", newcmd, NULL);
|
cmd = g_strconcat("command ", newcmd, NULL);
|
||||||
if (server != NULL)
|
|
||||||
server_redirect_default(SERVER(server), cmd);
|
|
||||||
|
|
||||||
g_strdown(cmd);
|
g_strdown(cmd);
|
||||||
|
|
||||||
oldcmd = current_command;
|
oldcmd = current_command;
|
||||||
current_command = cmd+8;
|
current_command = cmd+8;
|
||||||
if (!signal_emit(cmd, 3, args, server, item)) {
|
if (!signal_emit(cmd, 3, args, server, item)) {
|
||||||
|
@ -21,11 +21,6 @@ GIOChannel *connect_pipe[2];
|
|||||||
int connect_tag;
|
int connect_tag;
|
||||||
int connect_pid;
|
int connect_pid;
|
||||||
|
|
||||||
/* For deciding if event should be handled internally */
|
|
||||||
GHashTable *eventtable; /* "event xxx" : GSList* of REDIRECT_RECs */
|
|
||||||
GHashTable *eventgrouptable; /* event group : GSList* of REDIRECT_RECs */
|
|
||||||
GHashTable *cmdtable; /* "command xxx" : REDIRECT_CMD_REC* */
|
|
||||||
|
|
||||||
RAWLOG_REC *rawlog;
|
RAWLOG_REC *rawlog;
|
||||||
LINEBUF_REC *buffer; /* receive buffer */
|
LINEBUF_REC *buffer; /* receive buffer */
|
||||||
GHashTable *module_data;
|
GHashTable *module_data;
|
||||||
|
@ -1,359 +0,0 @@
|
|||||||
/*
|
|
||||||
server-redirect.c : irssi
|
|
||||||
|
|
||||||
Copyright (C) 1999-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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "module.h"
|
|
||||||
#include "signals.h"
|
|
||||||
#include "misc.h"
|
|
||||||
|
|
||||||
#include "servers.h"
|
|
||||||
#include "servers-redirect.h"
|
|
||||||
|
|
||||||
static int redirect_group;
|
|
||||||
|
|
||||||
static void server_eventtable_destroy(char *key, GSList *value)
|
|
||||||
{
|
|
||||||
GSList *tmp;
|
|
||||||
|
|
||||||
g_free(key);
|
|
||||||
|
|
||||||
for (tmp = value; tmp != NULL; tmp = tmp->next) {
|
|
||||||
REDIRECT_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
g_free_not_null(rec->arg);
|
|
||||||
g_free(rec->name);
|
|
||||||
g_free(rec);
|
|
||||||
}
|
|
||||||
g_slist_free(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void server_eventgrouptable_destroy(gpointer key, GSList *value)
|
|
||||||
{
|
|
||||||
g_slist_foreach(value, (GFunc) g_free, NULL);
|
|
||||||
g_slist_free(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void server_cmdtable_destroy(char *key, REDIRECT_CMD_REC *value)
|
|
||||||
{
|
|
||||||
g_free(key);
|
|
||||||
|
|
||||||
g_slist_foreach(value->events, (GFunc) g_free, NULL);
|
|
||||||
g_slist_free(value->events);
|
|
||||||
g_free(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sig_disconnected(SERVER_REC *server)
|
|
||||||
{
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
|
||||||
|
|
||||||
if (server->eventtable != NULL) {
|
|
||||||
g_hash_table_foreach(server->eventtable,
|
|
||||||
(GHFunc) server_eventtable_destroy, NULL);
|
|
||||||
g_hash_table_destroy(server->eventtable);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_foreach(server->eventgrouptable,
|
|
||||||
(GHFunc) server_eventgrouptable_destroy, NULL);
|
|
||||||
g_hash_table_destroy(server->eventgrouptable);
|
|
||||||
|
|
||||||
if (server->cmdtable != NULL) {
|
|
||||||
g_hash_table_foreach(server->cmdtable,
|
|
||||||
(GHFunc) server_cmdtable_destroy, NULL);
|
|
||||||
g_hash_table_destroy(server->cmdtable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void server_redirect_initv(SERVER_REC *server, const char *command,
|
|
||||||
int last, GSList *list)
|
|
||||||
{
|
|
||||||
REDIRECT_CMD_REC *rec;
|
|
||||||
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
|
||||||
g_return_if_fail(command != NULL);
|
|
||||||
g_return_if_fail(last > 0);
|
|
||||||
|
|
||||||
if (g_hash_table_lookup(server->cmdtable, command) != NULL) {
|
|
||||||
/* already in hash table. list of events SHOULD be the same. */
|
|
||||||
g_slist_foreach(list, (GFunc) g_free, NULL);
|
|
||||||
g_slist_free(list);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rec = g_new(REDIRECT_CMD_REC, 1);
|
|
||||||
rec->last = last;
|
|
||||||
rec->events = list;
|
|
||||||
g_hash_table_insert(server->cmdtable, g_strdup(command), rec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void server_redirect_init(SERVER_REC *server, const char *command,
|
|
||||||
int last, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
GSList *list;
|
|
||||||
char *event;
|
|
||||||
|
|
||||||
va_start(args, last);
|
|
||||||
list = NULL;
|
|
||||||
while ((event = va_arg(args, gchar *)) != NULL)
|
|
||||||
list = g_slist_append(list, g_strdup(event));
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
server_redirect_initv(server, command, last, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
int server_redirect_single_event(SERVER_REC *server, const char *arg,
|
|
||||||
int last, int group, const char *event,
|
|
||||||
const char *signal, int argpos)
|
|
||||||
{
|
|
||||||
REDIRECT_REC *rec;
|
|
||||||
GSList *list, *grouplist;
|
|
||||||
char *origkey;
|
|
||||||
|
|
||||||
g_return_val_if_fail(IS_SERVER(server), 0);
|
|
||||||
g_return_val_if_fail(event != NULL, 0);
|
|
||||||
g_return_val_if_fail(signal != NULL, 0);
|
|
||||||
g_return_val_if_fail(arg != NULL || argpos == -1, 0);
|
|
||||||
|
|
||||||
if (group == 0) group = ++redirect_group;
|
|
||||||
|
|
||||||
rec = g_new0(REDIRECT_REC, 1);
|
|
||||||
rec->arg = arg == NULL ? NULL : g_strdup(arg);
|
|
||||||
rec->argpos = argpos;
|
|
||||||
rec->name = g_strdup(signal);
|
|
||||||
rec->group = group;
|
|
||||||
rec->last = last;
|
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended(server->eventtable, event,
|
|
||||||
(gpointer *) &origkey,
|
|
||||||
(gpointer *) &list)) {
|
|
||||||
g_hash_table_remove(server->eventtable, origkey);
|
|
||||||
} else {
|
|
||||||
list = NULL;
|
|
||||||
origkey = g_strdup(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
grouplist = g_hash_table_lookup(server->eventgrouptable,
|
|
||||||
GINT_TO_POINTER(group));
|
|
||||||
if (grouplist != NULL) {
|
|
||||||
g_hash_table_remove(server->eventgrouptable,
|
|
||||||
GINT_TO_POINTER(group));
|
|
||||||
}
|
|
||||||
|
|
||||||
list = g_slist_append(list, rec);
|
|
||||||
grouplist = g_slist_append(grouplist, g_strdup(event));
|
|
||||||
|
|
||||||
g_hash_table_insert(server->eventtable, origkey, list);
|
|
||||||
g_hash_table_insert(server->eventgrouptable,
|
|
||||||
GINT_TO_POINTER(group), grouplist);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
void server_redirect_event(SERVER_REC *server, const char *arg, int last, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
char *event, *signal;
|
|
||||||
int argpos, group;
|
|
||||||
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
|
||||||
|
|
||||||
va_start(args, last);
|
|
||||||
|
|
||||||
group = 0;
|
|
||||||
while ((event = va_arg(args, gchar *)) != NULL) {
|
|
||||||
signal = va_arg(args, gchar *);
|
|
||||||
argpos = va_arg(args, gint);
|
|
||||||
|
|
||||||
group = server_redirect_single_event(server, arg, last > 0,
|
|
||||||
group, event, signal,
|
|
||||||
argpos);
|
|
||||||
last--;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void server_redirect_default(SERVER_REC *server, const char *command)
|
|
||||||
{
|
|
||||||
REDIRECT_CMD_REC *cmdrec;
|
|
||||||
REDIRECT_REC *rec;
|
|
||||||
GSList *events, *list, *grouplist;
|
|
||||||
char *event, *origkey;
|
|
||||||
int last;
|
|
||||||
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
|
||||||
g_return_if_fail(command != NULL);
|
|
||||||
|
|
||||||
if (server->cmdtable == NULL)
|
|
||||||
return; /* not connected yet */
|
|
||||||
|
|
||||||
cmdrec = g_hash_table_lookup(server->cmdtable, command);
|
|
||||||
if (cmdrec == NULL) return;
|
|
||||||
|
|
||||||
/* add all events used by command to eventtable and eventgrouptable */
|
|
||||||
redirect_group++; grouplist = NULL; last = cmdrec->last;
|
|
||||||
for (events = cmdrec->events; events != NULL; events = events->next) {
|
|
||||||
event = events->data;
|
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended(server->eventtable, event,
|
|
||||||
(gpointer *) &origkey,
|
|
||||||
(gpointer *) &list)) {
|
|
||||||
g_hash_table_remove(server->eventtable, origkey);
|
|
||||||
} else {
|
|
||||||
list = NULL;
|
|
||||||
origkey = g_strdup(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
rec = g_new0(REDIRECT_REC, 1);
|
|
||||||
rec->argpos = -1;
|
|
||||||
rec->name = g_strdup(event);
|
|
||||||
rec->group = redirect_group;
|
|
||||||
rec->last = last > 0;
|
|
||||||
|
|
||||||
grouplist = g_slist_append(grouplist, g_strdup(event));
|
|
||||||
list = g_slist_append(list, rec);
|
|
||||||
g_hash_table_insert(server->eventtable, origkey, list);
|
|
||||||
|
|
||||||
last--;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_insert(server->eventgrouptable,
|
|
||||||
GINT_TO_POINTER(redirect_group), grouplist);
|
|
||||||
}
|
|
||||||
|
|
||||||
void server_redirect_remove_next(SERVER_REC *server, const char *event,
|
|
||||||
GSList *item)
|
|
||||||
{
|
|
||||||
REDIRECT_REC *rec;
|
|
||||||
GSList *grouplist, *list, *events, *tmp;
|
|
||||||
char *origkey;
|
|
||||||
int group;
|
|
||||||
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
|
||||||
g_return_if_fail(event != NULL);
|
|
||||||
|
|
||||||
if (!g_hash_table_lookup_extended(server->eventtable, event,
|
|
||||||
(gpointer *) &origkey,
|
|
||||||
(gpointer *) &list))
|
|
||||||
return;
|
|
||||||
|
|
||||||
rec = item == NULL ? list->data : item->data;
|
|
||||||
if (!rec->last) {
|
|
||||||
/* this wasn't last expected event */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
group = rec->group;
|
|
||||||
|
|
||||||
/* get list of events from this group */
|
|
||||||
grouplist = g_hash_table_lookup(server->eventgrouptable,
|
|
||||||
GINT_TO_POINTER(group));
|
|
||||||
|
|
||||||
/* remove all of them */
|
|
||||||
for (list = grouplist; list != NULL; list = list->next) {
|
|
||||||
char *event = list->data;
|
|
||||||
|
|
||||||
if (!g_hash_table_lookup_extended(server->eventtable, event,
|
|
||||||
(gpointer *) &origkey,
|
|
||||||
(gpointer *) &events)) {
|
|
||||||
g_warning("server_redirect_remove_next() : "
|
|
||||||
"event in eventgrouptable but not in "
|
|
||||||
"eventtable");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove the right group */
|
|
||||||
for (tmp = events; tmp != NULL; tmp = tmp->next) {
|
|
||||||
rec = tmp->data;
|
|
||||||
|
|
||||||
if (rec->group == group)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec == NULL) {
|
|
||||||
g_warning("server_redirect_remove_next() : "
|
|
||||||
"event in eventgrouptable but not in "
|
|
||||||
"eventtable (group)");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(event);
|
|
||||||
|
|
||||||
events = g_slist_remove(events, rec);
|
|
||||||
g_free_not_null(rec->arg);
|
|
||||||
g_free(rec->name);
|
|
||||||
g_free(rec);
|
|
||||||
|
|
||||||
/* update hash table */
|
|
||||||
g_hash_table_remove(server->eventtable, origkey);
|
|
||||||
if (events == NULL)
|
|
||||||
g_free(origkey);
|
|
||||||
else {
|
|
||||||
g_hash_table_insert(server->eventtable,
|
|
||||||
origkey, events);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_remove(server->eventgrouptable, GINT_TO_POINTER(group));
|
|
||||||
g_slist_free(grouplist);
|
|
||||||
}
|
|
||||||
|
|
||||||
GSList *server_redirect_getqueue(SERVER_REC *server, const char *event,
|
|
||||||
const char *args)
|
|
||||||
{
|
|
||||||
REDIRECT_REC *rec;
|
|
||||||
GSList *list;
|
|
||||||
char **arglist;
|
|
||||||
int found;
|
|
||||||
|
|
||||||
g_return_val_if_fail(IS_SERVER(server), NULL);
|
|
||||||
g_return_val_if_fail(event != NULL, NULL);
|
|
||||||
|
|
||||||
list = g_hash_table_lookup(server->eventtable, event);
|
|
||||||
|
|
||||||
for (; list != NULL; list = list->next) {
|
|
||||||
rec = list->data;
|
|
||||||
if (rec->argpos == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (rec->arg == NULL || args == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* we need to check that the argument is right.. */
|
|
||||||
arglist = g_strsplit(args, " ", -1);
|
|
||||||
found = (strarray_length(arglist) > rec->argpos &&
|
|
||||||
find_substr(rec->arg, arglist[rec->argpos]));
|
|
||||||
g_strfreev(arglist);
|
|
||||||
|
|
||||||
if (found) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void servers_redirect_init(void)
|
|
||||||
{
|
|
||||||
redirect_group = 0;
|
|
||||||
|
|
||||||
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void servers_redirect_deinit(void)
|
|
||||||
{
|
|
||||||
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
#ifndef __SERVERS_REDIRECT_H
|
|
||||||
#define __SERVERS_REDIRECT_H
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int last; /* number of "last" events at the start of the events list */
|
|
||||||
GSList *events; /* char* list of events */
|
|
||||||
} REDIRECT_CMD_REC;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *name; /* event name */
|
|
||||||
|
|
||||||
char *arg; /* argument for event we are expecting or NULL */
|
|
||||||
int argpos; /* argument position */
|
|
||||||
|
|
||||||
int group; /* group of events this belongs to */
|
|
||||||
int last; /* if this event is received, remove all the events in this group */
|
|
||||||
}
|
|
||||||
REDIRECT_REC;
|
|
||||||
|
|
||||||
void server_redirect_init(SERVER_REC *server, const char *command, int last, ...);
|
|
||||||
void server_redirect_initv(SERVER_REC *server, const char *command, int last, GSList *list);
|
|
||||||
/* ... = char *event1, char *event2, ..., NULL */
|
|
||||||
|
|
||||||
void server_redirect_event(SERVER_REC *server, const char *arg, int last, ...);
|
|
||||||
/* ... = char *event, char *callback_signal, int argpos, ..., NULL */
|
|
||||||
|
|
||||||
int server_redirect_single_event(SERVER_REC *server, const char *arg, int last, int group,
|
|
||||||
const char *event, const char *signal, int argpos);
|
|
||||||
void server_redirect_default(SERVER_REC *server, const char *command);
|
|
||||||
void server_redirect_remove_next(SERVER_REC *server, const char *event, GSList *item);
|
|
||||||
GSList *server_redirect_getqueue(SERVER_REC *server, const char *event, const char *args);
|
|
||||||
|
|
||||||
void servers_redirect_init(void);
|
|
||||||
void servers_redirect_deinit(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -31,7 +31,6 @@
|
|||||||
#include "chat-protocols.h"
|
#include "chat-protocols.h"
|
||||||
#include "servers.h"
|
#include "servers.h"
|
||||||
#include "servers-reconnect.h"
|
#include "servers-reconnect.h"
|
||||||
#include "servers-redirect.h"
|
|
||||||
#include "servers-setup.h"
|
#include "servers-setup.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
@ -136,10 +135,6 @@ void server_connect_finished(SERVER_REC *server)
|
|||||||
server->connect_time = time(NULL);
|
server->connect_time = time(NULL);
|
||||||
server->rawlog = rawlog_create();
|
server->rawlog = rawlog_create();
|
||||||
|
|
||||||
server->eventtable = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
|
|
||||||
server->eventgrouptable = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
|
|
||||||
server->cmdtable = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
|
|
||||||
|
|
||||||
servers = g_slist_append(servers, server);
|
servers = g_slist_append(servers, server);
|
||||||
signal_emit("server connected", 1, server);
|
signal_emit("server connected", 1, server);
|
||||||
}
|
}
|
||||||
@ -553,7 +548,6 @@ void servers_init(void)
|
|||||||
signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);
|
signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);
|
||||||
|
|
||||||
servers_reconnect_init();
|
servers_reconnect_init();
|
||||||
servers_redirect_init();
|
|
||||||
servers_setup_init();
|
servers_setup_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +556,6 @@ void servers_deinit(void)
|
|||||||
signal_remove("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);
|
signal_remove("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);
|
||||||
|
|
||||||
servers_setup_deinit();
|
servers_setup_deinit();
|
||||||
servers_redirect_deinit();
|
|
||||||
servers_reconnect_deinit();
|
servers_reconnect_deinit();
|
||||||
|
|
||||||
module_uniq_destroy("SERVER");
|
module_uniq_destroy("SERVER");
|
||||||
|
@ -309,17 +309,10 @@ static void event_connected(IRC_SERVER_REC *server)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* someone has our nick, find out who. */
|
/* someone has our nick, find out who. */
|
||||||
|
server_redirect_event(server, "whois", nick, FALSE, NULL,
|
||||||
|
"event 311", "nickfind event whois",
|
||||||
|
"", "event empty", NULL);
|
||||||
irc_send_cmdv(server, "WHOIS %s", nick);
|
irc_send_cmdv(server, "WHOIS %s", nick);
|
||||||
server_redirect_event((SERVER_REC *) server, nick, 1,
|
|
||||||
"event 318", "event empty", 1,
|
|
||||||
"event 401", "event empty", 1,
|
|
||||||
"event 311", "nickfind event whois", 1,
|
|
||||||
"event 301", "event empty", 1,
|
|
||||||
"event 312", "event empty", 1,
|
|
||||||
"event 313", "event empty", 1,
|
|
||||||
"event 317", "event empty", 1,
|
|
||||||
"event 319", "event empty", 1, NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_nickfind_whois(IRC_SERVER_REC *server, const char *data)
|
static void event_nickfind_whois(IRC_SERVER_REC *server, const char *data)
|
||||||
|
@ -30,7 +30,8 @@ libirc_core_a_SOURCES = \
|
|||||||
modes.c \
|
modes.c \
|
||||||
mode-lists.c \
|
mode-lists.c \
|
||||||
netsplit.c \
|
netsplit.c \
|
||||||
server-idle.c
|
servers-idle.c \
|
||||||
|
servers-redirect.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
bans.h \
|
bans.h \
|
||||||
@ -49,4 +50,5 @@ noinst_HEADERS = \
|
|||||||
mode-lists.h \
|
mode-lists.h \
|
||||||
module.h \
|
module.h \
|
||||||
netsplit.h \
|
netsplit.h \
|
||||||
server-idle.h
|
servers-idle.h \
|
||||||
|
servers-redirect.h
|
||||||
|
@ -209,11 +209,10 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||||||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||||
chanrec = tmp->data;
|
chanrec = tmp->data;
|
||||||
|
|
||||||
server_redirect_event((SERVER_REC *) server, chanstr, 4,
|
server_redirect_event(server, "mode channel", chanstr, -1,
|
||||||
"event 403", "chanquery mode abort", 1,
|
"chanquery mode abort",
|
||||||
"event 442", "chanquery mode abort", 1, /* "you're not on that channel" */
|
"event 324", "chanquery mode",
|
||||||
"event 479", "chanquery mode abort", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
|
"", "chanquery mode abort", NULL);
|
||||||
"event 324", "chanquery mode", 1, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -223,11 +222,11 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||||||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||||
chanrec = tmp->data;
|
chanrec = tmp->data;
|
||||||
|
|
||||||
server_redirect_event((SERVER_REC *) server, chanstr, 3,
|
server_redirect_event(server, "who", chanstr, -1,
|
||||||
"event 401", "chanquery who abort", 1,
|
"chanquery who abort",
|
||||||
"event 403", "chanquery who abort", 1,
|
"event 315", "chanquery who end",
|
||||||
"event 315", "chanquery who end", 1,
|
"event 352", "silent event who",
|
||||||
"event 352", "silent event who", 1, NULL);
|
"", "chanquery who abort", NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -240,12 +239,11 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||||||
mode requests - if channels are joined manually
|
mode requests - if channels are joined manually
|
||||||
irssi could ask modes separately but afterwards
|
irssi could ask modes separately but afterwards
|
||||||
join the two b/e/I modes together */
|
join the two b/e/I modes together */
|
||||||
server_redirect_event((SERVER_REC *) server, chanstr, 4,
|
server_redirect_event(server, "mode b", chanstr, -1,
|
||||||
"event 403", "chanquery mode abort", 1,
|
"chanquery mode abort",
|
||||||
"event 442", "chanquery mode abort", 1, /* "you're not on that channel" */
|
"event 367", "chanquery ban",
|
||||||
"event 479", "chanquery mode abort", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
|
"event 368", "chanquery ban end",
|
||||||
"event 368", "chanquery ban end", 1,
|
"", "chanquery mode abort", NULL);
|
||||||
"event 367", "chanquery ban", 1, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -254,12 +252,11 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||||||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||||
chanrec = tmp->data;
|
chanrec = tmp->data;
|
||||||
|
|
||||||
server_redirect_event((SERVER_REC *) server, chanstr, 4,
|
server_redirect_event(server, "mode e", chanstr, -1,
|
||||||
"event 403", "chanquery mode abort", 1,
|
"chanquery mode abort",
|
||||||
"event 442", "chanquery mode abort", 1, /* "you're not on that channel" */
|
"event 348", "chanquery eban",
|
||||||
"event 479", "chanquery mode abort", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
|
"event 349", "chanquery eban end",
|
||||||
"event 349", "chanquery eban end", 1,
|
"", "chanquery mode abort", NULL);
|
||||||
"event 348", "chanquery eban", 1, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -268,12 +265,11 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||||||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||||
chanrec = tmp->data;
|
chanrec = tmp->data;
|
||||||
|
|
||||||
server_redirect_event((SERVER_REC *) server, chanstr, 4,
|
server_redirect_event(server, "mode I", chanstr, -1,
|
||||||
"event 403", "chanquery mode abort", 1,
|
"chanquery mode abort",
|
||||||
"event 442", "chanquery mode abort", 1, /* "you're not on that channel" */
|
"event 346", "chanquery ilist",
|
||||||
"event 479", "chanquery mode abort", 1, /* "Cannot join channel (illegal name)" IMHO this is not a logical reply from server. */
|
"event 347", "chanquery ilist end",
|
||||||
"event 347", "chanquery ilist end", 1,
|
"", "chanquery mode abort", NULL);
|
||||||
"event 346", "chanquery ilist", 1, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -423,14 +419,6 @@ static void event_channel_mode(IRC_SERVER_REC *server, const char *data,
|
|||||||
g_free(params);
|
g_free(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void multi_query_remove(IRC_SERVER_REC *server, const char *event, const char *data)
|
|
||||||
{
|
|
||||||
GSList *queue;
|
|
||||||
|
|
||||||
while ((queue = server_redirect_getqueue((SERVER_REC *) server, event, data)) != NULL)
|
|
||||||
server_redirect_remove_next((SERVER_REC *) server, event, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void event_end_of_who(IRC_SERVER_REC *server, const char *data)
|
static void event_end_of_who(IRC_SERVER_REC *server, const char *data)
|
||||||
{
|
{
|
||||||
IRC_CHANNEL_REC *chanrec;
|
IRC_CHANNEL_REC *chanrec;
|
||||||
@ -447,7 +435,6 @@ static void event_end_of_who(IRC_SERVER_REC *server, const char *data)
|
|||||||
/* instead of multiple End of WHO replies we get
|
/* instead of multiple End of WHO replies we get
|
||||||
only this one... */
|
only this one... */
|
||||||
server->one_endofwho = TRUE;
|
server->one_endofwho = TRUE;
|
||||||
multi_query_remove(server, "event 315", data);
|
|
||||||
|
|
||||||
/* check that the WHO actually did return something
|
/* check that the WHO actually did return something
|
||||||
(that it understood #chan1,#chan2,..) */
|
(that it understood #chan1,#chan2,..) */
|
||||||
@ -549,8 +536,6 @@ static void multi_command_error(IRC_SERVER_REC *server, const char *data,
|
|||||||
char *params, *channel, **chans;
|
char *params, *channel, **chans;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
multi_query_remove(server, event, data);
|
|
||||||
|
|
||||||
params = event_get_params(data, 2, NULL, &channel);
|
params = event_get_params(data, 2, NULL, &channel);
|
||||||
|
|
||||||
chans = g_strsplit(channel, ",", -1);
|
chans = g_strsplit(channel, ",", -1);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "server-idle.h"
|
#include "servers-idle.h"
|
||||||
#include "ignore.h"
|
#include "ignore.h"
|
||||||
|
|
||||||
static void ctcp_queue_clean(IRC_SERVER_REC *server)
|
static void ctcp_queue_clean(IRC_SERVER_REC *server)
|
||||||
@ -57,7 +57,7 @@ void ctcp_send_reply(IRC_SERVER_REC *server, const char *data)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Add to first in idle queue */
|
/* Add to first in idle queue */
|
||||||
tag = server_idle_add(server, data, NULL, 0, NULL);
|
tag = server_idle_add(server, data);
|
||||||
server->ctcpqueue =
|
server->ctcpqueue =
|
||||||
g_slist_append(server->ctcpqueue, GINT_TO_POINTER(tag));
|
g_slist_append(server->ctcpqueue, GINT_TO_POINTER(tag));
|
||||||
}
|
}
|
||||||
|
@ -244,9 +244,6 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server,
|
|||||||
|
|
||||||
irc_send_cmdv(server, "LIST %s", str);
|
irc_send_cmdv(server, "LIST %s", str);
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
|
|
||||||
/* add default redirection */
|
|
||||||
server_redirect_default((SERVER_REC *) server, "bogus command list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYNTAX: WHO [<nicks> | <channels> | **] */
|
/* SYNTAX: WHO [<nicks> | <channels> | **] */
|
||||||
@ -275,9 +272,6 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server,
|
|||||||
irc_send_cmdv(server, *rest == '\0' ? "WHO %s" : "WHO %s %s",
|
irc_send_cmdv(server, *rest == '\0' ? "WHO %s" : "WHO %s %s",
|
||||||
channel, rest);
|
channel, rest);
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
|
|
||||||
/* add default redirection */
|
|
||||||
server_redirect_default((SERVER_REC *) server, "bogus command who");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_names(const char *data, IRC_SERVER_REC *server,
|
static void cmd_names(const char *data, IRC_SERVER_REC *server,
|
||||||
@ -323,43 +317,10 @@ static void cmd_nick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item
|
|||||||
if (!cmd_get_params(data, &free_arg, 1, &nick))
|
if (!cmd_get_params(data, &free_arg, 1, &nick))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (strcmp(nick, server->nick) == 0) {
|
|
||||||
/* don't bother trying to change the nick to the one you
|
|
||||||
already have */
|
|
||||||
cmd_params_free(free_arg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
server->nick_changing = TRUE;
|
|
||||||
irc_send_cmdv(server, "NICK %s", nick);
|
irc_send_cmdv(server, "NICK %s", nick);
|
||||||
|
|
||||||
nick = g_strdup_printf("%s :%s", nick, nick);
|
|
||||||
server_redirect_event(SERVER(server), nick, 5,
|
|
||||||
"event nick", "nickchange over", -1,
|
|
||||||
"event 433", "nickchange over", 1,
|
|
||||||
/* 437: ircnet = target unavailable,
|
|
||||||
dalnet = banned in channel,
|
|
||||||
can't change nick */
|
|
||||||
"event 437", "nickchange over", -1,
|
|
||||||
"event 432", "nickchange over", 1,
|
|
||||||
"event 438", "nickchange over", 1, NULL);
|
|
||||||
g_free(nick);
|
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_nickchange_over(IRC_SERVER_REC *server, const char *data,
|
|
||||||
const char *nick, const char *addr)
|
|
||||||
{
|
|
||||||
char *signal;
|
|
||||||
|
|
||||||
server->nick_changing = FALSE;
|
|
||||||
|
|
||||||
signal = g_strconcat("event ", current_server_event, NULL);
|
|
||||||
g_strdown(signal+6);
|
|
||||||
signal_emit(signal, 4, server, data, nick, addr);
|
|
||||||
g_free(signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *get_redirect_nicklist(const char *nicks, int *free)
|
static char *get_redirect_nicklist(const char *nicks, int *free)
|
||||||
{
|
{
|
||||||
char *str, *ret;
|
char *str, *ret;
|
||||||
@ -419,20 +380,21 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server,
|
|||||||
event_402 = "whois event noserver";
|
event_402 = "whois event noserver";
|
||||||
}
|
}
|
||||||
|
|
||||||
server->whois_found = FALSE;
|
|
||||||
irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd);
|
|
||||||
|
|
||||||
/* do automatic /WHOWAS if any of the nicks wasn't found */
|
/* do automatic /WHOWAS if any of the nicks wasn't found */
|
||||||
query = get_redirect_nicklist(query, &free_nick);
|
query = get_redirect_nicklist(query, &free_nick);
|
||||||
|
|
||||||
str = g_strconcat(qserver, " ", query, NULL);
|
str = g_strconcat(qserver, " ", query, NULL);
|
||||||
server_redirect_event(SERVER(server), str, 2,
|
server_redirect_event(server, "whois", str, *qserver != '\0',
|
||||||
"event 318", "event 318", 1,
|
NULL,
|
||||||
"event 402", event_402, 1,
|
"event 318", "event 318",
|
||||||
"event 401", "whois not found", 1,
|
"event 402", event_402,
|
||||||
"event 311", "whois event", 1, NULL);
|
"event 401", "whois not found",
|
||||||
|
"event 311", "whois event", NULL);
|
||||||
g_free(str);
|
g_free(str);
|
||||||
|
|
||||||
|
server->whois_found = FALSE;
|
||||||
|
irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd);
|
||||||
|
|
||||||
if (free_nick) g_free(query);
|
if (free_nick) g_free(query);
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
@ -451,13 +413,14 @@ static void sig_whois_not_found(IRC_SERVER_REC *server, const char *data)
|
|||||||
g_return_if_fail(data != NULL);
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
params = event_get_params(data, 2, NULL, &nick);
|
params = event_get_params(data, 2, NULL, &nick);
|
||||||
irc_send_cmdv(server, "WHOWAS %s 1", nick);
|
|
||||||
|
|
||||||
server->whowas_found = FALSE;
|
server->whowas_found = FALSE;
|
||||||
server_redirect_event(SERVER(server), nick, 1,
|
server_redirect_event(server, "whowas", nick, -1, NULL,
|
||||||
"event 369", "whowas event end", 1,
|
"event 314", "whowas event",
|
||||||
"event 314", "whowas event", 1,
|
"event 369", "whowas event end",
|
||||||
"event 406", "event empty", 1, NULL);
|
"", "event empty", NULL);
|
||||||
|
irc_send_cmdv(server, "WHOWAS %s 1", nick);
|
||||||
|
|
||||||
g_free(params);
|
g_free(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +433,7 @@ static void event_whowas(IRC_SERVER_REC *server, const char *data, const char *n
|
|||||||
/* SYNTAX: WHOWAS [<nicks> [<count>]] */
|
/* SYNTAX: WHOWAS [<nicks> [<count>]] */
|
||||||
static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
|
static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
char *nicks, *count;
|
char *nicks, *count, *nicks_redir;
|
||||||
void *free_arg;
|
void *free_arg;
|
||||||
int free_nick;
|
int free_nick;
|
||||||
|
|
||||||
@ -480,15 +443,15 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
|
|||||||
return;
|
return;
|
||||||
if (*nicks == '\0') nicks = server->nick;
|
if (*nicks == '\0') nicks = server->nick;
|
||||||
|
|
||||||
|
nicks_redir = get_redirect_nicklist(nicks, &free_nick);
|
||||||
|
server_redirect_event(server, "whowas", nicks_redir, -1, NULL,
|
||||||
|
"event 314", "whowas event", NULL);
|
||||||
|
if (free_nick) g_free(nicks_redir);
|
||||||
|
|
||||||
server->whowas_found = FALSE;
|
server->whowas_found = FALSE;
|
||||||
irc_send_cmdv(server, *count == '\0' ? "WHOWAS %s" :
|
irc_send_cmdv(server, *count == '\0' ? "WHOWAS %s" :
|
||||||
"WHOWAS %s %s", nicks, count);
|
"WHOWAS %s %s", nicks, count);
|
||||||
|
|
||||||
nicks = get_redirect_nicklist(nicks, &free_nick);
|
|
||||||
server_redirect_event(SERVER(server), nicks, 1,
|
|
||||||
"event 369", "event 369", 1,
|
|
||||||
"event 314", "whowas event", 1, NULL);
|
|
||||||
if (free_nick) g_free(nicks);
|
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,48 +877,6 @@ static void command_2self(const char *data, IRC_SERVER_REC *server)
|
|||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_connected(IRC_SERVER_REC *server)
|
|
||||||
{
|
|
||||||
g_return_if_fail(server != NULL);
|
|
||||||
|
|
||||||
/* FIXME: these two aren't probably needed? this whole redirection
|
|
||||||
thing might need some rethinking :) */
|
|
||||||
/* WHOIS */
|
|
||||||
/*server_redirect_init(SERVER(server), "", 2,
|
|
||||||
"event 318", "event 402", "event 401",
|
|
||||||
"event 301", "event 311", "event 312", "event 313",
|
|
||||||
"event 317", "event 319", NULL);*/
|
|
||||||
|
|
||||||
/* NICK */
|
|
||||||
/*server_redirect_init(SERVER(server), "", 5,
|
|
||||||
"event nick", "event 433", "event 437",
|
|
||||||
"event 432", "event 438", NULL);*/
|
|
||||||
|
|
||||||
/* problem (doesn't really apply currently since there's no GUI):
|
|
||||||
|
|
||||||
second argument of server_redirect_init() is the command that
|
|
||||||
generates the redirection automatically when it's called, but the
|
|
||||||
command handler doesn't really know about the redirection itself.
|
|
||||||
|
|
||||||
every time the command is called, this redirection is generated.
|
|
||||||
this is a problem if the redirection is wanted sometimes but not
|
|
||||||
always. for example /WHO #channel could create a window with a
|
|
||||||
list of people in channel redirecting WHO's events to it's own use,
|
|
||||||
but /WHO -nogui #channel would use the default WHO handler which
|
|
||||||
doesn't know anything about redirection. with GUI /WHO the
|
|
||||||
redirection would be done twice then..
|
|
||||||
|
|
||||||
so the kludgy workaround currently is this: make the default
|
|
||||||
handler handle the redirection always.. when default WHO/LIST
|
|
||||||
handler is called, they call
|
|
||||||
server_redirect_default("bogus command who") or ..list..
|
|
||||||
|
|
||||||
this is really a problem if some script/plugin wants to override
|
|
||||||
some default command to use redirections.. */
|
|
||||||
server_redirect_init(SERVER(server), "bogus command who", 2, "event 401", "event 315", "event 352", NULL);
|
|
||||||
server_redirect_init(SERVER(server), "bogus command list", 1, "event 321", "event 322", "event 323", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void irc_commands_init(void)
|
void irc_commands_init(void)
|
||||||
{
|
{
|
||||||
tmpstr = g_string_new(NULL);
|
tmpstr = g_string_new(NULL);
|
||||||
@ -1048,11 +969,9 @@ void irc_commands_init(void)
|
|||||||
|
|
||||||
signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
|
signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
|
||||||
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||||
signal_add("nickchange over", (SIGNAL_FUNC) sig_nickchange_over);
|
|
||||||
signal_add("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
|
signal_add("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
|
||||||
signal_add("whois event", (SIGNAL_FUNC) event_whois);
|
signal_add("whois event", (SIGNAL_FUNC) event_whois);
|
||||||
signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
|
signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
|
||||||
signal_add("server connected", (SIGNAL_FUNC) sig_connected);
|
|
||||||
|
|
||||||
command_set_options("connect", "+ircnet");
|
command_set_options("connect", "+ircnet");
|
||||||
command_set_options("topic", "delete");
|
command_set_options("topic", "delete");
|
||||||
@ -1119,11 +1038,9 @@ void irc_commands_deinit(void)
|
|||||||
|
|
||||||
signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
|
signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
|
||||||
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||||
signal_remove("nickchange over", (SIGNAL_FUNC) sig_nickchange_over);
|
|
||||||
signal_remove("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
|
signal_remove("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
|
||||||
signal_remove("whois event", (SIGNAL_FUNC) event_whois);
|
signal_remove("whois event", (SIGNAL_FUNC) event_whois);
|
||||||
signal_remove("whowas event", (SIGNAL_FUNC) event_whowas);
|
signal_remove("whowas event", (SIGNAL_FUNC) event_whowas);
|
||||||
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
|
|
||||||
|
|
||||||
g_string_free(tmpstr, TRUE);
|
g_string_free(tmpstr, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,9 @@
|
|||||||
#include "irc-servers-setup.h"
|
#include "irc-servers-setup.h"
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "channel-rejoin.h"
|
#include "channel-rejoin.h"
|
||||||
#include "server-idle.h"
|
#include "servers-idle.h"
|
||||||
#include "servers-reconnect.h"
|
#include "servers-reconnect.h"
|
||||||
|
#include "servers-redirect.h"
|
||||||
#include "modes.h"
|
#include "modes.h"
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
@ -304,6 +305,7 @@ 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);
|
||||||
|
|
||||||
/* remove from queue */
|
/* remove from queue */
|
||||||
g_free(cmd);
|
g_free(cmd);
|
||||||
@ -506,6 +508,7 @@ void irc_servers_init(void)
|
|||||||
|
|
||||||
irc_servers_setup_init();
|
irc_servers_setup_init();
|
||||||
irc_servers_reconnect_init();
|
irc_servers_reconnect_init();
|
||||||
|
servers_redirect_init();
|
||||||
servers_idle_init();
|
servers_idle_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,5 +530,6 @@ void irc_servers_deinit(void)
|
|||||||
|
|
||||||
irc_servers_setup_deinit();
|
irc_servers_setup_deinit();
|
||||||
irc_servers_reconnect_deinit();
|
irc_servers_reconnect_deinit();
|
||||||
|
servers_redirect_deinit();
|
||||||
servers_idle_deinit();
|
servers_idle_deinit();
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,16 @@ struct _IRC_SERVER_CONNECT_REC {
|
|||||||
struct _IRC_SERVER_REC {
|
struct _IRC_SERVER_REC {
|
||||||
#include "server-rec.h"
|
#include "server-rec.h"
|
||||||
|
|
||||||
|
/* For deciding if event should be redirected */
|
||||||
|
GSList *redirects;
|
||||||
|
void *redirect_next;
|
||||||
|
void *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 .. */
|
||||||
char *userhost; /* /USERHOST <nick> - set when joined to first channel */
|
char *userhost; /* /USERHOST <nick> - set when joined to first channel */
|
||||||
int channels_formed; /* channels formed in irc network */
|
int channels_formed; /* channels formed in irc network */
|
||||||
|
|
||||||
unsigned int nick_changing:1; /* We've sent nick change command to server */
|
|
||||||
unsigned int whois_coming:1; /* Mostly just to display away message right.. */
|
unsigned int whois_coming:1; /* Mostly just to display away message right.. */
|
||||||
unsigned int whois_found:1; /* Did WHOIS return any entries? */
|
unsigned int whois_found:1; /* Did WHOIS return any entries? */
|
||||||
unsigned int whowas_found:1; /* Did WHOWAS return any entries? */
|
unsigned int whowas_found:1; /* Did WHOWAS return any entries? */
|
||||||
|
@ -62,8 +62,10 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
|
|||||||
cmd = str;
|
cmd = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_now)
|
if (send_now) {
|
||||||
rawlog_output(server->rawlog, cmd);
|
rawlog_output(server->rawlog, cmd);
|
||||||
|
server_redirect_command(server, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
/* Add CR+LF to command */
|
/* Add CR+LF to command */
|
||||||
@ -253,39 +255,34 @@ char *event_get_params(const char *data, int count, ...)
|
|||||||
return duprec;
|
return duprec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void irc_server_event(IRC_SERVER_REC *server, const char *line, const char *nick, const char *address)
|
static void irc_server_event(IRC_SERVER_REC *server, const char *line,
|
||||||
|
const char *nick, const char *address)
|
||||||
{
|
{
|
||||||
char *event, *args, *callcmd;
|
const char *signal;
|
||||||
GSList *list;
|
char *event, *args;
|
||||||
|
|
||||||
g_return_if_fail(line != NULL);
|
g_return_if_fail(line != NULL);
|
||||||
|
|
||||||
/* get command.. */
|
/* split event / args */
|
||||||
event = g_strconcat("event ", line, NULL);
|
event = g_strconcat("event ", line, NULL);
|
||||||
args = strchr(event+6, ' ');
|
args = strchr(event+6, ' ');
|
||||||
if (args != NULL) *args++ = '\0'; else args = "";
|
if (args != NULL) *args++ = '\0'; else args = "";
|
||||||
while (*args == ' ') args++;
|
while (*args == ' ') args++;
|
||||||
|
g_strdown(event);
|
||||||
|
|
||||||
list = server_redirect_getqueue((SERVER_REC *) server, event, args);
|
/* check if event needs to be redirected */
|
||||||
if (list == NULL)
|
signal = server_redirect_get_signal(server, event, args);
|
||||||
callcmd = g_strdup(event);
|
if (signal == NULL)
|
||||||
else {
|
signal = event;
|
||||||
/* event is redirected somewhere else.. */
|
else
|
||||||
REDIRECT_REC *rec;
|
rawlog_redirect(server->rawlog, signal);
|
||||||
|
|
||||||
rec = list->data;
|
|
||||||
callcmd = g_strdup(rec->name);
|
|
||||||
rawlog_redirect(server->rawlog, callcmd);
|
|
||||||
server_redirect_remove_next((SERVER_REC *) server, event, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* emit it */
|
||||||
current_server_event = event+6;
|
current_server_event = event+6;
|
||||||
g_strdown(callcmd);
|
if (!signal_emit(signal, 4, server, args, nick, address))
|
||||||
if (!signal_emit(callcmd, 4, server, args, nick, address))
|
|
||||||
signal_emit_id(signal_default_event, 4, server, line, nick, address);
|
signal_emit_id(signal_default_event, 4, server, line, nick, address);
|
||||||
current_server_event = NULL;
|
current_server_event = NULL;
|
||||||
|
|
||||||
g_free(callcmd);
|
|
||||||
g_free(event);
|
g_free(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
|
#include "servers-redirect.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IRC_SERVER_REC *server;
|
IRC_SERVER_REC *server;
|
||||||
@ -53,6 +54,20 @@ static void lag_free(LAG_REC *rec)
|
|||||||
g_free(rec);
|
g_free(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lag_send(LAG_REC *lag)
|
||||||
|
{
|
||||||
|
IRC_SERVER_REC *server;
|
||||||
|
|
||||||
|
g_get_current_time(&lag->time);
|
||||||
|
|
||||||
|
server = lag->server;
|
||||||
|
server->lag_sent = server->lag_last_check = time(NULL);
|
||||||
|
server_redirect_event(server, "ping", NULL, FALSE,
|
||||||
|
"lag ping error",
|
||||||
|
"event pong", "lag pong", NULL);
|
||||||
|
irc_send_cmdv(server, "PING %s", server->real_address);
|
||||||
|
}
|
||||||
|
|
||||||
static void lag_get(IRC_SERVER_REC *server)
|
static void lag_get(IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
LAG_REC *lag;
|
LAG_REC *lag;
|
||||||
@ -61,57 +76,42 @@ static void lag_get(IRC_SERVER_REC *server)
|
|||||||
|
|
||||||
/* nick changes may fail this check, so we should never do this
|
/* nick changes may fail this check, so we should never do this
|
||||||
while there's nick change request waiting for reply in server.. */
|
while there's nick change request waiting for reply in server.. */
|
||||||
if (server->nick_changing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lag = g_new0(LAG_REC, 1);
|
lag = g_new0(LAG_REC, 1);
|
||||||
lags = g_slist_append(lags, lag);
|
lags = g_slist_append(lags, lag);
|
||||||
lag->server = server;
|
lag->server = server;
|
||||||
|
|
||||||
g_get_current_time(&lag->time);
|
lag_send(lag);
|
||||||
|
|
||||||
if (server->lag_sent == 0)
|
|
||||||
server->lag_sent = time(NULL);
|
|
||||||
server->lag_last_check = time(NULL);
|
|
||||||
|
|
||||||
irc_send_cmdv(server, "NOTICE %s :\001IRSSILAG %ld %ld\001",
|
|
||||||
server->nick, lag->time.tv_sec, lag->time.tv_usec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we use "ctcp reply" signal here, because "ctcp reply irssilag" can be
|
/* we didn't receive PONG for some reason .. try again */
|
||||||
ignored with /IGNORE * CTCPS */
|
static void lag_ping_error(IRC_SERVER_REC *server)
|
||||||
static void sig_irssilag(IRC_SERVER_REC *server, const char *data,
|
|
||||||
const char *nick, const char *addr,
|
|
||||||
const char *target)
|
|
||||||
{
|
{
|
||||||
GTimeVal now, sent;
|
LAG_REC *lag;
|
||||||
|
|
||||||
|
lag = lag_find(server);
|
||||||
|
if (lag != NULL)
|
||||||
|
lag_send(lag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lag_event_pong(IRC_SERVER_REC *server, const char *data,
|
||||||
|
const char *nick, const char *addr)
|
||||||
|
{
|
||||||
|
GTimeVal now;
|
||||||
LAG_REC *lag;
|
LAG_REC *lag;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
if (strncmp(data, "IRSSILAG ", 9) != 0)
|
|
||||||
return;
|
|
||||||
data += 9;
|
|
||||||
|
|
||||||
lag = lag_find(server);
|
lag = lag_find(server);
|
||||||
if (lag == NULL) {
|
if (lag == NULL) {
|
||||||
/* not expecting lag reply.. */
|
/* not expecting lag reply.. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcasecmp(nick, server->nick) != 0) {
|
|
||||||
/* we didn't sent this - not a lag notice */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, it is a lag notice. */
|
|
||||||
server->lag_sent = 0;
|
server->lag_sent = 0;
|
||||||
|
|
||||||
if (sscanf(data, "%ld %ld", &sent.tv_sec, &sent.tv_usec) == 2) {
|
g_get_current_time(&now);
|
||||||
g_get_current_time(&now);
|
server->lag = (int) get_timeval_diff(&now, &lag->time);
|
||||||
server->lag = (int) get_timeval_diff(&now, &sent);
|
signal_emit("server lag", 1, server);
|
||||||
signal_emit("server lag", 1, server);
|
|
||||||
}
|
|
||||||
|
|
||||||
lag_free(lag);
|
lag_free(lag);
|
||||||
}
|
}
|
||||||
@ -154,11 +154,6 @@ static int sig_check_lag(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_empty(void)
|
|
||||||
{
|
|
||||||
/* don't print the "CTCP IRSSILAG reply .." text */
|
|
||||||
}
|
|
||||||
|
|
||||||
void lag_init(void)
|
void lag_init(void)
|
||||||
{
|
{
|
||||||
settings_add_int("misc", "lag_check_time", 30);
|
settings_add_int("misc", "lag_check_time", 30);
|
||||||
@ -166,8 +161,8 @@ void lag_init(void)
|
|||||||
|
|
||||||
lags = NULL;
|
lags = NULL;
|
||||||
timeout_tag = g_timeout_add(1000, (GSourceFunc) sig_check_lag, NULL);
|
timeout_tag = g_timeout_add(1000, (GSourceFunc) sig_check_lag, NULL);
|
||||||
signal_add("ctcp reply", (SIGNAL_FUNC) sig_irssilag);
|
signal_add_first("lag pong", (SIGNAL_FUNC) lag_event_pong);
|
||||||
signal_add("ctcp reply irssilag", (SIGNAL_FUNC) sig_empty);
|
signal_add("lag ping error", (SIGNAL_FUNC) lag_ping_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lag_deinit(void)
|
void lag_deinit(void)
|
||||||
@ -175,6 +170,6 @@ void lag_deinit(void)
|
|||||||
g_source_remove(timeout_tag);
|
g_source_remove(timeout_tag);
|
||||||
while (lags != NULL)
|
while (lags != NULL)
|
||||||
lag_free(lags->data);
|
lag_free(lags->data);
|
||||||
signal_remove("ctcp reply", (SIGNAL_FUNC) sig_irssilag);
|
signal_remove("lag pong", (SIGNAL_FUNC) lag_event_pong);
|
||||||
signal_remove("ctcp reply irssilag", (SIGNAL_FUNC) sig_empty);
|
signal_remove("lag ping error", (SIGNAL_FUNC) lag_ping_error);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#ifndef __SERVER_IDLE_H
|
|
||||||
#define __SERVER_IDLE_H
|
|
||||||
|
|
||||||
/* Add new idle command to queue */
|
|
||||||
int server_idle_add(IRC_SERVER_REC *server, const char *cmd, const char *arg, int last, ...);
|
|
||||||
|
|
||||||
/* Add new idle command to first of queue */
|
|
||||||
int server_idle_add_first(IRC_SERVER_REC *server, const char *cmd, const char *arg, int last, ...);
|
|
||||||
|
|
||||||
/* Add new idle command to specified position of queue */
|
|
||||||
int server_idle_insert(IRC_SERVER_REC *server, const char *cmd, const char *arg, int tag, int last, ...);
|
|
||||||
|
|
||||||
/* Check if record is still in queue */
|
|
||||||
int server_idle_find(IRC_SERVER_REC *server, int tag);
|
|
||||||
|
|
||||||
/* Remove record from idle queue */
|
|
||||||
int server_idle_remove(IRC_SERVER_REC *server, int tag);
|
|
||||||
|
|
||||||
void servers_idle_init(void);
|
|
||||||
void servers_idle_deinit(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -22,49 +22,54 @@
|
|||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
|
|
||||||
#include "irc-servers.h"
|
#include "irc-servers.h"
|
||||||
#include "server-idle.h"
|
#include "servers-idle.h"
|
||||||
#include "servers-redirect.h"
|
#include "servers-redirect.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *event;
|
|
||||||
char *signal;
|
|
||||||
int argpos;
|
|
||||||
} REDIRECT_IDLE_REC;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *arg;
|
char *arg;
|
||||||
int tag;
|
int tag;
|
||||||
|
|
||||||
int last;
|
char *redirect_cmd;
|
||||||
|
int remote;
|
||||||
|
char *failure_signal;
|
||||||
GSList *redirects;
|
GSList *redirects;
|
||||||
} SERVER_IDLE_REC;
|
} SERVER_IDLE_REC;
|
||||||
|
|
||||||
static int idle_tag, idlepos;
|
static int idle_tag, idlepos;
|
||||||
|
|
||||||
/* Add new idle command to queue */
|
/* Add new idle command to queue */
|
||||||
static SERVER_IDLE_REC *server_idle_create(const char *cmd, const char *arg, int last, va_list args)
|
static SERVER_IDLE_REC *
|
||||||
|
server_idle_create(const char *cmd, const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, va_list va)
|
||||||
{
|
{
|
||||||
REDIRECT_IDLE_REC *rrec;
|
|
||||||
SERVER_IDLE_REC *rec;
|
SERVER_IDLE_REC *rec;
|
||||||
char *event;
|
const char *event, *signal;
|
||||||
|
|
||||||
g_return_val_if_fail(cmd != NULL, FALSE);
|
g_return_val_if_fail(cmd != NULL, FALSE);
|
||||||
|
|
||||||
rec = g_new0(SERVER_IDLE_REC, 1);
|
rec = g_new0(SERVER_IDLE_REC, 1);
|
||||||
|
|
||||||
rec->tag = ++idlepos;
|
|
||||||
rec->arg = arg == NULL ? NULL : g_strdup(arg);
|
|
||||||
rec->cmd = g_strdup(cmd);
|
rec->cmd = g_strdup(cmd);
|
||||||
rec->last = last;
|
rec->arg = g_strdup(arg);
|
||||||
|
rec->tag = ++idlepos;
|
||||||
|
|
||||||
while ((event = va_arg(args, char *)) != NULL) {
|
rec->redirect_cmd = g_strdup(redirect_cmd);
|
||||||
rrec = g_new(REDIRECT_IDLE_REC, 1);
|
rec->remote = remote;
|
||||||
rec->redirects = g_slist_append(rec->redirects, rrec);
|
rec->failure_signal = g_strdup(failure_signal);
|
||||||
|
|
||||||
rrec->event = g_strdup(event);
|
while ((event = va_arg(va, const char *)) != NULL) {
|
||||||
rrec->signal = g_strdup(va_arg(args, char *));
|
signal = va_arg(va, const char *);
|
||||||
rrec->argpos = va_arg(args, int);
|
if (signal == NULL) {
|
||||||
|
g_warning("server_idle_create(%s): "
|
||||||
|
"signal not specified for event",
|
||||||
|
redirect_cmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec->redirects =
|
||||||
|
g_slist_append(rec->redirects, g_strdup(event));
|
||||||
|
rec->redirects =
|
||||||
|
g_slist_append(rec->redirects, g_strdup(signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rec;
|
return rec;
|
||||||
@ -87,78 +92,82 @@ static SERVER_IDLE_REC *server_idle_find_rec(IRC_SERVER_REC *server, int tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new idle command to queue */
|
/* Add new idle command to queue */
|
||||||
int server_idle_add(IRC_SERVER_REC *server, const char *cmd, const char *arg, int last, ...)
|
int server_idle_add_redir(IRC_SERVER_REC *server, const char *cmd,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list va;
|
||||||
SERVER_IDLE_REC *rec;
|
SERVER_IDLE_REC *rec;
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, -1);
|
g_return_val_if_fail(server != NULL, -1);
|
||||||
|
|
||||||
va_start(args, last);
|
va_start(va, failure_signal);
|
||||||
rec = server_idle_create(cmd, arg, last, args);
|
rec = server_idle_create(cmd, redirect_cmd, arg, remote,
|
||||||
|
failure_signal, va);
|
||||||
server->idles = g_slist_append(server->idles, rec);
|
server->idles = g_slist_append(server->idles, rec);
|
||||||
va_end(args);
|
va_end(va);
|
||||||
|
|
||||||
return rec->tag;
|
return rec->tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add new idle command to first of queue */
|
/* Add new idle command to first of queue */
|
||||||
int server_idle_add_first(IRC_SERVER_REC *server, const char *cmd, const char *arg, int last, ...)
|
int server_idle_add_first_redir(IRC_SERVER_REC *server, const char *cmd,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list va;
|
||||||
SERVER_IDLE_REC *rec;
|
SERVER_IDLE_REC *rec;
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, -1);
|
g_return_val_if_fail(server != NULL, -1);
|
||||||
|
|
||||||
va_start(args, last);
|
va_start(va, failure_signal);
|
||||||
rec = server_idle_create(cmd, arg, last, args);
|
rec = server_idle_create(cmd, redirect_cmd, arg, remote,
|
||||||
|
failure_signal, va);
|
||||||
server->idles = g_slist_prepend(server->idles, rec);
|
server->idles = g_slist_prepend(server->idles, rec);
|
||||||
va_end(args);
|
va_end(va);
|
||||||
|
|
||||||
return rec->tag;
|
return rec->tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add new idle command to specified position of queue */
|
/* Add new idle command to specified position of queue */
|
||||||
int server_idle_insert(IRC_SERVER_REC *server, const char *cmd, const char *arg, int tag, int last, ...)
|
int server_idle_insert_redir(IRC_SERVER_REC *server, const char *cmd, int tag,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list va;
|
||||||
SERVER_IDLE_REC *rec;
|
SERVER_IDLE_REC *rec;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, -1);
|
g_return_val_if_fail(server != NULL, -1);
|
||||||
|
|
||||||
va_start(args, last);
|
va_start(va, failure_signal);
|
||||||
|
|
||||||
/* find the position of tag in idle list */
|
/* find the position of tag in idle list */
|
||||||
rec = server_idle_find_rec(server, tag);
|
rec = server_idle_find_rec(server, tag);
|
||||||
pos = g_slist_index(server->idles, rec);
|
pos = g_slist_index(server->idles, rec);
|
||||||
|
|
||||||
rec = server_idle_create(cmd, arg, last, args);
|
rec = server_idle_create(cmd, redirect_cmd, arg, remote,
|
||||||
|
failure_signal, va);
|
||||||
server->idles = pos < 0 ?
|
server->idles = pos < 0 ?
|
||||||
g_slist_append(server->idles, rec) :
|
g_slist_append(server->idles, rec) :
|
||||||
g_slist_insert(server->idles, rec, pos);
|
g_slist_insert(server->idles, rec, pos);
|
||||||
va_end(args);
|
va_end(va);
|
||||||
|
|
||||||
return rec->tag;
|
return rec->tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_idle_destroy(IRC_SERVER_REC *server, SERVER_IDLE_REC *rec)
|
static void server_idle_destroy(IRC_SERVER_REC *server, SERVER_IDLE_REC *rec)
|
||||||
{
|
{
|
||||||
GSList *tmp;
|
|
||||||
|
|
||||||
g_return_if_fail(server != NULL);
|
g_return_if_fail(server != NULL);
|
||||||
|
|
||||||
server->idles = g_slist_remove(server->idles, rec);
|
server->idles = g_slist_remove(server->idles, rec);
|
||||||
|
|
||||||
for (tmp = rec->redirects; tmp != NULL; tmp = tmp->next) {
|
g_slist_foreach(rec->redirects, (GFunc) g_free, NULL);
|
||||||
REDIRECT_IDLE_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
g_free(rec->event);
|
|
||||||
g_free(rec->signal);
|
|
||||||
g_free(rec);
|
|
||||||
}
|
|
||||||
g_slist_free(rec->redirects);
|
g_slist_free(rec->redirects);
|
||||||
|
|
||||||
g_free_not_null(rec->arg);
|
g_free_not_null(rec->arg);
|
||||||
|
g_free_not_null(rec->redirect_cmd);
|
||||||
|
g_free_not_null(rec->failure_signal);
|
||||||
g_free(rec->cmd);
|
g_free(rec->cmd);
|
||||||
g_free(rec);
|
g_free(rec);
|
||||||
}
|
}
|
||||||
@ -188,26 +197,20 @@ int server_idle_remove(IRC_SERVER_REC *server, int tag)
|
|||||||
static void server_idle_next(IRC_SERVER_REC *server)
|
static void server_idle_next(IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
SERVER_IDLE_REC *rec;
|
SERVER_IDLE_REC *rec;
|
||||||
GSList *tmp;
|
|
||||||
int group;
|
|
||||||
|
|
||||||
g_return_if_fail(server != NULL);
|
g_return_if_fail(server != NULL);
|
||||||
|
|
||||||
if (server->idles == NULL) return;
|
if (server->idles == NULL)
|
||||||
|
return;
|
||||||
rec = server->idles->data;
|
rec = server->idles->data;
|
||||||
|
|
||||||
/* Send command */
|
/* Send command */
|
||||||
irc_send_cmd(server, rec->cmd);
|
if (rec->redirect_cmd != NULL) {
|
||||||
|
server_redirect_event_list(server, rec->redirect_cmd, rec->arg,
|
||||||
/* Add server redirections */
|
rec->remote, rec->failure_signal,
|
||||||
group = 0;
|
rec->redirects);
|
||||||
for (tmp = rec->redirects; tmp != NULL; tmp = tmp->next) {
|
|
||||||
REDIRECT_IDLE_REC *rrec = tmp->data;
|
|
||||||
|
|
||||||
group = server_redirect_single_event((SERVER_REC *) server, rec->arg, rec->last > 0,
|
|
||||||
group, rrec->event, rrec->signal, rrec->argpos);
|
|
||||||
if (rec->last > 0) rec->last--;
|
|
||||||
}
|
}
|
||||||
|
irc_send_cmd(server, rec->cmd);
|
||||||
|
|
||||||
server_idle_destroy(server, rec);
|
server_idle_destroy(server, rec);
|
||||||
}
|
}
|
34
src/irc/core/servers-idle.h
Normal file
34
src/irc/core/servers-idle.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __SERVERS_IDLE_H
|
||||||
|
#define __SERVERS_IDLE_H
|
||||||
|
|
||||||
|
/* Add new idle command to queue */
|
||||||
|
int server_idle_add_redir(IRC_SERVER_REC *server, const char *cmd,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...);
|
||||||
|
#define server_idle_add(server, cmd) \
|
||||||
|
server_idle_add_redir(server, cmd, NULL, NULL, 0, NULL, NULL)
|
||||||
|
|
||||||
|
/* Add new idle command to first of queue */
|
||||||
|
int server_idle_add_first_redir(IRC_SERVER_REC *server, const char *cmd,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...);
|
||||||
|
#define server_idle_add_first(server, cmd) \
|
||||||
|
server_idle_add_first_redir(server, cmd, NULL, NULL, 0, NULL, NULL)
|
||||||
|
|
||||||
|
/* Add new idle command to specified position of queue */
|
||||||
|
int server_idle_insert_redir(IRC_SERVER_REC *server, const char *cmd, int tag,
|
||||||
|
const char *redirect_cmd, const char *arg,
|
||||||
|
int remote, const char *failure_signal, ...);
|
||||||
|
#define server_idle_insert(server, cmd, tag) \
|
||||||
|
server_idle_insert_redir(server, cmd, tag, NULL, NULL, 0, NULL, NULL)
|
||||||
|
|
||||||
|
/* Check if record is still in queue */
|
||||||
|
int server_idle_find(IRC_SERVER_REC *server, int tag);
|
||||||
|
|
||||||
|
/* Remove record from idle queue */
|
||||||
|
int server_idle_remove(IRC_SERVER_REC *server, int tag);
|
||||||
|
|
||||||
|
void servers_idle_init(void);
|
||||||
|
void servers_idle_deinit(void);
|
||||||
|
|
||||||
|
#endif
|
569
src/irc/core/servers-redirect.c
Normal file
569
src/irc/core/servers-redirect.c
Normal file
@ -0,0 +1,569 @@
|
|||||||
|
/*
|
||||||
|
server-redirect.c : irssi
|
||||||
|
|
||||||
|
Copyright (C) 1999-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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "module.h"
|
||||||
|
#include "signals.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "irc-servers.h"
|
||||||
|
#include "servers-redirect.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
int remote;
|
||||||
|
int timeout;
|
||||||
|
GSList *start, *stop; /* char *event, int argpos, ... */
|
||||||
|
} REDIRECT_CMD_REC;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
REDIRECT_CMD_REC *cmd;
|
||||||
|
time_t created;
|
||||||
|
int destroyed;
|
||||||
|
|
||||||
|
char *arg;
|
||||||
|
int remote;
|
||||||
|
char *failure_signal, *default_signal;
|
||||||
|
GSList *signals; /* event, signal, ... */
|
||||||
|
} REDIRECT_REC;
|
||||||
|
|
||||||
|
static GHashTable *command_redirects; /* "command xxx" : REDIRECT_CMD_REC* */
|
||||||
|
|
||||||
|
/* Find redirection command record for specified command line. */
|
||||||
|
static REDIRECT_CMD_REC *redirect_cmd_find(const char *command)
|
||||||
|
{
|
||||||
|
REDIRECT_CMD_REC *rec;
|
||||||
|
const char *p;
|
||||||
|
char *cmd;
|
||||||
|
|
||||||
|
p = strchr(command, ' ');
|
||||||
|
if (p == NULL)
|
||||||
|
rec = g_hash_table_lookup(command_redirects, command);
|
||||||
|
else {
|
||||||
|
cmd = g_strndup(command, (int) (p-command));
|
||||||
|
rec = g_hash_table_lookup(command_redirects, cmd);
|
||||||
|
g_free(cmd);
|
||||||
|
}
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirect_cmd_destroy(REDIRECT_CMD_REC *rec)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
for (tmp = rec->start; tmp != NULL; tmp = tmp->next->next)
|
||||||
|
g_free(tmp->data);
|
||||||
|
for (tmp = rec->stop; tmp != NULL; tmp = tmp->next->next)
|
||||||
|
g_free(tmp->data);
|
||||||
|
g_slist_free(rec->start);
|
||||||
|
g_slist_free(rec->stop);
|
||||||
|
g_free(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirect_cmd_ref(REDIRECT_CMD_REC *rec)
|
||||||
|
{
|
||||||
|
rec->refcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirect_cmd_unref(REDIRECT_CMD_REC *rec)
|
||||||
|
{
|
||||||
|
if (--rec->refcount <= 0)
|
||||||
|
redirect_cmd_destroy(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirect_destroy(REDIRECT_REC *rec)
|
||||||
|
{
|
||||||
|
redirect_cmd_unref(rec->cmd);
|
||||||
|
|
||||||
|
g_free_not_null(rec->arg);
|
||||||
|
g_free_not_null(rec->failure_signal);
|
||||||
|
g_free_not_null(rec->default_signal);
|
||||||
|
g_slist_foreach(rec->signals, (GFunc) g_free, NULL);
|
||||||
|
g_slist_free(rec->signals);
|
||||||
|
g_free(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void server_redirect_register(const char *command,
|
||||||
|
int remote, int timeout, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
GSList *start, *stop, **list;
|
||||||
|
const char *event;
|
||||||
|
int argpos;
|
||||||
|
|
||||||
|
va_start(va, timeout);
|
||||||
|
start = stop = NULL; list = &start;
|
||||||
|
for (;;) {
|
||||||
|
event = va_arg(va, const char *);
|
||||||
|
if (event == NULL) {
|
||||||
|
if (list == &stop)
|
||||||
|
break;
|
||||||
|
list = &stop;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
argpos = va_arg(va, int);
|
||||||
|
*list = g_slist_append(*list, g_strdup(event));
|
||||||
|
*list = g_slist_append(*list, GINT_TO_POINTER(argpos));
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
server_redirect_register_list(command, remote, timeout, start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void server_redirect_register_list(const char *command,
|
||||||
|
int remote, int timeout,
|
||||||
|
GSList *start, GSList *stop)
|
||||||
|
{
|
||||||
|
REDIRECT_CMD_REC *rec;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_return_if_fail(command != NULL);
|
||||||
|
g_return_if_fail(stop != NULL);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended(command_redirects, command,
|
||||||
|
&key, &value)) {
|
||||||
|
/* Already registered - might have changed so destroy
|
||||||
|
the old one */
|
||||||
|
g_hash_table_remove(command_redirects, command);
|
||||||
|
redirect_cmd_unref(value);
|
||||||
|
g_free(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
rec = g_new0(REDIRECT_CMD_REC, 1);
|
||||||
|
redirect_cmd_ref(rec);
|
||||||
|
rec->remote = remote;
|
||||||
|
rec->timeout = timeout;
|
||||||
|
rec->start = start;
|
||||||
|
rec->stop = stop;
|
||||||
|
g_hash_table_insert(command_redirects, g_strdup(command), rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void server_redirect_event(IRC_SERVER_REC *server, const char *command,
|
||||||
|
const char *arg, int remote,
|
||||||
|
const char *failure_signal, ...)
|
||||||
|
{
|
||||||
|
GSList *signals;
|
||||||
|
const char *event, *signal;
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
va_start(va, failure_signal);
|
||||||
|
signals = NULL;
|
||||||
|
while ((event = va_arg(va, const char *)) != NULL) {
|
||||||
|
signal = va_arg(va, const char *);
|
||||||
|
if (signal == NULL) {
|
||||||
|
g_warning("server_redirect_event(%s): "
|
||||||
|
"signal not specified for event", command);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals = g_slist_append(signals, g_strdup(event));
|
||||||
|
signals = g_slist_append(signals, g_strdup(signal));
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
server_redirect_event_list(server, command, arg, remote,
|
||||||
|
failure_signal, signals);
|
||||||
|
}
|
||||||
|
|
||||||
|
void server_redirect_event_list(IRC_SERVER_REC *server, const char *command,
|
||||||
|
const char *arg, int remote,
|
||||||
|
const char *failure_signal, GSList *signals)
|
||||||
|
{
|
||||||
|
REDIRECT_CMD_REC *cmdrec;
|
||||||
|
REDIRECT_REC *rec;
|
||||||
|
GSList *default_signal;
|
||||||
|
char *default_signal_key;
|
||||||
|
|
||||||
|
g_return_if_fail(IS_IRC_SERVER(server));
|
||||||
|
g_return_if_fail(command != NULL);
|
||||||
|
g_return_if_fail((g_slist_length(signals) & 1) == 0);
|
||||||
|
|
||||||
|
if (server->redirect_next != NULL) {
|
||||||
|
redirect_destroy(server->redirect_next);
|
||||||
|
server->redirect_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdrec = g_hash_table_lookup(command_redirects, command);
|
||||||
|
if (cmdrec == NULL) {
|
||||||
|
g_warning("Unknown redirection command: %s", command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect_cmd_ref(cmdrec);
|
||||||
|
|
||||||
|
rec = g_new0(REDIRECT_REC, 1);
|
||||||
|
rec->created = time(NULL);
|
||||||
|
rec->cmd = cmdrec;
|
||||||
|
rec->arg = g_strdup(arg);
|
||||||
|
rec->remote = remote != -1 ? remote : cmdrec->remote;
|
||||||
|
rec->failure_signal = g_strdup(failure_signal);
|
||||||
|
|
||||||
|
default_signal = gslist_find_string(signals, "");
|
||||||
|
if (default_signal != NULL) {
|
||||||
|
default_signal_key = default_signal->data;
|
||||||
|
rec->default_signal = default_signal->next->data;
|
||||||
|
|
||||||
|
signals = g_slist_remove(signals, default_signal_key);
|
||||||
|
signals = g_slist_remove(signals, rec->default_signal);
|
||||||
|
g_free(default_signal_key);
|
||||||
|
}
|
||||||
|
rec->signals = signals;
|
||||||
|
|
||||||
|
server->redirect_next = rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void server_redirect_command(IRC_SERVER_REC *server, const char *command)
|
||||||
|
{
|
||||||
|
REDIRECT_CMD_REC *cmdrec;
|
||||||
|
REDIRECT_REC *rec;
|
||||||
|
|
||||||
|
g_return_if_fail(IS_IRC_SERVER(server));
|
||||||
|
g_return_if_fail(command != NULL);
|
||||||
|
|
||||||
|
if (server->redirect_next != NULL) {
|
||||||
|
rec = server->redirect_next;
|
||||||
|
server->redirect_next = NULL;
|
||||||
|
} else {
|
||||||
|
cmdrec = redirect_cmd_find(command);
|
||||||
|
if (cmdrec == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* no redirection wanted, but still register the command
|
||||||
|
so future redirections wont get messed up. */
|
||||||
|
redirect_cmd_ref(cmdrec);
|
||||||
|
|
||||||
|
rec = g_new0(REDIRECT_REC, 1);
|
||||||
|
rec->created = time(NULL);
|
||||||
|
rec->cmd = cmdrec;
|
||||||
|
rec->remote = cmdrec->remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->redirects = g_slist_append(server->redirects, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int redirect_args_match(const char *event_args,
|
||||||
|
const char *arg, int pos)
|
||||||
|
{
|
||||||
|
const char *start;
|
||||||
|
|
||||||
|
if (pos == -1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* skip to the start of the wanted argument */
|
||||||
|
while (pos > 0 && *event_args != '\0') {
|
||||||
|
while (*event_args != ' ' && *event_args != '\0') event_args++;
|
||||||
|
while (*event_args == ' ') event_args++;
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now compare the arguments */
|
||||||
|
start = event_args;
|
||||||
|
while (*arg != '\0') {
|
||||||
|
while (*arg != '\0' && *arg != ' ' && *event_args != '\0') {
|
||||||
|
if (*arg != *event_args)
|
||||||
|
break;
|
||||||
|
arg++; event_args++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*arg == '\0' || *arg == ' ') &&
|
||||||
|
(*event_args == '\0' || *event_args == ' '))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* compare the next argument */
|
||||||
|
while (*arg != ' ' && *arg != '\0') arg++;
|
||||||
|
while (*arg == ' ') arg++;
|
||||||
|
|
||||||
|
event_args = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSList *redirect_cmd_list_find(GSList *list, const char *event)
|
||||||
|
{
|
||||||
|
while (list != NULL) {
|
||||||
|
const char *str = list->data;
|
||||||
|
|
||||||
|
if (strcmp(str, event) == 0)
|
||||||
|
break;
|
||||||
|
list = list->next->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *redirect_match(REDIRECT_REC *redirect, const char *event,
|
||||||
|
const char *args, int *match_stop)
|
||||||
|
{
|
||||||
|
GSList *tmp, *cmdpos;
|
||||||
|
int stop_signal;
|
||||||
|
|
||||||
|
for (tmp = redirect->signals; tmp != NULL; tmp = tmp->next->next) {
|
||||||
|
if (strcmp(tmp->data, event) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
event) != NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static REDIRECT_REC *redirect_find(IRC_SERVER_REC *server, const char *event,
|
||||||
|
const char *args, const char **signal,
|
||||||
|
int *match_stop)
|
||||||
|
{
|
||||||
|
REDIRECT_REC *redirect;
|
||||||
|
GSList *tmp, *next;
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
/* find the redirection */
|
||||||
|
*signal = NULL; redirect = NULL;
|
||||||
|
for (tmp = server->redirects; tmp != NULL; tmp = tmp->next) {
|
||||||
|
REDIRECT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
*signal = redirect_match(rec, event, args, match_stop);
|
||||||
|
if (*signal != NULL) {
|
||||||
|
redirect = rec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the destroyed, non-remote and timeouted remote
|
||||||
|
redirections that should have happened before this redirection */
|
||||||
|
now = time(NULL);
|
||||||
|
for (tmp = server->redirects; tmp != NULL; tmp = next) {
|
||||||
|
REDIRECT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec == redirect)
|
||||||
|
break;
|
||||||
|
|
||||||
|
next = tmp->next;
|
||||||
|
if (rec->destroyed ||
|
||||||
|
(rec->remote && (now-rec->created) > rec->cmd->timeout) ||
|
||||||
|
(redirect != NULL && !rec->remote)) {
|
||||||
|
server->redirects =
|
||||||
|
g_slist_remove(server->redirects, rec);
|
||||||
|
if (!rec->destroyed && rec->failure_signal != NULL) {
|
||||||
|
/* emit the failure signal */
|
||||||
|
signal_emit(rec->failure_signal, 1, server);
|
||||||
|
}
|
||||||
|
redirect_destroy(rec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *server_redirect_get_signal(IRC_SERVER_REC *server,
|
||||||
|
const char *event,
|
||||||
|
const char *args)
|
||||||
|
{
|
||||||
|
REDIRECT_REC *redirect;
|
||||||
|
const char *signal;
|
||||||
|
int match_stop;
|
||||||
|
|
||||||
|
if (server->redirects == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (server->redirect_continue == NULL) {
|
||||||
|
/* find the redirection */
|
||||||
|
redirect = redirect_find(server, event, args,
|
||||||
|
&signal, &match_stop);
|
||||||
|
} else {
|
||||||
|
/* redirection is already started, now we'll just need to
|
||||||
|
keep redirecting until stop-event is found. */
|
||||||
|
redirect = server->redirect_continue;
|
||||||
|
signal = redirect_match(redirect, event, NULL, &match_stop);
|
||||||
|
if (signal == NULL) {
|
||||||
|
/* unknown event - redirect to the default signal.
|
||||||
|
FIXME: if stop event isn't properly got, this
|
||||||
|
could break everything. Add some checks that if
|
||||||
|
we get eg. 10 different unknown events after this,
|
||||||
|
or if one of them matches to another redirection,
|
||||||
|
abort this. */
|
||||||
|
signal = redirect->default_signal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_stop || redirect == NULL)
|
||||||
|
server->redirect_continue = redirect;
|
||||||
|
else {
|
||||||
|
/* stop event - remove this redirection next time this
|
||||||
|
function is called (can't destroy now or our return
|
||||||
|
value would be corrupted) */
|
||||||
|
redirect->destroyed = TRUE;
|
||||||
|
server->redirect_continue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_disconnected(IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
if (!IS_IRC_SERVER(server))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_slist_foreach(server->redirects, (GFunc) redirect_destroy, NULL);
|
||||||
|
g_slist_free(server->redirects);
|
||||||
|
|
||||||
|
if (server->redirect_next != NULL)
|
||||||
|
redirect_destroy(server->redirect_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_redirect_destroy(char *key, REDIRECT_CMD_REC *cmd)
|
||||||
|
{
|
||||||
|
g_free(key);
|
||||||
|
redirect_cmd_unref(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void servers_redirect_init(void)
|
||||||
|
{
|
||||||
|
command_redirects = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal);
|
||||||
|
|
||||||
|
/* WHOIS - register as remote command by default
|
||||||
|
with a timeout of one minute */
|
||||||
|
server_redirect_register("whois", TRUE, 60,
|
||||||
|
"event 311", 1, /* Begins the WHOIS */
|
||||||
|
"event 401", 1, /* No such nick */
|
||||||
|
NULL,
|
||||||
|
"event 318", 1, /* End of WHOIS */
|
||||||
|
"event 402", 1, /* No such server */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* WHOWAS */
|
||||||
|
server_redirect_register("whowas", FALSE, 0,
|
||||||
|
"event 314", 1, /* Begins the WHOWAS */
|
||||||
|
"event 406", 1, /* There was no such nick */
|
||||||
|
NULL,
|
||||||
|
"event 369", 1, /* End of WHOWAS */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* WHO */
|
||||||
|
server_redirect_register("who", FALSE, 0,
|
||||||
|
"event 352", 1, /* Begins the WHO */
|
||||||
|
"event 401", 1, /* No such nick/channel */
|
||||||
|
NULL,
|
||||||
|
"event 315", 1, /* End of WHO */
|
||||||
|
"event 403", 1, /* no such channel */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* LIST */
|
||||||
|
server_redirect_register("list", FALSE, 0,
|
||||||
|
"event 321", 1, /* Begins the LIST */
|
||||||
|
NULL,
|
||||||
|
"event 323", 1, /* End of LIST */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* ISON */
|
||||||
|
server_redirect_register("ison", FALSE, 0,
|
||||||
|
NULL,
|
||||||
|
"event 303", 1, /* ISON */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* USERHOST */
|
||||||
|
server_redirect_register("userhost", FALSE, 0,
|
||||||
|
"event 401", 1, /* no such nick */
|
||||||
|
NULL,
|
||||||
|
"event 302", 1, /* Userhost */
|
||||||
|
"event 461", 1, /* Not enough parameters */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* MODE #channel */
|
||||||
|
server_redirect_register("mode channel", FALSE, 0,
|
||||||
|
NULL,
|
||||||
|
"event 324", 1, /* MODE-reply */
|
||||||
|
"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);
|
||||||
|
|
||||||
|
/* MODE #channel b */
|
||||||
|
server_redirect_register("mode b", FALSE, 0,
|
||||||
|
"event 367", 1,
|
||||||
|
NULL,
|
||||||
|
"event 368", 1, /* End of Channel ban List */
|
||||||
|
"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);
|
||||||
|
|
||||||
|
/* MODE #channel e */
|
||||||
|
server_redirect_register("mode e", FALSE, 0,
|
||||||
|
"event 348", 1,
|
||||||
|
NULL,
|
||||||
|
"event 349", 1, /* End of ban exceptions */
|
||||||
|
"event 482", 1, /* not channel operator - OPN's ircd doesn't want non-ops to see ban exceptions */
|
||||||
|
"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. */
|
||||||
|
"event 472", -1, /* unknown mode (you should check e-mode's existance from 004 event instead of relying on this) */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* MODE #channel I */
|
||||||
|
server_redirect_register("mode e", FALSE, 0,
|
||||||
|
"event 346", 1,
|
||||||
|
NULL,
|
||||||
|
"event 347", 1, /* End of invite list */
|
||||||
|
"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. */
|
||||||
|
"event 472", -1, /* unknown mode (you should check I-mode's existance from 004 event instead of relying on this) */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* PING */
|
||||||
|
server_redirect_register("ping", TRUE, 60,
|
||||||
|
NULL,
|
||||||
|
"event 402", -1, /* no such server */
|
||||||
|
"event pong", -1, /* PONG */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void servers_redirect_deinit(void)
|
||||||
|
{
|
||||||
|
g_hash_table_foreach(command_redirects,
|
||||||
|
(GHFunc) cmd_redirect_destroy, NULL);
|
||||||
|
g_hash_table_destroy(command_redirects);
|
||||||
|
|
||||||
|
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
||||||
|
}
|
66
src/irc/core/servers-redirect.h
Normal file
66
src/irc/core/servers-redirect.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef __SERVERS_REDIRECT_H
|
||||||
|
#define __SERVERS_REDIRECT_H
|
||||||
|
|
||||||
|
/* Register new redirection command.
|
||||||
|
|
||||||
|
remote - Specifies if the command is by default a remote command
|
||||||
|
(eg. sent to another server). server_redirect_event() may override this.
|
||||||
|
|
||||||
|
timeout - If remote is TRUE, specifies how many seconds to wait for
|
||||||
|
reply before aborting.
|
||||||
|
|
||||||
|
... - char *start, int argpos, char *start, int argpos, ..., NULL,
|
||||||
|
char *stop, int argpos, char *stop, int argpos, ..., NULL
|
||||||
|
List of events that start and stop this redirection.
|
||||||
|
Start event list may be just NULL, but there must be at least one
|
||||||
|
stop event. `argpos' specifies the word number in event string which
|
||||||
|
is compared to wanted argument, -1 = don't compare, TRUE always. */
|
||||||
|
void server_redirect_register(const char *command,
|
||||||
|
int remote, int timeout, ...);
|
||||||
|
/* start/stop 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);
|
||||||
|
|
||||||
|
/* Specify that the next command sent to server will be redirected.
|
||||||
|
NOTE: This command MUST be called before irc_send_cmd().
|
||||||
|
|
||||||
|
command - Specifies the registered command that should be used for this
|
||||||
|
redirection.
|
||||||
|
|
||||||
|
arg - The argument to be compared in event strings. You can give multiple
|
||||||
|
arguments separated with space.
|
||||||
|
|
||||||
|
remote - Specifies if the command is a remote command, -1 = use default.
|
||||||
|
|
||||||
|
failure_signal - If irssi can't find the stop signal for the redirection,
|
||||||
|
this signal is called.
|
||||||
|
|
||||||
|
... - char *event, char *redirect_signal, ..., NULL
|
||||||
|
If the `event' is "", all the events belonging to the redirection but not
|
||||||
|
specified here, will be sent there. */
|
||||||
|
void server_redirect_event(IRC_SERVER_REC *server, const char *command,
|
||||||
|
const char *arg, int remote,
|
||||||
|
const char *failure_signal, ...);
|
||||||
|
/* Signals list shouldn't be free'd after, and it's strings should be
|
||||||
|
dynamically allocated */
|
||||||
|
void server_redirect_event_list(IRC_SERVER_REC *server, const char *command,
|
||||||
|
const char *arg, int remote,
|
||||||
|
const char *failure_signal, GSList *signals);
|
||||||
|
|
||||||
|
/* INTERNAL: */
|
||||||
|
|
||||||
|
/* irc_send_cmd() calls this to make sure redirecting knows
|
||||||
|
what's sent to server */
|
||||||
|
void server_redirect_command(IRC_SERVER_REC *server, const char *command);
|
||||||
|
/* Returns the redirection signal for specified event.
|
||||||
|
This is the function that contains the real redirecting logic. */
|
||||||
|
const char *server_redirect_get_signal(IRC_SERVER_REC *server,
|
||||||
|
const char *event,
|
||||||
|
const char *args);
|
||||||
|
|
||||||
|
void servers_redirect_init(void);
|
||||||
|
void servers_redirect_deinit(void);
|
||||||
|
|
||||||
|
#endif
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#define MODULE_NAME "irc/notifylist"
|
#define MODULE_NAME "irc/notifylist"
|
||||||
|
|
||||||
#define ISON_EVENT "event 303"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *nick;
|
char *nick;
|
||||||
char *user, *host, *realname, *awaymsg;
|
char *user, *host, *realname, *awaymsg;
|
||||||
@ -22,6 +20,8 @@ typedef struct {
|
|||||||
} NOTIFY_NICK_REC;
|
} NOTIFY_NICK_REC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int ison_count; /* number of ISON requests sent */
|
||||||
|
|
||||||
GSList *notify_users; /* NOTIFY_NICK_REC's of notifylist people who are in IRC */
|
GSList *notify_users; /* NOTIFY_NICK_REC's of notifylist people who are in IRC */
|
||||||
GSList *ison_tempusers; /* Temporary list for saving /ISON events.. */
|
GSList *ison_tempusers; /* Temporary list for saving /ISON events.. */
|
||||||
} MODULE_SERVER_REC;
|
} MODULE_SERVER_REC;
|
||||||
|
@ -81,28 +81,19 @@ NOTIFY_NICK_REC *notify_nick_find(IRC_SERVER_REC *server, const char *nick)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_ison_queue_empty(IRC_SERVER_REC *server)
|
|
||||||
{
|
|
||||||
GSList *tmp;
|
|
||||||
|
|
||||||
tmp = server_redirect_getqueue((SERVER_REC *) server, ISON_EVENT, NULL);
|
|
||||||
for (; tmp != NULL; tmp = tmp->next) {
|
|
||||||
REDIRECT_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
if (strcmp(rec->name, "notifylist event") == 0)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ison_send(IRC_SERVER_REC *server, GString *cmd)
|
static void ison_send(IRC_SERVER_REC *server, GString *cmd)
|
||||||
{
|
{
|
||||||
|
MODULE_SERVER_REC *mserver;
|
||||||
|
|
||||||
|
mserver = MODULE_DATA(server);
|
||||||
|
mserver->ison_count++;
|
||||||
|
|
||||||
g_string_truncate(cmd, cmd->len-1);
|
g_string_truncate(cmd, cmd->len-1);
|
||||||
g_string_prepend(cmd, "ISON :");
|
g_string_prepend(cmd, "ISON :");
|
||||||
|
|
||||||
|
server_redirect_event(server, "ison", NULL, -1, NULL,
|
||||||
|
"event 303", "notifylist event", NULL);
|
||||||
irc_send_cmd(server, cmd->str);
|
irc_send_cmd(server, cmd->str);
|
||||||
server_redirect_event((SERVER_REC *) server, NULL, 1, ISON_EVENT, "notifylist event", -1, NULL);
|
|
||||||
|
|
||||||
g_string_truncate(cmd, 0);
|
g_string_truncate(cmd, 0);
|
||||||
}
|
}
|
||||||
@ -111,6 +102,7 @@ static void ison_send(IRC_SERVER_REC *server, GString *cmd)
|
|||||||
notify list is in IRC */
|
notify list is in IRC */
|
||||||
static void notifylist_timeout_server(IRC_SERVER_REC *server)
|
static void notifylist_timeout_server(IRC_SERVER_REC *server)
|
||||||
{
|
{
|
||||||
|
MODULE_SERVER_REC *mserver;
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
GString *cmd;
|
GString *cmd;
|
||||||
char *nick, *ptr;
|
char *nick, *ptr;
|
||||||
@ -121,7 +113,8 @@ static void notifylist_timeout_server(IRC_SERVER_REC *server)
|
|||||||
if (!IS_IRC_SERVER(server))
|
if (!IS_IRC_SERVER(server))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!is_ison_queue_empty(server)) {
|
mserver = MODULE_DATA(server);
|
||||||
|
if (mserver->ison_count > 0) {
|
||||||
/* still not received all replies to previous /ISON commands.. */
|
/* still not received all replies to previous /ISON commands.. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -184,16 +177,13 @@ static void whois_send(IRC_SERVER_REC *server, char *nicks)
|
|||||||
for (p = str+strlen(nicks)+1; *p != '\0'; p++)
|
for (p = str+strlen(nicks)+1; *p != '\0'; p++)
|
||||||
if (*p == ',') *p = ' ';
|
if (*p == ',') *p = ' ';
|
||||||
|
|
||||||
server_redirect_event((SERVER_REC *) server, str, 2,
|
server_redirect_event(server, "whois", str, FALSE,
|
||||||
"event 318", "notifylist event whois end", 1,
|
"notifylist event whois end",
|
||||||
"event 402", "event empty", 1,
|
"event 318", "notifylist event whois end",
|
||||||
"event 401", "event empty", 1,
|
"event 311", "notifylist event whois",
|
||||||
"event 311", "notifylist event whois", 1,
|
"event 301", "notifylist event whois away",
|
||||||
"event 301", "notifylist event whois away", 1,
|
"event 317", "notifylist event whois idle",
|
||||||
"event 312", "event empty", 1,
|
"", "event empty", NULL);
|
||||||
"event 313", "event empty", 1,
|
|
||||||
"event 317", "notifylist event whois idle", 1,
|
|
||||||
"event 319", "event empty", 1, NULL);
|
|
||||||
g_free(str);
|
g_free(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +301,7 @@ static void event_ison(IRC_SERVER_REC *server, const char *data)
|
|||||||
mserver = MODULE_DATA(server);
|
mserver = MODULE_DATA(server);
|
||||||
ison_save_users(mserver, online);
|
ison_save_users(mserver, online);
|
||||||
|
|
||||||
if (!is_ison_queue_empty(server)) {
|
if (--mserver->ison_count > 0) {
|
||||||
/* wait for the rest of the /ISON replies */
|
/* wait for the rest of the /ISON replies */
|
||||||
g_free(params);
|
g_free(params);
|
||||||
return;
|
return;
|
||||||
|
@ -144,8 +144,10 @@ static void event_whois_end(IRC_SERVER_REC *server, const char *data)
|
|||||||
|
|
||||||
if (event != NULL) {
|
if (event != NULL) {
|
||||||
signal_emit(event, 6, server, rec->nick,
|
signal_emit(event, 6, server, rec->nick,
|
||||||
rec->user, rec->host,
|
rec->user != NULL ? rec->user : "??",
|
||||||
rec->realname, rec->awaymsg);
|
rec->host != NULL ? rec->host : "??",
|
||||||
|
rec->realname != NULL ? rec->realname : "??",
|
||||||
|
rec->awaymsg);
|
||||||
}
|
}
|
||||||
rec->idle_ok = notify->idle_check_time <= 0 ||
|
rec->idle_ok = notify->idle_check_time <= 0 ||
|
||||||
rec->idle_time <= notify->idle_check_time;
|
rec->idle_time <= notify->idle_check_time;
|
||||||
|
@ -196,8 +196,6 @@ static void notifylist_init_server(IRC_SERVER_REC *server)
|
|||||||
|
|
||||||
rec = g_new0(MODULE_SERVER_REC,1 );
|
rec = g_new0(MODULE_SERVER_REC,1 );
|
||||||
MODULE_DATA_SET(server, rec);
|
MODULE_DATA_SET(server, rec);
|
||||||
|
|
||||||
server_redirect_init((SERVER_REC *) server, "command ison", 1, ISON_EVENT, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notifylist_deinit_server(IRC_SERVER_REC *server)
|
static void notifylist_deinit_server(IRC_SERVER_REC *server)
|
||||||
|
@ -46,47 +46,6 @@ void
|
|||||||
server_disconnect(server)
|
server_disconnect(server)
|
||||||
Irssi::Server server
|
Irssi::Server server
|
||||||
|
|
||||||
void
|
|
||||||
server_redirect_init(server, command, last, ...)
|
|
||||||
Irssi::Server server
|
|
||||||
char *command
|
|
||||||
int last
|
|
||||||
PREINIT:
|
|
||||||
STRLEN n_a;
|
|
||||||
GSList *list;
|
|
||||||
int n;
|
|
||||||
CODE:
|
|
||||||
list = NULL;
|
|
||||||
for (n = 3; n < items; n++) {
|
|
||||||
list = g_slist_append(list, SvPV(ST(n), n_a));
|
|
||||||
}
|
|
||||||
server_redirect_initv(server, command, last, list);
|
|
||||||
|
|
||||||
int
|
|
||||||
server_redirect_single_event(server, arg, last, group, event, signal, argpos)
|
|
||||||
Irssi::Server server
|
|
||||||
char *arg
|
|
||||||
int last
|
|
||||||
int group
|
|
||||||
char *event
|
|
||||||
char *signal
|
|
||||||
int argpos
|
|
||||||
|
|
||||||
void
|
|
||||||
server_redirect_event(server, arg, last, ...)
|
|
||||||
Irssi::Server server
|
|
||||||
char *arg
|
|
||||||
int last
|
|
||||||
PREINIT:
|
|
||||||
STRLEN n_a;
|
|
||||||
int n, group;
|
|
||||||
CODE:
|
|
||||||
group = 0;
|
|
||||||
for (n = 3; n+3 <= items; n += 3, last--) {
|
|
||||||
group = server_redirect_single_event(server, arg, last > 0, group,
|
|
||||||
(char *) SvPV(ST(n), n_a), (char *) SvPV(ST(n+1), n_a), (int) SvIV(ST(n+2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
isnickflag(server, flag)
|
isnickflag(server, flag)
|
||||||
Irssi::Server server
|
Irssi::Server server
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "chatnets.h"
|
#include "chatnets.h"
|
||||||
#include "servers.h"
|
#include "servers.h"
|
||||||
#include "servers-reconnect.h"
|
#include "servers-reconnect.h"
|
||||||
#include "servers-redirect.h"
|
|
||||||
#include "servers-setup.h"
|
#include "servers-setup.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
|
@ -35,6 +35,44 @@ ctcp_send_reply(server, data)
|
|||||||
Irssi::Irc::Server server
|
Irssi::Irc::Server server
|
||||||
char *data
|
char *data
|
||||||
|
|
||||||
|
MODULE = Irssi::Irc::Server PACKAGE = Irssi::Irc::Server PREFIX = server_
|
||||||
|
|
||||||
|
void
|
||||||
|
server_redirect_register(command, remote, timeout, ...)
|
||||||
|
char *command
|
||||||
|
int remote
|
||||||
|
int timeout
|
||||||
|
PREINIT:
|
||||||
|
STRLEN n_a;
|
||||||
|
GSList *start, *stop, **list;
|
||||||
|
int n;
|
||||||
|
CODE:
|
||||||
|
start = stop = NULL; list = &start;
|
||||||
|
for (n = 3; n < items; n++) {
|
||||||
|
if (ST(n) == &PL_sv_undef) list = &stop;
|
||||||
|
if (SvPOK(ST(n)))
|
||||||
|
*list = g_slist_append(*list, SvPV(ST(n), n_a));
|
||||||
|
}
|
||||||
|
server_redirect_register_list(command, remote, timeout, start, stop);
|
||||||
|
|
||||||
|
void
|
||||||
|
server_redirect_event(server, command, arg, remote, failure_signal, ...)
|
||||||
|
Irssi::Irc::Server server
|
||||||
|
char *command
|
||||||
|
char *arg
|
||||||
|
int remote
|
||||||
|
char *failure_signal
|
||||||
|
PREINIT:
|
||||||
|
STRLEN n_a;
|
||||||
|
GSList *list;
|
||||||
|
int n;
|
||||||
|
CODE:
|
||||||
|
list = NULL;
|
||||||
|
for (n = 5; n < items; n++) {
|
||||||
|
list = g_slist_append(list, SvPV(ST(n), n_a));
|
||||||
|
}
|
||||||
|
server_redirect_event_list(server, command, arg, remote, failure_signal, list);
|
||||||
|
|
||||||
MODULE = Irssi::Irc::Server PACKAGE = Irssi::Irc::Connect PREFIX = irc_server_
|
MODULE = Irssi::Irc::Server PACKAGE = Irssi::Irc::Connect PREFIX = irc_server_
|
||||||
|
|
||||||
Irssi::Irc::Server
|
Irssi::Irc::Server
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "modes.h"
|
#include "modes.h"
|
||||||
#include "mode-lists.h"
|
#include "mode-lists.h"
|
||||||
#include "netsplit.h"
|
#include "netsplit.h"
|
||||||
|
#include "servers-redirect.h"
|
||||||
|
|
||||||
#include "dcc/dcc.h"
|
#include "dcc/dcc.h"
|
||||||
#include "dcc/dcc-file.h"
|
#include "dcc/dcc-file.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user