summaryrefslogtreecommitdiffstats
path: root/src/irc/proxy/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irc/proxy/dump.c')
-rw-r--r--src/irc/proxy/dump.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/irc/proxy/dump.c b/src/irc/proxy/dump.c
new file mode 100644
index 0000000..82dc1fe
--- /dev/null
+++ b/src/irc/proxy/dump.c
@@ -0,0 +1,303 @@
+/*
+ dump.c : proxy plugin - output all information about irc session
+
+ Copyright (C) 1999-2001 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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "module.h"
+#include <irssi/src/core/network.h>
+#include <irssi/src/core/net-sendbuffer.h>
+#include <irssi/src/core/settings.h>
+#include <irssi/irssi-version.h>
+#include <irssi/src/core/recode.h>
+
+#include <irssi/src/irc/core/irc-servers.h>
+#include <irssi/src/irc/core/irc-channels.h>
+#include <irssi/src/irc/core/irc-nicklist.h>
+#include <irssi/src/irc/core/modes.h>
+
+void proxy_outdata(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);
+ net_sendbuffer_send(client->handle, str, strlen(str));
+ g_free(str);
+
+ va_end(args);
+}
+
+void proxy_outdata_all(IRC_SERVER_REC *server, const char *data, ...)
+{
+ va_list args;
+ GSList *tmp;
+ char *str;
+ int len;
+
+ g_return_if_fail(server != NULL);
+ g_return_if_fail(data != NULL);
+
+ va_start(args, data);
+
+ str = g_strdup_vprintf(data, args);
+ len = strlen(str);
+ for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
+ CLIENT_REC *rec = tmp->data;
+
+ if (rec->connected && rec->server == server)
+ net_sendbuffer_send(rec->handle, str, len);
+ }
+ g_free(str);
+
+ 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\r\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\r\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\r\n", rec->nick,
+ settings_get_str("user_name"), str);
+ }
+ }
+ g_free(str);
+
+ va_end(args);
+}
+
+static void create_names_start(GString *str, IRC_CHANNEL_REC *channel,
+ CLIENT_REC *client)
+{
+ g_string_printf(str, ":%s 353 %s %c %s :",
+ client->proxy_address, client->nick,
+ channel_mode_is_set(channel, 'p') ? '*' :
+ channel_mode_is_set(channel, 's') ? '@' : '=',
+ channel->name);
+}
+
+static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client)
+{
+ GSList *tmp, *nicks;
+ GString *str;
+ int first;
+ char *recoded;
+
+ proxy_outserver(client, "JOIN %s", channel->name);
+
+ str = g_string_new(NULL);
+ create_names_start(str, channel, client);
+
+ first = TRUE;
+ nicks = nicklist_getnicks(CHANNEL(channel));
+ for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
+ NICK_REC *nick = tmp->data;
+
+ if (str->len >= 500) {
+ g_string_append(str, "\r\n");
+ proxy_outdata(client, "%s", str->str);
+ create_names_start(str, channel, client);
+ first = TRUE;
+ }
+
+ if (first)
+ first = FALSE;
+ else
+ g_string_append_c(str, ' ');
+
+ if (nick->prefixes[0])
+ g_string_append_c(str, nick->prefixes[0]);
+ g_string_append(str, nick->nick);
+ }
+ g_slist_free(nicks);
+
+ g_string_append(str, "\r\n");
+ proxy_outdata(client, "%s", str->str);
+ g_string_free(str, TRUE);
+
+ proxy_outdata(client, ":%s 366 %s %s :End of /NAMES list.\r\n",
+ client->proxy_address, client->nick, channel->name);
+ if (channel->topic != NULL) {
+ /* this is needed because the topic may be encoded into other charsets internaly */
+ recoded = recode_out(SERVER(client->server), channel->topic, channel->name);
+ proxy_outdata(client, ":%s 332 %s %s :%s\r\n",
+ client->proxy_address, client->nick,
+ channel->name, recoded);
+ g_free(recoded);
+ if (channel->topic_time > 0)
+ proxy_outdata(client, ":%s 333 %s %s %s %d\r\n",
+ client->proxy_address, client->nick,
+ channel->name, channel->topic_by, channel->topic_time);
+ }
+}
+
+void proxy_client_reset_nick(CLIENT_REC *client)
+{
+ if (client->server == NULL ||
+ g_strcmp0(client->nick, client->server->nick) == 0)
+ return;
+
+ proxy_outdata(client, ":%s!proxy NICK :%s\r\n",
+ client->nick, client->server->nick);
+
+ g_free(client->nick);
+ client->nick = g_strdup(client->server->nick);
+}
+
+static void proxy_dump_data_005(gpointer key, gpointer value, gpointer context)
+{
+ if (*(char *)value != '\0')
+ g_string_append_printf(context, "%s=%s ", (char *)key, (char *)value);
+ else
+ g_string_append_printf(context, "%s ", (char *)key);
+}
+
+void proxy_dump_data(CLIENT_REC *client)
+{
+ GString *isupport_out, *paramstr;
+ char **paramlist, **tmp;
+ int count;
+
+ proxy_client_reset_nick(client);
+
+ /* welcome info */
+ proxy_outdata(client, ":%s 001 %s :Welcome to the Internet Relay Network %s!%s@proxy\r\n", client->proxy_address, client->nick, client->nick, settings_get_str("user_name"));
+ proxy_outdata(client, ":%s 002 %s :Your host is irssi-proxy, running version %s\r\n", client->proxy_address, client->nick, PACKAGE_VERSION);
+ proxy_outdata(client, ":%s 003 %s :This server was created ...\r\n", client->proxy_address, client->nick);
+ if (client->server == NULL || !client->server->emode_known)
+ proxy_outdata(client, ":%s 004 %s %s %s oirw abiklmnopqstv\r\n", client->proxy_address, client->nick, client->proxy_address, PACKAGE_VERSION);
+ else
+ proxy_outdata(client, ":%s 004 %s %s %s oirw abeIiklmnopqstv\r\n", client->proxy_address, client->nick, client->proxy_address, PACKAGE_VERSION);
+
+ if (client->server != NULL && client->server->isupport_sent) {
+ isupport_out = g_string_new(NULL);
+ g_hash_table_foreach(client->server->isupport, proxy_dump_data_005, isupport_out);
+ if (isupport_out->len > 0)
+ g_string_truncate(isupport_out, isupport_out->len-1);
+
+ proxy_outdata(client, ":%s 005 %s ", client->proxy_address, client->nick);
+
+ paramstr = g_string_new(NULL);
+ paramlist = g_strsplit(isupport_out->str, " ", -1);
+ count = 0;
+ tmp = paramlist;
+
+ for (;; tmp++) {
+ if (*tmp != NULL) {
+ g_string_append_printf(paramstr, "%s ", *tmp);
+ if (++count < 15)
+ continue;
+ }
+
+ count = 0;
+ if (paramstr->len > 0)
+ g_string_truncate(paramstr, paramstr->len-1);
+ g_string_append_printf(paramstr, " :are supported by this server\r\n");
+ proxy_outdata(client, "%s", paramstr->str);
+ g_string_truncate(paramstr, 0);
+ g_string_printf(paramstr, ":%s 005 %s ", client->proxy_address, client->nick);
+
+ if (*tmp == NULL || tmp[1] == NULL)
+ break;
+ }
+
+ g_string_free(isupport_out, TRUE);
+ g_string_free(paramstr, TRUE);
+ g_strfreev(paramlist);
+ }
+
+ proxy_outdata(client, ":%s 251 %s :There are 0 users and 0 invisible on 1 servers\r\n", client->proxy_address, client->nick);
+ proxy_outdata(client, ":%s 255 %s :I have 0 clients, 0 services and 0 servers\r\n", client->proxy_address, client->nick);
+ proxy_outdata(client, ":%s 422 %s :MOTD File is missing\r\n", client->proxy_address, client->nick);
+
+ /* user mode / away status */
+ if (client->server != NULL) {
+ if (client->server->usermode != NULL) {
+ proxy_outserver(client, "MODE %s :+%s",
+ client->server->nick,
+ client->server->usermode);
+ }
+ if (client->server->usermode_away) {
+ proxy_outdata(client, ":%s 306 %s :You have been marked as being away\r\n",
+ client->proxy_address, client->nick);
+ }
+
+ /* Send channel joins */
+ g_slist_foreach(client->server->channels, (GFunc) dump_join, client);
+ }
+}