diff options
Diffstat (limited to 'src/irc/proxy/dump.c')
-rw-r--r-- | src/irc/proxy/dump.c | 303 |
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); + } +} |