summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in29
-rw-r--r--src/irc/Makefile.am6
-rw-r--r--src/irc/proxy/.cvsignore8
-rw-r--r--src/irc/proxy/Makefile.am14
-rw-r--r--src/irc/proxy/dump.c124
-rw-r--r--src/irc/proxy/listen.c399
-rw-r--r--src/irc/proxy/module.h11
-rw-r--r--src/irc/proxy/proxy.c136
-rw-r--r--src/irc/proxy/proxy.h55
9 files changed, 773 insertions, 9 deletions
diff --git a/configure.in b/configure.in
index e5ac155d..fd7feeba 100644
--- a/configure.in
+++ b/configure.in
@@ -53,6 +53,20 @@ AC_ARG_WITH(bot,
fi,
want_irssibot=no)
+AC_ARG_WITH(proxy,
+[ --with-proxy Build irssi-proxy],
+ if test x$withval = xyes; then
+ want_irssiproxy=yes
+ else
+ if test "x$withval" = xno; then
+ want_irssiproxy=no
+ else
+ want_irssiproxy=yes
+ fi
+ fi,
+ want_irssiproxy=no)
+
+
AC_ARG_WITH(modules,
[ --with-modules Specify what modules to build in binary],
build_modules="$withval")
@@ -279,6 +293,7 @@ fi
dnl ** check what we want to build
AM_CONDITIONAL(BUILD_TEXTUI, test "$want_textui" = "yes")
AM_CONDITIONAL(BUILD_IRSSIBOT, test "$want_irssibot" = "yes")
+AM_CONDITIONAL(BUILD_IRSSIPROXY, test "$want_irssiproxy" = "yes")
AM_CONDITIONAL(BUILD_PLUGINS, test "$want_plugins" = "yes")
AM_CONDITIONAL(BUILD_SERVERTEST, test "$want_servertest" = "yes")
AM_CONDITIONAL(HAVE_PERL, test "$want_perl" = "yes")
@@ -301,11 +316,6 @@ AC_SUBST(CHAT_MODULES)
AC_SUBST(irc_MODULES)
CORE_LIBS="../core/libcore.a ../lib-config/libirssi_config.a ../lib-popt/libpopt.a"
-if test "$want_perl" = "yes"; then
- PERL_LIBS="../perl/libperl.a"
-else
- PERL_LIBS=""
-fi
FE_COMMON_LIBS=""
CHAT_LIBS=""
@@ -365,7 +375,7 @@ if test "x$MSGFMT" = "xno"; then
fi
dnl ** common libraries needed by frontends
-COMMON_NOUI_LIBS="$PERL_LIBS $CHAT_LIBS $CORE_LIBS $INTLLIBS"
+COMMON_NOUI_LIBS="$CHAT_LIBS $CORE_LIBS $INTLLIBS"
COMMON_LIBS="$FE_COMMON_LIBS $COMMON_NOUI_LIBS"
AC_SUBST(COMMON_NOUI_LIBS)
AC_SUBST(COMMON_LIBS)
@@ -398,6 +408,7 @@ src/irc/core/Makefile
src/irc/bot/Makefile
src/irc/dcc/Makefile
src/irc/notifylist/Makefile
+src/irc/proxy/Makefile
src/irc/flood/Makefile
src/fe-common/Makefile
src/fe-common/core/Makefile
@@ -410,7 +421,8 @@ src/fe-text/Makefile
src/lib-config/Makefile
src/lib-popt/Makefile
src/perl/Makefile
-src/perl/xs/Makefile.PL
+src/perl/core/Makefile.PL
+src/perl/irc/Makefile.PL
servertest/Makefile
scripts/Makefile
docs/Makefile
@@ -426,7 +438,7 @@ if test "x$want_perl" = "xyes"; then
old_dir=`pwd` && cd $srcdir && whole_dir=`pwd` && cd $old_dir
if test "x$old_dir" != "x$whole_dir"; then
- for file in $whole_dir/src/perl/xs/typemap $whole_dir/src/perl/xs/module.h $whole_dir/src/perl/xs/*.xs; do
+ for file in $whole_dir/src/perl/core/typemap $whole_dir/src/perl/core/module.h $whole_dir/src/perl/core/*.xs $whole_dir/src/perl/irc/typemap $whole_dir/src/perl/irc/module.h $whole_dir/src/perl/irc/*.xs; do
ln -sf $file `echo $file|sed "s?$whole_dir/??"`
done
fi
@@ -449,6 +461,7 @@ else
echo " installed (usually in ncurses-devel package)"
fi
echo "Building irssi bot ......... : $want_irssibot"
+echo "Building irssi proxy ....... : $want_irssiproxy"
echo "Building with IPv6 support . : $want_ipv6"
echo "Building with Perl support . : $want_perl"
if test "x$want_perl" = "xyes"; then
diff --git a/src/irc/Makefile.am b/src/irc/Makefile.am
index 651fedc6..cdea8d60 100644
--- a/src/irc/Makefile.am
+++ b/src/irc/Makefile.am
@@ -2,7 +2,11 @@ if BUILD_IRSSIBOT
BOT=bot
endif
-SUBDIRS = core $(BOT) dcc flood notifylist
+if BUILD_IRSSIPROXY
+PROXY=proxy
+endif
+
+SUBDIRS = core $(BOT) dcc flood notifylist $(PROXY)
noinst_LIBRARIES = libirc.a
diff --git a/src/irc/proxy/.cvsignore b/src/irc/proxy/.cvsignore
new file mode 100644
index 00000000..8553e9e9
--- /dev/null
+++ b/src/irc/proxy/.cvsignore
@@ -0,0 +1,8 @@
+*.la
+*.lo
+*.o
+.deps
+.libs
+Makefile
+Makefile.in
+so_locations
diff --git a/src/irc/proxy/Makefile.am b/src/irc/proxy/Makefile.am
new file mode 100644
index 00000000..ebf7e4d9
--- /dev/null
+++ b/src/irc/proxy/Makefile.am
@@ -0,0 +1,14 @@
+moduledir = $(libdir)/irssi/modules
+module_LTLIBRARIES = libproxy.la
+
+INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/src/core/ \
+ -I$(top_srcdir)/src/irc/core/
+
+libproxy_la_SOURCES = \
+ proxy.c \
+ dump.c \
+ listen.c \
+
+noinst_HEADERS = \
+ proxy.h \
+ module.h
diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c
new file mode 100644
index 00000000..eb222956
--- /dev/null
+++ b/src/irc/proxy/dump.c
@@ -0,0 +1,124 @@
+/*
+ dump.c : proxy plugin - output all information about irc session
+
+ Copyright (C) 1999 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 "common.h"
+#include "network.h"
+#include "servers.h"
+#include "irc-servers.h"
+#include "channels.h"
+#include "modes.h"
+#include "nicklist.h"
+#include "settings.h"
+#include "proxy.h"
+
+static void outdata(gint handle, gchar *data, ...)
+{
+ va_list args;
+ gchar *str;
+
+ va_start(args, data);
+
+ str = g_strdup_vprintf(data, args);
+ net_transmit(handle, str, strlen(str));
+ g_free(str);
+
+ va_end(args);
+}
+
+static void outserver(gint handle, SERVER_REC *server, gchar *data, ...)
+{
+ va_list args;
+ gchar *str;
+
+ va_start(args, data);
+
+ str = g_strdup_vprintf(data, args);
+ outdata(handle, ":%s!%s@proxy %s\n", server->nick, settings_get_str("user_name"), str);
+ g_free(str);
+
+ va_end(args);
+}
+
+void plugin_proxy_dump_data(CLIENT_REC *client)
+{
+ SERVER_REC *server;
+ GSList *tmp, *tmp2, *nicks;
+ gint handle;
+
+ handle = client->handle;
+ server = servers->data;
+ 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);
+ client->nick = g_strdup(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);
+ outdata(handle, ":proxy 003 %s :This server was created ...\n", client->nick);
+ if (!IRC_SERVER(server)->emode_known)
+ outdata(handle, ":proxy 004 %s proxy %s oirw abiklmnopqstv\n", client->nick, VERSION);
+ else
+ outdata(handle, ":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);
+ outdata(handle, ":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);
+
+ /* nick / mode */
+ outserver(handle, server, "MODE %s :+%s", server->nick, IRC_SERVER(server)->usermode);
+
+ if (server->usermode_away)
+ outdata(handle, ":proxy 306 %s :You have been marked as being away\n", server->nick);
+
+ /* Send channel joins */
+ for (tmp = server->channels; tmp != NULL; tmp = tmp->next)
+ {
+ 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);
+ }
+}
diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c
new file mode 100644
index 00000000..c5453442
--- /dev/null
+++ b/src/irc/proxy/listen.c
@@ -0,0 +1,399 @@
+/*
+ listen.c : sample plugin for irssi
+
+ Copyright (C) 1999 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 "proxy.h"
+#include "net-sendbuffer.h"
+#include "fe-common/core/printtext.h"
+#include "levels.h"
+
+static PLUGIN_DATA *proxy_data;
+static GString *next_line;
+
+void remove_client(PLUGIN_DATA *data, CLIENT_REC *rec)
+{
+ data->clients = g_slist_remove(data->clients, rec);
+
+ net_disconnect(rec->handle);
+ g_source_remove(rec->tag);
+ line_split_free(rec->buffer);
+ g_free(rec);
+}
+
+static void proxy_redirect_event(CLIENT_REC *client, gchar *args, gint last, ...)
+{
+ va_list vargs;
+ gchar *event;
+ gint argpos, group;
+ GString *str;
+
+ g_return_if_fail(client != NULL);
+
+ va_start(vargs, last);
+
+ str = g_string_new(NULL);
+ group = 0;
+ while ((event = va_arg(vargs, gchar *)) != NULL)
+ {
+ argpos = va_arg(vargs, gint);
+ g_string_sprintf(str, "proxy %d", client->handle);
+ group = server_redirect_single_event(client->server, args, last > 0, group, event, str->str, argpos);
+ last--;
+ }
+ g_string_free(str, TRUE);
+
+ va_end(vargs);
+}
+
+static void grab_who(CLIENT_REC *client, gchar *channel)
+{
+ gchar *chlist;
+ gchar **list, **tmp;
+
+ /* /WHO a,b,c may respond with either one "a,b,c End of WHO" message or
+ three different "a End of WHO", "b End of WHO", .. messages */
+ chlist = g_strdup(channel);
+ list = g_strsplit(channel, ",", -1);
+
+ for (tmp = list; *tmp != NULL; tmp++)
+ {
+ if (strcmp(*tmp, "0") == 0)
+ {
+ /* /who 0 displays everyone */
+ **tmp = '*';
+ }
+
+ channel = g_strdup_printf("%s %s", chlist, *tmp);
+ proxy_redirect_event(client, channel, 2,
+ "event 401", 1, "event 315", 1,
+ "event 352", -1, NULL);
+ g_free(channel);
+ }
+ g_strfreev(list);
+ g_free(chlist);
+}
+
+static void sig_listen_client(CLIENT_REC *client, gint handle)
+{
+ char tmpbuf[1024], *str, *cmd, *args, *p;
+ int ret, recvlen;
+
+ g_return_if_fail(client != NULL);
+
+ for (;;)
+ {
+ 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;
+ }
+ else if (strcmp(cmd, "NICK") == 0)
+ client->nick = g_strdup(args);
+ else if (strcmp(cmd, "USER") == 0)
+ {
+ if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent))
+ {
+ /* stupid client didn't send us NICK/PASS or, kill it */
+ remove_client(proxy_data, client);
+ break;
+ }
+ client->connected = TRUE;
+ plugin_proxy_dump_data(client);
+ }
+ }
+ else if (strcmp(cmd, "QUIT") == 0)
+ {
+ remove_client(proxy_data, client);
+ break;
+ }
+ else if (strcmp(cmd, "PING") == 0)
+ {
+ net_transmit(handle, "PONG proxy :nick\n", 17);
+ }
+ else
+ {
+ net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str));
+ net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1);
+
+ if (strcmp(cmd, "WHO") == 0)
+ {
+ grab_who(client, args);
+ }
+ else if (strcmp(cmd, "WHOIS") == 0)
+ {
+ /* convert dots to spaces */
+ for (p = args; *p != '\0'; p++)
+ if (*p == ',') *p = ' ';
+
+ proxy_redirect_event(client, args, 2,
+ "event 318", -1, "event 402", -1,
+ "event 401", 1, "event 311", 1,
+ "event 301", 1, "event 312", 1,
+ "event 313", 1, "event 317", 1,
+ "event 319", 1, NULL);
+ }
+ else if (strcmp(cmd, "ISON") == 0)
+ {
+ proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL);
+ }
+ else if (strcmp(cmd, "USERHOST") == 0)
+ {
+ proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL);
+ }
+ else if (strcmp(cmd, "MODE") == 0)
+ {
+ /* convert dots to spaces */
+ gchar *slist, *str, mode;
+ gint argc;
+
+ p = strchr(args, ' ');
+ if (p != NULL) *p++ = '\0';
+ mode = p == NULL ? '\0' : *p;
+
+ slist = g_strdup(args);
+ argc = 1;
+ for (p = slist; *p != '\0'; p++)
+ {
+ if (*p == ',')
+ {
+ *p = ' ';
+ argc++;
+ }
+ }
+
+ /* get channel mode / bans / exception / invite list */
+ str = g_strdup_printf("%s %s", args, slist);
+ switch (mode)
+ {
+ case '\0':
+ while (argc-- > 0)
+ proxy_redirect_event(client, str, 3, "event 403", 1,
+ "event 443", 1, "event 324", 1, NULL);
+ break;
+ case 'b':
+ while (argc-- > 0)
+ proxy_redirect_event(client, str, 2, "event 403", 1,
+ "event 368", 1, "event 367", 1, NULL);
+ break;
+ case 'e':
+ while (argc-- > 0)
+ proxy_redirect_event(client, str, 4, "event 403", 1,
+ "event 482", 1, "event 472", -1,
+ "event 349", 1, "event 348", 1, NULL);
+ break;
+ case 'I':
+ while (argc-- > 0)
+ proxy_redirect_event(client, str, 4, "event 403", 1,
+ "event 482", 1, "event 472", -1,
+ "event 347", 1, "event 346", 1, NULL);
+ break;
+ }
+ g_free(str);
+ g_free(slist);
+ }
+ }
+ g_free(cmd);
+ }
+}
+
+static void sig_listen(PLUGIN_DATA *data, gint handle)
+{
+ CLIENT_REC *rec;
+ IPADDR ip;
+ gint port;
+
+ g_return_if_fail(data != NULL);
+ if (servers == NULL) return;
+
+ /* accept connection */
+ handle = net_accept(handle, &ip, &port);
+ if (handle == -1)
+ return;
+
+ rec = g_new0(CLIENT_REC, 1);
+ rec->handle = handle;
+ rec->server = servers == NULL ? NULL : servers->data;
+ rec->tag = g_input_add(handle, G_INPUT_READ, (GInputFunction) sig_listen_client, rec);
+
+ data->clients = g_slist_append(data->clients, rec);
+}
+
+static gboolean sig_incoming(SERVER_REC *server, gchar *line)
+{
+ g_return_val_if_fail(line != NULL, FALSE);
+
+ /* send server event to all clients */
+ g_string_sprintf(next_line, "%s\n", line);
+ return TRUE;
+}
+
+static gboolean sig_server_event(gchar *line, SERVER_REC *server, gchar *nick, gchar *address)
+{
+ GSList *tmp, *list;
+ gchar *event, *args;
+
+ g_return_val_if_fail(line != NULL, FALSE);
+
+ /* get command.. */
+ event = g_strconcat("event ", line, NULL);
+ args = strchr(event+6, ' ');
+ if (args != NULL) *args++ = '\0'; else args = "";
+ while (*args == ' ') args++;
+
+ list = server_redirect_getqueue(server, event, args);
+
+ if (list != NULL)
+ {
+ /* we want to send this to one client (or proxy itself) only */
+ REDIRECT_REC *rec;
+ gint handle;
+
+ rec = list->data;
+ if (g_strncasecmp(rec->name, "proxy ", 6) != 0)
+ {
+ /* proxy only */
+ 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;
+ }
+
+ proxy_data->clients = NULL;
+ proxy_data->listen_tag = g_input_add(proxy_data->listen_handle, G_INPUT_READ,
+ (GInputFunction) sig_listen, proxy_data);
+
+ signal_add("server incoming", (SIGNAL_FUNC) sig_incoming);
+ signal_add("server event", (SIGNAL_FUNC) sig_server_event);
+ signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
+ signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
+}
+
+void plugin_proxy_listen_deinit(PLUGIN_DATA *data)
+{
+ g_return_if_fail(data != NULL);
+
+ g_string_free(next_line, TRUE);
+ while (data->clients != NULL)
+ remove_client(data, data->clients->data);
+
+ net_disconnect(data->listen_handle);
+ g_source_remove(data->listen_tag);
+}
diff --git a/src/irc/proxy/module.h b/src/irc/proxy/module.h
new file mode 100644
index 00000000..809c2c51
--- /dev/null
+++ b/src/irc/proxy/module.h
@@ -0,0 +1,11 @@
+#include "common.h"
+
+#define MODULE_NAME "proxy"
+
+
+
+
+
+
+
+
diff --git a/src/irc/proxy/proxy.c b/src/irc/proxy/proxy.c
new file mode 100644
index 00000000..879d3205
--- /dev/null
+++ b/src/irc/proxy/proxy.c
@@ -0,0 +1,136 @@
+/*
+ sample.c : sample plugin for irssi
+
+ Copyright (C) 1999 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 "proxy.h"
+#include "levels.h"
+#include "fe-common/core/printtext.h"
+#include "servers.h"
+#include "net-sendbuffer.h"
+
+#include "lib-config/iconfig.h"
+#include "settings.h"
+
+PLUGIN_DATA *proxy_data;
+MODULE_REC *plug;
+
+
+
+gchar *plugin_description(void)
+{
+ return "IRC proxy plugin";
+}
+
+/*gint plugin_version(void)
+{
+ return PLUGIN_LAYER_VERSION;
+}
+*/
+
+void proxy_settings_init(void)
+{
+ 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! */
+ printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "Warning!! Password not specified, everyone can use this proxy! Use /set proxy_listen_password <password> to set it");
+ }
+
+ if (servers == NULL)
+ {
+ /* 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;
+}
diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h
new file mode 100644
index 00000000..dadc044d
--- /dev/null
+++ b/src/irc/proxy/proxy.h
@@ -0,0 +1,55 @@
+#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