mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Proxy plugin fixes and cleanups. Supports now multiple servers, doesn't
let clients see CTCP requests and if one client writes message, other clients will see it as well. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@810 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
2fc8c5b83f
commit
a8c139d5e2
@ -12,5 +12,4 @@ libproxy_la_SOURCES = \
|
|||||||
listen.c
|
listen.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
proxy.h \
|
|
||||||
module.h
|
module.h
|
||||||
|
@ -18,107 +18,198 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "module.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "servers.h"
|
|
||||||
#include "irc-servers.h"
|
|
||||||
#include "channels.h"
|
|
||||||
#include "modes.h"
|
|
||||||
#include "nicklist.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "proxy.h"
|
|
||||||
|
|
||||||
static void outdata(gint handle, gchar *data, ...)
|
#include "irc-servers.h"
|
||||||
|
#include "irc-channels.h"
|
||||||
|
#include "irc-nicklist.h"
|
||||||
|
#include "modes.h"
|
||||||
|
|
||||||
|
void proxy_outdata(CLIENT_REC *client, const char *data, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *str;
|
char *str;
|
||||||
|
|
||||||
|
g_return_if_fail(client != NULL);
|
||||||
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
va_start(args, data);
|
va_start(args, data);
|
||||||
|
|
||||||
str = g_strdup_vprintf(data, args);
|
str = g_strdup_vprintf(data, args);
|
||||||
net_transmit(handle, str, strlen(str));
|
net_transmit(client->handle, str, strlen(str));
|
||||||
g_free(str);
|
g_free(str);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void outserver(gint handle, SERVER_REC *server, gchar *data, ...)
|
void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *str;
|
GSList *tmp;
|
||||||
|
char *str;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
g_return_if_fail(server != NULL);
|
||||||
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
va_start(args, data);
|
va_start(args, data);
|
||||||
|
|
||||||
str = g_strdup_vprintf(data, args);
|
str = g_strdup_vprintf(data, args);
|
||||||
outdata(handle, ":%s!%s@proxy %s\n", server->nick, settings_get_str("user_name"), str);
|
len = strlen(str);
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec->server == server)
|
||||||
|
net_transmit(rec->handle, str, len);
|
||||||
|
}
|
||||||
g_free(str);
|
g_free(str);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void proxy_outserver(CLIENT_REC *client, const char *data, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
g_return_if_fail(client != NULL);
|
||||||
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
|
va_start(args, data);
|
||||||
|
|
||||||
|
str = g_strdup_vprintf(data, args);
|
||||||
|
proxy_outdata(client, ":%s!%s@proxy %s\n", client->nick,
|
||||||
|
settings_get_str("user_name"), str);
|
||||||
|
g_free(str);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void proxy_outserver_all(IRC_SERVER_REC *server, const char *data, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
GSList *tmp;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
g_return_if_fail(server != NULL);
|
||||||
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
|
va_start(args, data);
|
||||||
|
|
||||||
|
str = g_strdup_vprintf(data, args);
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec->server == server) {
|
||||||
|
proxy_outdata(rec, ":%s!%s@proxy %s\n", rec->nick,
|
||||||
|
settings_get_str("user_name"), str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(str);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void proxy_outserver_all_except(CLIENT_REC *client, const char *data, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
GSList *tmp;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
g_return_if_fail(client != NULL);
|
||||||
|
g_return_if_fail(data != NULL);
|
||||||
|
|
||||||
|
va_start(args, data);
|
||||||
|
|
||||||
|
str = g_strdup_vprintf(data, args);
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec != client &&
|
||||||
|
rec->server == client->server) {
|
||||||
|
proxy_outdata(rec, ":%s!%s@proxy %s\n", rec->nick,
|
||||||
|
settings_get_str("user_name"), str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(str);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client)
|
||||||
|
{
|
||||||
|
GSList *tmp, *nicks;
|
||||||
|
GString *str;
|
||||||
|
|
||||||
|
proxy_outserver(client, "JOIN %s", channel->name);
|
||||||
|
proxy_outdata(client, ":proxy 353 %s %c %s :", client->nick,
|
||||||
|
channel_mode_is_set(channel, 'p') ? '*' :
|
||||||
|
channel_mode_is_set(channel, 's') ? '@' : '=',
|
||||||
|
channel->name);
|
||||||
|
|
||||||
|
str = g_string_new(NULL);
|
||||||
|
|
||||||
|
nicks = nicklist_getnicks(CHANNEL(channel));
|
||||||
|
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
||||||
|
NICK_REC *nick = tmp->data;
|
||||||
|
|
||||||
|
if (tmp != nicks)
|
||||||
|
g_string_append_c(str, ' ');
|
||||||
|
|
||||||
|
if (nick->op)
|
||||||
|
g_string_append_c(str, '@');
|
||||||
|
else if (nick->halfop)
|
||||||
|
g_string_append_c(str, '%');
|
||||||
|
else if (nick->voice)
|
||||||
|
g_string_append_c(str, '+');
|
||||||
|
g_string_append(str, nick->nick);
|
||||||
|
}
|
||||||
|
g_slist_free(nicks);
|
||||||
|
|
||||||
|
g_string_append_c(str, '\n');
|
||||||
|
proxy_outdata(client, str->str);
|
||||||
|
g_string_free(str, TRUE);
|
||||||
|
|
||||||
|
proxy_outdata(client, ":proxy 366 %s %s :End of /NAMES list.\n",
|
||||||
|
client->nick, channel->name);
|
||||||
|
if (channel->topic != NULL) {
|
||||||
|
proxy_outdata(client, ":proxy 332 %s %s :%s\n",
|
||||||
|
client->nick, channel->name, channel->topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void plugin_proxy_dump_data(CLIENT_REC *client)
|
void plugin_proxy_dump_data(CLIENT_REC *client)
|
||||||
{
|
{
|
||||||
SERVER_REC *server;
|
if (strcmp(client->server->nick, client->nick) != 0) {
|
||||||
GSList *tmp, *tmp2, *nicks;
|
/* change nick first so that clients won't try to eg. set
|
||||||
gint handle;
|
their own user mode with wrong nick.. hopefully works
|
||||||
|
with all clients. */
|
||||||
handle = client->handle;
|
proxy_outdata(client, ":%s!proxy NICK :%s\n",
|
||||||
server = servers->data;
|
client->nick, client->server->nick);
|
||||||
if (strcmp(server->nick, client->nick) != 0)
|
|
||||||
{
|
|
||||||
/* change nick first so that clients won't try to eg. set their own
|
|
||||||
user mode with wrong nick.. hopefully works with all clients. */
|
|
||||||
outdata(handle, ":%s!proxy NICK :%s\n", client->nick, server->nick);
|
|
||||||
g_free(client->nick);
|
g_free(client->nick);
|
||||||
client->nick = g_strdup(server->nick);
|
client->nick = g_strdup(client->server->nick);
|
||||||
}
|
}
|
||||||
outdata(handle, ":proxy 001 %s :Welcome to the Internet Relay Network\n", client->nick);
|
|
||||||
outdata(handle, ":proxy 002 %s :Your host is irssi-proxy, running version %s\n", client->nick, VERSION);
|
/* welcome info */
|
||||||
outdata(handle, ":proxy 003 %s :This server was created ...\n", client->nick);
|
proxy_outdata(client, ":proxy 001 %s :Welcome to the Internet Relay Network\n", client->nick);
|
||||||
if (!IRC_SERVER(server)->emode_known)
|
proxy_outdata(client, ":proxy 002 %s :Your host is irssi-proxy, running version %s\n", client->nick, VERSION);
|
||||||
outdata(handle, ":proxy 004 %s proxy %s oirw abiklmnopqstv\n", client->nick, VERSION);
|
proxy_outdata(client, ":proxy 003 %s :This server was created ...\n", client->nick);
|
||||||
|
if (!client->server->emode_known)
|
||||||
|
proxy_outdata(client, ":proxy 004 %s proxy %s oirw abiklmnopqstv\n", client->nick, VERSION);
|
||||||
else
|
else
|
||||||
outdata(handle, ":proxy 004 %s proxy %s oirw abeIiklmnopqstv\n", client->nick, VERSION);
|
proxy_outdata(client, ":proxy 004 %s proxy %s oirw abeIiklmnopqstv\n", client->nick, VERSION);
|
||||||
outdata(handle, ":proxy 251 %s :There are 0 users and 0 invisible on 1 servers\n", client->nick);
|
proxy_outdata(client, ":proxy 251 %s :There are 0 users and 0 invisible on 1 servers\n", client->nick);
|
||||||
outdata(handle, ":proxy 255 %s :I have 0 clients, 0 services and 0 servers\n", client->nick);
|
proxy_outdata(client, ":proxy 255 %s :I have 0 clients, 0 services and 0 servers\n", client->nick);
|
||||||
outdata(handle, ":proxy 422 %s :MOTD File is missing\n", client->nick);
|
proxy_outdata(client, ":proxy 422 %s :MOTD File is missing\n", client->nick);
|
||||||
|
|
||||||
/* nick / mode */
|
/* user mode / away status */
|
||||||
outserver(handle, server, "MODE %s :+%s", server->nick, IRC_SERVER(server)->usermode);
|
proxy_outserver(client, "MODE %s :+%s", client->server->nick,
|
||||||
|
client->server->usermode);
|
||||||
if (server->usermode_away)
|
if (client->server->usermode_away)
|
||||||
outdata(handle, ":proxy 306 %s :You have been marked as being away\n", server->nick);
|
proxy_outdata(client, ":proxy 306 %s :You have been marked as being away\n", client->nick);
|
||||||
|
|
||||||
/* Send channel joins */
|
/* Send channel joins */
|
||||||
for (tmp = server->channels; tmp != NULL; tmp = tmp->next)
|
g_slist_foreach(client->server->channels, (GFunc) dump_join, client);
|
||||||
{
|
|
||||||
CHANNEL_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
outserver(handle, rec->server, "JOIN %s", rec->name);
|
|
||||||
outdata(handle, ":proxy 353 %s %c %s :", rec->server->nick,
|
|
||||||
channel_mode_is_set(IRC_CHANNEL(rec), 'p') ? '*' :
|
|
||||||
channel_mode_is_set(IRC_CHANNEL(rec), 's') ? '@' : '=',
|
|
||||||
rec->name);
|
|
||||||
|
|
||||||
nicks = nicklist_getnicks(rec);
|
|
||||||
for (tmp2 = nicks; tmp2 != NULL; tmp2 = tmp2->next)
|
|
||||||
{
|
|
||||||
NICK_REC *nick = tmp2->data;
|
|
||||||
|
|
||||||
if (tmp2 != nicks)
|
|
||||||
net_transmit(handle, " ", 1);
|
|
||||||
|
|
||||||
if (nick->op)
|
|
||||||
net_transmit(handle, "@", 1);
|
|
||||||
else if (nick->voice)
|
|
||||||
net_transmit(handle, "+", 1);
|
|
||||||
net_transmit(handle, nick->nick, strlen(nick->nick));
|
|
||||||
}
|
|
||||||
g_slist_free(nicks);
|
|
||||||
net_transmit(handle, "\n", 1);
|
|
||||||
|
|
||||||
outdata(handle, ":proxy 366 %s %s :End of /NAMES list.\n", rec->server->nick, rec->name);
|
|
||||||
if (rec->topic != NULL)
|
|
||||||
outdata(handle, ":proxy 332 %s %s :%s\n", rec->server->nick, rec->name, rec->topic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,30 +19,42 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "proxy.h"
|
#include "signals.h"
|
||||||
#include "net-sendbuffer.h"
|
#include "net-sendbuffer.h"
|
||||||
#include "fe-common/core/printtext.h"
|
#include "servers-redirect.h"
|
||||||
#include "levels.h"
|
#include "levels.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
#include "irc.h"
|
||||||
|
#include "irc-channels.h"
|
||||||
|
|
||||||
|
#include "fe-common/core/printtext.h"
|
||||||
|
|
||||||
|
GSList *proxy_listens;
|
||||||
|
GSList *proxy_clients;
|
||||||
|
|
||||||
static PLUGIN_DATA *proxy_data;
|
|
||||||
static GString *next_line;
|
static GString *next_line;
|
||||||
|
|
||||||
void remove_client(PLUGIN_DATA *data, CLIENT_REC *rec)
|
static void remove_client(CLIENT_REC *rec)
|
||||||
{
|
{
|
||||||
data->clients = g_slist_remove(data->clients, rec);
|
g_return_if_fail(rec != NULL);
|
||||||
|
|
||||||
|
proxy_clients = g_slist_remove(proxy_clients, rec);
|
||||||
|
|
||||||
net_disconnect(rec->handle);
|
net_disconnect(rec->handle);
|
||||||
g_source_remove(rec->tag);
|
g_source_remove(rec->tag);
|
||||||
line_split_free(rec->buffer);
|
line_split_free(rec->buffer);
|
||||||
|
g_free_not_null(rec->nick);
|
||||||
g_free(rec);
|
g_free(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proxy_redirect_event(CLIENT_REC *client, gchar *args, gint last, ...)
|
static void proxy_redirect_event(CLIENT_REC *client,
|
||||||
|
const char *args, int last, ...)
|
||||||
{
|
{
|
||||||
va_list vargs;
|
va_list vargs;
|
||||||
gchar *event;
|
|
||||||
gint argpos, group;
|
|
||||||
GString *str;
|
GString *str;
|
||||||
|
char *event;
|
||||||
|
int argpos, group;
|
||||||
|
|
||||||
g_return_if_fail(client != NULL);
|
g_return_if_fail(client != NULL);
|
||||||
|
|
||||||
@ -50,11 +62,11 @@ static void proxy_redirect_event(CLIENT_REC *client, gchar *args, gint last, ...
|
|||||||
|
|
||||||
str = g_string_new(NULL);
|
str = g_string_new(NULL);
|
||||||
group = 0;
|
group = 0;
|
||||||
while ((event = va_arg(vargs, gchar *)) != NULL)
|
while ((event = va_arg(vargs, char *)) != NULL) {
|
||||||
{
|
argpos = va_arg(vargs, int);
|
||||||
argpos = va_arg(vargs, gint);
|
|
||||||
g_string_sprintf(str, "proxy %d", client->handle);
|
g_string_sprintf(str, "proxy %d", client->handle);
|
||||||
group = server_redirect_single_event(client->server, args, last > 0, group, event, str->str, argpos);
|
group = server_redirect_single_event(SERVER(client->server), args, last > 0,
|
||||||
|
group, event, str->str, argpos);
|
||||||
last--;
|
last--;
|
||||||
}
|
}
|
||||||
g_string_free(str, TRUE);
|
g_string_free(str, TRUE);
|
||||||
@ -62,108 +74,90 @@ static void proxy_redirect_event(CLIENT_REC *client, gchar *args, gint last, ...
|
|||||||
va_end(vargs);
|
va_end(vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grab_who(CLIENT_REC *client, gchar *channel)
|
static void grab_who(CLIENT_REC *client, const char *channel)
|
||||||
{
|
{
|
||||||
gchar *chlist;
|
char *chlist, *chanevent;
|
||||||
gchar **list, **tmp;
|
char **list, **tmp;
|
||||||
|
|
||||||
/* /WHO a,b,c may respond with either one "a,b,c End of WHO" message or
|
/* /WHO a,b,c may respond with either one "a,b,c End of WHO" message
|
||||||
three different "a End of WHO", "b End of WHO", .. messages */
|
or three different "a End of WHO", "b End of WHO", .. messages */
|
||||||
chlist = g_strdup(channel);
|
chlist = g_strdup(channel);
|
||||||
list = g_strsplit(channel, ",", -1);
|
list = g_strsplit(channel, ",", -1);
|
||||||
|
|
||||||
for (tmp = list; *tmp != NULL; tmp++)
|
for (tmp = list; *tmp != NULL; tmp++) {
|
||||||
{
|
if (strcmp(*tmp, "0") == 0) {
|
||||||
if (strcmp(*tmp, "0") == 0)
|
|
||||||
{
|
|
||||||
/* /who 0 displays everyone */
|
/* /who 0 displays everyone */
|
||||||
**tmp = '*';
|
**tmp = '*';
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = g_strdup_printf("%s %s", chlist, *tmp);
|
chanevent = g_strdup_printf("%s %s", chlist, *tmp);
|
||||||
proxy_redirect_event(client, channel, 2,
|
proxy_redirect_event(client, chanevent, 2,
|
||||||
"event 401", 1, "event 315", 1,
|
"event 401", 1, "event 315", 1,
|
||||||
"event 352", -1, NULL);
|
"event 352", -1, NULL);
|
||||||
g_free(channel);
|
g_free(chanevent);
|
||||||
}
|
}
|
||||||
g_strfreev(list);
|
g_strfreev(list);
|
||||||
g_free(chlist);
|
g_free(chlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_listen_client(CLIENT_REC *client, gint handle)
|
static void handle_client_connect_cmd(CLIENT_REC *client,
|
||||||
|
const char *cmd, const char *args)
|
||||||
{
|
{
|
||||||
char tmpbuf[1024], *str, *cmd, *args, *p;
|
const char *password;
|
||||||
int ret, recvlen;
|
|
||||||
|
|
||||||
g_return_if_fail(client != NULL);
|
password = settings_get_str("irssiproxy_password");
|
||||||
|
|
||||||
for (;;)
|
if (password != NULL && strcmp(cmd, "PASS") == 0) {
|
||||||
{
|
if (strcmp(password, args) == 0)
|
||||||
recvlen = net_receive(handle, tmpbuf, sizeof(tmpbuf));
|
|
||||||
ret = line_split(tmpbuf, recvlen, &str, &client->buffer);
|
|
||||||
if (ret == -1)
|
|
||||||
{
|
|
||||||
/* connection lost */
|
|
||||||
remove_client(proxy_data, client);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret == 0) break;
|
|
||||||
|
|
||||||
if (client->server == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cmd = g_strdup(str);
|
|
||||||
args = strchr(cmd, ' ');
|
|
||||||
if (args != NULL) *args++ = '\0'; else args = "";
|
|
||||||
if (*args == ':') args++;
|
|
||||||
g_strup(cmd);
|
|
||||||
|
|
||||||
if (!client->connected)
|
|
||||||
{
|
|
||||||
if (proxy_data->password != NULL && strcmp(cmd, "PASS") == 0)
|
|
||||||
{
|
|
||||||
if (strcmp(proxy_data->password, args) != 0)
|
|
||||||
{
|
|
||||||
/* wrong password! */
|
|
||||||
remove_client(proxy_data, client);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
client->pass_sent = TRUE;
|
client->pass_sent = TRUE;
|
||||||
|
else {
|
||||||
|
/* wrong password! */
|
||||||
|
remove_client(client);
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "NICK") == 0)
|
} else if (strcmp(cmd, "NICK") == 0) {
|
||||||
|
g_free_not_null(client->nick);
|
||||||
client->nick = g_strdup(args);
|
client->nick = g_strdup(args);
|
||||||
else if (strcmp(cmd, "USER") == 0)
|
} else if (strcmp(cmd, "USER") == 0) {
|
||||||
{
|
if (client->nick == NULL ||
|
||||||
if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent))
|
(*password != '\0' && !client->pass_sent)) {
|
||||||
{
|
/* stupid client didn't send us NICK/PASS, kill it */
|
||||||
/* stupid client didn't send us NICK/PASS or, kill it */
|
remove_client(client);
|
||||||
remove_client(proxy_data, client);
|
} else {
|
||||||
break;
|
|
||||||
}
|
|
||||||
client->connected = TRUE;
|
client->connected = TRUE;
|
||||||
plugin_proxy_dump_data(client);
|
plugin_proxy_dump_data(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "QUIT") == 0)
|
|
||||||
{
|
|
||||||
remove_client(proxy_data, client);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "PING") == 0)
|
|
||||||
|
static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args)
|
||||||
{
|
{
|
||||||
net_transmit(handle, "PONG proxy :nick\n", 17);
|
int server_handle;
|
||||||
|
|
||||||
|
if (!client->connected) {
|
||||||
|
handle_client_connect_cmd(client, cmd, args);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (strcmp(cmd, "QUIT") == 0) {
|
||||||
net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str));
|
remove_client(client);
|
||||||
net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1);
|
return;
|
||||||
|
}
|
||||||
|
if (strcmp(cmd, "PING") == 0) {
|
||||||
|
proxy_outdata(client, "PONG proxy :%s\n", args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server_handle = net_sendbuffer_handle(client->server->handle);
|
||||||
|
net_transmit(server_handle, cmd, strlen(cmd));
|
||||||
|
net_transmit(server_handle, " ", 1);
|
||||||
|
net_transmit(server_handle, args, strlen(args));
|
||||||
|
net_transmit(server_handle, "\n", 1);
|
||||||
|
|
||||||
if (strcmp(cmd, "WHO") == 0)
|
if (strcmp(cmd, "WHO") == 0)
|
||||||
{
|
|
||||||
grab_who(client, args);
|
grab_who(client, args);
|
||||||
}
|
else if (strcmp(cmd, "WHOIS") == 0) {
|
||||||
else if (strcmp(cmd, "WHOIS") == 0)
|
char *p;
|
||||||
{
|
|
||||||
/* convert dots to spaces */
|
/* convert dots to spaces */
|
||||||
for (p = args; *p != '\0'; p++)
|
for (p = args; *p != '\0'; p++)
|
||||||
if (*p == ',') *p = ' ';
|
if (*p == ',') *p = ' ';
|
||||||
@ -174,20 +168,14 @@ static void sig_listen_client(CLIENT_REC *client, gint handle)
|
|||||||
"event 301", 1, "event 312", 1,
|
"event 301", 1, "event 312", 1,
|
||||||
"event 313", 1, "event 317", 1,
|
"event 313", 1, "event 317", 1,
|
||||||
"event 319", 1, NULL);
|
"event 319", 1, NULL);
|
||||||
}
|
} else if (strcmp(cmd, "ISON") == 0)
|
||||||
else if (strcmp(cmd, "ISON") == 0)
|
|
||||||
{
|
|
||||||
proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL);
|
proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL);
|
||||||
}
|
|
||||||
else if (strcmp(cmd, "USERHOST") == 0)
|
else if (strcmp(cmd, "USERHOST") == 0)
|
||||||
{
|
|
||||||
proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL);
|
proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL);
|
||||||
}
|
else if (strcmp(cmd, "MODE") == 0) {
|
||||||
else if (strcmp(cmd, "MODE") == 0)
|
|
||||||
{
|
|
||||||
/* convert dots to spaces */
|
/* convert dots to spaces */
|
||||||
gchar *slist, *str, mode;
|
char *slist, *str, mode, *p;
|
||||||
gint argc;
|
int argc;
|
||||||
|
|
||||||
p = strchr(args, ' ');
|
p = strchr(args, ' ');
|
||||||
if (p != NULL) *p++ = '\0';
|
if (p != NULL) *p++ = '\0';
|
||||||
@ -195,10 +183,8 @@ static void sig_listen_client(CLIENT_REC *client, gint handle)
|
|||||||
|
|
||||||
slist = g_strdup(args);
|
slist = g_strdup(args);
|
||||||
argc = 1;
|
argc = 1;
|
||||||
for (p = slist; *p != '\0'; p++)
|
for (p = slist; *p != '\0'; p++) {
|
||||||
{
|
if (*p == ',') {
|
||||||
if (*p == ',')
|
|
||||||
{
|
|
||||||
*p = ' ';
|
*p = ' ';
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
@ -206,8 +192,7 @@ static void sig_listen_client(CLIENT_REC *client, gint handle)
|
|||||||
|
|
||||||
/* get channel mode / bans / exception / invite list */
|
/* get channel mode / bans / exception / invite list */
|
||||||
str = g_strdup_printf("%s %s", args, slist);
|
str = g_strdup_printf("%s %s", args, slist);
|
||||||
switch (mode)
|
switch (mode) {
|
||||||
{
|
|
||||||
case '\0':
|
case '\0':
|
||||||
while (argc-- > 0)
|
while (argc-- > 0)
|
||||||
proxy_redirect_event(client, str, 3, "event 403", 1,
|
proxy_redirect_event(client, str, 3, "event 403", 1,
|
||||||
@ -233,49 +218,96 @@ static void sig_listen_client(CLIENT_REC *client, gint handle)
|
|||||||
}
|
}
|
||||||
g_free(str);
|
g_free(str);
|
||||||
g_free(slist);
|
g_free(slist);
|
||||||
|
} else if (strcmp(cmd, "PRIVMSG") == 0) {
|
||||||
|
/* send the message to other clients as well */
|
||||||
|
char *params, *target, *msg;
|
||||||
|
|
||||||
|
params = event_get_params(args, 2 | PARAM_FLAG_GETREST,
|
||||||
|
&target, &msg);
|
||||||
|
proxy_outserver_all_except(client, "PRIVMSG %s", args);
|
||||||
|
signal_emit("message public", 5, client->server, msg,
|
||||||
|
client->nick, "proxy", target);
|
||||||
|
g_free(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sig_listen_client(CLIENT_REC *client)
|
||||||
|
{
|
||||||
|
char tmpbuf[1024], *str, *cmd, *args;
|
||||||
|
int ret, recvlen;
|
||||||
|
|
||||||
|
g_return_if_fail(client != NULL);
|
||||||
|
|
||||||
|
while (g_slist_find(proxy_clients, client) != NULL) {
|
||||||
|
recvlen = net_receive(client->handle, tmpbuf, sizeof(tmpbuf));
|
||||||
|
ret = line_split(tmpbuf, recvlen, &str, &client->buffer);
|
||||||
|
if (ret == -1) {
|
||||||
|
/* connection lost */
|
||||||
|
remove_client(client);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) break;
|
||||||
|
|
||||||
|
if (client->server == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cmd = g_strdup(str);
|
||||||
|
args = strchr(cmd, ' ');
|
||||||
|
if (args != NULL) *args++ = '\0'; else args = "";
|
||||||
|
if (*args == ':') args++;
|
||||||
|
g_strup(cmd);
|
||||||
|
|
||||||
|
handle_client_cmd(client, cmd, args);
|
||||||
|
|
||||||
g_free(cmd);
|
g_free(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_listen(PLUGIN_DATA *data, gint handle)
|
static void sig_listen(LISTEN_REC *listen)
|
||||||
{
|
{
|
||||||
CLIENT_REC *rec;
|
CLIENT_REC *rec;
|
||||||
IPADDR ip;
|
IPADDR ip;
|
||||||
gint port;
|
char host[MAX_IP_LEN];
|
||||||
|
int port, handle;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
g_return_if_fail(listen != NULL);
|
||||||
if (servers == NULL) return;
|
|
||||||
|
|
||||||
/* accept connection */
|
/* accept connection */
|
||||||
handle = net_accept(handle, &ip, &port);
|
handle = net_accept(listen->handle, &ip, &port);
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
return;
|
return;
|
||||||
|
net_ip2host(&ip, host);
|
||||||
|
|
||||||
rec = g_new0(CLIENT_REC, 1);
|
rec = g_new0(CLIENT_REC, 1);
|
||||||
|
rec->listen = listen;
|
||||||
rec->handle = handle;
|
rec->handle = handle;
|
||||||
rec->server = servers == NULL ? NULL : servers->data;
|
rec->server = IRC_SERVER(server_find_chatnet(listen->ircnet));
|
||||||
rec->tag = g_input_add(handle, G_INPUT_READ, (GInputFunction) sig_listen_client, rec);
|
rec->tag = g_input_add(handle, G_INPUT_READ,
|
||||||
|
(GInputFunction) sig_listen_client, rec);
|
||||||
|
|
||||||
data->clients = g_slist_append(data->clients, rec);
|
proxy_clients = g_slist_append(proxy_clients, rec);
|
||||||
|
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
"Proxy: Client connected from %s", host);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean sig_incoming(SERVER_REC *server, gchar *line)
|
static void sig_incoming(IRC_SERVER_REC *server, const char *line)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(line != NULL, FALSE);
|
g_return_if_fail(line != NULL);
|
||||||
|
|
||||||
/* send server event to all clients */
|
/* send server event to all clients */
|
||||||
g_string_sprintf(next_line, "%s\n", line);
|
g_string_sprintf(next_line, "%s\n", line);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean sig_server_event(gchar *line, SERVER_REC *server, gchar *nick, gchar *address)
|
static void sig_server_event(const char *line, IRC_SERVER_REC *server,
|
||||||
|
const char *nick, const char *address)
|
||||||
{
|
{
|
||||||
GSList *tmp, *list;
|
GSList *list;
|
||||||
gchar *event, *args;
|
char *event, *args;
|
||||||
|
|
||||||
g_return_val_if_fail(line != NULL, FALSE);
|
g_return_if_fail(line != NULL);
|
||||||
|
if (!IS_IRC_SERVER(server))
|
||||||
|
return;
|
||||||
|
|
||||||
/* get command.. */
|
/* get command.. */
|
||||||
event = g_strconcat("event ", line, NULL);
|
event = g_strconcat("event ", line, NULL);
|
||||||
@ -283,117 +315,223 @@ static gboolean sig_server_event(gchar *line, SERVER_REC *server, gchar *nick, g
|
|||||||
if (args != NULL) *args++ = '\0'; else args = "";
|
if (args != NULL) *args++ = '\0'; else args = "";
|
||||||
while (*args == ' ') args++;
|
while (*args == ' ') args++;
|
||||||
|
|
||||||
list = server_redirect_getqueue(server, event, args);
|
list = server_redirect_getqueue(SERVER(server), event, args);
|
||||||
|
|
||||||
if (list != NULL)
|
if (list != NULL) {
|
||||||
{
|
|
||||||
/* we want to send this to one client (or proxy itself) only */
|
/* we want to send this to one client (or proxy itself) only */
|
||||||
REDIRECT_REC *rec;
|
REDIRECT_REC *rec;
|
||||||
gint handle;
|
int handle;
|
||||||
|
|
||||||
rec = list->data;
|
rec = list->data;
|
||||||
if (g_strncasecmp(rec->name, "proxy ", 6) != 0)
|
if (g_strncasecmp(rec->name, "proxy ", 6) != 0) {
|
||||||
{
|
|
||||||
/* proxy only */
|
/* proxy only */
|
||||||
g_free(event);
|
g_free(event);
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sscanf(rec->name+6, "%d", &handle) == 1)
|
|
||||||
{
|
|
||||||
/* send it to specific client only */
|
|
||||||
server_redirect_remove_next(server, event, list);
|
|
||||||
net_transmit(handle, next_line->str, next_line->len);
|
|
||||||
g_free(event);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_strcasecmp(event, "event ping") == 0)
|
|
||||||
{
|
|
||||||
/* We want to answer ourself to PINGs.. */
|
|
||||||
g_free(event);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send the data to clients.. */
|
|
||||||
for (tmp = proxy_data->clients; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
CLIENT_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
if (rec->server == server)
|
|
||||||
net_transmit(rec->handle, next_line->str, next_line->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(event);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean sig_server_connected(SERVER_REC *server)
|
|
||||||
{
|
|
||||||
GSList *tmp;
|
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, FALSE);
|
|
||||||
|
|
||||||
for (tmp = proxy_data->clients; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
CLIENT_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
if (rec->server == NULL)
|
|
||||||
rec->server = server;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean sig_server_disconnected(SERVER_REC *server)
|
|
||||||
{
|
|
||||||
GSList *tmp;
|
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, FALSE);
|
|
||||||
|
|
||||||
for (tmp = proxy_data->clients; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
CLIENT_REC *rec = tmp->data;
|
|
||||||
|
|
||||||
if (rec->server == server)
|
|
||||||
rec->server = NULL;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void plugin_proxy_listen_init(PLUGIN_DATA *data)
|
|
||||||
{
|
|
||||||
proxy_data = data;
|
|
||||||
g_return_if_fail(proxy_data != NULL);
|
|
||||||
|
|
||||||
next_line = g_string_new(NULL);
|
|
||||||
|
|
||||||
/* start listening */
|
|
||||||
proxy_data->listen_handle = net_listen(&proxy_data->ip, &proxy_data->port);
|
|
||||||
if (proxy_data->listen_handle == -1)
|
|
||||||
{
|
|
||||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Listen failed");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy_data->clients = NULL;
|
if (sscanf(rec->name+6, "%d", &handle) == 1) {
|
||||||
proxy_data->listen_tag = g_input_add(proxy_data->listen_handle, G_INPUT_READ,
|
/* send it to specific client only */
|
||||||
(GInputFunction) sig_listen, proxy_data);
|
server_redirect_remove_next(SERVER(server), event, list);
|
||||||
|
net_transmit(handle, next_line->str, next_line->len);
|
||||||
|
g_free(event);
|
||||||
|
signal_stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcasecmp(event, "event ping") == 0 ||
|
||||||
|
(g_strcasecmp(event, "event privmsg") == 0 &&
|
||||||
|
strstr(args, " :\001") != NULL)) {
|
||||||
|
/* We want to answer ourself to PINGs and CTCPs */
|
||||||
|
g_free(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send the data to clients.. */
|
||||||
|
proxy_outdata_all(server, next_line->str);
|
||||||
|
|
||||||
|
g_free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_server_connected(IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
if (!IS_IRC_SERVER(server) || server->connrec->chatnet == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec->server == NULL &&
|
||||||
|
g_strcasecmp(server->connrec->chatnet, rec->listen->ircnet) == 0) {
|
||||||
|
proxy_outserver(rec, "NOTICE %s :Connected to server", rec->nick);
|
||||||
|
rec->server = server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proxy_server_disconnected(CLIENT_REC *client,
|
||||||
|
IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
proxy_outdata(client, ":proxy NOTICE %s :Connection lost to server %s\n",
|
||||||
|
client->nick, server->connrec->address);
|
||||||
|
|
||||||
|
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
|
||||||
|
IRC_CHANNEL_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
proxy_outserver(client, "PART %s :Connection lost to server",
|
||||||
|
rec->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_server_disconnected(IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
if (!IS_IRC_SERVER(server))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec->server == server) {
|
||||||
|
proxy_server_disconnected(rec, server);
|
||||||
|
rec->server = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_nick(const char *data, IRC_SERVER_REC *server)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
if (*data == ':') data++;
|
||||||
|
for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
|
||||||
|
CLIENT_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->connected && rec->server == server) {
|
||||||
|
g_free(rec->nick);
|
||||||
|
rec->nick = g_strdup(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LISTEN_REC *find_listen(const char *ircnet, int port)
|
||||||
|
{
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
for (tmp = proxy_listens; tmp != NULL; tmp = tmp->next) {
|
||||||
|
LISTEN_REC *rec = tmp->data;
|
||||||
|
|
||||||
|
if (rec->port == port &&
|
||||||
|
g_strcasecmp(rec->ircnet, ircnet) == 0)
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_listen(const char *ircnet, int port)
|
||||||
|
{
|
||||||
|
LISTEN_REC *rec;
|
||||||
|
|
||||||
|
if (port <= 0 || *ircnet == '\0') return;
|
||||||
|
|
||||||
|
rec = g_new0(LISTEN_REC, 1);
|
||||||
|
rec->ircnet = g_strdup(ircnet);
|
||||||
|
rec->port = port;
|
||||||
|
|
||||||
|
/* start listening */
|
||||||
|
rec->handle = net_listen(NULL, &rec->port);
|
||||||
|
if (rec->handle == -1) {
|
||||||
|
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
|
||||||
|
"Proxy: Listen in port %d failed: %s",
|
||||||
|
rec->port, g_strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec->tag = g_input_add(rec->handle, G_INPUT_READ,
|
||||||
|
(GInputFunction) sig_listen, rec);
|
||||||
|
|
||||||
|
proxy_listens = g_slist_append(proxy_listens, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_listen(LISTEN_REC *rec)
|
||||||
|
{
|
||||||
|
proxy_listens = g_slist_remove(proxy_listens, rec);
|
||||||
|
|
||||||
|
net_disconnect(rec->handle);
|
||||||
|
g_source_remove(rec->tag);
|
||||||
|
g_free(rec->ircnet);
|
||||||
|
g_free(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_settings(void)
|
||||||
|
{
|
||||||
|
LISTEN_REC *rec;
|
||||||
|
GSList *remove_listens;
|
||||||
|
char **ports, **tmp, *ircnet, *port;
|
||||||
|
int portnum;
|
||||||
|
|
||||||
|
remove_listens = g_slist_copy(proxy_listens);
|
||||||
|
|
||||||
|
ports = g_strsplit(settings_get_str("irssiproxy_ports"), " ", -1);
|
||||||
|
for (tmp = ports; *tmp != NULL; tmp++) {
|
||||||
|
ircnet = *tmp;
|
||||||
|
port = strchr(ircnet, '=');
|
||||||
|
if (port == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*port++ = '\0';
|
||||||
|
portnum = atoi(port);
|
||||||
|
if (portnum <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rec = find_listen(ircnet, portnum);
|
||||||
|
if (rec == NULL)
|
||||||
|
add_listen(ircnet, portnum);
|
||||||
|
else
|
||||||
|
remove_listens = g_slist_remove(remove_listens, rec);
|
||||||
|
}
|
||||||
|
g_strfreev(ports);
|
||||||
|
|
||||||
|
while (remove_listens != NULL) {
|
||||||
|
remove_listen(remove_listens->data);
|
||||||
|
g_slist_remove(remove_listens, remove_listens->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_proxy_listen_init(void)
|
||||||
|
{
|
||||||
|
next_line = g_string_new(NULL);
|
||||||
|
|
||||||
|
proxy_clients = NULL;
|
||||||
|
proxy_listens = NULL;
|
||||||
|
read_settings();
|
||||||
|
|
||||||
signal_add("server incoming", (SIGNAL_FUNC) sig_incoming);
|
signal_add("server incoming", (SIGNAL_FUNC) sig_incoming);
|
||||||
signal_add("server event", (SIGNAL_FUNC) sig_server_event);
|
signal_add("server event", (SIGNAL_FUNC) sig_server_event);
|
||||||
signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
|
signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
|
||||||
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||||
|
signal_add("event nick", (SIGNAL_FUNC) event_nick);
|
||||||
|
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void plugin_proxy_listen_deinit(PLUGIN_DATA *data)
|
void plugin_proxy_listen_deinit(void)
|
||||||
{
|
{
|
||||||
g_return_if_fail(data != NULL);
|
while (proxy_clients != NULL)
|
||||||
|
remove_client(proxy_clients->data);
|
||||||
|
while (proxy_listens != NULL)
|
||||||
|
remove_listen(proxy_listens->data);
|
||||||
g_string_free(next_line, TRUE);
|
g_string_free(next_line, TRUE);
|
||||||
while (data->clients != NULL)
|
|
||||||
remove_client(data, data->clients->data);
|
|
||||||
|
|
||||||
net_disconnect(data->listen_handle);
|
signal_remove("server incoming", (SIGNAL_FUNC) sig_incoming);
|
||||||
g_source_remove(data->listen_tag);
|
signal_remove("server event", (SIGNAL_FUNC) sig_server_event);
|
||||||
|
signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected);
|
||||||
|
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
|
||||||
|
signal_remove("event nick", (SIGNAL_FUNC) event_nick);
|
||||||
|
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,46 @@
|
|||||||
|
|
||||||
#define MODULE_NAME "proxy"
|
#define MODULE_NAME "proxy"
|
||||||
|
|
||||||
|
#include "network.h"
|
||||||
|
#include "line-split.h"
|
||||||
|
#include "irc-servers.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int port;
|
||||||
|
char *ircnet;
|
||||||
|
|
||||||
|
int tag;
|
||||||
|
int handle;
|
||||||
|
} LISTEN_REC;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LINEBUF_REC *buffer;
|
||||||
|
|
||||||
|
char *nick;
|
||||||
|
int handle;
|
||||||
|
int tag;
|
||||||
|
|
||||||
|
LISTEN_REC *listen;
|
||||||
|
IRC_SERVER_REC *server;
|
||||||
|
int pass_sent:1;
|
||||||
|
int connected:1;
|
||||||
|
} CLIENT_REC;
|
||||||
|
|
||||||
|
extern GSList *proxy_listens;
|
||||||
|
extern GSList *proxy_clients;
|
||||||
|
|
||||||
|
void plugin_proxy_setup_init(void);
|
||||||
|
void plugin_proxy_setup_deinit(void);
|
||||||
|
|
||||||
|
void plugin_proxy_listen_init(void);
|
||||||
|
void plugin_proxy_listen_deinit(void);
|
||||||
|
|
||||||
|
void proxy_settings_init(void);
|
||||||
|
|
||||||
|
void plugin_proxy_dump_data(CLIENT_REC *client);
|
||||||
|
|
||||||
|
void proxy_outdata(CLIENT_REC *client, const char *data, ...);
|
||||||
|
void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...);
|
||||||
|
void proxy_outserver(CLIENT_REC *client, const char *data, ...);
|
||||||
|
/*void proxy_outserver_all(const char *data, ...);*/
|
||||||
|
void proxy_outserver_all_except(CLIENT_REC *client, const char *data, ...);
|
||||||
|
@ -18,119 +18,34 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "proxy.h"
|
#include "module.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "levels.h"
|
#include "levels.h"
|
||||||
#include "fe-common/core/printtext.h"
|
#include "fe-common/core/printtext.h"
|
||||||
#include "servers.h"
|
|
||||||
#include "net-sendbuffer.h"
|
|
||||||
|
|
||||||
#include "lib-config/iconfig.h"
|
void proxy_deinit(void)
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
PLUGIN_DATA *proxy_data;
|
|
||||||
MODULE_REC *plug;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gchar *plugin_description(void)
|
|
||||||
{
|
{
|
||||||
return "IRC proxy plugin";
|
plugin_proxy_listen_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*gint plugin_version(void)
|
void proxy_init(void)
|
||||||
{
|
{
|
||||||
return PLUGIN_LAYER_VERSION;
|
settings_add_str("irssiproxy", "irssiproxy_ports", "");
|
||||||
}
|
settings_add_str("irssiproxy", "irssiproxy_password", "");
|
||||||
*/
|
|
||||||
|
|
||||||
void proxy_settings_init(void)
|
if (*settings_get_str("irssiproxy_password") == '\0') {
|
||||||
{
|
|
||||||
settings_add_str("proxy", "proxy_listen_addr", "localhost");
|
|
||||||
settings_add_int("proxy", "proxy_listen_port", 2777);
|
|
||||||
settings_add_str("proxy", "proxy_listen_password", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* If we call plugin_deinit() in this code, it doesn't necessarily point to
|
|
||||||
_THIS_ module's plugin_deinit() but instead some other module's.. So,
|
|
||||||
we create static deinit() function which should be used.. */
|
|
||||||
static void deinit(/*MODULE_REC *plugin*/)
|
|
||||||
{
|
|
||||||
plugin_proxy_listen_deinit(proxy_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void proxy_deinit(/*MODULE_REC *plugin*/)
|
|
||||||
{
|
|
||||||
deinit(/*plugin*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean proxy_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
gchar ipaddr[MAX_IP_LEN];
|
|
||||||
|
|
||||||
const char *password;
|
|
||||||
const char *addr;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
proxy_settings_init();
|
|
||||||
|
|
||||||
proxy_data = g_new0(PLUGIN_DATA, 1);
|
|
||||||
password = settings_get_str("proxy_listen_password");
|
|
||||||
addr = settings_get_str("proxy_listen_addr");
|
|
||||||
port = settings_get_int("proxy_listen_port");
|
|
||||||
|
|
||||||
plug = module_find("proxy");
|
|
||||||
proxy_data->plugin = plug;
|
|
||||||
|
|
||||||
if (*password != '\0')
|
|
||||||
{
|
|
||||||
/* args = password */
|
|
||||||
proxy_data->password = g_strdup(password);
|
|
||||||
}
|
|
||||||
if (*addr != '\0')
|
|
||||||
{
|
|
||||||
/* specify ip address to listen */
|
|
||||||
net_host2ip(addr, &proxy_data->ip);
|
|
||||||
}
|
|
||||||
if (port != 0)
|
|
||||||
{
|
|
||||||
/* specify port to use */
|
|
||||||
proxy_data->port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy_data->password == NULL)
|
|
||||||
{
|
|
||||||
/* no password - bad idea! */
|
/* no password - bad idea! */
|
||||||
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Warning!! Password not specified, everyone can use this proxy! Use /set proxy_listen_password <password> to set it");
|
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
"Warning!! Password not specified, everyone can "
|
||||||
|
"use this proxy! Use /set irssiproxy_password "
|
||||||
|
"<password> to set it");
|
||||||
|
}
|
||||||
|
if (*settings_get_str("irssiproxy_ports") == '\0') {
|
||||||
|
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
"No proxy ports specified. Use /SET "
|
||||||
|
"irssiproxy_ports <ircnet>=<port> <ircnet2>=<port2> "
|
||||||
|
"... to set them.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servers == NULL)
|
plugin_proxy_listen_init();
|
||||||
{
|
|
||||||
/* FIXME: not good */
|
|
||||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "You need to specify IP address to listen with /set proxy_listen_addr <address>");
|
|
||||||
deinit();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SERVER_REC *server;
|
|
||||||
|
|
||||||
server = servers->data;
|
|
||||||
if (net_getsockname(net_sendbuffer_handle(server->handle), &proxy_data->ip, NULL))
|
|
||||||
{
|
|
||||||
deinit();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
net_ip2host(&proxy_data->ip, ipaddr);
|
|
||||||
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Proxy plugin loaded - listening in interface %s port %d", ipaddr, proxy_data->port);
|
|
||||||
|
|
||||||
plugin_proxy_listen_init(proxy_data);
|
|
||||||
|
|
||||||
proxy_data->loaded = TRUE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
#ifndef __PROXY_H
|
|
||||||
#define __PROXY_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "module.h"
|
|
||||||
#include "../../core/modules.h"
|
|
||||||
|
|
||||||
#include "network.h"
|
|
||||||
#include <core/line-split.h>
|
|
||||||
#include <core/servers-redirect.h>
|
|
||||||
#include "commands.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MODULE_REC *plugin;
|
|
||||||
gboolean loaded;
|
|
||||||
|
|
||||||
IPADDR ip;
|
|
||||||
gint port;
|
|
||||||
gchar *password;
|
|
||||||
|
|
||||||
gint listen_tag;
|
|
||||||
gint listen_handle;
|
|
||||||
|
|
||||||
GSList *clients;
|
|
||||||
}
|
|
||||||
PLUGIN_DATA;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
LINEBUF_REC *buffer;
|
|
||||||
|
|
||||||
gchar *nick;
|
|
||||||
gint handle;
|
|
||||||
gint tag;
|
|
||||||
|
|
||||||
SERVER_REC *server;
|
|
||||||
gboolean pass_sent;
|
|
||||||
gboolean connected;
|
|
||||||
}
|
|
||||||
CLIENT_REC;
|
|
||||||
|
|
||||||
void plugin_proxy_setup_init(MODULE_REC *plugin);
|
|
||||||
void plugin_proxy_setup_deinit(MODULE_REC *plugin);
|
|
||||||
|
|
||||||
void plugin_proxy_listen_init();
|
|
||||||
void plugin_proxy_listen_deinit();
|
|
||||||
|
|
||||||
void proxy_settings_init(void);
|
|
||||||
|
|
||||||
void plugin_proxy_dump_data(CLIENT_REC *client);
|
|
||||||
|
|
||||||
/* #define MODULE_NAME "proxy" */
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user