Lots of moving stuff around - hopefully I didn't break too much :)

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@632 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2000-08-26 15:39:44 +00:00 committed by cras
commit e395e87ded
160 changed files with 3954 additions and 2959 deletions

View file

@ -1,56 +1,54 @@
noinst_LTLIBRARIES = libirc_core.la
noinst_LIBRARIES = libirc_core.a
INCLUDES = \
$(GLIB_CFLAGS) \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-I$(top_srcdir)/src -I$(top_srcdir)/src/core
libirc_core_la_SOURCES = \
libirc_core_a_SOURCES = \
bans.c \
ctcp.c \
channels.c \
channels-query.c \
channels-setup.c \
channel-events.c \
channel-rejoin.c \
ignore.c \
irc.c \
irc-core.c \
irc-channels.c \
irc-channels-setup.c \
irc-chatnets.c \
irc-commands.c \
irc-log.c \
irc-masks.c \
irc-nicklist.c \
irc-queries.c \
irc-rawlog.c \
irc-server.c \
irc-servers.c \
irc-servers-reconnect.c \
irc-servers-setup.c \
irc-special-vars.c \
ircnet-setup.c \
lag.c \
masks.c \
massjoin.c \
modes.c \
mode-lists.c \
netsplit.c \
nicklist.c \
query.c \
server-idle.c \
server-reconnect.c \
server-setup.c
server-idle.c
noinst_HEADERS = \
bans.h \
ctcp.h \
channels.h \
channels-setup.h \
ignore.h \
irc.h \
irc-channels.h \
irc-chatnets.h \
irc-commands.h \
irc-server.h \
ircnet-setup.h \
masks.h \
irc-masks.h \
irc-nicklist.h \
irc-queries.h \
irc-servers.h \
irc-servers-setup.h \
modes.h \
mode-lists.h \
module.h \
netsplit.h \
nicklist.h \
query.h \
server-idle.h \
server-reconnect.h \
server-setup.h
server-idle.h

View file

@ -19,12 +19,11 @@
*/
#include "module.h"
#include "signals.h"
#include "commands.h"
#include "misc.h"
#include "signals.h"
#include "masks.h"
#include "irc-masks.h"
#include "modes.h"
#include "mode-lists.h"
#include "irc.h"
@ -33,15 +32,15 @@
static int bantype;
/* Get ban mask */
char *ban_get_mask(CHANNEL_REC *channel, const char *nick)
char *ban_get_mask(IRC_CHANNEL_REC *channel, const char *nick)
{
NICK_REC *rec;
char *str, *user, *host;
g_return_val_if_fail(channel != NULL, NULL);
g_return_val_if_fail(IS_IRC_CHANNEL(channel), NULL);
g_return_val_if_fail(nick != NULL, NULL);
rec = nicklist_find(channel, nick);
rec = nicklist_find(CHANNEL(channel), nick);
if (rec == NULL || rec->host == NULL) return NULL;
str = irc_get_mask(nick, rec->host, bantype);
@ -109,7 +108,7 @@ void ban_set_type(const char *type)
signal_emit("ban type changed", 1, bantypestr);
}
void ban_set(CHANNEL_REC *channel, const char *bans)
void ban_set(IRC_CHANNEL_REC *channel, const char *bans)
{
GString *str;
char **ban, **banlist, *realban;
@ -136,12 +135,13 @@ void ban_set(CHANNEL_REC *channel, const char *bans)
if (str->len > 0) {
g_string_truncate(str, str->len-1);
channel_set_singlemode(channel->server, channel->name, str->str, "+b");
channel_set_singlemode(channel->server, channel->name,
str->str, "+b");
}
g_string_free(str, TRUE);
}
void ban_remove(CHANNEL_REC *channel, const char *bans)
void ban_remove(IRC_CHANNEL_REC *channel, const char *bans)
{
GString *str;
GSList *tmp;
@ -160,18 +160,19 @@ void ban_remove(CHANNEL_REC *channel, const char *bans)
g_strfreev(banlist);
if (str->len > 0)
channel_set_singlemode(channel->server, channel->name, str->str, "-b");
channel_set_singlemode(channel->server, channel->name,
str->str, "-b");
g_string_free(str, TRUE);
}
static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item, int set)
static void command_set_ban(const char *data, IRC_SERVER_REC *server, void *item, int set)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *channel, *nicks;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (server == NULL || !server->connected || !IS_IRC_SERVER(server))
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
@ -184,9 +185,11 @@ static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC
nicks = (char *) data;
}
chanrec = channel_find(server, channel);
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
if (!chanrec->wholist) cmd_param_error(CMDERR_CHAN_NOT_SYNCED);
chanrec = irc_channel_find(server, channel);
if (chanrec == NULL)
cmd_param_error(CMDERR_CHAN_NOT_FOUND);
if (!chanrec->wholist)
cmd_param_error(CMDERR_CHAN_NOT_SYNCED);
if (set)
ban_set(chanrec, nicks);
@ -204,13 +207,13 @@ static void cmd_bantype(const char *data)
}
/* SYNTAX: BAN <nicks/masks> */
static void cmd_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_ban(const char *data, IRC_SERVER_REC *server, void *item)
{
command_set_ban(data, server, item, TRUE);
}
/* SYNTAX: UNBAN <masks> */
static void cmd_unban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_unban(const char *data, IRC_SERVER_REC *server, void *item)
{
command_set_ban(data, server, item, FALSE);
}

View file

@ -1,15 +1,15 @@
#ifndef __BANS_H
#define __BANS_H
#include "channels.h"
#include "irc-channels.h"
void bans_init(void);
void bans_deinit(void);
char *ban_get_mask(CHANNEL_REC *channel, const char *nick);
char *ban_get_mask(IRC_CHANNEL_REC *channel, const char *nick);
void ban_set_type(const char *type);
void ban_set(CHANNEL_REC *channel, const char *bans);
void ban_remove(CHANNEL_REC *channel, const char *ban);
void ban_set(IRC_CHANNEL_REC *channel, const char *bans);
void ban_remove(IRC_CHANNEL_REC *channel, const char *ban);
#endif

View file

@ -20,10 +20,10 @@
#include "module.h"
#include "signals.h"
#include "misc.h"
#include "channels.h"
#include "irc.h"
#include "irc-channels.h"
static void event_cannot_join(const char *data, IRC_SERVER_REC *server)
{
@ -37,12 +37,12 @@ static void event_cannot_join(const char *data, IRC_SERVER_REC *server)
if (channel[0] == '!' && channel[1] == '!')
channel++; /* server didn't understand !channels */
chanrec = channel_find(server, channel);
chanrec = channel_find(SERVER(server), channel);
if (chanrec == NULL && channel[0] == '!') {
/* it probably replied with the full !channel name,
find the channel with the short name.. */
channel = g_strdup_printf("!%s", channel+6);
chanrec = channel_find(server, channel);
chanrec = channel_find(SERVER(server), channel);
g_free(channel);
}
@ -73,7 +73,7 @@ static void channel_change_topic(IRC_SERVER_REC *server, const char *channel, co
{
CHANNEL_REC *chanrec;
chanrec = channel_find(server, channel);
chanrec = channel_find(SERVER(server), channel);
if (chanrec != NULL) {
g_free_not_null(chanrec->topic);
chanrec->topic = *topic == '\0' ? NULL : g_strdup(topic);
@ -105,16 +105,18 @@ static void event_topic(const char *data, IRC_SERVER_REC *server)
/* Find any unjoined channel that matches `channel'. Long channel names are
also a bit problematic, so find a channel where start of the name matches. */
static CHANNEL_REC *channel_find_unjoined(IRC_SERVER_REC *server, const char *channel)
static IRC_CHANNEL_REC *channel_find_unjoined(IRC_SERVER_REC *server,
const char *channel)
{
GSList *tmp;
int len;
len = strlen(channel);
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data;
IRC_CHANNEL_REC *rec = tmp->data;
if (rec->joined) continue;
if (!IS_IRC_CHANNEL(rec) || rec->joined)
continue;
if (g_strncasecmp(channel, rec->name, len) == 0 &&
(len > 20 || rec->name[len] == '\0'))
@ -127,7 +129,7 @@ static CHANNEL_REC *channel_find_unjoined(IRC_SERVER_REC *server, const char *ch
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
{
char *params, *channel, *tmp;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
g_return_if_fail(data != NULL);
@ -159,7 +161,7 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
g_free(shortchan);
}
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL && chanrec->joined) {
/* already joined this channel - this check was added
here because of broken irssi proxy :) */
@ -170,7 +172,7 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
chanrec = channel_find_unjoined(server, channel);
if (chanrec == NULL) {
/* didn't get here with /join command.. */
chanrec = channel_create(server, channel, TRUE);
chanrec = irc_channel_create(server, channel, TRUE);
}
chanrec->joined = TRUE;
if (strcmp(chanrec->name, channel) != 0) {
@ -195,7 +197,7 @@ static void event_part(const char *data, IRC_SERVER_REC *server, const char *nic
params = event_get_params(data, 2, &channel, &reason);
chanrec = channel_find(server, channel);
chanrec = channel_find(SERVER(server), channel);
if (chanrec != NULL) {
chanrec->left = TRUE;
channel_destroy(chanrec);
@ -219,7 +221,7 @@ static void event_kick(const char *data, IRC_SERVER_REC *server)
return;
}
chanrec = channel_find(server, channel);
chanrec = channel_find(SERVER(server), channel);
if (chanrec != NULL) {
chanrec->kicked = TRUE;
channel_destroy(chanrec);

View file

@ -21,25 +21,29 @@
#include "module.h"
#include "signals.h"
#include "misc.h"
#include "channels.h"
#include "irc.h"
#include "irc-channels.h"
#define REJOIN_TIMEOUT (1000*60*5) /* try to rejoin every 5 minutes */
static int rejoin_tag;
#define channel_have_key(chan) \
((chan) != NULL && (chan)->key != NULL && (chan)->key[0] != '\0')
static void channel_rejoin(IRC_SERVER_REC *server, const char *channel)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *str;
chanrec = channel_find(server, channel);
str = chanrec == NULL || chanrec->key == NULL || *chanrec->key == '\0' ?
g_strdup(channel) : g_strdup_printf("%s %s", channel, chanrec->key);
chanrec = irc_channel_find(server, channel);
str = channel_have_key(chanrec) ? g_strdup(channel) :
g_strdup_printf("%s %s", channel, chanrec->key);
server->rejoin_channels = g_slist_append(server->rejoin_channels, str);
server->rejoin_channels =
g_slist_append(server->rejoin_channels, str);
}
static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
@ -59,7 +63,7 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
static void sig_disconnected(IRC_SERVER_REC *server)
{
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
g_slist_foreach(server->rejoin_channels, (GFunc) g_free, NULL);
@ -71,8 +75,9 @@ static void server_rejoin_channels(IRC_SERVER_REC *server)
while (server->rejoin_channels != NULL) {
char *channel = server->rejoin_channels->data;
channels_join(server, channel, TRUE);
server->rejoin_channels = g_slist_remove(server->rejoin_channels, channel);
irc_channels_join(server, channel, TRUE);
server->rejoin_channels =
g_slist_remove(server->rejoin_channels, channel);
}
}
@ -83,7 +88,7 @@ static int sig_rejoin(void)
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
IRC_SERVER_REC *rec = tmp->data;
if (irc_server_check(rec))
if (IS_IRC_SERVER(rec))
server_rejoin_channels(rec);
}
@ -92,7 +97,8 @@ static int sig_rejoin(void)
void channel_rejoin_init(void)
{
rejoin_tag = g_timeout_add(REJOIN_TIMEOUT, (GSourceFunc) sig_rejoin, NULL);
rejoin_tag = g_timeout_add(REJOIN_TIMEOUT,
(GSourceFunc) sig_rejoin, NULL);
signal_add_first("event 437", (SIGNAL_FUNC) event_target_unavailable);
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);

View file

@ -39,7 +39,6 @@ loop:
*/
#include "module.h"
#include "modules.h"
#include "misc.h"
#include "signals.h"
@ -48,8 +47,8 @@ loop:
#include "modes.h"
#include "mode-lists.h"
#include "nicklist.h"
#include "irc-server.h"
#include "server-redirect.h"
#include "irc-servers.h"
#include "servers-redirect.h"
enum {
CHANNEL_QUERY_MODE,
@ -73,7 +72,7 @@ static void sig_connected(IRC_SERVER_REC *server)
SERVER_QUERY_REC *rec;
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
rec = g_new0(SERVER_QUERY_REC, 1);
@ -86,7 +85,7 @@ static void sig_disconnected(IRC_SERVER_REC *server)
int n;
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
rec = server->chanqueries;
@ -99,7 +98,7 @@ static void sig_disconnected(IRC_SERVER_REC *server)
}
/* Add channel to query list */
static void channel_query_add(CHANNEL_REC *channel, int query)
static void channel_query_add(IRC_CHANNEL_REC *channel, int query)
{
SERVER_QUERY_REC *rec;
@ -111,7 +110,7 @@ static void channel_query_add(CHANNEL_REC *channel, int query)
rec->queries[query] = g_slist_append(rec->queries[query], channel);
}
static void channel_query_remove_all(CHANNEL_REC *channel)
static void channel_query_remove_all(IRC_CHANNEL_REC *channel)
{
SERVER_QUERY_REC *rec;
int n;
@ -125,7 +124,7 @@ static void channel_query_remove_all(CHANNEL_REC *channel)
}
static void sig_channel_destroyed(CHANNEL_REC *channel)
static void sig_channel_destroyed(IRC_CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
@ -138,9 +137,9 @@ static int channels_have_all_names(IRC_SERVER_REC *server)
GSList *tmp;
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data;
IRC_CHANNEL_REC *rec = tmp->data;
if (!rec->names_got)
if (IS_IRC_CHANNEL(rec) && !rec->names_got)
return 0;
}
@ -162,7 +161,7 @@ static int find_next_query(SERVER_QUERY_REC *server)
static void channel_send_query(IRC_SERVER_REC *server, int query)
{
SERVER_QUERY_REC *rec;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
GSList *tmp, *chans;
char *cmd, *chanstr_commas, *chanstr;
int onlyone;
@ -183,8 +182,8 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
chans = rec->queries[query];
chanstr_commas = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), ",");
chanstr_spaces = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(CHANNEL_REC, name), " ");
chanstr_commas = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(IRC_CHANNEL_REC, name), ",");
chanstr_spaces = gslistptr_to_string(rec->queries[query], G_STRUCT_OFFSET(IRC_CHANNEL_REC, name), " ");
chanstr = g_strconcat(chanstr_commas, " ", chanstr_spaces, NULL);
g_free(chanstr_spaces);
@ -304,7 +303,7 @@ static void channels_query_check(IRC_SERVER_REC *server)
channel_send_query(server, query);
}
static void sig_channel_query(CHANNEL_REC *channel)
static void sig_channel_query(IRC_CHANNEL_REC *channel)
{
SERVER_QUERY_REC *rec;
@ -328,7 +327,7 @@ static void sig_channel_query(CHANNEL_REC *channel)
}
/* if there's no more queries in queries in buffer, send the sync signal */
static void channel_checksync(CHANNEL_REC *channel)
static void channel_checksync(IRC_CHANNEL_REC *channel)
{
SERVER_QUERY_REC *rec;
int n;
@ -350,7 +349,7 @@ static void channel_checksync(CHANNEL_REC *channel)
signal_emit("channel sync", 1, channel);
}
static void channel_got_query(IRC_SERVER_REC *server, CHANNEL_REC *chanrec, const char *channel)
static void channel_got_query(IRC_SERVER_REC *server, IRC_CHANNEL_REC *chanrec, const char *channel)
{
SERVER_QUERY_REC *rec;
@ -371,13 +370,13 @@ static void channel_got_query(IRC_SERVER_REC *server, CHANNEL_REC *chanrec, cons
static void event_channel_mode(char *data, IRC_SERVER_REC *server, const char *nick)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, *mode;
g_return_if_fail(data != NULL);
params = event_get_params(data, 3 | PARAM_FLAG_GETREST, NULL, &channel, &mode);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL)
parse_channel_modes(chanrec, nick, mode);
channel_got_query(server, chanrec, channel);
@ -395,7 +394,7 @@ static void multi_query_remove(IRC_SERVER_REC *server, const char *event, const
static void event_end_of_who(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
NICK_REC *nick;
char *params, *channel, **chans;
int n, onewho;
@ -414,14 +413,14 @@ static void event_end_of_who(const char *data, IRC_SERVER_REC *server)
/* check that the WHO actually did return something
(that it understood #chan1,#chan2,..) */
chanrec = channel_find(server, chans[0]);
nick = nicklist_find(chanrec, server->nick);
chanrec = irc_channel_find(server, chans[0]);
nick = nicklist_find(CHANNEL(chanrec), server->nick);
if (nick->host == NULL)
server->no_multi_who = TRUE;
}
for (n = 0; chans[n] != NULL; n++) {
chanrec = channel_find(server, chans[n]);
chanrec = irc_channel_find(server, chans[n]);
if (chanrec == NULL)
continue;
@ -449,13 +448,13 @@ static void event_end_of_who(const char *data, IRC_SERVER_REC *server)
static void event_end_of_banlist(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2, NULL, &channel);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
channel_got_query(server, chanrec, channel);
@ -464,13 +463,13 @@ static void event_end_of_banlist(const char *data, IRC_SERVER_REC *server)
static void event_end_of_ebanlist(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2, NULL, &channel);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
channel_got_query(server, chanrec, channel);
@ -479,13 +478,13 @@ static void event_end_of_ebanlist(const char *data, IRC_SERVER_REC *server)
static void event_end_of_invitelist(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2, NULL, &channel);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
channel_got_query(server, chanrec, channel);
@ -494,9 +493,9 @@ static void event_end_of_invitelist(const char *data, IRC_SERVER_REC *server)
static void channel_lost(IRC_SERVER_REC *server, const char *channel)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL) {
/* channel not found - probably created a new channel
and left it immediately. */
@ -508,7 +507,7 @@ static void channel_lost(IRC_SERVER_REC *server, const char *channel)
static void multi_command_error(IRC_SERVER_REC *server, const char *data, int query, const char *event)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, **chans;
int n;
@ -519,7 +518,7 @@ static void multi_command_error(IRC_SERVER_REC *server, const char *data, int qu
chans = g_strsplit(channel, ",", -1);
for (n = 0; chans[n] != NULL; n++)
{
chanrec = channel_find(server, chans[n]);
chanrec = irc_channel_find(server, chans[n]);
if (chanrec != NULL)
channel_query_add(chanrec, query);
}

View file

@ -1,253 +0,0 @@
/*
channels-setup.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 "irc.h"
#include "channels.h"
#include "channels-setup.h"
#include "nicklist.h"
#include "irc-server.h"
#include "server-setup.h"
#include "special-vars.h"
#include "lib-config/iconfig.h"
#include "settings.h"
GSList *setupchannels;
#define ircnet_match(a, b) \
((a) == NULL || (a[0]) == '\0' || (b != NULL && g_strcasecmp(a, b) == 0))
static void channel_config_add(SETUP_CHANNEL_REC *channel)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("(channels", TRUE);
node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
iconfig_node_set_str(node, "name", channel->name);
iconfig_node_set_str(node, "ircnet", channel->ircnet);
if (channel->autojoin)
config_node_set_bool(node, "autojoin", TRUE);
iconfig_node_set_str(node, "password", channel->password);
iconfig_node_set_str(node, "botmasks", channel->botmasks);
iconfig_node_set_str(node, "autosendcmd", channel->autosendcmd);
iconfig_node_set_str(node, "background", channel->background);
iconfig_node_set_str(node, "font", channel->font);
}
static void channel_config_remove(SETUP_CHANNEL_REC *channel)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("channels", FALSE);
if (node != NULL) iconfig_node_list_remove(node, g_slist_index(setupchannels, channel));
}
void channels_setup_create(SETUP_CHANNEL_REC *channel)
{
if (g_slist_find(setupchannels, channel) != NULL) {
channel_config_remove(channel);
setupchannels = g_slist_remove(setupchannels, channel);
}
setupchannels = g_slist_append(setupchannels, channel);
channel_config_add(channel);
}
static void channels_setup_destroy_rec(SETUP_CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
setupchannels = g_slist_remove(setupchannels, channel);
g_free(channel->name);
g_free(channel->ircnet);
g_free_not_null(channel->password);
g_free_not_null(channel->botmasks);
g_free_not_null(channel->autosendcmd);
g_free_not_null(channel->background);
g_free_not_null(channel->font);
g_free(channel);
}
void channels_setup_destroy(SETUP_CHANNEL_REC *channel)
{
channel_config_remove(channel);
channels_setup_destroy_rec(channel);
}
SETUP_CHANNEL_REC *channels_setup_find(const char *channel, const char *ircnet)
{
GSList *tmp;
g_return_val_if_fail(channel != NULL, NULL);
for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
SETUP_CHANNEL_REC *rec = tmp->data;
if (g_strcasecmp(rec->name, channel) == 0 &&
ircnet_match(rec->ircnet, ircnet))
return rec;
}
return NULL;
}
/* connected to server, autojoin to channels. */
static void event_connected(IRC_SERVER_REC *server)
{
GString *chans;
GSList *tmp;
g_return_if_fail(server != NULL);
if (server->connrec->reconnection)
return;
/* join to the channels marked with autojoin in setup */
chans = g_string_new(NULL);
for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
SETUP_CHANNEL_REC *rec = tmp->data;
if (!rec->autojoin || !ircnet_match(rec->ircnet, server->connrec->ircnet))
continue;
g_string_sprintfa(chans, "%s,", rec->name);
}
if (chans->len > 0) {
g_string_truncate(chans, chans->len-1);
channels_join(server, chans->str, TRUE);
}
g_string_free(chans, TRUE);
}
/* channel wholist received: send the auto send command */
static void channel_wholist(CHANNEL_REC *channel)
{
SETUP_CHANNEL_REC *rec;
NICK_REC *nick;
char **bots, **bot;
g_return_if_fail(channel != NULL);
rec = channels_setup_find(channel->name, channel->server->connrec->ircnet);
if (rec == NULL || rec->autosendcmd == NULL || !*rec->autosendcmd)
return;
if (rec->botmasks == NULL || !*rec->botmasks) {
/* just send the command. */
eval_special_string(rec->autosendcmd, "", channel->server, channel);
return;
}
/* find first available bot.. */
bots = g_strsplit(rec->botmasks, " ", -1);
for (bot = bots; *bot != NULL; bot++) {
const char *botnick = *bot;
nick = nicklist_find(channel, isnickflag(*botnick) ?
botnick+1 : botnick);
if (nick == NULL)
continue;
if ((*botnick == '@' && !nick->op) ||
(*botnick == '+' && !nick->voice && !nick->op))
continue;
/* got one! */
eval_special_string(rec->autosendcmd, nick->nick, channel->server, channel);
break;
}
g_strfreev(bots);
}
static SETUP_CHANNEL_REC *setupchannel_add(CONFIG_NODE *node)
{
SETUP_CHANNEL_REC *rec;
char *channel, *ircnet, *password, *botmasks, *autosendcmd, *background, *font;
g_return_val_if_fail(node != NULL, NULL);
channel = config_node_get_str(node, "name", NULL);
ircnet = config_node_get_str(node, "ircnet", NULL);
if (channel == NULL || ircnet == NULL) {
/* missing information.. */
return NULL;
}
password = config_node_get_str(node, "password", NULL);
botmasks = config_node_get_str(node, "botmasks", NULL);
autosendcmd = config_node_get_str(node, "autosendcmd", NULL);
background = config_node_get_str(node, "background", NULL);
font = config_node_get_str(node, "font", NULL);
rec = g_new(SETUP_CHANNEL_REC, 1);
rec->autojoin = config_node_get_bool(node, "autojoin", FALSE);
rec->name = g_strdup(channel);
rec->ircnet = g_strdup(ircnet);
rec->password = (password == NULL || *password == '\0') ? NULL : g_strdup(password);
rec->botmasks = (botmasks == NULL || *botmasks == '\0') ? NULL : g_strdup(botmasks);
rec->autosendcmd = (autosendcmd == NULL || *autosendcmd == '\0') ? NULL : g_strdup(autosendcmd);
rec->background = (background == NULL || *background == '\0') ? NULL : g_strdup(background);
rec->font = (font == NULL || *font == '\0') ? NULL : g_strdup(font);
setupchannels = g_slist_append(setupchannels, rec);
return rec;
}
static void channels_read_config(void)
{
CONFIG_NODE *node;
GSList *tmp;
while (setupchannels != NULL)
channels_setup_destroy_rec(setupchannels->data);
/* Read channels */
node = iconfig_node_traverse("channels", FALSE);
if (node != NULL) {
for (tmp = node->value; tmp != NULL; tmp = tmp->next)
setupchannel_add(tmp->data);
}
}
void channels_setup_init(void)
{
source_host_ok = FALSE;
channels_read_config();
signal_add("event connected", (SIGNAL_FUNC) event_connected);
signal_add("channel wholist", (SIGNAL_FUNC) channel_wholist);
signal_add("setup reread", (SIGNAL_FUNC) channels_read_config);
}
void channels_setup_deinit(void)
{
while (setupchannels != NULL)
channels_setup_destroy(setupchannels->data);
signal_remove("event connected", (SIGNAL_FUNC) event_connected);
signal_remove("channel wholist", (SIGNAL_FUNC) channel_wholist);
signal_remove("setup reread", (SIGNAL_FUNC) channels_read_config);
}

View file

@ -1,28 +0,0 @@
#ifndef __CHANNELS_SETUP_H
#define __CHANNELS_SETUP_H
typedef struct {
int autojoin;
char *name;
char *ircnet;
char *password;
char *botmasks;
char *autosendcmd;
char *background;
char *font;
} SETUP_CHANNEL_REC;
extern GSList *setupchannels;
void channels_setup_init(void);
void channels_setup_deinit(void);
void channels_setup_create(SETUP_CHANNEL_REC *channel);
void channels_setup_destroy(SETUP_CHANNEL_REC *channel);
SETUP_CHANNEL_REC *channels_setup_find(const char *channel, const char *ircnet);
#endif

View file

@ -1,62 +0,0 @@
#ifndef __CHANNELS_H
#define __CHANNELS_H
#include "irc-server.h"
typedef struct {
int type;
GHashTable *module_data;
IRC_SERVER_REC *server;
char *name;
int new_data;
int last_color;
time_t createtime;
GHashTable *nicks; /* list of nicks */
GSList *banlist; /* list of bans */
GSList *ebanlist; /* list of ban exceptions */
GSList *invitelist; /* invite list */
char *topic;
/* channel mode */
int no_modes:1; /* channel doesn't support modes */
char *mode;
int limit; /* user limit */
char *key; /* password key */
int chanop:1; /* You're a channel operator */
int names_got:1; /* Received /NAMES list */
int wholist:1; /* WHO list got */
int synced:1; /* Channel synced - all queries done */
int joined:1; /* Have we even received JOIN event for this channel? */
int left:1; /* You just left the channel */
int kicked:1; /* You just got kicked */
int destroying:1;
time_t massjoin_start; /* Massjoin start time */
int massjoins; /* Number of nicks waiting for massjoin signal.. */
int last_massjoins; /* Massjoins when last checked in timeout function */
} CHANNEL_REC;
extern GSList *channels;
void channels_init(void);
void channels_deinit(void);
/* Create new channel record */
CHANNEL_REC *channel_create(IRC_SERVER_REC *server, const char *channel, int automatic);
void channel_destroy(CHANNEL_REC *channel);
/* find channel by name, if `server' is NULL, search from all servers */
CHANNEL_REC *channel_find(IRC_SERVER_REC *server, const char *channel);
/* Join to channels. `data' contains channels and channel keys */
void channels_join(IRC_SERVER_REC *server, const char *data, int automatic);
#endif

View file

@ -1,7 +1,7 @@
/*
ctcp.c : irssi
Copyright (C) 1999 Timo Sirainen
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
@ -25,7 +25,7 @@
#include "settings.h"
#include "irc.h"
#include "irc-server.h"
#include "irc-servers.h"
#include "server-idle.h"
#include "ignore.h"
@ -35,8 +35,10 @@ static void ctcp_queue_clean(IRC_SERVER_REC *server)
for (tmp = server->ctcpqueue; tmp != NULL; tmp = tmp->next) {
next = tmp->next;
if (!server_idle_find(server, GPOINTER_TO_INT(tmp->data)))
server->ctcpqueue = g_slist_remove(server->ctcpqueue, tmp->data);
if (!server_idle_find(server, GPOINTER_TO_INT(tmp->data))) {
server->ctcpqueue =
g_slist_remove(server->ctcpqueue, tmp->data);
}
}
}
@ -50,15 +52,19 @@ void ctcp_send_reply(IRC_SERVER_REC *server, const char *data)
ctcp_queue_clean(server);
if (g_slist_length(server->ctcpqueue) < settings_get_int("max_ctcp_queue")) {
/* Add to first in idle queue */
tag = server_idle_add(server, data, NULL, 0, NULL);
server->ctcpqueue = g_slist_append(server->ctcpqueue, GINT_TO_POINTER(tag));
}
if ((int)g_slist_length(server->ctcpqueue) >=
settings_get_int("max_ctcp_queue"))
return;
/* Add to first in idle queue */
tag = server_idle_add(server, data, NULL, 0, NULL);
server->ctcpqueue =
g_slist_append(server->ctcpqueue, GINT_TO_POINTER(tag));
}
/* CTCP ping */
static void ctcp_ping(const char *data, IRC_SERVER_REC *server, const char *nick)
static void ctcp_ping(const char *data, IRC_SERVER_REC *server,
const char *nick)
{
char *str;
@ -72,14 +78,16 @@ static void ctcp_ping(const char *data, IRC_SERVER_REC *server, const char *nick
}
/* CTCP version */
static void ctcp_version(const char *data, IRC_SERVER_REC *server, const char *nick)
static void ctcp_version(const char *data, IRC_SERVER_REC *server,
const char *nick)
{
char *str, *reply;
g_return_if_fail(server != NULL);
g_return_if_fail(nick != NULL);
reply = parse_special_string(settings_get_str("ctcp_version_reply"), server, NULL, "", NULL);
reply = parse_special_string(settings_get_str("ctcp_version_reply"),
SERVER(server), NULL, "", NULL);
str = g_strdup_printf("NOTICE %s :\001VERSION %s\001", nick, reply);
ctcp_send_reply(server, str);
g_free(str);
@ -107,7 +115,8 @@ static void ctcp_time(const char *data, IRC_SERVER_REC *server, const char *nick
g_free(reply);
}
static void ctcp_msg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr, const char *target)
static void ctcp_msg(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr, const char *target)
{
char *args, *str;
@ -119,12 +128,15 @@ static void ctcp_msg(const char *data, IRC_SERVER_REC *server, const char *nick,
if (args != NULL) *args++ = '\0'; else args = "";
g_strdown(str+9);
if (!signal_emit(str, 5, args, server, nick, addr, target))
signal_emit("default ctcp msg", 5, data, server, nick, addr, target);
if (!signal_emit(str, 5, args, server, nick, addr, target)) {
signal_emit("default ctcp msg", 5,
data, server, nick, addr, target);
}
g_free(str);
}
static void ctcp_reply(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr, const char *target)
static void ctcp_reply(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr, const char *target)
{
char *args, *str;
@ -136,12 +148,15 @@ static void ctcp_reply(const char *data, IRC_SERVER_REC *server, const char *nic
if (args != NULL) *args++ = '\0'; else args = "";
g_strdown(str+11);
if (!signal_emit(str, 5, args, server, nick, addr, target))
signal_emit("default ctcp reply", 5, data, server, nick, addr, target);
if (!signal_emit(str, 5, args, server, nick, addr, target)) {
signal_emit("default ctcp reply", 5,
data, server, nick, addr, target);
}
g_free(str);
}
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
static void event_privmsg(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr)
{
char *params, *target, *msg, *ptr;
@ -162,7 +177,8 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
g_free(params);
}
static void event_notice(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
static void event_notice(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr)
{
char *params, *target, *ptr, *msg;
@ -186,7 +202,7 @@ static void sig_disconnected(IRC_SERVER_REC *server)
{
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
g_slist_free(server->ctcpqueue);
@ -194,7 +210,8 @@ static void sig_disconnected(IRC_SERVER_REC *server)
void ctcp_init(void)
{
settings_add_str("misc", "ctcp_version_reply", PACKAGE" v$J - running on $sysname");
settings_add_str("misc", "ctcp_version_reply",
PACKAGE" v$J - running on $sysname");
settings_add_int("flood", "max_ctcp_queue", 5);
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);

View file

@ -26,10 +26,10 @@
#include "settings.h"
#include "irc.h"
#include "masks.h"
#include "irc-server.h"
#include "channels.h"
#include "nicklist.h"
#include "irc-masks.h"
#include "irc-servers.h"
#include "irc-channels.h"
#include "irc-nicklist.h"
#include "ignore.h"
@ -39,7 +39,7 @@ GSList *ignores;
static int ignore_check_replies(IGNORE_REC *rec, IRC_SERVER_REC *server,
const char *channel, const char *text)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
GSList *nicks, *tmp;
g_return_val_if_fail(rec != NULL, FALSE);
@ -47,10 +47,10 @@ static int ignore_check_replies(IGNORE_REC *rec, IRC_SERVER_REC *server,
g_return_val_if_fail(channel != NULL, FALSE);
g_return_val_if_fail(text != NULL, FALSE);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec == NULL) return FALSE;
nicks = nicklist_find_multiple(chanrec, rec->mask);
nicks = nicklist_find_multiple(CHANNEL(chanrec), rec->mask);
if (nicks == NULL) return FALSE;
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
@ -103,7 +103,7 @@ int ignore_check(IRC_SERVER_REC *server, const char *nick, const char *host,
ok = ((host == NULL || *host == '\0')) ?
match_wildcards(rec->mask, nick) :
irc_mask_match_address(rec->mask, nick, host);
mask_match_address(SERVER(server), rec->mask, nick, host);
if (!ok) {
/* nick didn't match, but maybe this is a reply to nick? */
if (!rec->replies || channel == NULL || text == NULL ||

View file

@ -0,0 +1,116 @@
/*
irc-channels-setup.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 "nicklist.h"
#include "servers.h"
#include "special-vars.h"
#include "servers-setup.h"
#include "channels-setup.h"
#include "irc.h"
#include "irc-chatnets.h"
#include "irc-servers.h"
#include "irc-channels.h"
/* connected to server, autojoin to channels. */
static void event_connected(IRC_SERVER_REC *server)
{
GString *chans;
GSList *tmp;
g_return_if_fail(server != NULL);
if (server->connrec->reconnection)
return;
/* join to the channels marked with autojoin in setup */
chans = g_string_new(NULL);
for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
CHANNEL_SETUP_REC *rec = tmp->data;
if (!rec->autojoin ||
!channel_chatnet_match(rec->chatnet,
server->connrec->chatnet))
continue;
g_string_sprintfa(chans, "%s,", rec->name);
}
if (chans->len > 0) {
g_string_truncate(chans, chans->len-1);
irc_channels_join(server, chans->str, TRUE);
}
g_string_free(chans, TRUE);
}
/* channel wholist received: send the auto send command */
static void channel_wholist(CHANNEL_REC *channel)
{
CHANNEL_SETUP_REC *rec;
NICK_REC *nick;
char **bots, **bot;
g_return_if_fail(channel != NULL);
rec = channels_setup_find(channel->name, channel->server->connrec->chatnet);
if (rec == NULL || rec->autosendcmd == NULL || !*rec->autosendcmd)
return;
if (rec->botmasks == NULL || !*rec->botmasks) {
/* just send the command. */
eval_special_string(rec->autosendcmd, "", channel->server, channel);
return;
}
/* find first available bot.. */
bots = g_strsplit(rec->botmasks, " ", -1);
for (bot = bots; *bot != NULL; bot++) {
const char *botnick = *bot;
nick = nicklist_find(channel, isnickflag(*botnick) ?
botnick+1 : botnick);
if (nick == NULL)
continue;
if ((*botnick == '@' && !nick->op) ||
(*botnick == '+' && !nick->voice && !nick->op))
continue;
/* got one! */
eval_special_string(rec->autosendcmd, nick->nick, channel->server, channel);
break;
}
g_strfreev(bots);
}
void irc_channels_setup_init(void)
{
signal_add("event connected", (SIGNAL_FUNC) event_connected);
signal_add("channel wholist", (SIGNAL_FUNC) channel_wholist);
}
void irc_channels_setup_deinit(void)
{
signal_remove("event connected", (SIGNAL_FUNC) event_connected);
signal_remove("channel wholist", (SIGNAL_FUNC) channel_wholist);
}

View file

@ -1,7 +1,7 @@
/*
channels.c : irssi
irc-channels.c : irssi
Copyright (C) 1999 Timo Sirainen
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
@ -20,17 +20,16 @@
#include "module.h"
#include "signals.h"
#include "modules.h"
#include "misc.h"
#include "bans.h"
#include "channels.h"
#include "irc-channels.h"
#include "channels-setup.h"
#include "irc.h"
#include "modes.h"
#include "levels.h"
#include "mode-lists.h"
#include "nicklist.h"
#include "irc-nicklist.h"
void channels_query_init(void);
void channels_query_deinit(void);
@ -44,96 +43,43 @@ void channel_rejoin_deinit(void);
void massjoin_init(void);
void massjoin_deinit(void);
GSList *channels; /* List of all channels */
CHANNEL_REC *channel_create(IRC_SERVER_REC *server, const char *channel, int automatic)
IRC_CHANNEL_REC *irc_channel_create(IRC_SERVER_REC *server,
const char *name, int automatic)
{
CHANNEL_REC *rec;
IRC_CHANNEL_REC *rec;
g_return_val_if_fail(channel != NULL, NULL);
g_return_val_if_fail(server == NULL || IS_IRC_SERVER(server), NULL);
g_return_val_if_fail(name != NULL, NULL);
rec = g_new0(CHANNEL_REC, 1);
channels = g_slist_append(channels, rec);
if (server != NULL)
server->channels = g_slist_append(server->channels, rec);
MODULE_DATA_INIT(rec);
rec->type = module_get_uniq_id("IRC", WI_IRC_CHANNEL);
rec->name = g_strdup(channel);
rec = g_new0(IRC_CHANNEL_REC, 1);
rec->chat_type = module_get_uniq_id("IRC CHANNEL", 0);
rec->name = g_strdup(name);
rec->server = server;
rec->createtime = time(NULL);
rec->mode = g_strdup("");
if (*channel == '+')
rec->no_modes = TRUE;
signal_emit("channel created", 2, rec, GINT_TO_POINTER(automatic));
if (*name == '+') rec->no_modes = TRUE;
channel_init((CHANNEL_REC *) rec, automatic);
return rec;
}
void channel_destroy(CHANNEL_REC *channel)
void sig_channel_destroyed(IRC_CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
if (channel->destroying) return;
channel->destroying = TRUE;
channels = g_slist_remove(channels, channel);
if (channel->server != NULL)
channel->server->channels = g_slist_remove(channel->server->channels, channel);
signal_emit("channel destroyed", 1, channel);
if (!IS_IRC_CHANNEL(channel))
return;
if (channel->server != NULL && !channel->left && !channel->kicked) {
/* destroying channel record without actually left the channel yet */
/* destroying channel record without actually
having left the channel yet */
irc_send_cmdv(channel->server, "PART %s", channel->name);
}
MODULE_DATA_DEINIT(channel);
g_free_not_null(channel->topic);
g_free_not_null(channel->key);
g_free(channel->name);
g_free(channel);
}
static CHANNEL_REC *channel_find_server(IRC_SERVER_REC *server, const char *channel)
{
GSList *tmp;
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data;
if (g_strcasecmp(channel, rec->name) == 0)
return rec;
/* check after removing ABCDE from !ABCDEchannel */
if (*channel == '!' && *rec->name == '!' &&
g_strcasecmp(channel+1, rec->name+6) == 0)
return rec;
}
return NULL;
}
CHANNEL_REC *channel_find(IRC_SERVER_REC *server, const char *channel)
{
g_return_val_if_fail(channel != NULL, NULL);
if (server != NULL)
return channel_find_server(server, channel);
/* find from any server */
return gslist_foreach_find(servers, (FOREACH_FIND_FUNC) channel_find_server, (void *) channel);
}
#define get_join_key(key) \
(((key) == NULL || *(key) == '\0') ? "x" : (key))
void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
void irc_channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
{
SETUP_CHANNEL_REC *schannel;
CHANNEL_REC *chanrec;
CHANNEL_SETUP_REC *schannel;
IRC_CHANNEL_REC *chanrec;
GString *outchans, *outkeys;
char *channels, *keys, *key;
char **chanlist, **keylist, **tmp, **tmpkey, *channel;
@ -141,7 +87,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
int use_keys;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channels, &keys))
@ -160,9 +106,9 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
channel = ischannel(**tmp) ? g_strdup(*tmp) :
g_strdup_printf("#%s", *tmp);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec == NULL) {
schannel = channels_setup_find(channel, server->connrec->ircnet);
schannel = channels_setup_find(channel, server->connrec->chatnet);
g_string_sprintfa(outchans, "%s,", channel);
if (*tmpkey != NULL && **tmpkey != '\0')
@ -174,7 +120,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
} else key = NULL;
g_string_sprintfa(outkeys, "%s,", get_join_key(key));
chanrec = channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
chanrec = irc_channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
if (key != NULL) chanrec->key = g_strdup(key);
}
g_free(channel);
@ -199,8 +145,43 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
cmd_params_free(free_arg);
}
void channels_init(void)
/* function for finding IRC channels - adds support for !channels */
static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server,
const char *channel)
{
GSList *tmp;
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data;
if (rec->chat_type != server->channel_type)
continue;
if (g_strcasecmp(channel, rec->name) == 0)
return rec;
/* check after removing ABCDE from !ABCDEchannel */
if (*channel == '!' && *rec->name == '!' &&
g_strcasecmp(channel+1, rec->name+6) == 0)
return rec;
}
return NULL;
}
static void sig_connected(SERVER_REC *server)
{
if (!IS_IRC_SERVER(server))
return;
server->channel_find_func = (void *) irc_channel_find_server;
server->channel_type = module_get_uniq_id("IRC CHANNEL", 0);;
}
void irc_channels_init(void)
{
signal_add("server connected", (SIGNAL_FUNC) sig_connected);
channel_events_init();
channel_rejoin_init();
channels_query_init();
@ -210,11 +191,13 @@ void channels_init(void)
modes_init();
mode_lists_init();
massjoin_init();
nicklist_init();
irc_nicklist_init();
}
void channels_deinit(void)
void irc_channels_deinit(void)
{
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
channel_events_deinit();
channel_rejoin_deinit();
channels_query_deinit();
@ -224,5 +207,7 @@ void channels_deinit(void)
modes_deinit();
mode_lists_deinit();
massjoin_deinit();
nicklist_deinit();
irc_nicklist_deinit();
module_uniq_destroy("IRC CHANNEL");
}

View file

@ -0,0 +1,42 @@
#ifndef __IRC_CHANNELS_H
#define __IRC_CHANNELS_H
#include "channels.h"
#include "irc-servers.h"
#define IS_IRC_CHANNEL(channel) \
((channel) != NULL && \
module_find_id("IRC CHANNEL", \
((IRC_CHANNEL_REC *) (channel))->chat_type) != -1)
/* Returns IRC_CHANNEL_REC if it's IRC channel, NULL if it isn't. */
#define IRC_CHANNEL(channel) \
(IS_IRC_CHANNEL(channel) ? (IRC_CHANNEL_REC *) (channel) : NULL)
#define STRUCT_SERVER_REC IRC_SERVER_REC
typedef struct {
#include "channel-rec.h"
GSList *banlist; /* list of bans */
GSList *ebanlist; /* list of ban exceptions */
GSList *invitelist; /* invite list */
time_t massjoin_start; /* Massjoin start time */
int massjoins; /* Number of nicks waiting for massjoin signal.. */
int last_massjoins; /* Massjoins when last checked in timeout function */
} IRC_CHANNEL_REC;
void irc_channels_init(void);
void irc_channels_deinit(void);
/* Create new IRC channel record */
IRC_CHANNEL_REC *irc_channel_create(IRC_SERVER_REC *server,
const char *name, int automatic);
#define irc_channel_find(server, name) \
IRC_CHANNEL(channel_find(SERVER(server), name))
/* Join to channels. `data' contains channels and channel keys */
void irc_channels_join(IRC_SERVER_REC *server, const char *data, int automatic);
#endif

132
src/irc/core/irc-chatnets.c Normal file
View file

@ -0,0 +1,132 @@
/*
irc-chatnets.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 "servers.h"
#include "chatnets.h"
#include "special-vars.h"
#include "lib-config/iconfig.h"
#include "settings.h"
#include "irc-chatnets.h"
static void ircnet_read(CONFIG_NODE *node)
{
IRC_CHATNET_REC *rec;
if (node == NULL || node->key == NULL)
return;
rec = g_new0(IRC_CHATNET_REC, 1);
rec->chat_type = module_get_uniq_id("IRC CHATNET", 0);
rec->max_cmds_at_once = config_node_get_int(node, "cmdmax", 0);
rec->cmd_queue_speed = config_node_get_int(node, "cmdspeed", 0);
rec->max_kicks = config_node_get_int(node, "max_kicks", 0);
rec->max_msgs = config_node_get_int(node, "max_msgs", 0);
rec->max_modes = config_node_get_int(node, "max_modes", 0);
rec->max_whois = config_node_get_int(node, "max_whois", 0);
chatnet_read((CHATNET_REC *) rec, node);
}
static void ircnet_save(IRC_CHATNET_REC *rec)
{
CONFIG_NODE *node;
g_return_if_fail(IS_IRC_CHATNET(rec));
node = iconfig_node_traverse("ircnets", TRUE);
node = chatnet_save(CHATNET(rec), node);
if (rec->max_cmds_at_once > 0)
config_node_set_int(node, "cmdmax", rec->max_cmds_at_once);
if (rec->cmd_queue_speed > 0)
config_node_set_int(node, "cmdspeed", rec->cmd_queue_speed);
if (rec->max_kicks > 0)
config_node_set_int(node, "max_kicks", rec->max_kicks);
if (rec->max_msgs > 0)
config_node_set_int(node, "max_msgs", rec->max_msgs);
if (rec->max_modes > 0)
config_node_set_int(node, "max_modes", rec->max_modes);
if (rec->max_whois > 0)
config_node_set_int(node, "max_whois", rec->max_whois);
}
static void ircnet_remove(IRC_CHATNET_REC *rec)
{
CONFIG_NODE *node;
g_return_if_fail(IS_IRC_CHATNET(rec));
node = iconfig_node_traverse("ircnets", FALSE);
if (node != NULL) iconfig_node_set_str(node, rec->name, NULL);
}
void ircnet_create(IRC_CHATNET_REC *rec)
{
g_return_if_fail(rec != NULL);
rec->chat_type = module_get_uniq_id("IRC CHATNET", 0);
ircnet_save(rec);
chatnet_create(CHATNET(rec));
}
static void read_ircnets(void)
{
CONFIG_NODE *node;
GSList *tmp;
while (chatnets != NULL)
chatnet_destroy(chatnets->data);
/* read ircnets */
node = iconfig_node_traverse("ircnets", FALSE);
if (node != NULL) {
for (tmp = node->value; tmp != NULL; tmp = tmp->next)
ircnet_read(tmp->data);
}
}
static void sig_chatnet_removed(IRC_CHATNET_REC *rec)
{
if (IS_IRC_CHATNET(rec))
ircnet_remove(rec);
}
void irc_chatnets_init(void)
{
read_ircnets();
signal_add("chatnet removed", (SIGNAL_FUNC) sig_chatnet_removed);
signal_add("setup reread", (SIGNAL_FUNC) read_ircnets);
}
void irc_chatnets_deinit(void)
{
signal_remove("chatnet removed", (SIGNAL_FUNC) sig_chatnet_removed);
signal_remove("setup reread", (SIGNAL_FUNC) read_ircnets);
module_uniq_destroy("IRC CHATNET");
}

View file

@ -0,0 +1,33 @@
#ifndef __IRC_CHATNETS_H
#define __IRC_CHATNETS_H
#define IS_IRC_CHATNET(chatnet) \
((chatnet) != NULL && \
module_find_id("IRC CHATNET", (chatnet)->chat_type) != -1)
/* returns IRC_CHATNET_REC if it's IRC network, NULL if it isn't */
#define IRC_CHATNET(chatnet) \
(IS_IRC_CHATNET(chatnet) ? (IRC_CHATNET_REC *) (chatnet) : NULL)
#define IS_IRCNET(ircnet) IS_IRC_CHATNET(ircnet)
#define IRCNET(ircnet) IRC_CHATNET(ircnet)
typedef struct {
#include "chatnet-rec.h"
int max_cmds_at_once;
int cmd_queue_speed;
/* max. number of kicks/msgs/mode/whois per command */
int max_kicks, max_msgs, max_modes, max_whois;
} IRC_CHATNET_REC;
void ircnet_create(IRC_CHATNET_REC *rec);
#define irc_chatnet_find(name) \
IRC_CHATNET(chatnet_find(name))
#define ircnet_find(name) irc_chatnet_find(name)
void irc_chatnets_init(void);
void irc_chatnets_deinit(void);
#endif

View file

@ -24,20 +24,23 @@
#include "misc.h"
#include "special-vars.h"
#include "settings.h"
#include "window-item-def.h"
#include "nicklist.h"
#include "servers-redirect.h"
#include "servers-setup.h"
#include "bans.h"
#include "channels.h"
#include "irc-server.h"
#include "irc.h"
#include "nicklist.h"
#include "server-redirect.h"
#include "server-setup.h"
#include "irc-servers.h"
#include "irc-channels.h"
#include "irc-queries.h"
/* How often to check if there's anyone to be unbanned in knockout list */
#define KNOCKOUT_TIMECHECK 10000
typedef struct {
CHANNEL_REC *channel;
IRC_CHANNEL_REC *channel;
char *ban;
int timeleft;
} KNOCKOUT_REC;
@ -85,7 +88,7 @@ IRC_SERVER_REC *irccmd_options_get_server(const char *cmd,
static IRC_SERVER_REC *connect_server(const char *data)
{
IRC_SERVER_CONNECT_REC *conn;
SERVER_CONNECT_REC *conn;
IRC_SERVER_REC *server;
GHashTable *optlist;
char *addr, *portstr, *password, *nick, *ircnet, *host;
@ -107,11 +110,11 @@ static IRC_SERVER_REC *connect_server(const char *data)
*password = '\0';
/* connect to server */
conn = irc_server_create_conn(addr, atoi(portstr), password, nick);
conn = server_create_conn(addr, atoi(portstr), password, nick);
ircnet = g_hash_table_lookup(optlist, "ircnet");
if (ircnet != NULL && *ircnet != '\0') {
g_free_not_null(conn->ircnet);
conn->ircnet = g_strdup(ircnet);
g_free_not_null(conn->chatnet);
conn->chatnet = g_strdup(ircnet);
}
host = g_hash_table_lookup(optlist, "host");
if (host != NULL && *host != '\0') {
@ -123,7 +126,7 @@ static IRC_SERVER_REC *connect_server(const char *data)
memcpy(conn->own_ip, &ip, sizeof(IPADDR));
}
}
server = irc_server_connect(conn);
server = irc_server_connect(IRC_SERVER_CONNECT(conn));
cmd_params_free(free_arg);
return server;
@ -146,15 +149,12 @@ static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
g_return_if_fail(data != NULL);
if (g_strncasecmp(data, "RECON-", 6) == 0)
return; /* remove reconnection, handle in server-reconnect.c */
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &tag, &msg))
return;
if (*tag != '\0' && strcmp(tag, "*") != 0)
server = (IRC_SERVER_REC *) server_find_tag(tag);
if (server == NULL || !irc_server_check(server))
if (server == NULL || !IS_IRC_SERVER(server))
cmd_param_error(CMDERR_NOT_CONNECTED);
if (*msg == '\0') msg = (char *) settings_get_str("quit_message");
@ -192,7 +192,7 @@ static void cmd_server(const char *data, IRC_SERVER_REC *server)
if (*addr == '+' || server == NULL) {
channels = away_reason = usermode = ircnet = NULL;
} else {
ircnet = g_strdup(server->connrec->ircnet);
ircnet = g_strdup(server->connrec->chatnet);
channels = irc_server_get_channels((IRC_SERVER_REC *) server);
if (*channels == '\0')
g_free_and_null(channels);
@ -204,8 +204,8 @@ static void cmd_server(const char *data, IRC_SERVER_REC *server)
server = connect_server(data);
if (*addr == '+' || server == NULL ||
(ircnet != NULL && server->connrec->ircnet != NULL &&
g_strcasecmp(ircnet, server->connrec->ircnet) != 0)) {
(ircnet != NULL && server->connrec->chatnet != NULL &&
g_strcasecmp(ircnet, server->connrec->chatnet) != 0)) {
g_free_not_null(channels);
g_free_not_null(usermode);
g_free_not_null(away_reason);
@ -244,7 +244,7 @@ static void cmd_quit(const char *data)
}
/* SYNTAX: MSG [-<server tag>] <targets> <message> */
static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
GHashTable *optlist;
char *target, *msg;
@ -260,14 +260,14 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
server = irccmd_options_get_server("msg", optlist, server);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_param_error(CMDERR_NOT_CONNECTED);
free_ret = FALSE;
if (strcmp(target, ",") == 0 || strcmp(target, ".") == 0)
target = parse_special(&target, server, item, NULL, &free_ret, NULL);
target = parse_special(&target, SERVER(server), item, NULL, &free_ret, NULL);
else if (strcmp(target, "*") == 0 &&
(irc_item_channel(item) || irc_item_query(item)))
(IS_IRC_CHANNEL(item) || IS_IRC_QUERY(item)))
target = item->name;
if (target != NULL) {
g_string_sprintf(tmpstr, "PRIVMSG %s :%s", target, msg);
@ -286,7 +286,7 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
@ -306,7 +306,7 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
@ -330,7 +330,7 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
@ -352,7 +352,7 @@ static void cmd_join(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS |
@ -361,32 +361,32 @@ static void cmd_join(const char *data, IRC_SERVER_REC *server)
if (g_hash_table_lookup(optlist, "invite")) {
if (server->last_invite != NULL)
channels_join(server, server->last_invite, FALSE);
irc_channels_join(server, server->last_invite, FALSE);
} else {
/* -<server tag> */
server = irccmd_options_get_server("join", optlist, server);
if (server != NULL) channels_join(server, channels, FALSE);
if (server != NULL) irc_channels_join(server, channels, FALSE);
}
cmd_params_free(free_arg);
}
/* SYNTAX: PART [<channels>] [<message>] */
static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *channame, *msg;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg))
return;
if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame);
chanrec = irc_channel_find(server, channame);
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s",
@ -396,13 +396,13 @@ static void cmd_part(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
/* SYNTAX: KICK [<channel>] <nicks> [<reason>] */
static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
char *channame, *nicks, *reason;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
@ -419,14 +419,14 @@ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
/* SYNTAX: TOPIC [-delete] [<channel>] [<topic>] */
static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
GHashTable *optlist;
char *channame, *topic;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN |
@ -442,13 +442,13 @@ static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item
}
/* SYNTAX: INVITE <nick> [<channel>] */
static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
char *nick, *channame;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2, &nick, &channame))
@ -456,7 +456,7 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *ite
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*channame == '\0' || strcmp(channame, "*") == 0) {
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(item))
cmd_param_error(CMDERR_NOT_JOINED);
channame = item->name;
@ -467,14 +467,14 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *ite
}
/* SYNTAX: LIST [-yes] [<channel>] */
static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
GHashTable *optlist;
char *str;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
@ -492,20 +492,20 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
/* SYNTAX: WHO <nicks>|<channels>|** */
static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
char *channel, *rest;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &channel, &rest))
return;
if (strcmp(channel, "*") == 0 || *channel == '\0') {
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(item))
cmd_param_error(CMDERR_NOT_JOINED);
channel = item->name;
@ -524,16 +524,16 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
/* SYNTAX: NAMES [-yes] [<channels>] */
static void cmd_names(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_names(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '\0') cmd_return_error(CMDERR_NOT_GOOD_IDEA);
if (strcmp(data, "*") == 0) {
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(item))
cmd_return_error(CMDERR_NOT_JOINED);
data = item->name;
@ -572,7 +572,7 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server)
int free_nick;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2, &qserver, &query))
@ -642,7 +642,7 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
int free_nick;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2, &nicks, &count))
@ -662,17 +662,17 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
}
/* SYNTAX: PING <nicks> */
static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
GTimeVal tv;
char *str;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '\0' || strcmp(data, "*") == 0) {
if (!irc_item_check(item))
if (!IS_IRC_ITEM(item))
cmd_return_error(CMDERR_NOT_JOINED);
data = item->name;
@ -701,7 +701,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
@ -719,7 +719,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server)
static void cmd_deop(const char *data, IRC_SERVER_REC *server)
{
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '\0')
@ -730,7 +730,7 @@ static void cmd_deop(const char *data, IRC_SERVER_REC *server)
static void cmd_sconnect(const char *data, IRC_SERVER_REC *server)
{
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -741,7 +741,7 @@ static void cmd_sconnect(const char *data, IRC_SERVER_REC *server)
static void cmd_quote(const char *data, IRC_SERVER_REC *server)
{
g_return_if_fail(data != NULL);
if (server == NULL || !irc_server_check(server))
if (server == NULL || !IS_IRC_SERVER(server))
cmd_return_error(CMDERR_NOT_CONNECTED);
irc_send_cmd(server, data);
@ -753,15 +753,15 @@ static void cmd_wall_hash(gpointer key, NICK_REC *nick, GSList **nicks)
}
/* SYNTAX: WALL [<channel>] <message> */
static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
char *channame, *msg, *args;
void *free_arg;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
GSList *tmp, *nicks;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN |
@ -769,7 +769,7 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
return;
if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame);
chanrec = irc_channel_find(server, channame);
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
/* send notice to all ops */
@ -777,7 +777,8 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
g_hash_table_foreach(chanrec->nicks, (GHFunc) cmd_wall_hash, &nicks);
args = g_strconcat(chanrec->name, " ", msg, NULL);
msg = parse_special_string(settings_get_str("wall_format"), server, item, args, NULL);
msg = parse_special_string(settings_get_str("wall_format"),
SERVER(server), item, args, NULL);
g_free(args);
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
@ -793,21 +794,21 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
/* SYNTAX: CYCLE [<channel>] [<message>] */
static void cmd_cycle(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_cycle(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *channame, *msg;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN, item, &channame, &msg))
return;
if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
chanrec = channel_find(server, channame);
chanrec = irc_channel_find(server, channame);
if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);
irc_send_cmdv(server, *msg == '\0' ? "PART %s" : "PART %s :%s",
@ -819,7 +820,7 @@ static void cmd_cycle(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item
}
/* SYNTAX: KICKBAN [<channel>] <nick> <reason> */
static void cmd_kickban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_kickban(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
{
char *nick;
void *free_arg;
@ -850,7 +851,7 @@ static void knockout_timeout_server(IRC_SERVER_REC *server)
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
t = server->knockout_lastcheck == 0 ? 0 :
@ -878,19 +879,19 @@ static int knockout_timeout(void)
}
/* SYNTAX: KNOCKOUT [<seconds>] <nick> <reason> */
static void cmd_knockout(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_knockout(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
KNOCKOUT_REC *rec;
CHANNEL_REC *channel;
char *nick, *reason, *timeoutstr, *str;
void *free_arg;
int timeleft;
g_return_if_fail(data != NULL);
if (server == NULL) cmd_return_error(CMDERR_NOT_CONNECTED);
channel = irc_item_channel(item);
if (channel == NULL) cmd_return_error(CMDERR_NOT_JOINED);
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!IS_IRC_CHANNEL(channel))
cmd_return_error(CMDERR_NOT_JOINED);
if (is_numeric(data, ' ')) {
/* first argument is the timeout */
@ -928,7 +929,7 @@ static void sig_server_disconnected(IRC_SERVER_REC *server)
{
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
while (server->knockoutlist != NULL)
@ -936,12 +937,12 @@ static void sig_server_disconnected(IRC_SERVER_REC *server)
}
/* destroy all knockouts in channel */
static void sig_channel_destroyed(CHANNEL_REC *channel)
static void sig_channel_destroyed(IRC_CHANNEL_REC *channel)
{
GSList *tmp, *next;
g_return_if_fail(channel != NULL);
if (channel->server == NULL) return;
if (!IS_IRC_CHANNEL(channel) || !IS_IRC_SERVER(channel->server))
return;
for (tmp = channel->server->knockoutlist; tmp != NULL; tmp = next) {
KNOCKOUT_REC *rec = tmp->data;
@ -959,7 +960,7 @@ static void cmd_oper(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2, &nick, &password))
@ -977,7 +978,7 @@ static void cmd_oper(const char *data, IRC_SERVER_REC *server)
static void command_self(const char *data, IRC_SERVER_REC *server)
{
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
irc_send_cmdv(server, *data == '\0' ? "%s" : "%s %s", current_command, data);
@ -986,7 +987,7 @@ static void command_self(const char *data, IRC_SERVER_REC *server)
static void command_1self(const char *data, IRC_SERVER_REC *server)
{
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -999,7 +1000,7 @@ static void command_2self(const char *data, IRC_SERVER_REC *server)
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (!IS_IRC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text))

View file

@ -20,9 +20,9 @@
#include "module.h"
#include "irc-server.h"
#include "channels.h"
#include "query.h"
#include "irc-servers.h"
#include "irc-channels.h"
#include "irc-queries.h"
#include "ctcp.h"
#include "ignore.h"
@ -47,8 +47,8 @@ void lag_deinit(void);
void irc_core_init(void)
{
irc_servers_init();
channels_init();
query_init();
irc_channels_init();
irc_queries_init();
ctcp_init();
irc_commands_init();
@ -72,8 +72,8 @@ void irc_core_deinit(void)
irc_commands_deinit();
ctcp_deinit();
query_deinit();
channels_deinit();
irc_queries_deinit();
irc_channels_deinit();
irc_irc_deinit();
irc_servers_deinit();
}

View file

@ -24,7 +24,7 @@
#include "log.h"
#include "settings.h"
#include "irc-server.h"
#include "irc-servers.h"
static LOG_REC *awaylog;
static int away_filepos;

View file

@ -20,98 +20,9 @@
#include "module.h"
#include "network.h"
#include "misc.h"
#include "irc.h"
#include "masks.h"
static int check_mask(const char *mask, int *wildcards)
{
while (*mask != '\0') {
if (*mask == '!')
return TRUE;
if (*mask == '?' || *mask == '*')
*wildcards = TRUE;
mask++;
}
return FALSE;
}
int irc_mask_match(const char *mask, const char *nick,
const char *user, const char *host)
{
char *str;
int ret, wildcards;
g_return_val_if_fail(mask != NULL, FALSE);
g_return_val_if_fail(nick != NULL, FALSE);
g_return_val_if_fail(user != NULL, FALSE);
g_return_val_if_fail(host != NULL, FALSE);
if (!check_mask(mask, &wildcards)) {
return wildcards ?
match_wildcards(mask, nick) :
g_strcasecmp(mask, nick) == 0;
}
str = g_strdup_printf("%s!%s@%s", nick, user, host);
ret = match_wildcards(mask, str);
g_free(str);
return ret;
}
int irc_mask_match_address(const char *mask, const char *nick,
const char *address)
{
char *str;
int ret, wildcards;
g_return_val_if_fail(mask != NULL, FALSE);
g_return_val_if_fail(nick != NULL, FALSE);
if (!check_mask(mask, &wildcards)) {
return wildcards ?
match_wildcards(mask, nick) :
g_strcasecmp(mask, nick) == 0;
}
str = g_strdup_printf("%s!%s", nick, address != NULL ? address : "");
ret = match_wildcards(mask, str);
g_free(str);
return ret;
}
int irc_masks_match(const char *masks, const char *nick, const char *address)
{
char **list, **tmp, *mask;
int found;
g_return_val_if_fail(masks != NULL, FALSE);
found = FALSE;
mask = g_strdup_printf("%s!%s", nick, address);
list = g_strsplit(masks, " ", -1);
for (tmp = list; *tmp != NULL; tmp++) {
if (strchr(*tmp, '!') == NULL &&
g_strcasecmp(*tmp, nick) == 0) {
found = TRUE;
break;
}
if (match_wildcards(*tmp, mask)) {
found = TRUE;
break;
}
}
g_strfreev(list);
g_free(mask);
return found;
}
#include "irc-masks.h"
static char *get_domain_mask(char *host)
{

13
src/irc/core/irc-masks.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __IRC_MASKS_H
#define __IRC_MASKS_H
#include "masks.h"
#define IRC_MASK_NICK 0x01
#define IRC_MASK_USER 0x02
#define IRC_MASK_HOST 0x04
#define IRC_MASK_DOMAIN 0x08
char *irc_get_mask(const char *nick, const char *address, int flags);
#endif

View file

@ -1,5 +1,5 @@
/*
nicklist.c : irssi
irc-nicklist.c : irssi
Copyright (C) 1999-2000 Timo Sirainen
@ -22,187 +22,20 @@
#include "signals.h"
#include "misc.h"
#include "channels.h"
#include "irc.h"
#include "masks.h"
#include "irc-channels.h"
#include "irc-masks.h"
#include "irc-nicklist.h"
#include "modes.h"
#include "nicklist.h"
#include "irc-server.h"
/* Add new nick to list */
NICK_REC *nicklist_insert(CHANNEL_REC *channel, const char *nick,
int op, int voice, int send_massjoin)
{
NICK_REC *rec;
g_return_val_if_fail(channel != NULL, NULL);
g_return_val_if_fail(nick != NULL, NULL);
rec = g_new0(NICK_REC, 1);
if (op) rec->op = TRUE;
if (voice) rec->voice = TRUE;
rec->send_massjoin = send_massjoin;
rec->nick = g_strdup(nick);
rec->host = NULL;
g_hash_table_insert(channel->nicks, rec->nick, rec);
signal_emit("nicklist new", 2, channel, rec);
return rec;
}
static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick)
{
signal_emit("nicklist remove", 2, channel, nick);
g_free(nick->nick);
g_free_not_null(nick->realname);
g_free_not_null(nick->host);
g_free(nick);
}
/* remove nick from list */
void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick)
{
g_return_if_fail(channel != NULL);
g_return_if_fail(nick != NULL);
g_hash_table_remove(channel->nicks, nick->nick);
nicklist_destroy(channel, nick);
}
static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel,
const char *mask)
{
GSList *nicks, *tmp;
NICK_REC *nick;
nicks = nicklist_getnicks(channel);
nick = NULL;
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
nick = tmp->data;
if (irc_mask_match_address(mask, nick->nick, nick->host))
break;
}
g_slist_free(nicks);
return tmp == NULL ? NULL : nick;
}
GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask)
{
GSList *nicks, *tmp, *next;
nicks = nicklist_getnicks(channel);
for (tmp = nicks; tmp != NULL; tmp = next) {
NICK_REC *nick = tmp->data;
next = tmp->next;
if (!irc_mask_match_address(mask, nick->nick, nick->host))
nicks = g_slist_remove(nicks, tmp->data);
}
return nicks;
}
/* Find nick record from list */
NICK_REC *nicklist_find(CHANNEL_REC *channel, const char *mask)
{
NICK_REC *nickrec;
char *nick, *host;
g_return_val_if_fail(channel != NULL, NULL);
g_return_val_if_fail(mask != NULL, NULL);
nick = g_strdup(mask);
host = strchr(nick, '!');
if (host != NULL) *host++ = '\0';
if (strchr(nick, '*') || strchr(nick, '?')) {
g_free(nick);
return nicklist_find_wildcards(channel, mask);
}
nickrec = g_hash_table_lookup(channel->nicks, nick);
if (nickrec != NULL && host != NULL &&
(nickrec->host == NULL || !match_wildcards(host, nickrec->host))) {
/* hosts didn't match */
nickrec = NULL;
}
g_free(nick);
return nickrec;
}
static void get_nicks_hash(gpointer key, NICK_REC *rec, GSList **list)
{
*list = g_slist_append(*list, rec);
}
/* Get list of nicks */
GSList *nicklist_getnicks(CHANNEL_REC *channel)
{
GSList *list;
list = NULL;
g_hash_table_foreach(channel->nicks, (GHFunc) get_nicks_hash, &list);
return list;
}
typedef struct {
CHANNEL_REC *channel;
const char *nick;
GSList *list;
} NICKLIST_GET_SAME_REC;
static void get_nicks_same_hash(gpointer key, NICK_REC *nick, NICKLIST_GET_SAME_REC *rec)
{
if (g_strcasecmp(nick->nick, rec->nick) == 0) {
rec->list = g_slist_append(rec->list, rec->channel);
rec->list = g_slist_append(rec->list, nick);
}
}
GSList *nicklist_get_same(IRC_SERVER_REC *server, const char *nick)
{
NICKLIST_GET_SAME_REC rec;
GSList *tmp;
rec.nick = nick;
rec.list = NULL;
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
rec.channel = tmp->data;
g_hash_table_foreach(rec.channel->nicks,
(GHFunc) get_nicks_same_hash, &rec);
}
return rec.list;
}
/* nick record comparision for sort functions */
int nicklist_compare(NICK_REC *p1, NICK_REC *p2)
{
if (p1 == NULL) return -1;
if (p2 == NULL) return 1;
if (p1->op && !p2->op) return -1;
if (!p1->op && p2->op) return 1;
if (!p1->op) {
if (p1->voice && !p2->voice) return -1;
if (!p1->voice && p2->voice) return 1;
}
return g_strcasecmp(p1->nick, p2->nick);
}
#include "servers.h"
#define isnickchar(a) \
(isalnum(a) || (a) == '`' || (a) == '-' || (a) == '_' || \
(isalnum((int) (a)) || (a) == '`' || (a) == '-' || (a) == '_' || \
(a) == '[' || (a) == ']' || (a) == '{' || (a) == '}' || \
(a) == '|' || (a) == '\\' || (a) == '^')
/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
char *nick_strip(const char *nick)
char *irc_nick_strip(const char *nick)
{
char *stripped, *spos;
@ -210,7 +43,8 @@ char *nick_strip(const char *nick)
spos = stripped = g_strdup(nick);
while (isnickchar(*nick)) {
if (isalnum((gint) *nick)) *spos++ = *nick;
if (isalnum((int) *nick))
*spos++ = *nick;
nick++;
}
if ((unsigned char) *nick >= 128)
@ -232,8 +66,8 @@ int irc_nick_match(const char *nick, const char *msg)
if (g_strncasecmp(msg, nick, len) == 0 && !isalnum((int) msg[len]))
return TRUE;
stripnick = nick_strip(nick);
stripmsg = nick_strip(msg);
stripnick = irc_nick_strip(nick);
stripmsg = irc_nick_strip(msg);
len = strlen(stripnick);
ret = len > 0 && g_strncasecmp(stripmsg, stripnick, len) == 0 &&
@ -245,7 +79,7 @@ int irc_nick_match(const char *nick, const char *msg)
return ret;
}
static void event_names_list(const char *data, IRC_SERVER_REC *server)
static void event_names_list(const char *data, SERVER_REC *server)
{
CHANNEL_REC *chanrec;
char *params, *type, *channel, *names, *ptr;
@ -267,9 +101,9 @@ static void event_names_list(const char *data, IRC_SERVER_REC *server)
get to know if the channel is +p or +s a few seconds before
we receive the MODE reply... */
if (*type == '*')
parse_channel_modes(chanrec, NULL, "+p");
parse_channel_modes(IRC_CHANNEL(chanrec), NULL, "+p");
else if (*type == '@')
parse_channel_modes(chanrec, NULL, "+s");
parse_channel_modes(IRC_CHANNEL(chanrec), NULL, "+s");
while (*names != '\0') {
while (*names == ' ') names++;
@ -287,16 +121,16 @@ static void event_names_list(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void event_end_of_names(const char *data, IRC_SERVER_REC *server)
static void event_end_of_names(const char *data, SERVER_REC *server)
{
char *params, *channel;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
g_return_if_fail(server != NULL);
params = event_get_params(data, 2, NULL, &channel);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL && !chanrec->names_got) {
chanrec->names_got = TRUE;
signal_emit("channel query", 1, chanrec);
@ -305,37 +139,7 @@ static void event_end_of_names(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void nicklist_update_flags(IRC_SERVER_REC *server, const char *nick,
int gone, int ircop)
{
GSList *nicks, *tmp;
CHANNEL_REC *channel;
NICK_REC *rec;
g_return_if_fail(server != NULL);
g_return_if_fail(nick != NULL);
nicks = nicklist_get_same(server, nick);
for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
channel = tmp->data;
rec = tmp->next->data;
rec->last_check = time(NULL);
if (gone != -1 && rec->gone != gone) {
rec->gone = gone;
signal_emit("nick gone changed", 2, channel, rec);
}
if (ircop != -1 && rec->ircop != ircop) {
rec->ircop = ircop;
signal_emit("nick ircop changed", 2, channel, rec);
}
}
g_slist_free(nicks);
}
static void event_who(const char *data, IRC_SERVER_REC *server)
static void event_who(const char *data, SERVER_REC *server)
{
char *params, *nick, *channel, *user, *host, *stat, *realname, *hops;
CHANNEL_REC *chanrec;
@ -354,7 +158,8 @@ static void event_who(const char *data, IRC_SERVER_REC *server)
/* update host, realname, hopcount */
chanrec = channel_find(server, channel);
nickrec = chanrec == NULL ? NULL : nicklist_find(chanrec, nick);
nickrec = chanrec == NULL ? NULL :
nicklist_find(chanrec, nick);
if (nickrec != NULL) {
if (nickrec->host == NULL)
nickrec->host = g_strdup_printf("%s@%s", user, host);
@ -385,7 +190,7 @@ static void event_whois(const char *data, IRC_SERVER_REC *server)
params = event_get_params(data, 6, NULL, &nick, NULL,
NULL, NULL, &realname);
nicks = nicklist_get_same(server, nick);
nicks = nicklist_get_same(SERVER(server), nick);
for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
rec = tmp->next->data;
@ -396,11 +201,11 @@ static void event_whois(const char *data, IRC_SERVER_REC *server)
/* reset gone and ircop status, we'll handle them in the following
WHOIS replies */
nicklist_update_flags(server, nick, FALSE, FALSE);
nicklist_update_flags(SERVER(server), nick, FALSE, FALSE);
g_free(params);
}
static void event_whois_away(const char *data, IRC_SERVER_REC *server)
static void event_whois_away(const char *data, SERVER_REC *server)
{
char *params, *nick, *awaymsg;
@ -412,7 +217,7 @@ static void event_whois_away(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void event_whois_ircop(const char *data, IRC_SERVER_REC *server)
static void event_whois_ircop(const char *data, SERVER_REC *server)
{
char *params, *nick, *awaymsg;
@ -487,10 +292,10 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void event_nick(const char *data, IRC_SERVER_REC *server,
static void event_nick(const char *data, SERVER_REC *server,
const char *orignick)
{
CHANNEL_REC *channel;
IRC_CHANNEL_REC *channel;
NICK_REC *nickrec;
GSList *nicks, *tmp;
char *params, *nick;
@ -529,7 +334,7 @@ static void event_nick(const char *data, IRC_SERVER_REC *server,
g_free(params);
}
static void event_userhost(const char *data, IRC_SERVER_REC *server)
static void event_userhost(const char *data, SERVER_REC *server)
{
char *params, *hosts, **phosts, **pos, *ptr;
@ -550,37 +355,14 @@ static void event_userhost(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void sig_usermode(IRC_SERVER_REC *server)
static void sig_usermode(SERVER_REC *server)
{
g_return_if_fail(server != NULL);
g_return_if_fail(IS_SERVER(server));
nicklist_update_flags(server, server->nick, server->usermode_away, -1);
}
static void sig_channel_created(CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
channel->nicks = g_hash_table_new((GHashFunc) g_istr_hash,
(GCompareFunc) g_istr_equal);
}
static void nicklist_remove_hash(gpointer key, NICK_REC *nick,
CHANNEL_REC *channel)
{
nicklist_destroy(channel, nick);
}
static void sig_channel_destroyed(CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
g_hash_table_foreach(channel->nicks,
(GHFunc) nicklist_remove_hash, channel);
g_hash_table_destroy(channel->nicks);
}
void nicklist_init(void)
void irc_nicklist_init(void)
{
signal_add("event nick", (SIGNAL_FUNC) event_nick);
signal_add_first("event 352", (SIGNAL_FUNC) event_who);
@ -597,11 +379,9 @@ void nicklist_init(void)
signal_add("event 302", (SIGNAL_FUNC) event_userhost);
signal_add("userhost event", (SIGNAL_FUNC) event_userhost);
signal_add("user mode changed", (SIGNAL_FUNC) sig_usermode);
signal_add_first("channel created", (SIGNAL_FUNC) sig_channel_created);
signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
}
void nicklist_deinit(void)
void irc_nicklist_deinit(void)
{
signal_remove("event nick", (SIGNAL_FUNC) event_nick);
signal_remove("event 352", (SIGNAL_FUNC) event_who);
@ -618,6 +398,4 @@ void nicklist_deinit(void)
signal_remove("event 302", (SIGNAL_FUNC) event_userhost);
signal_remove("userhost event", (SIGNAL_FUNC) event_userhost);
signal_remove("user mode changed", (SIGNAL_FUNC) sig_usermode);
signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created);
signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
}

View file

@ -0,0 +1,15 @@
#ifndef __IRC_NICKLIST_H
#define __IRC_NICKLIST_H
#include "nicklist.h"
void irc_nicklist_init(void);
void irc_nicklist_deinit(void);
/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
char *irc_nick_strip(const char *nick);
/* Check is `msg' is meant for `nick'. */
int irc_nick_match(const char *nick, const char *msg);
#endif

View file

@ -1,7 +1,7 @@
/*
query.c : irssi
irc-queries.c : irssi
Copyright (C) 1999 Timo Sirainen
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
@ -19,89 +19,34 @@
*/
#include "module.h"
#include "misc.h"
#include "signals.h"
#include "modules.h"
#include "misc.h"
#include "irc.h"
#include "query.h"
#include "irc-queries.h"
GSList *queries;
QUERY_REC *query_create(IRC_SERVER_REC *server, const char *nick, int automatic)
QUERY_REC *irc_query_create(IRC_SERVER_REC *server,
const char *nick, int automatic)
{
QUERY_REC *rec;
g_return_val_if_fail(server == NULL || IS_IRC_SERVER(server), NULL);
g_return_val_if_fail(nick != NULL, NULL);
rec = g_new0(QUERY_REC, 1);
queries = g_slist_append(queries, rec);
if (server != NULL) server->queries = g_slist_append(server->queries, rec);
MODULE_DATA_INIT(rec);
rec->type = module_get_uniq_id("IRC", WI_IRC_QUERY);
rec->nick = g_strdup(nick);
if (server != NULL) {
rec->server_tag = g_strdup(server->tag);
rec->server = server;
}
signal_emit("query created", 2, rec, GINT_TO_POINTER(automatic));
rec->chat_type = module_get_uniq_id("IRC QUERY", 0);
rec->name = g_strdup(nick);
rec->server = (SERVER_REC *) server;
query_init(rec, automatic);
return rec;
}
void query_destroy(QUERY_REC *query)
static void sig_connected(SERVER_REC *server)
{
g_return_if_fail(query != NULL);
if (!IS_IRC_SERVER(server))
return;
if (query->destroying) return;
query->destroying = TRUE;
queries = g_slist_remove(queries, query);
if (query->server != NULL)
query->server->queries = g_slist_remove(query->server->queries, query);
signal_emit("query destroyed", 1, query);
MODULE_DATA_DEINIT(query);
g_free_not_null(query->address);
g_free(query->nick);
g_free(query->server_tag);
g_free(query);
}
static QUERY_REC *query_find_server(IRC_SERVER_REC *server, const char *nick)
{
GSList *tmp;
for (tmp = server->queries; tmp != NULL; tmp = tmp->next) {
QUERY_REC *rec = tmp->data;
if (g_strcasecmp(nick, rec->nick) == 0)
return rec;
}
return NULL;
}
QUERY_REC *query_find(IRC_SERVER_REC *server, const char *nick)
{
g_return_val_if_fail(nick != NULL, NULL);
if (server != NULL)
return query_find_server(server, nick);
/* find from any server */
return gslist_foreach_find(servers, (FOREACH_FIND_FUNC) query_find_server, (void *) nick);
}
void query_change_server(QUERY_REC *query, IRC_SERVER_REC *server)
{
g_return_if_fail(query != NULL);
query->server = server;
signal_emit("query server changed", 2, query, server);
server->query_type = module_get_uniq_id("IRC QUERY", 0);;
}
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
@ -115,7 +60,7 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
if (addr != NULL && !ischannel(*target)) {
/* save nick's address to query */
query = query_find(server, nick);
query = irc_query_find(server, nick);
if (query != NULL && (query->address == NULL || strcmp(query->address, addr) != 0)) {
g_free_not_null(query->address);
query->address = g_strdup(addr);
@ -137,9 +82,9 @@ static void event_nick(const char *data, IRC_SERVER_REC *server, const char *ori
for (tmp = server->queries; tmp != NULL; tmp = tmp->next) {
QUERY_REC *rec = tmp->data;
if (g_strcasecmp(rec->nick, orignick) == 0) {
g_free(rec->nick);
rec->nick = g_strdup(nick);
if (g_strcasecmp(rec->name, orignick) == 0) {
g_free(rec->name);
rec->name = g_strdup(nick);
signal_emit("query nick changed", 1, rec);
}
}
@ -147,14 +92,18 @@ static void event_nick(const char *data, IRC_SERVER_REC *server, const char *ori
g_free(params);
}
void query_init(void)
void irc_queries_init(void)
{
signal_add("server connected", (SIGNAL_FUNC) sig_connected);
signal_add_last("event privmsg", (SIGNAL_FUNC) event_privmsg);
signal_add("event nick", (SIGNAL_FUNC) event_nick);
}
void query_deinit(void)
void irc_queries_deinit(void)
{
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg);
signal_remove("event nick", (SIGNAL_FUNC) event_nick);
module_uniq_destroy("IRC QUERY");
}

View file

@ -0,0 +1,25 @@
#ifndef __IRC_QUERIES_H
#define __IRC_QUERIES_H
#include "queries.h"
#include "irc-servers.h"
#define IS_IRC_QUERY(query) \
((query) != NULL && \
module_find_id("IRC QUERY", \
((QUERY_REC *) (query))->chat_type) != -1)
/* Returns IRC_QUERY_REC if it's IRC query, NULL if it isn't. */
#define IRC_QUERY(query) \
(IS_IRC_QUERY(query) ? (QUERY_REC *) (query) : NULL)
void irc_queries_init(void);
void irc_queries_deinit(void);
#define irc_query_find(server, name) \
query_find(SERVER(server), name)
QUERY_REC *irc_query_create(IRC_SERVER_REC *server,
const char *nick, int automatic);
#endif

View file

@ -20,12 +20,11 @@
#include "module.h"
#include "rawlog.h"
#include "modules.h"
#include "signals.h"
#include "misc.h"
#include "commands.h"
#include "server.h"
#include "servers.h"
#include "settings.h"

View file

@ -0,0 +1,118 @@
/*
servers-reconnect.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 "commands.h"
#include "network.h"
#include "signals.h"
#include "irc.h"
#include "modes.h"
#include "irc-servers.h"
#include "settings.h"
static void sig_server_connect_copy(SERVER_CONNECT_REC **dest,
IRC_SERVER_CONNECT_REC *src)
{
IRC_SERVER_CONNECT_REC *rec;
g_return_if_fail(dest != NULL);
if (!IS_IRC_SERVER_CONNECT(src))
return;
rec = g_new0(IRC_SERVER_CONNECT_REC, 1);
rec->chat_type = module_get_uniq_id("IRC SERVER CONNECT", 0);
rec->cmd_queue_speed = src->cmd_queue_speed;
rec->max_kicks = src->max_kicks;
rec->max_modes = src->max_modes;
rec->max_msgs = src->max_msgs;
rec->usermode = g_strdup(src->usermode);
*dest = (SERVER_CONNECT_REC *) rec;
}
static void sig_server_reconnect_save_status(IRC_SERVER_CONNECT_REC *conn,
IRC_SERVER_REC *server)
{
if (!IS_IRC_SERVER_CONNECT(conn))
return;
g_return_if_fail(IS_IRC_SERVER(server));
g_free_not_null(conn->channels);
conn->channels = irc_server_get_channels(server);
g_free_not_null(conn->usermode);
conn->usermode = g_strdup(server->usermode);
}
static int sig_set_user_mode(IRC_SERVER_REC *server)
{
const char *mode;
char *newmode;
if (g_slist_find(servers, server) == NULL)
return 0; /* got disconnected */
mode = server->connrec->usermode;
if (mode == NULL) return 0;
newmode = server->usermode == NULL ? NULL :
modes_join(server->usermode, mode);
if (server->usermode == NULL) {
/* server didn't set user mode, just set the new one */
irc_send_cmdv(server, "MODE %s %s", server->nick, mode);
} else {
if (strcmp(newmode, server->usermode) != 0)
irc_send_cmdv(server, "MODE %s -%s+%s", server->nick, server->usermode, mode);
}
g_free_not_null(newmode);
return 0;
}
static void sig_connected(IRC_SERVER_REC *server)
{
if (!server->connrec->reconnection)
return;
if (server->connrec->channels != NULL)
irc_channels_join(server, server->connrec->channels, TRUE);
if (server->connrec->away_reason != NULL)
signal_emit("command away", 2, server->connrec->away_reason, server, NULL);
if (server->connrec->usermode != NULL) {
/* wait a second and then send the user mode */
g_timeout_add(1000, (GSourceFunc) sig_set_user_mode, server);
}
}
void irc_servers_reconnect_init(void)
{
signal_add("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy);
signal_add("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status);
signal_add("event connected", (SIGNAL_FUNC) sig_connected);
}
void irc_servers_reconnect_deinit(void)
{
signal_remove("server connect copy", (SIGNAL_FUNC) sig_server_connect_copy);
signal_remove("server reconnect save status", (SIGNAL_FUNC) sig_server_reconnect_save_status);
signal_remove("event connected", (SIGNAL_FUNC) sig_connected);
}

View file

@ -0,0 +1,196 @@
/*
servers-setup.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 "network.h"
#include "servers-setup.h"
#include "lib-config/iconfig.h"
#include "settings.h"
#include "irc-chatnets.h"
#include "irc-servers-setup.h"
#include "irc-servers.h"
/* Fill information to connection from server setup record */
static void sig_server_setup_fill_reconn(IRC_SERVER_CONNECT_REC *conn,
IRC_SERVER_SETUP_REC *sserver)
{
if (!IS_IRC_SERVER_CONNECT(conn) ||
!IS_IRC_SERVER_SETUP(sserver))
return;
if (sserver->cmd_queue_speed > 0)
conn->cmd_queue_speed = sserver->cmd_queue_speed;
if (sserver->max_cmds_at_once > 0)
conn->max_cmds_at_once = sserver->max_cmds_at_once;
}
/* Create server connection record. `address' is required, rest can be NULL */
static void sig_server_create_conn(SERVER_CONNECT_REC **conn,
IRC_CHATNET_REC *ircnet)
{
IRC_SERVER_CONNECT_REC *rec;
g_return_if_fail(conn != NULL);
if (ircnet != NULL && !IS_IRCNET(ircnet))
return;
rec = g_new0(IRC_SERVER_CONNECT_REC, 1);
rec->chat_type = module_get_uniq_id("IRC SERVER CONNECT", 0);
rec->alternate_nick = g_strdup(settings_get_str("alternate_nick"));
*conn = (SERVER_CONNECT_REC *) rec;
signal_stop();
}
static void sig_server_setup_fill_chatnet(IRC_SERVER_CONNECT_REC *conn,
IRC_CHATNET_REC *ircnet)
{
if (!IS_IRC_SERVER_CONNECT(conn))
return;
g_return_if_fail(IS_IRCNET(ircnet));
if (ircnet->nick) g_free_and_null(conn->alternate_nick);
if (ircnet->max_kicks > 0) conn->max_kicks = ircnet->max_kicks;
if (ircnet->max_msgs > 0) conn->max_msgs = ircnet->max_msgs;
if (ircnet->max_modes > 0) conn->max_modes = ircnet->max_modes;
if (ircnet->max_whois > 0) conn->max_whois = ircnet->max_whois;
if (ircnet->max_cmds_at_once > 0)
conn->max_cmds_at_once = ircnet->max_cmds_at_once;
if (ircnet->cmd_queue_speed > 0)
conn->cmd_queue_speed = ircnet->cmd_queue_speed;
}
static void init_userinfo(void)
{
const char *set, *default_nick, *user_name;
char *str;
/* check if nick/username/realname wasn't read from setup.. */
set = settings_get_str("real_name");
if (set == NULL || *set == '\0') {
str = g_getenv("IRCNAME");
iconfig_set_str("settings", "real_name",
str != NULL ? str : g_get_real_name());
}
/* username */
user_name = settings_get_str("user_name");
if (user_name == NULL || *user_name == '\0') {
str = g_getenv("IRCUSER");
iconfig_set_str("settings", "user_name",
str != NULL ? str : g_get_user_name());
user_name = settings_get_str("user_name");
}
/* nick */
default_nick = settings_get_str("default_nick");
if (default_nick == NULL || *default_nick == '\0') {
str = g_getenv("IRCNICK");
iconfig_set_str("settings", "default_nick",
str != NULL ? str : user_name);
default_nick = settings_get_str("default_nick");
}
/* alternate nick */
set = settings_get_str("alternate_nick");
if (set == NULL || *set == '\0') {
if (strlen(default_nick) < 9)
str = g_strconcat(default_nick, "_", NULL);
else {
str = g_strdup(default_nick);
str[strlen(str)-1] = '_';
}
iconfig_set_str("settings", "alternate_nick", str);
g_free(str);
}
/* host name */
set = settings_get_str("hostname");
if (set == NULL || *set == '\0') {
str = g_getenv("IRCHOST");
if (str != NULL)
iconfig_set_str("settings", "hostname", str);
}
}
static void sig_server_setup_read(SERVER_SETUP_REC **setuprec,
CONFIG_NODE *node,
IRC_CHATNET_REC *chatnet)
{
IRC_SERVER_SETUP_REC *rec;
g_return_if_fail(setuprec != NULL);
g_return_if_fail(node != NULL);
if (chatnet != NULL && !IS_IRCNET(chatnet))
return;
rec = g_new0(IRC_SERVER_SETUP_REC, 1);
rec->chat_type = module_get_uniq_id("IRC SERVER SETUP", 0);
rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0);
rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0);
*setuprec = (SERVER_SETUP_REC *) rec;
signal_stop();
}
static void sig_server_setup_saved(IRC_SERVER_SETUP_REC *rec,
CONFIG_NODE *node)
{
if (!IS_IRC_SERVER_SETUP(rec))
return;
if (rec->max_cmds_at_once > 0)
config_node_set_int(node, "cmds_max_at_once", rec->max_cmds_at_once);
if (rec->cmd_queue_speed > 0)
config_node_set_int(node, "cmd_queue_speed", rec->cmd_queue_speed);
}
void irc_servers_setup_init(void)
{
settings_add_bool("server", "skip_motd", FALSE);
settings_add_str("server", "alternate_nick", NULL);
init_userinfo();
signal_add("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn);
signal_add("server setup connect", (SIGNAL_FUNC) sig_server_create_conn);
signal_add("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet);
signal_add("server setup read", (SIGNAL_FUNC) sig_server_setup_read);
signal_add("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved);
}
void irc_servers_setup_deinit(void)
{
signal_remove("server setup fill reconn", (SIGNAL_FUNC) sig_server_setup_fill_reconn);
signal_remove("server setup connect", (SIGNAL_FUNC) sig_server_create_conn);
signal_remove("server setup fill chatnet", (SIGNAL_FUNC) sig_server_setup_fill_chatnet);
signal_remove("server setup read", (SIGNAL_FUNC) sig_server_setup_read);
signal_remove("server setup saved", (SIGNAL_FUNC) sig_server_setup_saved);
module_uniq_destroy("IRC SERVER SETUP");
}

View file

@ -0,0 +1,21 @@
#ifndef __IRC_SERVERS_SETUP_H
#define __IRC_SERVERS_SETUP_H
#define IS_IRC_SERVER_SETUP(server) \
((server) != NULL && \
module_find_id("IRC SERVER SETUP", (server)->chat_type) != -1)
#define IRC_SERVER_SETUP(server) \
(IS_IRC_SERVER_SETUP(server) ? \
(IRC_SERVER_SETUP_REC *) (server) : NULL)
typedef struct {
#include "server-setup-rec.h"
int max_cmds_at_once; /* override the default if > 0 */
int cmd_queue_speed; /* override the default if > 0 */
} IRC_SERVER_SETUP_REC;
void irc_servers_setup_init(void);
void irc_servers_setup_deinit(void);
#endif

View file

@ -24,19 +24,19 @@
#include "net-sendbuffer.h"
#include "line-split.h"
#include "signals.h"
#include "modules.h"
#include "rawlog.h"
#include "misc.h"
#include "irc-server.h"
#include "server-idle.h"
#include "server-reconnect.h"
#include "server-setup.h"
#include "ircnet-setup.h"
#include "channels.h"
#include "modes.h"
#include "queries.h"
#include "irc.h"
#include "query.h"
#include "irc-chatnets.h"
#include "irc-servers-setup.h"
#include "irc-servers.h"
#include "server-idle.h"
#include "servers-reconnect.h"
#include "modes.h"
#include "settings.h"
@ -49,26 +49,17 @@
#define DEFAULT_CMD_QUEUE_SPEED 2200
#define DEFAULT_CMDS_MAX_AT_ONCE 5
void irc_servers_reconnect_init(void);
void irc_servers_reconnect_deinit(void);
static int cmd_tag;
void irc_server_connect_free(IRC_SERVER_CONNECT_REC *rec)
static void sig_server_connect_free(IRC_SERVER_CONNECT_REC *conn)
{
g_return_if_fail(rec != NULL);
if (!IS_IRC_SERVER_CONNECT(conn))
return;
g_free_not_null(rec->proxy);
g_free_not_null(rec->proxy_string);
g_free_not_null(rec->ircnet);
g_free_not_null(rec->password);
g_free_not_null(rec->nick);
g_free_not_null(rec->alternate_nick);
g_free_not_null(rec->username);
g_free_not_null(rec->realname);
g_free_not_null(rec->own_ip);
g_free_not_null(rec->channels);
g_free_not_null(rec->away_reason);
g_free_not_null(rec->usermode);
g_free_not_null(rec->address);
g_free(rec);
g_free_not_null(conn->alternate_nick);
}
static void server_init(IRC_SERVER_REC *server)
@ -116,12 +107,12 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn)
{
IRC_SERVER_REC *server;
g_return_val_if_fail(conn != NULL, NULL);
g_return_val_if_fail(IS_IRC_SERVER_CONNECT(conn), NULL);
if (conn->address == NULL || *conn->address == '\0') return NULL;
if (conn->nick == NULL || *conn->nick == '\0') return NULL;
server = g_new0(IRC_SERVER_REC, 1);
server->type = module_get_uniq_id("IRC SERVER", SERVER_TYPE_IRC);
server->chat_type = module_get_uniq_id("IRC SERVER", 0);
server->connrec = conn;
if (conn->port <= 0) conn->port = 6667;
@ -156,8 +147,8 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn)
server->max_msgs_in_cmd = conn->max_msgs > 0 ?
conn->max_msgs : DEFAULT_MAX_MSGS;
if (!server_connect((SERVER_REC *) server)) {
irc_server_connect_free(conn);
if (!server_start_connect((SERVER_REC *) server)) {
server_connect_free(SERVER_CONNECT(conn));
g_free(server->nick);
g_free(server);
return NULL;
@ -165,93 +156,47 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn)
return server;
}
static void sig_connected(IRC_SERVER_REC *server)
static void sig_server_connect(IRC_SERVER_REC **server,
IRC_SERVER_CONNECT_REC *conn)
{
if (!irc_server_check(server))
g_return_if_fail(server != NULL);
if (!IS_IRC_SERVER_CONNECT(conn))
return;
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);
server->splits = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
server_init(server);
*server = irc_server_connect(conn);
signal_stop();
}
static int server_remove_channels(IRC_SERVER_REC *server)
static void sig_connected(IRC_SERVER_REC *server)
{
GSList *tmp;
int found;
if (!IS_IRC_SERVER(server))
return;
g_return_val_if_fail(server != NULL, FALSE);
found = FALSE;
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *channel = tmp->data;
channel->server = NULL;
channel_destroy(channel);
found = TRUE;
}
for (tmp = server->queries; tmp != NULL; tmp = tmp->next)
query_change_server(tmp->data, NULL);
g_slist_free(server->channels);
g_slist_free(server->queries);
return found;
server->splits = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
server_init(server);
}
static void sig_disconnected(IRC_SERVER_REC *server)
{
int chans;
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
/* close all channels */
chans = server_remove_channels(server);
g_slist_foreach(server->cmdqueue, (GFunc) g_free, NULL);
g_slist_free(server->cmdqueue);
if (server->handle != NULL) {
if (!chans || server->connection_lost)
net_sendbuffer_destroy(server->handle, TRUE);
else {
/* we were on some channels, try to let the server
disconnect so that our quit message is guaranteed
to get displayed */
net_disconnect_later(net_sendbuffer_handle(server->handle));
net_sendbuffer_destroy(server->handle, FALSE);
}
server->handle = NULL;
}
irc_server_connect_free(server->connrec);
g_free_not_null(server->real_address);
g_free_not_null(server->usermode);
g_free_not_null(server->userhost);
g_free_not_null(server->last_invite);
}
static void sig_connect_failed(IRC_SERVER_REC *server)
{
if (!irc_server_check(server))
return;
server_remove_channels(server);
irc_server_connect_free(server->connrec);
}
static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now)
{
long usecs;
char *cmd;
int len, add_rawlog;
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
if (server->cmdcount == 0 && server->cmdqueue == NULL)
@ -456,9 +401,10 @@ void irc_servers_init(void)
cmd_tag = g_timeout_add(500, (GSourceFunc) servers_cmd_timeout, NULL);
signal_add("server connect free", (SIGNAL_FUNC) sig_server_connect_free);
signal_add("server connect", (SIGNAL_FUNC) sig_server_connect);
signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
signal_add_last("server connect failed", (SIGNAL_FUNC) sig_connect_failed);
signal_add("event 001", (SIGNAL_FUNC) event_connected);
signal_add("event 004", (SIGNAL_FUNC) event_server_info);
signal_add("event 465", (SIGNAL_FUNC) event_server_banned);
@ -466,10 +412,10 @@ void irc_servers_init(void)
signal_add("event ping", (SIGNAL_FUNC) event_ping);
signal_add("event empty", (SIGNAL_FUNC) event_empty);
servers_setup_init();
ircnets_setup_init();
irc_servers_setup_init();
irc_chatnets_init();
irc_servers_reconnect_init();
servers_idle_init();
servers_reconnect_init();
}
void irc_servers_deinit(void)
@ -481,9 +427,10 @@ void irc_servers_deinit(void)
g_source_remove(cmd_tag);
signal_remove("server connect free", (SIGNAL_FUNC) sig_server_connect_free);
signal_remove("server connect", (SIGNAL_FUNC) sig_server_connect);
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
signal_remove("server connect failed", (SIGNAL_FUNC) sig_connect_failed);
signal_remove("event 001", (SIGNAL_FUNC) event_connected);
signal_remove("event 004", (SIGNAL_FUNC) event_server_info);
signal_remove("event 465", (SIGNAL_FUNC) event_server_banned);
@ -491,10 +438,10 @@ void irc_servers_deinit(void)
signal_remove("event ping", (SIGNAL_FUNC) event_ping);
signal_remove("event empty", (SIGNAL_FUNC) event_empty);
servers_setup_deinit();
ircnets_setup_deinit();
irc_servers_setup_deinit();
irc_chatnets_deinit();
irc_servers_reconnect_deinit();
servers_idle_deinit();
servers_reconnect_deinit();
module_uniq_destroy("IRC SERVER");
}

View file

@ -1,44 +1,29 @@
#ifndef __IRC_SERVER_H
#define __IRC_SERVER_H
#ifndef __IRC_SERVERS_H
#define __IRC_SERVERS_H
#include "server.h"
#include "servers.h"
enum {
SERVER_TYPE_IRC
};
#define IS_IRC_SERVER(server) \
((server) != NULL && \
module_find_id("IRC SERVER", (server)->chat_type) != -1)
/* return if `server' doesn't point to IRC server record. */
#define irc_server_check(server) \
((server) != NULL && module_find_id("IRC SERVER", (server)->type) != -1)
#define IS_IRC_SERVER_CONNECT(conn) \
((conn) != NULL && \
module_find_id("IRC SERVER CONNECT", (conn)->chat_type) != -1)
/* returns IRC_SERVER_REC if it's IRC server, NULL if it isn't */
#define IRC_SERVER(server) \
(IS_IRC_SERVER(server) ? (IRC_SERVER_REC *) (server) : NULL)
#define IRC_SERVER_CONNECT(conn) \
(IS_IRC_SERVER_CONNECT(conn) ? \
(IRC_SERVER_CONNECT_REC *) (conn) : NULL)
/* all strings should be either NULL or dynamically allocated */
/* address and nick are mandatory, rest are optional */
typedef struct {
/* -- GENERIC SERVER_CONNECT_REC - don't change! -- */
/* if we're connecting via proxy, or just NULLs */
char *proxy;
int proxy_port;
char *proxy_string;
#include "server-connect-rec.h"
/* server where we want to connect */
char *address;
int port;
char *ircnet;
IPADDR *own_ip;
char *password;
char *nick;
char *username;
char *realname;
/* when reconnecting, the old server status */
int reconnection:1; /* we're trying to reconnect */
char *channels;
char *away_reason;
char *usermode;
/* -- IRC specific - change if you wish -- */
char *alternate_nick;
int max_cmds_at_once;
@ -46,48 +31,14 @@ typedef struct {
int max_kicks, max_msgs, max_modes, max_whois;
} IRC_SERVER_CONNECT_REC;
#define STRUCT_SERVER_CONNECT_REC IRC_SERVER_CONNECT_REC
typedef struct {
/* -- GENERIC SERVER_REC - don't change! -- */
int type; /* server type */
#include "server-rec.h"
IRC_SERVER_CONNECT_REC *connrec;
time_t connect_time; /* connection time */
time_t real_connect_time; /* time when server replied that we really are connected */
char *tag; /* tag name for addressing server */
char *nick; /* current nick */
int connected:1; /* connected to server */
int connection_lost:1; /* Connection lost unintentionally */
void *handle; /* NET_SENDBUF_REC socket */
int readtag; /* input tag */
/* for net_connect_nonblock() */
int connect_pipe[2];
int connect_tag;
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* */
void *rawlog;
void *buffer; /* receive buffer */
GHashTable *module_data;
char *version; /* server version - taken from 004 event */
char *away_reason;
int usermode_away:1;
int banned:1; /* not allowed to connect to this server */
/* -- IRC specific - change if you wish -- */
char *real_address; /* address the irc server gives */
char *usermode; /* The whole mode string .. */
char *userhost; /* /USERHOST <nick> - set when joined to first channel */
char *last_invite; /* channel where you were last invited */
int server_operator:1;
int whois_coming:1; /* Mostly just to display away message right.. */
int whois_found:1; /* Did WHOIS return any entries? */
@ -132,13 +83,10 @@ typedef struct {
time_t lag_last_check; /* last time we checked lag */
int lag; /* server lag in milliseconds */
GSList *channels;
GSList *queries;
GSList *rejoin_channels; /* try to join to these channels after a while -
channels go here if they're "temporarily unavailable"
because of netsplits */
gpointer chanqueries;
void *chanqueries;
} IRC_SERVER_REC;
IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn);
@ -147,9 +95,6 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn);
like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */
char *irc_server_get_channels(IRC_SERVER_REC *server);
/* INTERNAL: Free memory used by connection record */
void irc_server_connect_free(IRC_SERVER_CONNECT_REC *rec);
void irc_servers_init(void);
void irc_servers_deinit(void);

View file

@ -22,65 +22,49 @@
#include "misc.h"
#include "special-vars.h"
#include "settings.h"
#include "window-item-def.h"
#include "irc.h"
#include "irc-server.h"
#include "irc-servers.h"
#include "channels.h"
#include "query.h"
#include "queries.h"
static char *last_privmsg_from;
static char *last_sent_msg, *last_sent_msg_body;
static char *last_join, *last_public_from;
/* last person who sent you a MSG */
static char *expando_lastmsg(void *server, void *item, int *free_ret)
static char *expando_lastmsg(SERVER_REC *server, void *item, int *free_ret)
{
return last_privmsg_from;
}
/* last person to whom you sent a MSG */
static char *expando_lastmymsg(void *server, void *item, int *free_ret)
static char *expando_lastmymsg(SERVER_REC *server, void *item, int *free_ret)
{
return last_sent_msg;
}
/* last person to join a channel you are on */
static char *expando_lastjoin(void *server, void *item, int *free_ret)
static char *expando_lastjoin(SERVER_REC *server, void *item, int *free_ret)
{
return last_join;
}
/* last person to send a public message to a channel you are on */
static char *expando_lastpublic(void *server, void *item, int *free_ret)
static char *expando_lastpublic(SERVER_REC *server, void *item, int *free_ret)
{
return last_public_from;
}
/* text of your AWAY message, if any */
static char *expando_awaymsg(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->away_reason;
}
/* body of last MSG you sent */
static char *expando_lastmymsg_body(void *server, void *item, int *free_ret)
static char *expando_lastmymsg_body(SERVER_REC *server, void *item, int *free_ret)
{
return last_sent_msg_body;
}
/* current channel */
static char *expando_channel(void *server, void *item, int *free_ret)
{
CHANNEL_REC *channel;
channel = irc_item_channel(item);
return channel == NULL ? NULL : channel->name;
}
/* current server numeric being processed */
static char *expando_server_numeric(void *server, void *item, int *free_ret)
static char *expando_server_numeric(SERVER_REC *server, void *item, int *free_ret)
{
return current_server_event == NULL ||
!is_numeric(current_server_event, 0) ? NULL :
@ -88,90 +72,30 @@ static char *expando_server_numeric(void *server, void *item, int *free_ret)
}
/* channel you were last INVITEd to */
static char *expando_last_invite(void *server, void *item, int *free_ret)
static char *expando_last_invite(SERVER_REC *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
IRC_SERVER_REC *ircserver = IRC_SERVER(server);
return ircserver == NULL ? "" : ircserver->last_invite;
}
/* modes of current channel, if any */
static char *expando_chanmode(void *server, void *item, int *free_ret)
{
CHANNEL_REC *channel;
channel = irc_item_channel(item);
return channel == NULL ? NULL : channel->mode;
}
/* current nickname */
static char *expando_nick(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->nick;
}
/* value of STATUS_OPER if you are an irc operator */
static char *expando_statusoper(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL || !ircserver->server_operator ? "" :
(char *) settings_get_str("STATUS_OPER");
}
/* if you are a channel operator in $C, expands to a '@' */
static char *expando_chanop(void *server, void *item, int *free_ret)
{
CHANNEL_REC *channel;
channel = irc_item_channel(item);
if (channel == NULL) return NULL;
return channel->chanop ? "@" : "";
}
/* nickname of whomever you are QUERYing */
static char *expando_query(void *server, void *item, int *free_ret)
{
QUERY_REC *query;
query = irc_item_query(item);
return query == NULL ? NULL : query->nick;
}
/* version of current server */
static char *expando_serverversion(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->version;
}
/* current server name */
static char *expando_servername(void *server, void *item, int *free_ret)
static char *expando_servername(SERVER_REC *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
IRC_SERVER_REC *ircserver = IRC_SERVER(server);
return ircserver == NULL ? "" : ircserver->real_address;
}
/* target of current input (channel or QUERY nickname) */
static char *expando_target(void *server, void *item, int *free_ret)
{
if (!irc_item_check(item))
return NULL;
return ((WI_IRC_REC *) item)->name;
}
/* your /userhost $N address (user@host) */
static char *expando_userhost(void *server, void *item, int *free_ret)
static char *expando_userhost(SERVER_REC *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
IRC_SERVER_REC *ircserver;
const char *username;
char hostname[100];
ircserver = IRC_SERVER(server);
/* prefer the _real_ /userhost reply */
if (ircserver != NULL && ircserver->userhost != NULL)
return ircserver->userhost;
@ -188,31 +112,8 @@ static char *expando_userhost(void *server, void *item, int *free_ret)
return g_strconcat(username, "@", hostname, NULL);;
}
/* value of REALNAME */
static char *expando_realname(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->connrec->realname;
}
/* Server tag */
static char *expando_servertag(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->tag;
}
/* Server ircnet */
static char *expando_ircnet(void *server, void *item, int *free_ret)
{
IRC_SERVER_REC *ircserver = server;
return ircserver == NULL ? "" : ircserver->connrec->ircnet;
}
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
static void event_privmsg(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr)
{
char *params, *target, *msg;
@ -238,9 +139,12 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server)
g_return_if_fail(data != NULL);
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &msg))
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
&target, &msg))
return;
if (*target != '\0' && *msg != '\0' && !ischannel(*target) && isalpha(*target)) {
if (*target != '\0' && *msg != '\0' &&
!ischannel(*target) && isalpha(*target)) {
g_free_not_null(last_sent_msg);
g_free_not_null(last_sent_msg_body);
last_sent_msg = g_strdup(target);
@ -250,7 +154,8 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server)
cmd_params_free(free_arg);
}
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
static void event_join(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *address)
{
g_return_if_fail(nick != NULL);
@ -262,8 +167,6 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
void irc_special_vars_init(void)
{
settings_add_str("misc", "STATUS_OPER", "*");
last_privmsg_from = NULL;
last_sent_msg = NULL; last_sent_msg_body = NULL;
last_join = NULL; last_public_from = NULL;
@ -272,23 +175,11 @@ void irc_special_vars_init(void)
expando_create(".", expando_lastmymsg);
expando_create(":", expando_lastjoin);
expando_create(";", expando_lastpublic);
expando_create("A", expando_awaymsg);
expando_create("B", expando_lastmymsg_body);
expando_create("C", expando_channel);
expando_create("H", expando_server_numeric);
expando_create("I", expando_last_invite);
expando_create("M", expando_chanmode);
expando_create("N", expando_nick);
expando_create("O", expando_statusoper);
expando_create("P", expando_chanop);
expando_create("Q", expando_query);
expando_create("R", expando_serverversion);
expando_create("S", expando_servername);
expando_create("T", expando_target);
expando_create("X", expando_userhost);
expando_create("Y", expando_realname);
expando_create("tag", expando_servertag);
expando_create("ircnet", expando_ircnet);
signal_add("event privmsg", (SIGNAL_FUNC) event_privmsg);
signal_add("event join", (SIGNAL_FUNC) event_join);
@ -305,23 +196,11 @@ void irc_special_vars_deinit(void)
expando_destroy(".", expando_lastmymsg);
expando_destroy(":", expando_lastjoin);
expando_destroy(";", expando_lastpublic);
expando_destroy("A", expando_awaymsg);
expando_destroy("B", expando_lastmymsg_body);
expando_destroy("C", expando_channel);
expando_destroy("H", expando_server_numeric);
expando_destroy("I", expando_last_invite);
expando_destroy("M", expando_chanmode);
expando_destroy("N", expando_nick);
expando_destroy("O", expando_statusoper);
expando_destroy("P", expando_chanop);
expando_destroy("Q", expando_query);
expando_destroy("R", expando_serverversion);
expando_destroy("S", expando_servername);
expando_destroy("T", expando_target);
expando_destroy("X", expando_userhost);
expando_destroy("Y", expando_realname);
expando_destroy("tag", expando_servertag);
expando_destroy("ircnet", expando_ircnet);
signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg);
signal_remove("event join", (SIGNAL_FUNC) event_join);

View file

@ -26,9 +26,9 @@
#include "rawlog.h"
#include "irc.h"
#include "irc-server.h"
#include "channels.h"
#include "server-redirect.h"
#include "irc-servers.h"
#include "irc-channels.h"
#include "servers-redirect.h"
char *current_server_event;
static int signal_send_command;
@ -355,31 +355,29 @@ static void irc_init_server(IRC_SERVER_REC *server)
static char *irc_cmd_get_func(const char *data, int *count, va_list *vargs)
{
WI_IRC_REC *item;
CHANNEL_REC *channel;
IRC_CHANNEL_REC *channel;
char *ret, *args, *chan, *p;
if ((*count & PARAM_FLAG_OPTCHAN) == 0)
return g_strdup(data);
*count &= ~PARAM_FLAG_OPTCHAN;
item = (WI_IRC_REC *) va_arg(*vargs, WI_IRC_REC *);
channel = irc_item_channel(item);
channel = (void *) va_arg(*vargs, void *);
channel = IRC_CHANNEL(channel);
/* change first argument in data to full channel name. */
p = args = g_strdup(data);
chan = isoptchan(args) ? cmd_get_param(&args) : NULL;
if (chan != NULL && *chan == '!') {
if (chan != NULL && *chan == '!' && channel != NULL) {
/* whenever trying to send something to !channel,
change it to the real joined !XXXXXchannel */
channel = channel_find(channel->server, chan);
channel = irc_channel_find(channel->server, chan);
if (channel != NULL) chan = channel->name;
}
if (chan == NULL || strcmp(chan, "*") == 0) {
if (chan == NULL || strcmp(chan, "*") == 0)
chan = channel == NULL ? "*" : channel->name;
}
ret = g_strconcat(chan, " ", args, NULL);
g_free(p);

View file

@ -1,8 +1,7 @@
#ifndef __IRC_H
#define __IRC_H
#include "modules.h"
#include "irc-server.h"
#include "irc-servers.h"
/* From ircd 2.9.5:
none I line with ident
@ -26,46 +25,7 @@
(a) == '!' || /* secure */ \
(a) == '+') /* modeless */
/* values returned by module_category() */
enum {
WI_IRC_CHANNEL,
WI_IRC_QUERY
};
/* *MUST* have the same contents as WI_ITEM_REC in same order. */
typedef struct {
int type;
GHashTable *module_data;
IRC_SERVER_REC *server;
char *name;
int new_data;
int last_color;
} WI_IRC_REC;
/* return TRUE if `item' is an IRC type. */
#define irc_item_check(item) \
(item != NULL && module_find_id("IRC", ((WI_IRC_REC *) (item))->type) != -1)
/* return `item' type, or -1 if it's not IRC type. */
#define irc_item_get(item) \
(item == NULL ? -1 : module_find_id("IRC", ((WI_IRC_REC *) (item))->type))
/* Return `item' if it's channel, NULL if it isn't. */
#define irc_item_channel(item) \
(item != NULL && module_find_id("IRC", ((WI_IRC_REC *) (item))->type) == WI_IRC_CHANNEL ? \
(void *) (item) : NULL)
/* Return `item' if it's query, NULL if it isn't. */
#define irc_item_query(item) \
(item != NULL && module_find_id("IRC", ((WI_IRC_REC *) (item))->type) == WI_IRC_QUERY ? \
(void *) (item) : NULL)
/* Return `item' if it's DCC chat, NULL if it isn't. */
#define irc_item_dcc_chat(item) \
(item != NULL && module_find_id("IRC", ((WI_IRC_REC *) (item))->type) == WI_IRC_DCC_CHAT ? \
(void *) (item) : NULL)
#define IS_IRC_ITEM(rec) (IS_IRC_CHANNEL(rec) || IS_IRC_QUERY(rec))
extern char *current_server_event; /* current server event being processed */

View file

@ -1,184 +0,0 @@
/*
ircnet-setup.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 "network.h"
#include "signals.h"
#include "lib-config/iconfig.h"
#include "settings.h"
#include "irc-server.h"
#include "ircnet-setup.h"
#include "special-vars.h"
GSList *ircnets; /* list of available ircnets */
static void ircnet_config_add(IRCNET_REC *ircnet)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("ircnets", TRUE);
iconfig_node_set_str(node, ircnet->name, NULL);
node = config_node_section(node, ircnet->name, NODE_TYPE_BLOCK);
iconfig_node_set_str(node, "nick", ircnet->nick);
iconfig_node_set_str(node, "username", ircnet->username);
iconfig_node_set_str(node, "realname", ircnet->realname);
iconfig_node_set_str(node, "host", ircnet->own_host);
iconfig_node_set_str(node, "autosendcmd", ircnet->autosendcmd);
if (ircnet->max_cmds_at_once > 0)
config_node_set_int(node, "cmdmax", ircnet->max_cmds_at_once);
if (ircnet->cmd_queue_speed > 0)
config_node_set_int(node, "cmdspeed", ircnet->cmd_queue_speed);
if (ircnet->max_kicks > 0)
config_node_set_int(node, "max_kicks", ircnet->max_kicks);
if (ircnet->max_msgs > 0)
config_node_set_int(node, "max_msgs", ircnet->max_msgs);
if (ircnet->max_modes > 0)
config_node_set_int(node, "max_modes", ircnet->max_modes);
if (ircnet->max_whois > 0)
config_node_set_int(node, "max_whois", ircnet->max_whois);
}
static void ircnet_config_remove(IRCNET_REC *ircnet)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("ircnets", FALSE);
if (node != NULL) iconfig_node_set_str(node, ircnet->name, NULL);
}
void ircnet_create(IRCNET_REC *ircnet)
{
if (g_slist_find(ircnets, ircnet) == NULL)
ircnets = g_slist_append(ircnets, ircnet);
ircnet_config_add(ircnet);
}
static void ircnet_destroy_rec(IRCNET_REC *ircnet)
{
ircnets = g_slist_remove(ircnets, ircnet);
g_free(ircnet->name);
g_free_not_null(ircnet->nick);
g_free_not_null(ircnet->username);
g_free_not_null(ircnet->realname);
g_free_not_null(ircnet->own_host);
g_free_not_null(ircnet->autosendcmd);
g_free(ircnet);
}
void ircnet_destroy(IRCNET_REC *ircnet)
{
ircnet_config_remove(ircnet);
ircnet_destroy_rec(ircnet);
}
/* Find the irc network by name */
IRCNET_REC *ircnet_find(const char *name)
{
GSList *tmp;
g_return_val_if_fail(name != NULL, NULL);
for (tmp = ircnets; tmp != NULL; tmp = tmp->next) {
IRCNET_REC *rec = tmp->data;
if (g_strcasecmp(rec->name, name) == 0)
return rec;
}
return NULL;
}
static IRCNET_REC *ircnet_add(CONFIG_NODE *node)
{
IRCNET_REC *rec;
g_return_val_if_fail(node != NULL, NULL);
if (node->key == NULL) return NULL;
rec = g_new0(IRCNET_REC, 1);
rec->name = g_strdup(node->key);
rec->nick = g_strdup(config_node_get_str(node, "nick", NULL));
rec->username = g_strdup(config_node_get_str(node, "username", NULL));
rec->realname = g_strdup(config_node_get_str(node, "realname", NULL));
rec->own_host = g_strdup(config_node_get_str(node, "host", NULL));
rec->autosendcmd = g_strdup(config_node_get_str(node, "autosendcmd", NULL));
rec->max_cmds_at_once = config_node_get_int(node, "cmdmax", 0);
rec->cmd_queue_speed = config_node_get_int(node, "cmdspeed", 0);
rec->max_kicks = config_node_get_int(node, "max_kicks", 0);
rec->max_msgs = config_node_get_int(node, "max_msgs", 0);
rec->max_modes = config_node_get_int(node, "max_modes", 0);
rec->max_whois = config_node_get_int(node, "max_whois", 0);
ircnets = g_slist_append(ircnets, rec);
return rec;
}
static void read_ircnets(void)
{
CONFIG_NODE *node;
GSList *tmp;
while (ircnets != NULL)
ircnet_destroy_rec(ircnets->data);
/* read ircnets */
node = iconfig_node_traverse("ircnets", FALSE);
if (node != NULL) {
for (tmp = node->value; tmp != NULL; tmp = tmp->next)
ircnet_add(tmp->data);
}
}
static void sig_connected(IRC_SERVER_REC *server)
{
IRCNET_REC *ircnet;
if (server->connrec->ircnet == NULL) return;
ircnet = ircnet_find(server->connrec->ircnet);
if (ircnet != NULL && ircnet->autosendcmd)
eval_special_string(ircnet->autosendcmd, "", server, NULL);
}
void ircnets_setup_init(void)
{
read_ircnets();
signal_add("setup reread", (SIGNAL_FUNC) read_ircnets);
signal_add("event connected", (SIGNAL_FUNC) sig_connected);
}
void ircnets_setup_deinit(void)
{
while (ircnets != NULL)
ircnet_destroy(ircnets->data);
signal_remove("setup reread", (SIGNAL_FUNC) read_ircnets);
signal_remove("event connected", (SIGNAL_FUNC) sig_connected);
}

View file

@ -1,33 +0,0 @@
#ifndef __IRCNET_SETUP_H
#define __IRCNET_SETUP_H
typedef struct {
char *name;
char *nick;
char *username;
char *realname;
char *own_host; /* address to use when connecting this server */
char *autosendcmd; /* command to send after connecting to this ircnet */
IPADDR *own_ip; /* resolved own_address if not NULL */
int max_cmds_at_once;
int cmd_queue_speed;
/* max. number of kicks/msgs/mode/whois per command */
int max_kicks, max_msgs, max_modes, max_whois;
} IRCNET_REC;
extern GSList *ircnets; /* list of available ircnets */
void ircnet_create(IRCNET_REC *ircnet);
void ircnet_destroy(IRCNET_REC *ircnet);
/* Find the irc network by name */
IRCNET_REC *ircnet_find(const char *name);
void ircnets_setup_init(void);
void ircnets_setup_deinit(void);
#endif

View file

@ -24,7 +24,7 @@
#include "settings.h"
#include "irc.h"
#include "irc-server.h"
#include "irc-servers.h"
typedef struct {
IRC_SERVER_REC *server;
@ -130,7 +130,7 @@ static int sig_check_lag(void)
IRC_SERVER_REC *rec = tmp->data;
next = tmp->next;
if (!irc_server_check(rec))
if (!IS_IRC_SERVER(rec))
continue;
if (rec->lag_sent != 0) {

View file

@ -1,15 +0,0 @@
#ifndef __MASKS_H
#define __MASKS_H
#define IRC_MASK_NICK 0x01
#define IRC_MASK_USER 0x02
#define IRC_MASK_HOST 0x04
#define IRC_MASK_DOMAIN 0x08
int irc_mask_match(const char *mask, const char *nick, const char *user, const char *host);
int irc_mask_match_address(const char *mask, const char *nick, const char *address);
int irc_masks_match(const char *masks, const char *nick, const char *address);
char *irc_get_mask(const char *nick, const char *address, int flags);
#endif

View file

@ -22,10 +22,10 @@
#include "signals.h"
#include "settings.h"
#include "channels.h"
#include "irc.h"
#include "irc-servers.h"
#include "irc-channels.h"
#include "nicklist.h"
#include "irc-server.h"
static int massjoin_tag;
static int massjoin_max_joins;
@ -33,10 +33,11 @@ static int massjoin_max_joins;
/* Massjoin support - really useful when trying to do things (like op/deop)
to people after netjoins. It sends
"massjoin #channel nick!user@host nick2!user@host ..." signals */
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
static void event_join(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *address)
{
char *params, *channel, *ptr;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
NICK_REC *nickrec;
GSList *nicks, *tmp;
@ -52,12 +53,12 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
if (ptr != NULL) *ptr = '\0';
/* find channel */
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
g_free(params);
if (chanrec == NULL) return;
/* add user to nicklist */
nickrec = nicklist_insert(chanrec, nick, FALSE, FALSE, TRUE);
nickrec = nicklist_insert(CHANNEL(chanrec), nick, FALSE, FALSE, TRUE);
nickrec->host = g_strdup(address);
if (chanrec->massjoins == 0) {
@ -69,7 +70,7 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
if (nickrec->realname == NULL) {
/* Check if user is already in some other channel,
get the realname and other stuff from there */
nicks = nicklist_get_same(server, nick);
nicks = nicklist_get_same(SERVER(server), nick);
for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
NICK_REC *rec = tmp->next->data;
@ -86,10 +87,11 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
chanrec->massjoins++;
}
static void event_part(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
static void event_part(const char *data, IRC_SERVER_REC *server,
const char *nick, const char *addr)
{
char *params, *channel, *reason;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
NICK_REC *nickrec;
g_return_if_fail(data != NULL);
@ -102,28 +104,29 @@ static void event_part(const char *data, IRC_SERVER_REC *server, const char *nic
params = event_get_params(data, 2, &channel, &reason);
/* find channel */
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec == NULL) {
g_free(params);
return;
}
/* remove user from nicklist */
nickrec = nicklist_find(chanrec, nick);
nickrec = nicklist_find(CHANNEL(chanrec), nick);
if (nickrec != NULL) {
if (nickrec->send_massjoin) {
/* quick join/part after which it's useless to send
nick in massjoin */
chanrec->massjoins--;
}
nicklist_remove(chanrec, nickrec);
nicklist_remove(CHANNEL(chanrec), nickrec);
}
g_free(params);
}
static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nick)
static void event_quit(const char *data, IRC_SERVER_REC *server,
const char *nick)
{
CHANNEL_REC *channel;
IRC_CHANNEL_REC *channel;
NICK_REC *nickrec;
GSList *nicks, *tmp;
@ -135,7 +138,7 @@ static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nic
}
/* Remove nick from all channels */
nicks = nicklist_get_same(server, nick);
nicks = nicklist_get_same(SERVER(server), nick);
for (tmp = nicks; tmp != NULL; tmp = tmp->next->next) {
channel = tmp->data;
nickrec = tmp->next->data;
@ -145,7 +148,7 @@ static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nic
send nick in massjoin */
channel->massjoins--;
}
nicklist_remove(channel, nickrec);
nicklist_remove(CHANNEL(channel), nickrec);
}
g_slist_free(nicks);
}
@ -153,7 +156,7 @@ static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nic
static void event_kick(const char *data, IRC_SERVER_REC *server)
{
char *params, *channel, *nick, *reason;
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
NICK_REC *nickrec;
g_return_if_fail(data != NULL);
@ -167,15 +170,17 @@ static void event_kick(const char *data, IRC_SERVER_REC *server)
}
/* Remove user from nicklist */
chanrec = channel_find(server, channel);
nickrec = chanrec == NULL ? NULL : nicklist_find(chanrec, nick);
chanrec = irc_channel_find(server, channel);
nickrec = chanrec == NULL ? NULL :
nicklist_find(CHANNEL(chanrec), nick);
if (chanrec != NULL && nickrec != NULL) {
if (nickrec->send_massjoin) {
/* quick join/kick after which it's useless to
send nick in massjoin */
chanrec->massjoins--;
}
nicklist_remove(chanrec, nickrec);
nicklist_remove(CHANNEL(chanrec), nickrec);
}
g_free(params);
@ -190,7 +195,7 @@ static void massjoin_send_hash(gpointer key, NICK_REC *nick, GSList **list)
}
/* Send channel's massjoin list signal */
static void massjoin_send(CHANNEL_REC *channel)
static void massjoin_send(IRC_CHANNEL_REC *channel)
{
GSList *list;
@ -208,9 +213,9 @@ static void server_check_massjoins(IRC_SERVER_REC *server, time_t max)
/* Scan all channels through for massjoins */
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data;
IRC_CHANNEL_REC *rec = tmp->data;
if (rec->massjoins <= 0)
if (!IS_IRC_CHANNEL(rec) || rec->massjoins <= 0)
continue;
if (rec->massjoin_start < max || /* We've waited long enough */
@ -234,7 +239,7 @@ static int sig_massjoin_timeout(void)
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
IRC_SERVER_REC *server = tmp->data;
if (irc_server_check(server))
if (IS_IRC_SERVER(server))
server_check_massjoins(server, max);
}

View file

@ -43,7 +43,7 @@ void banlist_free(GSList *banlist)
ban_free(&banlist, banlist->data);
}
BAN_REC *banlist_add(CHANNEL_REC *channel, const char *ban,
BAN_REC *banlist_add(IRC_CHANNEL_REC *channel, const char *ban,
const char *nick, time_t time)
{
BAN_REC *rec;
@ -79,7 +79,7 @@ static BAN_REC *banlist_find(GSList *list, const char *ban)
return NULL;
}
void banlist_remove(CHANNEL_REC *channel, const char *ban)
void banlist_remove(IRC_CHANNEL_REC *channel, const char *ban)
{
BAN_REC *rec;
@ -93,7 +93,7 @@ void banlist_remove(CHANNEL_REC *channel, const char *ban)
}
}
BAN_REC *banlist_exception_add(CHANNEL_REC *channel, const char *ban,
BAN_REC *banlist_exception_add(IRC_CHANNEL_REC *channel, const char *ban,
const char *nick, time_t time)
{
BAN_REC *rec;
@ -113,7 +113,7 @@ BAN_REC *banlist_exception_add(CHANNEL_REC *channel, const char *ban,
return rec;
}
void banlist_exception_remove(CHANNEL_REC *channel, const char *ban)
void banlist_exception_remove(IRC_CHANNEL_REC *channel, const char *ban)
{
BAN_REC *rec;
@ -127,7 +127,7 @@ void banlist_exception_remove(CHANNEL_REC *channel, const char *ban)
}
}
static void invitelist_free(CHANNEL_REC *channel)
static void invitelist_free(IRC_CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
@ -135,7 +135,7 @@ static void invitelist_free(CHANNEL_REC *channel)
g_slist_free(channel->invitelist);
}
void invitelist_add(CHANNEL_REC *channel, const char *mask)
void invitelist_add(IRC_CHANNEL_REC *channel, const char *mask)
{
g_return_if_fail(channel != NULL);
g_return_if_fail(mask != NULL);
@ -145,7 +145,7 @@ void invitelist_add(CHANNEL_REC *channel, const char *mask)
signal_emit("invitelist new", 2, channel, mask);
}
void invitelist_remove(CHANNEL_REC *channel, const char *mask)
void invitelist_remove(IRC_CHANNEL_REC *channel, const char *mask)
{
GSList *tmp;
@ -160,7 +160,7 @@ void invitelist_remove(CHANNEL_REC *channel, const char *mask)
channel->invitelist = g_slist_remove(channel->invitelist, tmp->data);
}
static void channel_destroyed(CHANNEL_REC *channel)
static void channel_destroyed(IRC_CHANNEL_REC *channel)
{
g_return_if_fail(channel != NULL);
@ -171,14 +171,14 @@ static void channel_destroyed(CHANNEL_REC *channel)
static void event_banlist(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, *ban, *setby, *tims;
time_t tim;
g_return_if_fail(data != NULL);
params = event_get_params(data, 5, NULL, &channel, &ban, &setby, &tims);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL) {
tim = (time_t) atol(tims);
banlist_add(chanrec, ban, setby, tim);
@ -188,14 +188,14 @@ static void event_banlist(const char *data, IRC_SERVER_REC *server)
static void event_ebanlist(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, *ban, *setby, *tims;
time_t tim;
g_return_if_fail(data != NULL);
params = event_get_params(data, 5, NULL, &channel, &ban, &setby, &tims);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL) {
tim = (time_t) atol(tims);
banlist_exception_add(chanrec, ban, setby, tim);
@ -205,13 +205,13 @@ static void event_ebanlist(const char *data, IRC_SERVER_REC *server)
static void event_invite_list(const char *data, IRC_SERVER_REC *server)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, *invite;
g_return_if_fail(data != NULL);
params = event_get_params(data, 3, NULL, &channel, &invite);
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL)
invitelist_add(chanrec, invite);

View file

@ -1,7 +1,7 @@
#ifndef __MODE_LISTS_H
#define __MODE_LISTS_H
#include "channels.h"
#include "irc-channels.h"
typedef struct {
char *ban;
@ -9,14 +9,14 @@ typedef struct {
time_t time;
} BAN_REC;
BAN_REC *banlist_add(CHANNEL_REC *channel, const char *ban, const char *nick, time_t time);
void banlist_remove(CHANNEL_REC *channel, const char *ban);
BAN_REC *banlist_add(IRC_CHANNEL_REC *channel, const char *ban, const char *nick, time_t time);
void banlist_remove(IRC_CHANNEL_REC *channel, const char *ban);
BAN_REC *banlist_exception_add(CHANNEL_REC *channel, const char *ban, const char *nick, time_t time);
void banlist_exception_remove(CHANNEL_REC *channel, const char *ban);
BAN_REC *banlist_exception_add(IRC_CHANNEL_REC *channel, const char *ban, const char *nick, time_t time);
void banlist_exception_remove(IRC_CHANNEL_REC *channel, const char *ban);
void invitelist_add(CHANNEL_REC *channel, const char *mask);
void invitelist_remove(CHANNEL_REC *channel, const char *mask);
void invitelist_add(IRC_CHANNEL_REC *channel, const char *mask);
void invitelist_remove(IRC_CHANNEL_REC *channel, const char *mask);
void mode_lists_init(void);
void mode_lists_deinit(void);

View file

@ -28,15 +28,15 @@
#include "nicklist.h"
/* Change nick's mode in channel */
static void nick_mode_change(CHANNEL_REC *channel, const char *nick,
static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick,
const char mode, int type)
{
NICK_REC *nickrec;
g_return_if_fail(channel != NULL);
g_return_if_fail(IS_IRC_CHANNEL(channel));
g_return_if_fail(nick != NULL);
nickrec = nicklist_find(channel, nick);
nickrec = nicklist_find(CHANNEL(channel), nick);
if (nickrec == NULL) return; /* No /names list got yet */
if (mode == '@') nickrec->op = type == '+';
@ -185,22 +185,22 @@ static void mode_set_arg(GString *str, char type, char mode, const char *arg)
mode_add_sorted(str, mode, arg);
}
int channel_mode_is_set(CHANNEL_REC *channel, char mode)
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode)
{
g_return_val_if_fail(channel != NULL, FALSE);
g_return_val_if_fail(IS_IRC_CHANNEL(channel), FALSE);
return channel->mode == NULL ? FALSE :
mode_is_set(channel->mode, mode);
}
/* Parse channel mode string */
void parse_channel_modes(CHANNEL_REC *channel, const char *setby,
void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
const char *mode)
{
GString *newmode;
char *dup, *modestr, *arg, *curmode, type;
g_return_if_fail(channel != NULL);
g_return_if_fail(IS_IRC_CHANNEL(channel));
g_return_if_fail(mode != NULL);
type = '+';
@ -336,7 +336,7 @@ static void parse_user_mode(IRC_SERVER_REC *server, const char *modestr)
{
char *newmode, *oldmode;
g_return_if_fail(server != NULL);
g_return_if_fail(IS_IRC_SERVER(server));
g_return_if_fail(modestr != NULL);
newmode = modes_join(server->usermode, modestr);
@ -360,21 +360,23 @@ static void event_user_mode(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
static void event_mode(const char *data, IRC_SERVER_REC *server, const char *nick)
static void event_mode(const char *data, IRC_SERVER_REC *server,
const char *nick)
{
CHANNEL_REC *chanrec;
IRC_CHANNEL_REC *chanrec;
char *params, *channel, *mode;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &channel, &mode);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST,
&channel, &mode);
if (!ischannel(*channel)) {
/* user mode change */
parse_user_mode(server, mode);
} else {
/* channel mode change */
chanrec = channel_find(server, channel);
chanrec = irc_channel_find(server, channel);
if (chanrec != NULL)
parse_channel_modes(chanrec, nick, mode);
}
@ -406,10 +408,8 @@ void channel_set_singlemode(IRC_SERVER_REC *server, const char *channel,
int num, modepos;
char **nick, **nicklist;
g_return_if_fail(server != NULL);
g_return_if_fail(channel != NULL);
g_return_if_fail(nicks != NULL);
g_return_if_fail(mode != NULL);
g_return_if_fail(IS_IRC_SERVER(server));
g_return_if_fail(channel != NULL && nicks != NULL && mode != NULL);
if (*nicks == '\0') return;
num = modepos = 0;
@ -450,9 +450,8 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
GString *tmode, *targs;
int count;
g_return_if_fail(server != NULL);
g_return_if_fail(channel != NULL);
g_return_if_fail(mode != NULL);
g_return_if_fail(IS_IRC_SERVER(server));
g_return_if_fail(channel != NULL && mode != NULL);
tmode = g_string_new(NULL);
targs = g_string_new(NULL);
@ -468,7 +467,8 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
if (count == server->max_modes_in_cmd &&
HAS_MODE_ARG(type, *curmode)) {
irc_send_cmdv(server, "MODE %s %s%s", channel, tmode->str, targs->str);
irc_send_cmdv(server, "MODE %s %s%s",
channel, tmode->str, targs->str);
count = 0;
g_string_truncate(tmode, 0);
@ -486,21 +486,24 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel,
}
}
if (tmode->len > 0)
irc_send_cmdv(server, "MODE %s %s%s", channel, tmode->str, targs->str);
if (tmode->len > 0) {
irc_send_cmdv(server, "MODE %s %s%s",
channel, tmode->str, targs->str);
}
g_string_free(tmode, TRUE);
g_string_free(targs, TRUE);
g_free(orig);
}
static char *get_nicks(WI_IRC_REC *item, const char *data, int op, int voice)
static char *get_nicks(IRC_CHANNEL_REC *channel,
const char *data, int op, int voice)
{
GString *str;
GSList *nicks, *tmp;
char **matches, **match, *ret;
g_return_val_if_fail(item != NULL, NULL);
g_return_val_if_fail(channel != NULL, NULL);
g_return_val_if_fail(data != NULL, NULL);
if (*data == '\0') return NULL;
@ -514,7 +517,7 @@ static char *get_nicks(WI_IRC_REC *item, const char *data, int op, int voice)
}
/* wildcards */
nicks = nicklist_find_multiple((CHANNEL_REC *) item, data);
nicks = nicklist_find_multiple(CHANNEL(channel), data);
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
NICK_REC *rec = tmp->data;
@ -522,7 +525,7 @@ static char *get_nicks(WI_IRC_REC *item, const char *data, int op, int voice)
(voice == 1 && !rec->voice) || (voice == 0 && rec->voice))
continue;
if (g_strcasecmp(rec->nick, item->server->nick) == 0)
if (g_strcasecmp(rec->nick, channel->server->nick) == 0)
continue;
g_string_sprintfa(str, "%s ", rec->nick);
@ -537,69 +540,74 @@ static char *get_nicks(WI_IRC_REC *item, const char *data, int op, int voice)
}
/* SYNTAX: OP <nicks> */
static void cmd_op(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_op(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
char *nicks;
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(channel))
return;
nicks = get_nicks(item, data, 0, -1);
nicks = get_nicks(channel, data, 0, -1);
if (nicks != NULL && *nicks != '\0')
channel_set_singlemode(server, item->name, nicks, "+o");
channel_set_singlemode(server, channel->name, nicks, "+o");
g_free_not_null(nicks);
}
/* SYNTAX: DEOP <nicks> */
static void cmd_deop(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_deop(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
char *nicks;
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(channel))
return;
nicks = get_nicks(item, data, 1, -1);
nicks = get_nicks(channel, data, 1, -1);
if (nicks != NULL && *nicks != '\0')
channel_set_singlemode(server, item->name, nicks, "-o");
channel_set_singlemode(server, channel->name, nicks, "-o");
g_free_not_null(nicks);
}
/* SYNTAX: VOICE <nicks> */
static void cmd_voice(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_voice(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
char *nicks;
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(channel))
return;
nicks = get_nicks(item, data, 0, 0);
nicks = get_nicks(channel, data, 0, 0);
if (nicks != NULL && *nicks != '\0')
channel_set_singlemode(server, item->name, nicks, "+v");
channel_set_singlemode(server, channel->name, nicks, "+v");
g_free_not_null(nicks);
}
/* SYNTAX: DEVOICE <nicks> */
static void cmd_devoice(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_devoice(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
char *nicks;
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(channel))
return;
nicks = get_nicks(item, data, 0, 1);
nicks = get_nicks(channel, data, 0, 1);
if (nicks != NULL && *nicks != '\0')
channel_set_singlemode(server, item->name, nicks, "-v");
channel_set_singlemode(server, channel->name, nicks, "-v");
g_free_not_null(nicks);
}
/* SYNTAX: MODE <your nick>|<channel> [<mode> [<mode parameters>]] */
static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
static void cmd_mode(const char *data, IRC_SERVER_REC *server,
IRC_CHANNEL_REC *channel)
{
char *target, *mode;
void *free_arg;
g_return_if_fail(data != NULL);
if (server == NULL || !server->connected || !irc_server_check(server))
if (server == NULL || !server->connected || !IS_IRC_SERVER(server))
cmd_return_error(CMDERR_NOT_CONNECTED);
if (*data == '+' || *data == '-') {
@ -612,10 +620,10 @@ static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
}
if (strcmp(target, "*") == 0) {
if (!irc_item_channel(item))
if (!IS_IRC_CHANNEL(channel))
cmd_param_error(CMDERR_NOT_JOINED);
target = item->name;
target = channel->name;
}
if (*target == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

View file

@ -1,8 +1,8 @@
#ifndef __MODES_H
#define __MODES_H
#include "server.h"
#include "channels.h"
#include "irc-servers.h"
#include "irc-channels.h"
/* modes that have argument always */
#define HAS_MODE_ARG_ALWAYS(mode) \
@ -26,9 +26,9 @@ void modes_deinit(void);
/* add `mode' to `old' - return newly allocated mode. */
char *modes_join(const char *old, const char *mode);
int channel_mode_is_set(CHANNEL_REC *channel, char mode);
int channel_mode_is_set(IRC_CHANNEL_REC *channel, char mode);
void parse_channel_modes(CHANNEL_REC *channel, const char *setby,
void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby,
const char *modestr);
void channel_set_singlemode(IRC_SERVER_REC *server, const char *channel,

View file

@ -19,12 +19,11 @@
*/
#include "module.h"
#include "modules.h"
#include "signals.h"
#include "commands.h"
#include "misc.h"
#include "irc-server.h"
#include "irc-servers.h"
#include "netsplit.h"
/* How long to keep netsplits in memory (seconds) */
@ -284,7 +283,7 @@ static void sig_disconnected(IRC_SERVER_REC *server)
{
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
g_hash_table_foreach(server->splits, (GHFunc) netsplit_destroy_hash, server);
@ -308,7 +307,7 @@ static int split_check_old(void)
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
IRC_SERVER_REC *server = tmp->data;
if (irc_server_check(server))
if (IS_IRC_SERVER(server))
g_hash_table_foreach_remove(server->splits, (GHRFunc) split_server_check, server);
}

View file

@ -1,48 +0,0 @@
#ifndef __NICKLIST_H
#define __NICKLIST_H
#include "irc-server.h"
#include "channels.h"
typedef struct {
time_t last_check; /* last time gone was checked */
int send_massjoin; /* Waiting to be sent in massjoin signal */
char *nick;
char *host;
char *realname;
int hops;
int op:1;
int halfop:1;
int voice:1;
int gone:1;
int ircop:1;
} NICK_REC;
/* Add new nick to list */
NICK_REC *nicklist_insert(CHANNEL_REC *channel, const char *nick, int op, int voice, int send_massjoin);
/* remove nick from list */
void nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick);
/* Find nick record from list */
NICK_REC *nicklist_find(CHANNEL_REC *channel, const char *mask);
/* Get list of nicks that match the mask */
GSList *nicklist_find_multiple(CHANNEL_REC *channel, const char *mask);
/* Get list of nicks */
GSList *nicklist_getnicks(CHANNEL_REC *channel);
/* Get all the nick records of `nick'. Returns channel, nick, channel, ... */
GSList *nicklist_get_same(IRC_SERVER_REC *server, const char *nick);
/* Nick record comparision for sort functions */
int nicklist_compare(NICK_REC *p1, NICK_REC *p2);
/* Remove all "extra" characters from `nick'. Like _nick_ -> nick */
char *nick_strip(const char *nick);
/* Check is `msg' is meant for `nick'. */
int irc_nick_match(const char *nick, const char *msg);
void nicklist_init(void);
void nicklist_deinit(void);
#endif

View file

@ -1,35 +0,0 @@
#ifndef __QUERY_H
#define __QUERY_H
#include "server.h"
typedef struct {
int type;
GHashTable *module_data;
IRC_SERVER_REC *server;
char *nick;
int new_data;
int last_color;
char *address;
char *server_tag;
int unwanted:1; /* TRUE if the other side closed or some error occured (DCC chats!) */
int destroying:1;
} QUERY_REC;
extern GSList *queries;
QUERY_REC *query_create(IRC_SERVER_REC *server, const char *nick, int automatic);
void query_destroy(QUERY_REC *query);
/* Find query by name, if `server' is NULL, search from all servers */
QUERY_REC *query_find(IRC_SERVER_REC *server, const char *nick);
void query_change_server(QUERY_REC *query, IRC_SERVER_REC *server);
void query_init(void);
void query_deinit(void);
#endif

View file

@ -21,9 +21,9 @@
#include "module.h"
#include "signals.h"
#include "irc-server.h"
#include "irc-servers.h"
#include "server-idle.h"
#include "server-redirect.h"
#include "servers-redirect.h"
#include "irc.h"
typedef struct {
@ -217,7 +217,7 @@ static void sig_disconnected(IRC_SERVER_REC *server)
{
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
if (!IS_IRC_SERVER(server))
return;
while (server->idles != NULL)
@ -232,7 +232,7 @@ static int sig_idle_timeout(void)
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
IRC_SERVER_REC *rec = tmp->data;
if (irc_server_check(rec) &&
if (IS_IRC_SERVER(rec) &&
rec->idles != NULL && rec->cmdcount == 0) {
/* We're idling and we have idle commands to run! */
server_idle_next(rec);

View file

@ -1,7 +1,7 @@
#ifndef __SERVER_IDLE_H
#define __SERVER_IDLE_H
#include "irc-server.h"
#include "irc-servers.h"
/* Add new idle command to queue */
int server_idle_add(IRC_SERVER_REC *server, const char *cmd, const char *arg, int last, ...);

View file

@ -1,391 +0,0 @@
/*
server-reconnect.c : 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 "modules.h"
#include "commands.h"
#include "network.h"
#include "signals.h"
#include "irc.h"
#include "modes.h"
#include "irc-server.h"
#include "server-setup.h"
#include "server-reconnect.h"
#include "settings.h"
GSList *reconnects;
static int last_reconnect_tag;
static int reconnect_timeout_tag;
static int reconnect_time;
static void server_reconnect_add(IRC_SERVER_CONNECT_REC *conn, time_t next_connect)
{
RECONNECT_REC *rec;
rec = g_new(RECONNECT_REC, 1);
rec->tag = ++last_reconnect_tag;
rec->conn = conn;
rec->next_connect = next_connect;
reconnects = g_slist_append(reconnects, rec);
}
static void server_reconnect_destroy(RECONNECT_REC *rec, int free_conn)
{
reconnects = g_slist_remove(reconnects, rec);
signal_emit("server reconnect remove", 1, rec);
if (free_conn) irc_server_connect_free(rec->conn);
g_free(rec);
if (reconnects == NULL)
last_reconnect_tag = 0;
}
static int server_reconnect_timeout(void)
{
IRC_SERVER_CONNECT_REC *conn;
GSList *list, *tmp;
time_t now;
/* If irc_server_connect() removes the next reconnection in queue,
we're screwed. I don't think this should happen anymore, but just
to be sure we don't crash, do this safely. */
list = g_slist_copy(reconnects);
now = time(NULL);
for (tmp = list; tmp != NULL; tmp = tmp->next) {
RECONNECT_REC *rec = tmp->data;
if (g_slist_find(reconnects, rec) == NULL)
continue;
if (rec->next_connect <= now) {
conn = rec->conn;
server_reconnect_destroy(rec, FALSE);
irc_server_connect(conn);
}
}
g_slist_free(list);
return 1;
}
static void sserver_connect(SETUP_SERVER_REC *rec, IRC_SERVER_CONNECT_REC *conn)
{
conn->address = g_strdup(rec->address);
conn->port = rec->port;
server_setup_fill_conn(conn, rec);
if (rec->last_connect > time(NULL)-reconnect_time) {
/* can't reconnect this fast, wait.. */
server_reconnect_add(conn, rec->last_connect+reconnect_time);
} else {
/* connect to server.. */
irc_server_connect(conn);
}
}
static void server_connect_copy_skeleton(IRC_SERVER_CONNECT_REC *dest, IRC_SERVER_CONNECT_REC *src)
{
dest->proxy = g_strdup(src->proxy);
dest->proxy_port = src->proxy_port;
dest->proxy_string = g_strdup(src->proxy_string);
dest->ircnet = g_strdup(src->ircnet);
dest->nick = g_strdup(src->nick);
dest->username = g_strdup(src->username);
dest->realname = g_strdup(src->realname);
if (src->own_ip != NULL) {
dest->own_ip = g_new(IPADDR, 1);
memcpy(dest->own_ip, src->own_ip, sizeof(IPADDR));
}
dest->cmd_queue_speed = src->cmd_queue_speed;
dest->max_kicks = src->max_kicks;
dest->max_modes = src->max_modes;
dest->max_msgs = src->max_msgs;
}
#define server_should_reconnect(server) \
(irc_server_check(server) && (server)->connection_lost && \
((server)->connrec->ircnet != NULL || !(server)->banned))
static void sig_reconnect(IRC_SERVER_REC *server)
{
IRC_SERVER_CONNECT_REC *conn;
SETUP_SERVER_REC *sserver;
GSList *tmp;
int found, through;
time_t now;
g_return_if_fail(server != NULL);
if (reconnect_time == -1 || !server_should_reconnect(server))
return;
conn = g_new0(IRC_SERVER_CONNECT_REC, 1);
server_connect_copy_skeleton(conn, server->connrec);
/* save the server status */
if (!server->connected) {
conn->channels = g_strdup(server->connrec->channels);
conn->away_reason = g_strdup(server->connrec->away_reason);
conn->usermode = g_strdup(server->connrec->usermode);
} else {
conn->reconnection = TRUE;
conn->channels = irc_server_get_channels(server);
conn->away_reason = !server->usermode_away ? NULL :
g_strdup(server->away_reason);
conn->usermode = g_strdup(server->usermode);
}
sserver = server_setup_find(server->connrec->address,
server->connrec->port);
if (sserver != NULL) {
/* save the last connection time/status */
sserver->last_connect = server->connect_time == 0 ?
time(NULL) : server->connect_time;
sserver->last_failed = !server->connected;
if (server->banned) sserver->banned = TRUE;
}
if (sserver == NULL || conn->ircnet == NULL) {
/* not in any ircnet, just reconnect back to same server */
conn->address = g_strdup(server->connrec->address);
conn->port = server->connrec->port;
conn->password = server->connrec->password == NULL ? NULL :
g_strdup(server->connrec->password);
if (server->connect_time != 0 &&
time(NULL)-server->connect_time > reconnect_time) {
/* there's been enough time since last connection,
reconnect back immediately */
irc_server_connect(conn);
} else {
/* reconnect later.. */
server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) :
server->connect_time) + reconnect_time);
}
return;
}
/* always try to first connect to the first on the list where we
haven't got unsuccessful connection attempts for the last half
an hour. */
now = time(NULL);
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
SETUP_SERVER_REC *rec = tmp->data;
if (rec->ircnet != NULL && g_strcasecmp(conn->ircnet, rec->ircnet) == 0 &&
!rec->banned && (!rec->last_connect || !rec->last_failed ||
rec->last_connect < now-FAILED_RECONNECT_WAIT)) {
sserver_connect(rec, conn);
return;
}
}
/* just try the next server in list */
found = through = FALSE;
for (tmp = setupservers; tmp != NULL; ) {
SETUP_SERVER_REC *rec = tmp->data;
if (!found && g_strcasecmp(rec->address, server->connrec->address) == 0 &&
server->connrec->port == rec->port)
found = TRUE;
else if (found && !rec->banned && rec->ircnet != NULL &&
g_strcasecmp(conn->ircnet, rec->ircnet) == 0) {
sserver_connect(rec, conn);
break;
}
if (tmp->next != NULL) {
tmp = tmp->next;
continue;
}
if (through) {
/* shouldn't happen unless there's no servers in
this ircnet in setup.. */
irc_server_connect_free(conn);
break;
}
tmp = setupservers;
found = through = TRUE;
}
}
/* Remove all servers from reconnect list */
/* SYNTAX: RMRECONNS */
static void cmd_rmreconns(void)
{
while (reconnects != NULL)
server_reconnect_destroy(reconnects->data, TRUE);
}
static RECONNECT_REC *reconnect_find_tag(int tag)
{
GSList *tmp;
for (tmp = reconnects; tmp != NULL; tmp = tmp->next) {
RECONNECT_REC *rec = tmp->data;
if (rec->tag == tag)
return rec;
}
return NULL;
}
/* Try to reconnect immediately */
/* SYNTAX: RECONNECT <tag> */
static void cmd_reconnect(const char *data, IRC_SERVER_REC *server)
{
IRC_SERVER_CONNECT_REC *conn;
RECONNECT_REC *rec;
char *str;
int tag;
if (*data == '\0') {
/* reconnect back to same server */
if (server == NULL) cmd_return_error(CMDERR_NOT_CONNECTED);
str = g_strdup_printf("%s %d %s %s", server->connrec->address,
server->connrec->port, server->connrec->password,
server->connrec->nick);
signal_emit("command server", 2, str, server);
g_free(str);
return;
}
if (g_strncasecmp(data, "RECON-", 6) == 0)
data += 6;
tag = atoi(data);
rec = tag <= 0 ? NULL : reconnect_find_tag(tag);
if (rec == NULL)
signal_emit("server reconnect not found", 1, data);
else {
conn = rec->conn;
server_reconnect_destroy(rec, FALSE);
irc_server_connect(conn);
}
}
static void cmd_disconnect(const char *data, SERVER_REC *server)
{
RECONNECT_REC *rec;
int tag;
if (g_strncasecmp(data, "RECON-", 6) != 0)
return; /* handle only reconnection removing */
rec = sscanf(data+6, "%d", &tag) == 1 && tag > 0 ?
reconnect_find_tag(tag) : NULL;
if (rec == NULL)
signal_emit("server reconnect not found", 1, data);
else
server_reconnect_destroy(rec, TRUE);
}
static int sig_set_user_mode(IRC_SERVER_REC *server)
{
const char *mode;
char *newmode;
if (g_slist_find(servers, server) == NULL)
return 0; /* got disconnected */
mode = server->connrec->usermode;
if (mode == NULL) return 0;
newmode = server->usermode == NULL ? NULL :
modes_join(server->usermode, mode);
if (server->usermode == NULL) {
/* server didn't set user mode, just set the new one */
irc_send_cmdv(server, "MODE %s %s", server->nick, mode);
} else {
if (strcmp(newmode, server->usermode) != 0)
irc_send_cmdv(server, "MODE %s -%s+%s", server->nick, server->usermode, mode);
}
g_free_not_null(newmode);
return 0;
}
static void sig_connected(IRC_SERVER_REC *server)
{
if (!server->connrec->reconnection)
return;
if (server->connrec->channels != NULL)
channels_join(server, server->connrec->channels, TRUE);
if (server->connrec->away_reason != NULL)
signal_emit("command away", 2, server->connrec->away_reason, server, NULL);
if (server->connrec->usermode != NULL) {
/* wait a second and then send the user mode */
g_timeout_add(1000, (GSourceFunc) sig_set_user_mode, server);
}
}
static void read_settings(void)
{
reconnect_time = settings_get_int("server_reconnect_time");
}
void servers_reconnect_init(void)
{
reconnects = NULL;
last_reconnect_tag = 0;
reconnect_timeout_tag = g_timeout_add(1000, (GSourceFunc) server_reconnect_timeout, NULL);
read_settings();
signal_add("server connect failed", (SIGNAL_FUNC) sig_reconnect);
signal_add("server disconnected", (SIGNAL_FUNC) sig_reconnect);
signal_add("event connected", (SIGNAL_FUNC) sig_connected);
command_bind("rmreconns", NULL, (SIGNAL_FUNC) cmd_rmreconns);
command_bind("reconnect", NULL, (SIGNAL_FUNC) cmd_reconnect);
command_bind("disconnect", NULL, (SIGNAL_FUNC) cmd_disconnect);
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
}
void servers_reconnect_deinit(void)
{
g_source_remove(reconnect_timeout_tag);
while (reconnects != NULL)
server_reconnect_destroy(reconnects->data, TRUE);
signal_remove("server connect failed", (SIGNAL_FUNC) sig_reconnect);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_reconnect);
signal_remove("event connected", (SIGNAL_FUNC) sig_connected);
command_unbind("rmreconns", (SIGNAL_FUNC) cmd_rmreconns);
command_unbind("reconnect", (SIGNAL_FUNC) cmd_reconnect);
command_unbind("disconnect", (SIGNAL_FUNC) cmd_disconnect);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
}

View file

@ -1,20 +0,0 @@
#ifndef __SERVER_RECONNECT_H
#define __SERVER_RECONNECT_H
/* wait for half an hour before trying to reconnect to host where last
connection failed */
#define FAILED_RECONNECT_WAIT (60*30)
typedef struct {
int tag;
time_t next_connect;
IRC_SERVER_CONNECT_REC *conn;
} RECONNECT_REC;
extern GSList *reconnects;
void servers_reconnect_init(void);
void servers_reconnect_deinit(void);
#endif

View file

@ -1,464 +0,0 @@
/*
server-setup.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 "network.h"
#include "lib-config/iconfig.h"
#include "settings.h"
#include "irc-server.h"
#include "server-setup.h"
#include "server-reconnect.h"
#include "ircnet-setup.h"
GSList *setupservers; /* list of irc servers */
int source_host_ok; /* Use source_host_ip .. */
IPADDR *source_host_ip; /* Resolved address */
static void get_source_host_ip(void)
{
IPADDR ip;
/* FIXME: This will block! */
if (!source_host_ok) {
source_host_ok = *settings_get_str("hostname") != '\0' &&
net_gethostbyname(settings_get_str("hostname"), &ip) == 0;
if (source_host_ok) {
if (source_host_ip == NULL)
source_host_ip = g_new(IPADDR, 1);
memcpy(source_host_ip, &ip, sizeof(IPADDR));
}
}
}
static void conn_set_ip(IRC_SERVER_CONNECT_REC *conn, IPADDR **own_ip, const char *own_host)
{
IPADDR ip;
if (*own_ip != NULL) {
/* use already resolved IP */
if (conn->own_ip == NULL)
conn->own_ip = g_new(IPADDR, 1);
memcpy(conn->own_ip, *own_ip, sizeof(IPADDR));
return;
}
/* resolve the IP and use it */
if (net_gethostbyname(own_host, &ip) == 0) {
if (conn->own_ip == NULL)
conn->own_ip = g_new(IPADDR, 1);
memcpy(conn->own_ip, &ip, sizeof(IPADDR));
*own_ip = g_new(IPADDR, 1);
memcpy(*own_ip, &ip, sizeof(IPADDR));
}
}
/* Fill information to connection from server setup record */
void server_setup_fill_conn(IRC_SERVER_CONNECT_REC *conn, SETUP_SERVER_REC *sserver)
{
if (sserver->own_host != NULL)
conn_set_ip(conn, &sserver->own_ip, sserver->own_host);
if (sserver->ircnet != NULL && conn->ircnet == NULL)
conn->ircnet = g_strdup(sserver->ircnet);
if (sserver->password != NULL && conn->password == NULL)
conn->password = g_strdup(sserver->password);
if (sserver->cmd_queue_speed > 0)
conn->cmd_queue_speed = sserver->cmd_queue_speed;
if (sserver->max_cmds_at_once > 0)
conn->max_cmds_at_once = sserver->max_cmds_at_once;
}
/* Create server connection record. `address' is required, rest can be NULL */
static IRC_SERVER_CONNECT_REC *
create_addr_conn(const char *address, int port, const
char *password, const char *nick)
{
IRC_SERVER_CONNECT_REC *conn;
SETUP_SERVER_REC *sserver;
IRCNET_REC *ircnet;
g_return_val_if_fail(address != NULL, NULL);
conn = g_new0(IRC_SERVER_CONNECT_REC, 1);
conn->address = g_strdup(address);
conn->port = port > 0 ? port : 6667;
if (password && *password) conn->password = g_strdup(password);
if (nick && *nick) conn->nick = g_strdup(nick);
if (!conn->nick) conn->nick = g_strdup(settings_get_str("default_nick"));
conn->alternate_nick = g_strdup(settings_get_str("alternate_nick"));
conn->username = g_strdup(settings_get_str("user_name"));
conn->realname = g_strdup(settings_get_str("real_name"));
/* proxy settings */
if (settings_get_bool("use_ircproxy")) {
conn->proxy = g_strdup(settings_get_str("proxy_address"));
conn->proxy_port = settings_get_int("proxy_port");
conn->proxy_string = g_strdup(settings_get_str("proxy_string"));
}
/* source IP */
get_source_host_ip();
if (source_host_ok) {
conn->own_ip = g_new(IPADDR, 1);
memcpy(conn->own_ip, source_host_ip, sizeof(IPADDR));
}
/* fill the information from setup */
sserver = server_setup_find(conn->address, conn->port);
if (sserver == NULL) return conn;
if (sserver->port > 0) conn->port = sserver->port;
server_setup_fill_conn(conn, sserver);
sserver->last_connect = time(NULL);
/* fill the rest from IRC network settings */
ircnet = sserver->ircnet == NULL ? NULL : ircnet_find(sserver->ircnet);
if (ircnet == NULL) return conn;
if (ircnet->nick && !(nick && *nick)) {
g_free_and_null(conn->alternate_nick);
g_free(conn->nick);
conn->nick = g_strdup(ircnet->nick);;
}
if (ircnet->username) {
g_free(conn->username);
conn->username = g_strdup(ircnet->username);;
}
if (ircnet->realname) {
g_free(conn->realname);
conn->realname = g_strdup(ircnet->realname);;
}
if (ircnet->max_kicks > 0) conn->max_kicks = ircnet->max_kicks;
if (ircnet->max_msgs > 0) conn->max_msgs = ircnet->max_msgs;
if (ircnet->max_modes > 0) conn->max_modes = ircnet->max_modes;
if (ircnet->max_whois > 0) conn->max_whois = ircnet->max_whois;
if (ircnet->max_cmds_at_once > 0 && sserver->max_cmds_at_once <= 0)
conn->max_cmds_at_once = ircnet->max_cmds_at_once;
if (ircnet->cmd_queue_speed > 0 && sserver->cmd_queue_speed <= 0)
conn->cmd_queue_speed = ircnet->cmd_queue_speed;
if (sserver->own_host == NULL && ircnet->own_host != NULL)
conn_set_ip(conn, &ircnet->own_ip, ircnet->own_host);
return conn;
}
/* Connect to server where last connect succeeded (or we haven't tried to
connect yet). If there's no such server, connect to server where we
haven't connected for the longest time */
static IRC_SERVER_CONNECT_REC *
create_ircnet_conn(const char *dest, int port,
const char *password, const char *nick)
{
SETUP_SERVER_REC *bestrec;
GSList *tmp;
time_t now, besttime;
now = time(NULL);
bestrec = NULL; besttime = now;
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
SETUP_SERVER_REC *rec = tmp->data;
if (rec->ircnet == NULL || g_strcasecmp(rec->ircnet, dest) != 0)
continue;
if (!rec->last_failed) {
bestrec = rec;
break;
}
if (bestrec == NULL || besttime > rec->last_connect) {
bestrec = rec;
besttime = rec->last_connect;
}
}
return bestrec == NULL ? NULL :
create_addr_conn(bestrec->address, port, password, nick);
}
/* Create server connection record. `dest' is required, rest can be NULL.
`dest' is either a server address or irc network */
IRC_SERVER_CONNECT_REC *
irc_server_create_conn(const char *dest, int port,
const char *password, const char *nick)
{
IRC_SERVER_CONNECT_REC *rec;
g_return_val_if_fail(dest != NULL, NULL);
if (ircnet_find(dest) != NULL) {
rec = create_ircnet_conn(dest, port, password, nick);
if (rec != NULL)
return rec;
}
return create_addr_conn(dest, port, password, nick);
}
/* Find matching server from setup. Try to find record with a same port,
but fallback to any server with the same address. */
SETUP_SERVER_REC *server_setup_find(const char *address, int port)
{
SETUP_SERVER_REC *server;
GSList *tmp;
g_return_val_if_fail(address != NULL, NULL);
server = NULL;
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
SETUP_SERVER_REC *rec = tmp->data;
if (g_strcasecmp(rec->address, address) == 0) {
server = rec;
if (rec->port == port)
break;
}
}
return server;
}
/* Find matching server from setup. Ports must match or NULL is returned. */
SETUP_SERVER_REC *server_setup_find_port(const char *address, int port)
{
SETUP_SERVER_REC *rec;
rec = server_setup_find(address, port);
return rec == NULL || rec->port != port ? NULL : rec;
}
static void init_userinfo(void)
{
const char *set, *default_nick, *user_name;
char *str;
/* check if nick/username/realname wasn't read from setup.. */
set = settings_get_str("real_name");
if (set == NULL || *set == '\0') {
str = g_getenv("IRCNAME");
iconfig_set_str("settings", "real_name",
str != NULL ? str : g_get_real_name());
}
/* username */
user_name = settings_get_str("user_name");
if (user_name == NULL || *user_name == '\0') {
str = g_getenv("IRCUSER");
iconfig_set_str("settings", "user_name",
str != NULL ? str : g_get_user_name());
user_name = settings_get_str("user_name");
}
/* nick */
default_nick = settings_get_str("default_nick");
if (default_nick == NULL || *default_nick == '\0') {
str = g_getenv("IRCNICK");
iconfig_set_str("settings", "default_nick",
str != NULL ? str : user_name);
default_nick = settings_get_str("default_nick");
}
/* alternate nick */
set = settings_get_str("alternate_nick");
if (set == NULL || *set == '\0') {
if (strlen(default_nick) < 9)
str = g_strconcat(default_nick, "_", NULL);
else {
str = g_strdup(default_nick);
str[strlen(str)-1] = '_';
}
iconfig_set_str("settings", "alternate_nick", str);
g_free(str);
}
/* host name */
set = settings_get_str("hostname");
if (set == NULL || *set == '\0') {
str = g_getenv("IRCHOST");
if (str != NULL)
iconfig_set_str("settings", "hostname", str);
}
}
void setupserver_config_add(SETUP_SERVER_REC *rec)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("(servers", TRUE);
node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
iconfig_node_set_str(node, "address", rec->address);
iconfig_node_set_str(node, "ircnet", rec->ircnet);
config_node_set_int(node, "port", rec->port);
iconfig_node_set_str(node, "password", rec->password);
iconfig_node_set_str(node, "own_host", rec->own_host);
if (rec->autoconnect)
config_node_set_bool(node, "autoconnect", TRUE);
if (rec->max_cmds_at_once > 0)
config_node_set_int(node, "cmds_max_at_once", rec->max_cmds_at_once);
if (rec->cmd_queue_speed > 0)
config_node_set_int(node, "cmd_queue_speed", rec->cmd_queue_speed);
}
void setupserver_config_remove(SETUP_SERVER_REC *rec)
{
CONFIG_NODE *node;
node = iconfig_node_traverse("servers", FALSE);
if (node != NULL) iconfig_node_list_remove(node, g_slist_index(setupservers, rec));
}
static void setupserver_destroy(SETUP_SERVER_REC *rec)
{
setupservers = g_slist_remove(setupservers, rec);
g_free_not_null(rec->own_host);
g_free_not_null(rec->own_ip);
g_free_not_null(rec->ircnet);
g_free(rec->address);
g_free_not_null(rec->password);
g_free(rec);
}
void server_setup_add(SETUP_SERVER_REC *rec)
{
if (g_slist_find(setupservers, rec) != NULL) {
setupserver_config_remove(rec);
setupservers = g_slist_remove(setupservers, rec);
}
setupservers = g_slist_append(setupservers, rec);
setupserver_config_add(rec);
}
void server_setup_remove(SETUP_SERVER_REC *rec)
{
setupserver_config_remove(rec);
setupserver_destroy(rec);
}
static SETUP_SERVER_REC *setupserver_add_node(CONFIG_NODE *node)
{
SETUP_SERVER_REC *rec;
char *server;
int port;
g_return_val_if_fail(node != NULL, NULL);
server = config_node_get_str(node, "address", NULL);
if (server == NULL) return NULL;
port = config_node_get_int(node, "port", 6667);
if (server_setup_find_port(server, port) != NULL) {
/* already exists - don't let it get there twice or
server reconnects will screw up! */
return NULL;
}
rec = g_new0(SETUP_SERVER_REC, 1);
rec->ircnet = g_strdup(config_node_get_str(node, "ircnet", NULL));
rec->address = g_strdup(server);
rec->password = g_strdup(config_node_get_str(node, "password", NULL));
rec->port = port;
rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
rec->max_cmds_at_once = config_node_get_int(node, "cmds_max_at_once", 0);
rec->cmd_queue_speed = config_node_get_int(node, "cmd_queue_speed", 0);
rec->own_host = g_strdup(config_node_get_str(node, "own_host", 0));
setupservers = g_slist_append(setupservers, rec);
return rec;
}
static void read_servers(void)
{
CONFIG_NODE *node;
GSList *tmp;
while (setupservers != NULL)
setupserver_destroy(setupservers->data);
/* Read servers */
node = iconfig_node_traverse("servers", FALSE);
if (node != NULL) {
for (tmp = node->value; tmp != NULL; tmp = tmp->next)
setupserver_add_node(tmp->data);
}
}
static void read_settings(void)
{
g_free_and_null(source_host_ip);
source_host_ok = FALSE;
get_source_host_ip();
}
void servers_setup_init(void)
{
settings_add_int("server", "server_reconnect_time", 300);
settings_add_str("server", "hostname", "");
settings_add_bool("server", "skip_motd", FALSE);
settings_add_str("server", "default_nick", NULL);
settings_add_str("server", "alternate_nick", NULL);
settings_add_str("server", "user_name", NULL);
settings_add_str("server", "real_name", NULL);
settings_add_bool("ircproxy", "use_ircproxy", FALSE);
settings_add_str("ircproxy", "proxy_address", "");
settings_add_int("ircproxy", "proxy_port", 6667);
settings_add_str("ircproxy", "proxy_string", "CONNECT %s %d");
init_userinfo();
read_servers();
source_host_ip = NULL;
read_settings();
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
signal_add("setup reread", (SIGNAL_FUNC) read_servers);
}
void servers_setup_deinit(void)
{
g_free_not_null(source_host_ip);
while (setupservers != NULL)
setupserver_destroy(setupservers->data);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
signal_remove("setup reread", (SIGNAL_FUNC) read_servers);
}

View file

@ -1,50 +0,0 @@
#ifndef __SERVER_SETUP_H
#define __SERVER_SETUP_H
#include "irc-server.h"
/* servers */
typedef struct {
char *address;
int port;
char *ircnet;
char *password;
int autoconnect;
int max_cmds_at_once; /* override the default if > 0 */
int cmd_queue_speed; /* override the default if > 0 */
char *own_host; /* address to use when connecting this server */
IPADDR *own_ip; /* resolved own_address if not NULL */
time_t last_connect; /* to avoid reconnecting too fast.. */
int last_failed:1; /* if last connection attempt failed */
int banned:1; /* if we're banned from this server */
} SETUP_SERVER_REC;
extern GSList *setupservers; /* list of irc servers */
extern IPADDR *source_host_ip; /* Resolved address */
extern gboolean source_host_ok; /* Use source_host_ip .. */
/* Create server connection record. `dest' is required, rest can be NULL.
`dest' is either a server address or irc network */
IRC_SERVER_CONNECT_REC *
irc_server_create_conn(const char *dest, int port, const char *password, const char *nick);
/* Fill information to connection from server setup record */
void server_setup_fill_conn(IRC_SERVER_CONNECT_REC *conn, SETUP_SERVER_REC *sserver);
void server_setup_add(SETUP_SERVER_REC *rec);
void server_setup_remove(SETUP_SERVER_REC *rec);
/* Find matching server from setup. Try to find record with a same port,
but fallback to any server with the same address. */
SETUP_SERVER_REC *server_setup_find(const char *address, int port);
/* Find matching server from setup. Ports must match or NULL is returned. */
SETUP_SERVER_REC *server_setup_find_port(const char *address, int port);
void servers_setup_init(void);
void servers_setup_deinit(void);
#endif