mirror of
https://github.com/irssi/irssi.git
synced 2026-08-11 21:00:40 +02:00
.. lots of changes ..
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@197 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
bacfcb060c
commit
d3dc9a1307
106 changed files with 4864 additions and 1597 deletions
|
|
@ -55,7 +55,7 @@ char *ban_get_mask(CHANNEL_REC *channel, const char *nick)
|
|||
host = strchr(++user, '@');
|
||||
if (host == NULL) return str;
|
||||
|
||||
if ((int) (host-user) < 10) {
|
||||
if ((int) (host-user) > 10) {
|
||||
/* too long user mask */
|
||||
user[9] = '*';
|
||||
g_memmove(user+10, host, strlen(host)+1);
|
||||
|
|
@ -112,7 +112,7 @@ void ban_set_type(const char *type)
|
|||
void ban_set(CHANNEL_REC *channel, const char *bans)
|
||||
{
|
||||
GString *str;
|
||||
char **ban, **banlist;
|
||||
char **ban, **banlist, *realban;
|
||||
|
||||
g_return_if_fail(bans != NULL);
|
||||
|
||||
|
|
@ -121,19 +121,20 @@ void ban_set(CHANNEL_REC *channel, const char *bans)
|
|||
for (ban = banlist; *ban != NULL; ban++) {
|
||||
if (strchr(*ban, '!') != NULL) {
|
||||
/* explicit ban */
|
||||
g_string_sprintfa(str, " %s", *ban);
|
||||
g_string_sprintfa(str, "%s ", *ban);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ban nick */
|
||||
*ban = ban_get_mask(channel, *ban);
|
||||
if (*ban != NULL) {
|
||||
g_string_sprintfa(str, " %s", *ban);
|
||||
g_free(*ban);
|
||||
realban = ban_get_mask(channel, *ban);
|
||||
if (realban != NULL) {
|
||||
g_string_sprintfa(str, "%s ", realban);
|
||||
g_free(realban);
|
||||
}
|
||||
}
|
||||
g_strfreev(banlist);
|
||||
|
||||
g_string_truncate(str, str->len-1);
|
||||
channel_set_singlemode(channel->server, channel->name, str->str, "+b");
|
||||
g_string_free(str, TRUE);
|
||||
}
|
||||
|
|
@ -169,7 +170,7 @@ static void command_set_ban(const char *data, IRC_SERVER_REC *server, WI_IRC_REC
|
|||
if (server == NULL || !server->connected || !irc_server_check(server))
|
||||
cmd_return_error(CMDERR_NOT_CONNECTED);
|
||||
|
||||
params = cmd_get_params(data, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
|
||||
params = cmd_get_params(data, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST,
|
||||
item, &channel, &nicks);
|
||||
if (!ischannel(*channel)) cmd_param_error(CMDERR_NOT_JOINED);
|
||||
if (*nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,27 @@ static void event_topic(const char *data, IRC_SERVER_REC *server)
|
|||
g_free(params);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
GSList *tmp;
|
||||
int len;
|
||||
|
||||
len = strlen(channel);
|
||||
for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
|
||||
CHANNEL_REC *rec = tmp->data;
|
||||
|
||||
if (rec->joined) continue;
|
||||
|
||||
if (g_strncasecmp(channel, rec->name, len) == 0 &&
|
||||
(len > 20 || rec->name[len] == '\0'))
|
||||
return rec;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
|
||||
{
|
||||
char *params, *channel, *tmp;
|
||||
|
|
@ -120,10 +141,8 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
|
|||
!channel here to !ABCDEchannel */
|
||||
char *shortchan;
|
||||
|
||||
shortchan = g_strdup(channel);
|
||||
sprintf(shortchan, "!%s", channel+6);
|
||||
|
||||
chanrec = channel_find(server, shortchan);
|
||||
shortchan = g_strdup_printf("!%s", channel+6);
|
||||
chanrec = channel_find_unjoined(server, shortchan);
|
||||
if (chanrec != NULL) {
|
||||
g_free(chanrec->name);
|
||||
chanrec->name = g_strdup(channel);
|
||||
|
|
@ -132,11 +151,16 @@ static void event_join(const char *data, IRC_SERVER_REC *server, const char *nic
|
|||
g_free(shortchan);
|
||||
}
|
||||
|
||||
chanrec = channel_find(server, channel);
|
||||
chanrec = channel_find_unjoined(server, channel);
|
||||
if (chanrec == NULL) {
|
||||
/* didn't get here with /join command.. */
|
||||
chanrec = channel_create(server, channel, TRUE);
|
||||
}
|
||||
chanrec->joined = TRUE;
|
||||
if (strcmp(chanrec->name, channel) != 0) {
|
||||
g_free(chanrec->name);
|
||||
chanrec->name = g_strdup(channel);
|
||||
}
|
||||
|
||||
g_free(params);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||
chanrec = tmp->data;
|
||||
|
||||
server_redirect_event((SERVER_REC *) server, chanrec->name, 4,
|
||||
server_redirect_event((SERVER_REC *) server, chanrec->name, 2,
|
||||
"event 403", "chanquery mode abort", 1,
|
||||
"event 349", "chanquery eban end", 1,
|
||||
"event 348", "chanquery eban", 1, NULL);
|
||||
|
|
@ -244,7 +244,7 @@ static void channel_send_query(IRC_SERVER_REC *server, int query)
|
|||
for (tmp = chans; tmp != NULL; tmp = tmp->next) {
|
||||
chanrec = tmp->data;
|
||||
|
||||
server_redirect_event((SERVER_REC *) server, chanrec->name, 4,
|
||||
server_redirect_event((SERVER_REC *) server, chanrec->name, 2,
|
||||
"event 403", "chanquery mode abort", 1,
|
||||
"event 347", "chanquery ilist end", 1,
|
||||
"event 346", "chanquery ilist", 1, NULL);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "nicklist.h"
|
||||
#include "irc-server.h"
|
||||
#include "server-setup.h"
|
||||
#include "special-vars.h"
|
||||
|
||||
#include "lib-config/iconfig.h"
|
||||
#include "settings.h"
|
||||
|
|
@ -33,30 +34,52 @@
|
|||
GSList *setupchannels;
|
||||
|
||||
#define ircnet_match(a, b) \
|
||||
((a[0]) == '\0' || (b != NULL && g_strcasecmp(a, b) == 0))
|
||||
((a) == NULL || (a[0]) == '\0' || (b != NULL && g_strcasecmp(a, b) == 0))
|
||||
|
||||
SETUP_CHANNEL_REC *channels_setup_find(const char *channel, IRC_SERVER_REC *server)
|
||||
static void channel_config_add(SETUP_CHANNEL_REC *channel)
|
||||
{
|
||||
GSList *tmp;
|
||||
CONFIG_NODE *node;
|
||||
|
||||
g_return_val_if_fail(channel != NULL, NULL);
|
||||
g_return_val_if_fail(server != NULL, NULL);
|
||||
node = iconfig_node_traverse("(channels", TRUE);
|
||||
node = config_node_section(node, NULL, NODE_TYPE_BLOCK);
|
||||
|
||||
for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
|
||||
SETUP_CHANNEL_REC *rec = tmp->data;
|
||||
config_node_set_str(node, "name", channel->name);
|
||||
config_node_set_str(node, "ircnet", channel->ircnet);
|
||||
if (channel->autojoin)
|
||||
config_node_set_bool(node, "autojoin", TRUE);
|
||||
config_node_set_str(node, "password", channel->password);
|
||||
config_node_set_str(node, "botmasks", channel->botmasks);
|
||||
config_node_set_str(node, "autosendcmd", channel->autosendcmd);
|
||||
config_node_set_str(node, "background", channel->background);
|
||||
config_node_set_str(node, "font", channel->font);
|
||||
}
|
||||
|
||||
if (g_strcasecmp(rec->name, channel) == 0 &&
|
||||
ircnet_match(rec->ircnet, server->connrec->ircnet))
|
||||
return rec;
|
||||
static void channel_config_remove(SETUP_CHANNEL_REC *channel)
|
||||
{
|
||||
CONFIG_NODE *node;
|
||||
|
||||
node = iconfig_node_traverse("channels", FALSE);
|
||||
if (node != NULL) config_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);
|
||||
|
||||
return NULL;
|
||||
channel_config_add(channel);
|
||||
}
|
||||
|
||||
void channels_setup_destroy(SETUP_CHANNEL_REC *channel)
|
||||
{
|
||||
g_return_if_fail(channel != NULL);
|
||||
|
||||
channel_config_remove(channel);
|
||||
setupchannels = g_slist_remove(setupchannels, channel);
|
||||
|
||||
g_free(channel->name);
|
||||
g_free(channel->ircnet);
|
||||
g_free_not_null(channel->password);
|
||||
|
|
@ -65,16 +88,30 @@ void channels_setup_destroy(SETUP_CHANNEL_REC *channel)
|
|||
g_free_not_null(channel->background);
|
||||
g_free_not_null(channel->font);
|
||||
g_free(channel);
|
||||
}
|
||||
|
||||
setupchannels = g_slist_remove(setupchannels, 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, *keys;
|
||||
GString *chans;
|
||||
GSList *tmp;
|
||||
int use_keys;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
|
|
@ -83,9 +120,6 @@ static void event_connected(IRC_SERVER_REC *server)
|
|||
|
||||
/* join to the channels marked with autojoin in setup */
|
||||
chans = g_string_new(NULL);
|
||||
keys = g_string_new(NULL);
|
||||
|
||||
use_keys = FALSE;
|
||||
for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
|
||||
SETUP_CHANNEL_REC *rec = tmp->data;
|
||||
|
||||
|
|
@ -93,21 +127,14 @@ static void event_connected(IRC_SERVER_REC *server)
|
|||
continue;
|
||||
|
||||
g_string_sprintfa(chans, "%s,", rec->name);
|
||||
g_string_sprintfa(keys, "%s,", rec->password == NULL ? "x" : rec->password);
|
||||
if (rec->password != NULL)
|
||||
use_keys = TRUE;
|
||||
}
|
||||
|
||||
if (chans->len > 0) {
|
||||
g_string_truncate(chans, chans->len-1);
|
||||
g_string_truncate(keys, keys->len-1);
|
||||
if (use_keys) g_string_sprintfa(chans, " %s", keys->str);
|
||||
|
||||
channels_join(server, chans->str, TRUE);
|
||||
}
|
||||
|
||||
g_string_free(chans, TRUE);
|
||||
g_string_free(keys, TRUE);
|
||||
}
|
||||
|
||||
/* channel wholist received: send the auto send command */
|
||||
|
|
@ -115,17 +142,17 @@ static void channel_wholist(CHANNEL_REC *channel)
|
|||
{
|
||||
SETUP_CHANNEL_REC *rec;
|
||||
NICK_REC *nick;
|
||||
char **bots, **bot, *str;
|
||||
char **bots, **bot;
|
||||
|
||||
g_return_if_fail(channel != NULL);
|
||||
|
||||
rec = channels_setup_find(channel->name, channel->server);
|
||||
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. */
|
||||
signal_emit("send command", 3, rec->autosendcmd, channel->server, channel);
|
||||
eval_special_string(rec->autosendcmd, "", channel->server, channel);
|
||||
}
|
||||
|
||||
/* find first available bot.. */
|
||||
|
|
@ -136,9 +163,7 @@ static void channel_wholist(CHANNEL_REC *channel)
|
|||
continue;
|
||||
|
||||
/* got one! */
|
||||
str = g_strdup_printf(rec->autosendcmd, nick->nick);
|
||||
signal_emit("send command", 3, str, channel->server, channel);
|
||||
g_free(str);
|
||||
eval_special_string(rec->autosendcmd, nick->nick, channel->server, channel);
|
||||
break;
|
||||
}
|
||||
g_strfreev(bots);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ 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, IRC_SERVER_REC *server);
|
||||
SETUP_CHANNEL_REC *channels_setup_find(const char *channel, const char *ircnet);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -156,10 +156,12 @@ char *channel_get_mode(CHANNEL_REC *channel)
|
|||
|
||||
void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
||||
{
|
||||
SETUP_CHANNEL_REC *schannel;
|
||||
CHANNEL_REC *chanrec;
|
||||
GString *outchans, *outkeys;
|
||||
char *params, *channels, *keys;
|
||||
char **chanlist, **keylist, **tmp, **tmpkey, *channel;
|
||||
int use_keys;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
if (server == NULL || !server->connected || !irc_server_check(server))
|
||||
|
|
@ -174,19 +176,24 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
|||
outchans = g_string_new(NULL);
|
||||
outkeys = g_string_new(NULL);
|
||||
|
||||
use_keys = *keys != '\0';
|
||||
tmpkey = keylist;
|
||||
for (tmp = chanlist; *tmp != NULL; tmp++) {
|
||||
channel = ischannel(**tmp) ? g_strdup(*tmp) :
|
||||
g_strdup_printf("#%s", *tmp);
|
||||
|
||||
chanrec = channel_find(server, channel);
|
||||
if (chanrec != NULL) {
|
||||
/* already joined this channel */
|
||||
signal_emit("gui channel open", 1, chanrec);
|
||||
} else {
|
||||
if (chanrec == NULL) {
|
||||
schannel = channels_setup_find(channel, server->connrec->ircnet);
|
||||
|
||||
g_string_sprintfa(outchans, "%s,", channel);
|
||||
if (*keys != '\0')
|
||||
if (schannel == NULL || schannel->password == NULL)
|
||||
g_string_sprintfa(outkeys, "%s,", get_join_key(*tmpkey));
|
||||
else {
|
||||
/* get password from setup record */
|
||||
use_keys = TRUE;
|
||||
g_string_sprintfa(outkeys, "%s,", schannel->password);
|
||||
}
|
||||
|
||||
channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic);
|
||||
}
|
||||
|
|
@ -197,7 +204,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic)
|
|||
}
|
||||
|
||||
if (outchans->len > 0) {
|
||||
irc_send_cmdv(server, *keys == '\0' ? "JOIN %s" : "JOIN %s %s",
|
||||
irc_send_cmdv(server, use_keys ? "JOIN %s %s" : "JOIN %s",
|
||||
outchans->str, outkeys->str);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ typedef struct {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ void ctcp_send_reply(IRC_SERVER_REC *server, const char *data)
|
|||
|
||||
if (g_slist_length(server->ctcpqueue) < settings_get_int("max_ctcp_queue")) {
|
||||
/* Add to first in idle queue */
|
||||
tag = server_idle_add_first(server, data, NULL, 0, NULL);
|
||||
tag = server_idle_add(server, data, NULL, 0, NULL);
|
||||
server->ctcpqueue = g_slist_append(server->ctcpqueue, GINT_TO_POINTER(tag));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ static void read_ignores(void)
|
|||
IGNORE_REC *rec;
|
||||
CONFIG_NODE *node;
|
||||
GSList *tmp;
|
||||
char *str;
|
||||
|
||||
while (ignores != NULL)
|
||||
ignore_destroy(ignores->data);
|
||||
|
|
@ -269,8 +270,8 @@ static void read_ignores(void)
|
|||
|
||||
rec->mask = g_strdup(config_node_get_str(node, "mask", NULL));
|
||||
rec->pattern = g_strdup(config_node_get_str(node, "pattern", NULL));
|
||||
rec->level = level2bits(config_node_get_str(node, "level", 0));
|
||||
rec->except_level = level2bits(config_node_get_str(node, "except_level", 0));
|
||||
rec->level = level2bits(config_node_get_str(node, "level", ""));
|
||||
rec->except_level = level2bits(config_node_get_str(node, "except_level", ""));
|
||||
rec->regexp = config_node_get_bool(node, "regexp", FALSE);
|
||||
rec->fullword = config_node_get_bool(node, "fullword", FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "network.h"
|
||||
#include "commands.h"
|
||||
#include "misc.h"
|
||||
#include "special-vars.h"
|
||||
|
|
@ -46,23 +47,35 @@ static IRC_SERVER_REC *connect_server(const char *data)
|
|||
{
|
||||
IRC_SERVER_CONNECT_REC *conn;
|
||||
IRC_SERVER_REC *server;
|
||||
char *params, *addr, *portstr, *password, *nick;
|
||||
int port;
|
||||
char *params, *args, *ircnet, *host, *addr, *portstr, *password, *nick;
|
||||
|
||||
g_return_val_if_fail(data != NULL, NULL);
|
||||
|
||||
params = cmd_get_params(data, 4, &addr, &portstr, &password, &nick);
|
||||
args = "ircnet host";
|
||||
params = cmd_get_params(data, 7 | PARAM_FLAG_MULTIARGS,
|
||||
&args, &ircnet, &host, &addr,
|
||||
&portstr, &password, &nick);
|
||||
if (*addr == '+') addr++;
|
||||
if (*addr == '\0') return NULL;
|
||||
|
||||
if (strcmp(password, "-") == 0)
|
||||
*password = '\0';
|
||||
|
||||
port = 6667;
|
||||
if (*portstr != '\0')
|
||||
sscanf(portstr, "%d", &port);
|
||||
|
||||
/* connect to server */
|
||||
conn = irc_server_create_conn(addr, port, password, nick);
|
||||
conn = irc_server_create_conn(addr, atoi(portstr), password, nick);
|
||||
if (*ircnet != '\0') {
|
||||
g_free_not_null(conn->ircnet);
|
||||
conn->ircnet = g_strdup(ircnet);
|
||||
}
|
||||
if (*host != '\0') {
|
||||
IPADDR ip;
|
||||
|
||||
if (net_gethostname(host, &ip) == 0) {
|
||||
if (conn->own_ip == NULL)
|
||||
conn->own_ip = g_new(IPADDR, 1);
|
||||
memcpy(conn->own_ip, &ip, sizeof(IPADDR));
|
||||
}
|
||||
}
|
||||
server = irc_server_connect(conn);
|
||||
|
||||
g_free(params);
|
||||
|
|
@ -92,6 +105,9 @@ static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
|
|||
if (server == NULL || !irc_server_check(server))
|
||||
cmd_param_error(CMDERR_NOT_CONNECTED);
|
||||
|
||||
if (*msg == '\0') msg = (char *) settings_get_str("quit_message");
|
||||
signal_emit("server quit", 2, server, msg);
|
||||
|
||||
ircserver = (IRC_SERVER_REC *) server;
|
||||
if (ircserver->handle != -1 && ircserver->buffer != NULL) {
|
||||
/* flush transmit queue */
|
||||
|
|
@ -100,8 +116,6 @@ static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
|
|||
ircserver->cmdqueue = NULL;
|
||||
ircserver->cmdcount = 0;
|
||||
|
||||
/* then send quit message */
|
||||
if (*msg == '\0') msg = (char *) settings_get_str("default_quit_message");
|
||||
irc_send_cmdv(ircserver, "QUIT :%s", msg);
|
||||
}
|
||||
g_free(params);
|
||||
|
|
@ -111,12 +125,20 @@ static void cmd_disconnect(const char *data, IRC_SERVER_REC *server)
|
|||
|
||||
static void cmd_server(const char *data, IRC_SERVER_REC *server)
|
||||
{
|
||||
char *params, *args, *ircnetarg, *hostarg, *addr;
|
||||
char *channels, *away_reason, *usermode, *ircnet;
|
||||
int no_old_server;
|
||||
|
||||
g_return_if_fail(data != NULL);
|
||||
if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
|
||||
|
||||
if (*data == '+' || server == NULL) {
|
||||
args = "ircnet host";
|
||||
params = cmd_get_params(data, 4 | PARAM_FLAG_MULTIARGS,
|
||||
&args, &ircnetarg, &hostarg, &addr);
|
||||
if (*addr == '\0' || strcmp(addr, "+") == 0)
|
||||
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
|
||||
|
||||
no_old_server = server == NULL;
|
||||
if (*addr == '+' || server == NULL) {
|
||||
channels = away_reason = usermode = ircnet = NULL;
|
||||
} else {
|
||||
ircnet = g_strdup(server->connrec->ircnet);
|
||||
|
|
@ -129,20 +151,21 @@ static void cmd_server(const char *data, IRC_SERVER_REC *server)
|
|||
cmd_disconnect("* Changing server", server);
|
||||
}
|
||||
|
||||
server = connect_server(data + (*data == '+' ? 1 : 0));
|
||||
if (*data == '+' || server == NULL ||
|
||||
server = connect_server(data);
|
||||
if (*addr == '+' || server == NULL ||
|
||||
(ircnet != NULL && server->connrec->ircnet != NULL &&
|
||||
g_strcasecmp(ircnet, server->connrec->ircnet) != 0)) {
|
||||
g_free_not_null(channels);
|
||||
g_free_not_null(usermode);
|
||||
g_free_not_null(away_reason);
|
||||
} else if (server != NULL) {
|
||||
} else if (server != NULL && !no_old_server) {
|
||||
server->connrec->reconnection = TRUE;
|
||||
server->connrec->channels = channels;
|
||||
server->connrec->usermode = usermode;
|
||||
server->connrec->away_reason = away_reason;
|
||||
}
|
||||
g_free_not_null(ircnet);
|
||||
g_free(params);
|
||||
}
|
||||
|
||||
static void cmd_quit(const char *data)
|
||||
|
|
@ -154,7 +177,7 @@ static void cmd_quit(const char *data)
|
|||
g_return_if_fail(data != NULL);
|
||||
|
||||
quitmsg = *data != '\0' ? data :
|
||||
settings_get_str("default_quit_message");
|
||||
settings_get_str("quit_message");
|
||||
|
||||
/* disconnect from every server */
|
||||
for (tmp = servers; tmp != NULL; tmp = next) {
|
||||
|
|
@ -646,7 +669,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *i
|
|||
if (is_numeric(data, ' ')) {
|
||||
/* first argument is the timeout */
|
||||
params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &timeoutstr, &nick, &reason);
|
||||
timeleft = atol(timeoutstr);
|
||||
timeleft = atoi(timeoutstr);
|
||||
} else {
|
||||
timeleft = 0;
|
||||
params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &nick, &reason);
|
||||
|
|
@ -749,7 +772,7 @@ void irc_commands_init(void)
|
|||
{
|
||||
tmpstr = g_string_new(NULL);
|
||||
|
||||
settings_add_str("misc", "default_quit_message", "leaving");
|
||||
settings_add_str("misc", "quit_message", "leaving");
|
||||
settings_add_int("misc", "knockout_time", 300);
|
||||
|
||||
knockout_tag = g_timeout_add(KNOCKOUT_TIMECHECK, (GSourceFunc) knockout_timeout, NULL);
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ static void event_unaway(const char *data, IRC_SERVER_REC *server)
|
|||
|
||||
void irc_log_init(void)
|
||||
{
|
||||
settings_add_str("misc", "awaylog_file", "~/.irssi/away.log");
|
||||
settings_add_str("misc", "awaylog_level", "msgs hilight");
|
||||
settings_add_str("log", "awaylog_file", "~/.irssi/away.log");
|
||||
settings_add_str("log", "awaylog_level", "msgs hilight");
|
||||
|
||||
signal_add("print text stripped", (SIGNAL_FUNC) sig_log);
|
||||
signal_add("event 306", (SIGNAL_FUNC) event_away);
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ static int sig_set_user_mode(IRC_SERVER_REC *server)
|
|||
if (g_slist_find(servers, server) == NULL)
|
||||
return 0; /* got disconnected */
|
||||
|
||||
mode = settings_get_str("default_user_mode");
|
||||
mode = settings_get_str("usermode");
|
||||
newmode = server->usermode == NULL ? NULL :
|
||||
modes_join(server->usermode, mode);
|
||||
if (server->usermode == NULL || strcmp(newmode, server->usermode) != 0)
|
||||
|
|
@ -369,7 +369,7 @@ static void event_connected(const char *data, IRC_SERVER_REC *server, const char
|
|||
|
||||
if (!server->connrec->reconnection) {
|
||||
/* wait a second and then send the user mode */
|
||||
mode = settings_get_str("default_user_mode");
|
||||
mode = settings_get_str("usermode");
|
||||
if (*mode != '\0')
|
||||
g_timeout_add(1000, (GSourceFunc) sig_set_user_mode, server);
|
||||
}
|
||||
|
|
@ -414,7 +414,7 @@ static void event_empty(void)
|
|||
|
||||
void irc_servers_init(void)
|
||||
{
|
||||
settings_add_str("misc", "default_user_mode", DEFAULT_USER_MODE);
|
||||
settings_add_str("misc", "usermode", DEFAULT_USER_MODE);
|
||||
settings_add_int("flood", "cmd_queue_speed", DEFAULT_CMD_QUEUE_SPEED);
|
||||
settings_add_int("flood", "cmds_max_at_once", DEFAULT_CMDS_MAX_AT_ONCE);
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ typedef struct {
|
|||
|
||||
GSList *lastmsgs; /* List of nicks who last send you msg */
|
||||
GHashTable *splits; /* For keeping track of netsplits */
|
||||
GSList *split_servers; /* Servers that are currently in split */
|
||||
|
||||
time_t lag_sent; /* 0 or time when last lag query was sent to server */
|
||||
time_t lag_last_check; /* last time we checked lag */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ static void cmd_send(IRC_SERVER_REC *server, const char *cmd, int send_now, int
|
|||
/* just check that we don't send any longer commands than 512 bytes.. */
|
||||
strncpy(str, cmd, 510);
|
||||
len = strlen(cmd);
|
||||
if (len > 510) len = 510;
|
||||
str[len++] = 13; str[len++] = 10; str[len] = '\0';
|
||||
|
||||
ptr = str;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ static void read_ircnets(void)
|
|||
|
||||
void ircnets_setup_init(void)
|
||||
{
|
||||
read_ircnets();
|
||||
signal_add("setup reread", (SIGNAL_FUNC) read_ircnets);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "module.h"
|
||||
#include "signals.h"
|
||||
#include "common-setup.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "channels.h"
|
||||
#include "irc.h"
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include "irc-server.h"
|
||||
|
||||
static int massjoin_tag;
|
||||
static int massjoin_max_joins;
|
||||
|
||||
/* Massjoin support - really useful when trying to do things (like op/deop)
|
||||
to people after netjoins. It sends
|
||||
|
|
@ -210,7 +211,7 @@ static void server_check_massjoins(IRC_SERVER_REC *server, time_t max)
|
|||
continue;
|
||||
|
||||
if (rec->massjoin_start < max || /* We've waited long enough */
|
||||
rec->massjoins-5 < rec->last_massjoins) { /* Less than 5 joins since last check */
|
||||
rec->massjoins-massjoin_max_joins < rec->last_massjoins) { /* Less than x joins since last check */
|
||||
/* send them */
|
||||
massjoin_send(rec);
|
||||
} else {
|
||||
|
|
@ -226,21 +227,30 @@ static int sig_massjoin_timeout(void)
|
|||
GSList *tmp;
|
||||
time_t max;
|
||||
|
||||
max = time(NULL)-MAX_MASSJOIN_WAIT;
|
||||
max = time(NULL)-settings_get_int("massjoin_max_wait");
|
||||
for (tmp = servers; tmp != NULL; tmp = tmp->next)
|
||||
server_check_massjoins(tmp->data, max);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
massjoin_max_joins = settings_get_int("massjoin_max_joins");
|
||||
}
|
||||
|
||||
void massjoin_init(void)
|
||||
{
|
||||
settings_add_int("misc", "massjoin_max_wait", 5000);
|
||||
settings_add_int("misc", "massjoin_max_joins", 3);
|
||||
massjoin_tag = g_timeout_add(1000, (GSourceFunc) sig_massjoin_timeout, NULL);
|
||||
|
||||
read_settings();
|
||||
signal_add("event join", (SIGNAL_FUNC) event_join);
|
||||
signal_add("event part", (SIGNAL_FUNC) event_part);
|
||||
signal_add("event kick", (SIGNAL_FUNC) event_kick);
|
||||
signal_add("event quit", (SIGNAL_FUNC) event_quit);
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
}
|
||||
|
||||
void massjoin_deinit(void)
|
||||
|
|
@ -251,4 +261,5 @@ void massjoin_deinit(void)
|
|||
signal_remove("event part", (SIGNAL_FUNC) event_part);
|
||||
signal_remove("event kick", (SIGNAL_FUNC) event_kick);
|
||||
signal_remove("event quit", (SIGNAL_FUNC) event_quit);
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ void parse_channel_modes(CHANNEL_REC *channel, const char *setby, const char *mo
|
|||
ptr = cmd_get_param(&modestr);
|
||||
if (*ptr == '\0') break;
|
||||
|
||||
if (strcmp(channel->server->nick, ptr) == 0)
|
||||
if (g_strcasecmp(channel->server->nick, ptr) == 0)
|
||||
channel->chanop = type == '+' ? TRUE : FALSE;
|
||||
nick_mode_change(channel, ptr, '@', type == '+');
|
||||
break;
|
||||
|
|
@ -297,6 +297,9 @@ void channel_set_singlemode(IRC_SERVER_REC *server, const char *channel, const c
|
|||
|
||||
nicklist = g_strsplit(nicks, " ", -1);
|
||||
for (nick = nicklist; *nick != NULL; nick++) {
|
||||
if (*nick == '\0')
|
||||
continue;
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
g_string_sprintf(str, "MODE %s %s", channel, mode);
|
||||
|
|
@ -373,28 +376,94 @@ void channel_set_mode(IRC_SERVER_REC *server, const char *channel, const char *m
|
|||
g_free(orig);
|
||||
}
|
||||
|
||||
static void cmd_op(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
static char *get_nicks(WI_IRC_REC *item, const char *data, int op, int voice)
|
||||
{
|
||||
if (!irc_item_channel(item)) return;
|
||||
channel_set_singlemode(server, item->name, data, "+o");
|
||||
GString *str;
|
||||
GSList *nicks, *tmp;
|
||||
char **matches, **match, *ret;
|
||||
|
||||
str = g_string_new(NULL);
|
||||
matches = g_strsplit(data, " ", -1);
|
||||
for (match = matches; *match != NULL; match++) {
|
||||
if (strchr(*match, '*') == NULL && strchr(*match, '?') == NULL) {
|
||||
/* no wildcards */
|
||||
g_string_sprintfa(str, "%s ", *match);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* wildcards */
|
||||
nicks = nicklist_find_multiple((CHANNEL_REC *) item, data);
|
||||
for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
|
||||
NICK_REC *rec = tmp->data;
|
||||
|
||||
if ((op == 1 && !rec->op) || (op == 0 && rec->op) ||
|
||||
(voice == 1 && !rec->voice) || (voice == 0 && rec->voice))
|
||||
continue;
|
||||
|
||||
if (g_strcasecmp(rec->nick, item->server->nick) == 0)
|
||||
continue;
|
||||
|
||||
g_string_sprintfa(str, "%s ", rec->nick);
|
||||
}
|
||||
g_slist_free(nicks);
|
||||
}
|
||||
|
||||
g_string_truncate(str, str->len-1);
|
||||
ret = str->str;
|
||||
g_string_free(str, FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cmd_op(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
{
|
||||
char *nicks;
|
||||
|
||||
if (!irc_item_channel(item))
|
||||
return;
|
||||
|
||||
nicks = get_nicks(item, data, 0, -1);
|
||||
if (*nicks != '\0')
|
||||
channel_set_singlemode(server, item->name, nicks, "+o");
|
||||
g_free(nicks);
|
||||
}
|
||||
|
||||
static void cmd_deop(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
{
|
||||
if (!irc_item_channel(item)) return;
|
||||
channel_set_singlemode(server, item->name, data, "-o");
|
||||
char *nicks;
|
||||
|
||||
if (!irc_item_channel(item))
|
||||
return;
|
||||
|
||||
nicks = get_nicks(item, data, 1, -1);
|
||||
if (*nicks != '\0')
|
||||
channel_set_singlemode(server, item->name, nicks, "-o");
|
||||
g_free(nicks);
|
||||
}
|
||||
|
||||
static void cmd_voice(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
{
|
||||
if (!irc_item_channel(item)) return;
|
||||
channel_set_singlemode(server, item->name, data, "+v");
|
||||
char *nicks;
|
||||
|
||||
if (!irc_item_channel(item))
|
||||
return;
|
||||
|
||||
nicks = get_nicks(item, data, 0, 0);
|
||||
if (*nicks != '\0')
|
||||
channel_set_singlemode(server, item->name, nicks, "+v");
|
||||
g_free(nicks);
|
||||
}
|
||||
|
||||
static void cmd_devoice(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
{
|
||||
if (!irc_item_channel(item)) return;
|
||||
channel_set_singlemode(server, item->name, data, "-v");
|
||||
char *nicks;
|
||||
|
||||
if (!irc_item_channel(item))
|
||||
return;
|
||||
|
||||
nicks = get_nicks(item, data, 0, 1);
|
||||
if (*nicks != '\0')
|
||||
channel_set_singlemode(server, item->name, nicks, "-v");
|
||||
g_free(nicks);
|
||||
}
|
||||
|
||||
static void cmd_mode(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,46 @@
|
|||
|
||||
static int split_tag;
|
||||
|
||||
static NETSPLIT_SERVER_REC *netsplit_server_find(IRC_SERVER_REC *server, const char *servername, const char *destserver)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = server->split_servers; tmp != NULL; tmp = tmp->next) {
|
||||
NETSPLIT_SERVER_REC *rec = tmp->data;
|
||||
|
||||
if (g_strcasecmp(rec->server, servername) == 0 &&
|
||||
g_strcasecmp(rec->destserver, destserver) == 0)
|
||||
return rec;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static NETSPLIT_SERVER_REC *netsplit_server_create(IRC_SERVER_REC *server, const char *servername, const char *destserver)
|
||||
{
|
||||
NETSPLIT_SERVER_REC *rec;
|
||||
|
||||
rec = netsplit_server_find(server, servername, destserver);
|
||||
if (rec != NULL) return rec;
|
||||
|
||||
rec = g_new0(NETSPLIT_SERVER_REC, 1);
|
||||
rec->server = g_strdup(servername);
|
||||
rec->destserver = g_strdup(destserver);
|
||||
|
||||
server->split_servers = g_slist_append(server->split_servers, rec);
|
||||
signal_emit("netsplit new server", 1, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void netsplit_destroy_server(IRC_SERVER_REC *server, NETSPLIT_SERVER_REC *rec)
|
||||
{
|
||||
server->split_servers = g_slist_remove(server->split_servers, rec);
|
||||
|
||||
g_free(rec->server);
|
||||
g_free(rec->destserver);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick, const char *address, const char *servers)
|
||||
{
|
||||
NETSPLIT_REC *rec;
|
||||
|
|
@ -41,6 +81,7 @@ static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick, cons
|
|||
g_return_val_if_fail(nick != NULL, NULL);
|
||||
g_return_val_if_fail(address != NULL, NULL);
|
||||
|
||||
/* get splitted servers */
|
||||
dupservers = g_strdup(servers);
|
||||
p = strchr(dupservers, ' ');
|
||||
if (p == NULL) {
|
||||
|
|
@ -54,9 +95,8 @@ static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick, cons
|
|||
rec->address = g_strdup(address);
|
||||
rec->destroy = time(NULL)+NETSPLIT_MAX_REMEMBER;
|
||||
|
||||
/* get splitted servers */
|
||||
rec->server = g_strdup(dupservers);
|
||||
rec->destserver = g_strdup(p);
|
||||
rec->server = netsplit_server_create(server, dupservers, p);
|
||||
rec->server->count++;
|
||||
g_free(dupservers);
|
||||
|
||||
/* copy the channel nick records.. */
|
||||
|
|
@ -75,11 +115,12 @@ static NETSPLIT_REC *netsplit_add(IRC_SERVER_REC *server, const char *nick, cons
|
|||
}
|
||||
|
||||
g_hash_table_insert(server->splits, rec->nick, rec);
|
||||
|
||||
signal_emit("netsplit add", 1, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
static void netsplit_destroy(NETSPLIT_REC *rec)
|
||||
static void netsplit_destroy(IRC_SERVER_REC *server, NETSPLIT_REC *rec)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
|
|
@ -93,16 +134,17 @@ static void netsplit_destroy(NETSPLIT_REC *rec)
|
|||
g_free(rec);
|
||||
}
|
||||
|
||||
g_free(rec->server);
|
||||
g_free(rec->destserver);
|
||||
if (--rec->server->count == 0)
|
||||
netsplit_destroy_server(server, rec->server);
|
||||
|
||||
g_free(rec->nick);
|
||||
g_free(rec->address);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static void netsplit_destroy_hash(gpointer key, NETSPLIT_REC *rec)
|
||||
static void netsplit_destroy_hash(void *key, NETSPLIT_REC *rec, IRC_SERVER_REC *server)
|
||||
{
|
||||
netsplit_destroy(rec);
|
||||
netsplit_destroy(server, rec);
|
||||
}
|
||||
|
||||
NETSPLIT_REC *netsplit_find(IRC_SERVER_REC *server, const char *nick, const char *address)
|
||||
|
|
@ -136,13 +178,15 @@ NICK_REC *netsplit_find_channel(IRC_SERVER_REC *server, const char *nick, const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int is_split(const char *msg)
|
||||
int quitmsg_is_split(const char *msg)
|
||||
{
|
||||
char *params, *host1, *host2, *p;
|
||||
int ok;
|
||||
|
||||
g_return_val_if_fail(msg != NULL, FALSE);
|
||||
|
||||
if (msg[strlen(msg)-1] == ' ') msg[strlen(msg)-1] = '\0'; /*FIXME: remove - for debugging!*/
|
||||
|
||||
/* must have only two words */
|
||||
p = strchr(msg, ' ');
|
||||
if (p == NULL || strchr(p+1, ' ') != NULL) return FALSE;
|
||||
|
|
@ -171,19 +215,19 @@ static int is_split(const char *msg)
|
|||
return ok;
|
||||
}
|
||||
|
||||
static void split_set_timeout(gpointer key, NETSPLIT_REC *rec, NETSPLIT_REC *orig)
|
||||
static void split_set_timeout(void *key, NETSPLIT_REC *rec, NETSPLIT_REC *orig)
|
||||
{
|
||||
if (rec == orig) {
|
||||
/* original nick, destroy it in a few seconds.. */
|
||||
rec->destroy = time(NULL)+4;
|
||||
} else if (g_strcasecmp(rec->server, orig->server) == 0 &&
|
||||
g_strcasecmp(rec->destserver, orig->destserver) == 0) {
|
||||
} else if (g_strcasecmp(rec->server->server, orig->server->server) == 0 &&
|
||||
g_strcasecmp(rec->server->destserver, orig->server->destserver) == 0) {
|
||||
/* same servers -> split over -> destroy old records sooner.. */
|
||||
rec->destroy = time(NULL)+60;
|
||||
}
|
||||
}
|
||||
|
||||
static void event_join(gchar *data, IRC_SERVER_REC *server, gchar *nick, gchar *address)
|
||||
static void event_join(const char *data, IRC_SERVER_REC *server, const char *nick, const char *address)
|
||||
{
|
||||
NETSPLIT_REC *rec;
|
||||
|
||||
|
|
@ -202,7 +246,7 @@ static void event_join(gchar *data, IRC_SERVER_REC *server, gchar *nick, gchar *
|
|||
} else {
|
||||
/* back from different address.. just destroy it. */
|
||||
g_hash_table_remove(server->splits, rec->nick);
|
||||
netsplit_destroy(rec);
|
||||
netsplit_destroy(server, rec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +255,7 @@ static void event_quit(const char *data, IRC_SERVER_REC *server, const char *nic
|
|||
g_return_if_fail(data != NULL);
|
||||
|
||||
if (*data == ':') data++;
|
||||
if (g_strcasecmp(nick, server->nick) != 0 && is_split(data)) {
|
||||
if (g_strcasecmp(nick, server->nick) != 0 && quitmsg_is_split(data)) {
|
||||
/* netsplit! */
|
||||
netsplit_add(server, nick, address, data);
|
||||
}
|
||||
|
|
@ -221,17 +265,17 @@ static void sig_disconnected(IRC_SERVER_REC *server)
|
|||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
g_hash_table_foreach(server->splits, (GHFunc) netsplit_destroy_hash, NULL);
|
||||
g_hash_table_foreach(server->splits, (GHFunc) netsplit_destroy_hash, server);
|
||||
g_hash_table_destroy(server->splits);
|
||||
}
|
||||
|
||||
static int split_server_check(gpointer key, NETSPLIT_REC *rec, IRC_SERVER_REC *server)
|
||||
static int split_server_check(void *key, NETSPLIT_REC *rec, IRC_SERVER_REC *server)
|
||||
{
|
||||
/* Check if this split record is too old.. */
|
||||
if (rec->destroy > time(NULL))
|
||||
return FALSE;
|
||||
|
||||
netsplit_destroy(rec);
|
||||
netsplit_destroy(server, rec);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,16 @@
|
|||
#include "nicklist.h"
|
||||
|
||||
typedef struct {
|
||||
char *nick;
|
||||
char *address;
|
||||
char *server;
|
||||
char *destserver;
|
||||
int count;
|
||||
} NETSPLIT_SERVER_REC;
|
||||
|
||||
typedef struct {
|
||||
NETSPLIT_SERVER_REC *server;
|
||||
|
||||
char *nick;
|
||||
char *address;
|
||||
GSList *channels;
|
||||
|
||||
time_t destroy;
|
||||
|
|
@ -24,4 +30,6 @@ void netsplit_deinit(void);
|
|||
NETSPLIT_REC *netsplit_find(IRC_SERVER_REC *server, const char *nick, const char *address);
|
||||
NICK_REC *netsplit_find_channel(IRC_SERVER_REC *server, const char *nick, const char *address, const char *channel);
|
||||
|
||||
int quitmsg_is_split(const char *msg);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -87,6 +87,22 @@ static NICK_REC *nicklist_find_wildcards(CHANNEL_REC *channel, const char *mask)
|
|||
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 == NULL ? "" : 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)
|
||||
{
|
||||
|
|
@ -230,7 +246,7 @@ static void event_names_list(const char *data, IRC_SERVER_REC *server)
|
|||
while (*names != '\0' && *names != ' ') names++;
|
||||
if (*names != '\0') *names++ = '\0';
|
||||
|
||||
if (*ptr == '@' && strcmp(server->nick, ptr+1) == 0)
|
||||
if (*ptr == '@' && g_strcasecmp(server->nick, ptr+1) == 0)
|
||||
chanrec->chanop = TRUE;
|
||||
|
||||
nicklist_insert(chanrec, ptr+isnickflag(*ptr), *ptr == '@', *ptr == '+', FALSE);
|
||||
|
|
@ -390,7 +406,8 @@ static void event_nick_in_use(const char *data, IRC_SERVER_REC *server)
|
|||
}
|
||||
|
||||
/* nick already in use - need to change it .. */
|
||||
if (strcmp(server->nick, server->connrec->nick) == 0) {
|
||||
if (strcmp(server->nick, server->connrec->nick) == 0 &&
|
||||
server->connrec->alternate_nick != NULL) {
|
||||
/* first try, so try the alternative nick.. */
|
||||
g_free(server->nick);
|
||||
server->nick = g_strdup(server->connrec->alternate_nick);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ NICK_REC *nicklist_insert(CHANNEL_REC *channel, const char *nick, int op, int vo
|
|||
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, ... */
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ static int server_reconnect_timeout(void)
|
|||
|
||||
static void sserver_connect(SETUP_SERVER_REC *rec, IRC_SERVER_CONNECT_REC *conn)
|
||||
{
|
||||
conn->address = g_strdup(rec->server);
|
||||
conn->address = g_strdup(rec->address);
|
||||
conn->port = rec->port;
|
||||
conn->password = rec->password == NULL ? NULL :
|
||||
g_strdup(rec->password);
|
||||
|
|
@ -143,7 +143,6 @@ static void sig_reconnect(IRC_SERVER_REC *server)
|
|||
return;
|
||||
|
||||
conn = g_new0(IRC_SERVER_CONNECT_REC, 1);
|
||||
conn->reconnection = TRUE;
|
||||
server_connect_copy_skeleton(conn, server->connrec);
|
||||
|
||||
/* save the server status */
|
||||
|
|
@ -152,6 +151,7 @@ static void sig_reconnect(IRC_SERVER_REC *server)
|
|||
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);
|
||||
|
|
@ -213,7 +213,7 @@ static void sig_reconnect(IRC_SERVER_REC *server)
|
|||
for (tmp = setupservers; tmp != NULL; ) {
|
||||
SETUP_SERVER_REC *rec = tmp->data;
|
||||
|
||||
if (!found && g_strcasecmp(rec->server, server->connrec->address) == 0 &&
|
||||
if (!found && g_strcasecmp(rec->address, server->connrec->address) == 0 &&
|
||||
server->connrec->port == rec->port)
|
||||
found = TRUE;
|
||||
else if (found && rec->ircnet != NULL && g_strcasecmp(conn->ircnet, rec->ircnet) == 0) {
|
||||
|
|
@ -286,24 +286,36 @@ static RECONNECT_REC *reconnect_find_tag(int tag)
|
|||
}
|
||||
|
||||
/* Try to reconnect immediately */
|
||||
static void cmd_reconnect(const char *data)
|
||||
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;
|
||||
|
||||
rec = sscanf(data, "%d", &tag) == 1 && tag > 0 ?
|
||||
reconnect_find_tag(tag) : NULL;
|
||||
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(rec->conn);
|
||||
irc_server_connect(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ create_addr_conn(const char *address, int port, const char *password,
|
|||
conn->realname = g_strdup(settings_get_str("real_name"));
|
||||
|
||||
/* proxy settings */
|
||||
if (settings_get_bool("toggle_use_ircproxy")) {
|
||||
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"));
|
||||
|
|
@ -91,6 +91,25 @@ create_addr_conn(const char *address, int port, const char *password,
|
|||
sserver = server_setup_find(address, -1);
|
||||
if (sserver == NULL) return conn;
|
||||
|
||||
if (sserver->own_ip != NULL) {
|
||||
/* use already resolved IP */
|
||||
if (conn->own_ip == NULL)
|
||||
conn->own_ip = g_new(IPADDR, 1);
|
||||
memcpy(conn->own_ip, sserver->own_ip, sizeof(IPADDR));
|
||||
} else if (sserver->own_host != NULL) {
|
||||
/* resolve the IP and use it */
|
||||
IPADDR ip;
|
||||
|
||||
if (net_gethostname(sserver->own_host, &ip) == 0) {
|
||||
if (conn->own_ip == NULL)
|
||||
conn->own_ip = g_new(IPADDR, 1);
|
||||
memcpy(conn->own_ip, &ip, sizeof(IPADDR));
|
||||
|
||||
sserver->own_ip = g_new(IPADDR, 1);
|
||||
memcpy(sserver->own_ip, &ip, sizeof(IPADDR));
|
||||
}
|
||||
}
|
||||
|
||||
sserver->last_connect = time(NULL);
|
||||
|
||||
if (sserver->ircnet) conn->ircnet = g_strdup(sserver->ircnet);
|
||||
|
|
@ -151,7 +170,7 @@ irc_server_create_conn(const char *dest, int port, const char *password, const c
|
|||
continue;
|
||||
|
||||
if (n == 1 || !rec->last_failed || rec->last_connect < now-FAILED_RECONNECT_WAIT)
|
||||
return create_addr_conn(rec->server, port, password, nick);
|
||||
return create_addr_conn(rec->address, port, password, nick);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +187,7 @@ SETUP_SERVER_REC *server_setup_find(const char *address, int port)
|
|||
for (tmp = setupservers; tmp != NULL; tmp = tmp->next) {
|
||||
SETUP_SERVER_REC *rec = tmp->data;
|
||||
|
||||
if (g_strcasecmp(rec->server, address) == 0 &&
|
||||
if (g_strcasecmp(rec->address, address) == 0 &&
|
||||
(port == -1 || rec->port == port)) return rec;
|
||||
}
|
||||
|
||||
|
|
@ -223,19 +242,88 @@ static void init_userinfo(void)
|
|||
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);
|
||||
g_free(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SETUP_SERVER_REC *setupserver_add(CONFIG_NODE *node)
|
||||
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);
|
||||
|
||||
config_node_set_str(node, "address", rec->address);
|
||||
config_node_set_str(node, "ircnet", rec->ircnet);
|
||||
|
||||
config_node_set_int(node, "port", rec->port);
|
||||
config_node_set_str(node, "password", rec->password);
|
||||
config_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) config_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(rec->ircnet);
|
||||
g_free(rec->address);
|
||||
g_free(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_append(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 *ircnet, *server;
|
||||
char *server;
|
||||
int port;
|
||||
|
||||
g_return_val_if_fail(node != NULL, NULL);
|
||||
|
||||
ircnet = config_node_get_str(node, "ircnet", NULL);
|
||||
server = config_node_get_str(node, "server", NULL);
|
||||
if (ircnet == NULL || server == NULL) return 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(server, port) != NULL) {
|
||||
|
|
@ -245,28 +333,19 @@ static SETUP_SERVER_REC *setupserver_add(CONFIG_NODE *node)
|
|||
}
|
||||
|
||||
rec = g_new0(SETUP_SERVER_REC, 1);
|
||||
rec->ircnet = g_strdup(ircnet);
|
||||
rec->server = g_strdup(server);
|
||||
rec->password = g_strdup(config_node_get_str(node, "password", ""));
|
||||
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 setupserver_destroy(SETUP_SERVER_REC *rec)
|
||||
{
|
||||
setupservers = g_slist_remove(setupservers, rec);
|
||||
|
||||
g_free(rec->ircnet);
|
||||
g_free(rec->server);
|
||||
g_free(rec->password);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static void read_servers(void)
|
||||
{
|
||||
CONFIG_NODE *node;
|
||||
|
|
@ -276,10 +355,10 @@ static void read_servers(void)
|
|||
setupserver_destroy(setupservers->data);
|
||||
|
||||
/* Read servers */
|
||||
node = iconfig_node_traverse("(setupservers", FALSE);
|
||||
node = iconfig_node_traverse("servers", FALSE);
|
||||
if (node != NULL) {
|
||||
for (tmp = node->value; tmp != NULL; tmp = tmp->next)
|
||||
setupserver_add(tmp->data);
|
||||
setupserver_add_node(tmp->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -290,14 +369,14 @@ void servers_setup_init(void)
|
|||
|
||||
settings_add_int("server", "server_reconnect_time", 300);
|
||||
settings_add_str("server", "hostname", "");
|
||||
settings_add_bool("server", "toggle_skip_motd", FALSE);
|
||||
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", "toggle_use_ircproxy", FALSE);
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
/* servers */
|
||||
typedef struct {
|
||||
char *server;
|
||||
char *address;
|
||||
int port;
|
||||
|
||||
char *ircnet;
|
||||
|
|
@ -14,8 +14,8 @@ typedef struct {
|
|||
int max_cmds_at_once; /* override the default if > 0 */
|
||||
int cmd_queue_speed; /* override the default if > 0 */
|
||||
|
||||
char *own_address; /* address to use when connecting this server */
|
||||
IPADDR *own_ip; /* resolved own_address or full of zeros */
|
||||
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; /* if last connection attempt failed */
|
||||
|
|
@ -31,6 +31,9 @@ extern gboolean source_host_ok; /* Use source_host_ip .. */
|
|||
IRC_SERVER_CONNECT_REC *
|
||||
irc_server_create_conn(const char *dest, int port, const char *password, const char *nick);
|
||||
|
||||
void server_setup_add(SETUP_SERVER_REC *rec);
|
||||
void server_setup_remove(SETUP_SERVER_REC *rec);
|
||||
|
||||
/* Find matching server from setup. Set port to -1 if you don't care about it */
|
||||
SETUP_SERVER_REC *server_setup_find(const char *address, int port);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,4 @@ libirc_dcc_la_SOURCES = \
|
|||
dcc-files.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
dcc.h \
|
||||
dcc-chat.h \
|
||||
dcc-files.h
|
||||
dcc.h
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ static void cmd_dcc_chat(gchar *data, IRC_SERVER_REC *server)
|
|||
if (server == NULL || !server->connected)
|
||||
cmd_return_error(CMDERR_NOT_CONNECTED);
|
||||
|
||||
if (!net_getsockname(server->handle, &addr, NULL))
|
||||
if (net_getsockname(server->handle, &addr, NULL) == -1)
|
||||
cmd_return_error(CMDERR_GETSOCKNAME);
|
||||
|
||||
port = settings_get_int("dcc_port");
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __DCC_CHAT_H
|
||||
#define __DCC_CHAT_H
|
||||
|
||||
void dcc_chat_init(void);
|
||||
void dcc_chat_deinit(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -432,7 +432,7 @@ static void dcc_send_init(DCC_REC *dcc)
|
|||
g_source_remove(dcc->tagread);
|
||||
close(dcc->handle);
|
||||
|
||||
dcc->fastsend = settings_get_bool("toggle_dcc_fast_send");
|
||||
dcc->fastsend = settings_get_bool("dcc_fast_send");
|
||||
dcc->handle = handle;
|
||||
memcpy(&dcc->addr, &addr, sizeof(IPADDR));
|
||||
net_ip2host(&dcc->addr, dcc->addrstr);
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __DCC_FILES_H
|
||||
#define __DCC_FILES_H
|
||||
|
||||
void dcc_files_init(void);
|
||||
void dcc_files_deinit(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -30,6 +30,12 @@
|
|||
|
||||
#include "dcc.h"
|
||||
|
||||
void dcc_chat_init(void);
|
||||
void dcc_chat_deinit(void);
|
||||
|
||||
void dcc_files_init(void);
|
||||
void dcc_files_deinit(void);
|
||||
|
||||
#define DCC_TYPES 5
|
||||
|
||||
static gchar *dcc_types[] =
|
||||
|
|
@ -55,7 +61,7 @@ DCC_REC *dcc_create(gint type, gint handle, gchar *nick, gchar *arg, IRC_SERVER_
|
|||
|
||||
dcc = g_new0(DCC_REC, 1);
|
||||
dcc->type = type == DCC_TYPE_CHAT ? module_get_uniq_id("IRC", WI_IRC_DCC_CHAT) : -1;
|
||||
dcc->mirc_ctcp = settings_get_bool("toggle_dcc_mirc_ctcp");
|
||||
dcc->mirc_ctcp = settings_get_bool("dcc_mirc_ctcp");
|
||||
dcc->created = time(NULL);
|
||||
dcc->chat = chat;
|
||||
dcc->dcc_type = type;
|
||||
|
|
@ -307,7 +313,7 @@ static void dcc_ctcp_msg(gchar *data, IRC_SERVER_REC *server, gchar *sender, gch
|
|||
case DCC_TYPE_GET:
|
||||
cstr = settings_get_str("dcc_autoget_masks");
|
||||
/* check that autoget masks match */
|
||||
if (settings_get_bool("toggle_dcc_autoget") && (*cstr == '\0' || irc_masks_match(cstr, sender, sendaddr)) &&
|
||||
if (settings_get_bool("dcc_autoget") && (*cstr == '\0' || irc_masks_match(cstr, sender, sendaddr)) &&
|
||||
/* check file size limit, FIXME: it's possible to send a bogus file size and then just send what ever sized file.. */
|
||||
(settings_get_int("dcc_max_autoget_size") <= 0 || (settings_get_int("dcc_max_autoget_size") > 0 && size <= settings_get_int("dcc_max_autoget_size")*1024)))
|
||||
{
|
||||
|
|
@ -507,19 +513,19 @@ void dcc_init(void)
|
|||
dcc_conns = NULL;
|
||||
dcc_timeouttag = g_timeout_add(1000, (GSourceFunc) dcc_timeout_func, NULL);
|
||||
|
||||
settings_add_bool("dcc", "toggle_dcc_autorename", FALSE);
|
||||
settings_add_bool("dcc", "toggle_dcc_autogete", FALSE);
|
||||
settings_add_bool("dcc", "dcc_autorename", FALSE);
|
||||
settings_add_bool("dcc", "dcc_autoget", FALSE);
|
||||
settings_add_int("dcc", "dcc_max_autoget_size", 1000);
|
||||
settings_add_str("dcc", "dcc_download_path", "~");
|
||||
settings_add_int("dcc", "dcc_file_create_mode", 644);
|
||||
settings_add_str("dcc", "dcc_autoget_masks", "");
|
||||
settings_add_str("dcc", "dcc_autochat_masks", "");
|
||||
|
||||
settings_add_bool("dcc", "toggle_dcc_fast_send", TRUE);
|
||||
settings_add_bool("dcc", "dcc_fast_send", TRUE);
|
||||
settings_add_str("dcc", "dcc_upload_path", "~");
|
||||
|
||||
settings_add_bool("dcc", "toggle_dcc_mirc_ctcp", FALSE);
|
||||
settings_add_bool("dcc", "toggle_dcc_autodisplay_dialog", TRUE);
|
||||
settings_add_bool("dcc", "dcc_mirc_ctcp", FALSE);
|
||||
settings_add_bool("dcc", "dcc_autodisplay_dialog", TRUE);
|
||||
settings_add_int("dcc", "dcc_block_size", 2048);
|
||||
settings_add_int("dcc", "dcc_port", 0);
|
||||
settings_add_int("dcc", "dcc_timeout", 300);
|
||||
|
|
@ -531,10 +537,16 @@ void dcc_init(void)
|
|||
command_bind("dcc", NULL, (SIGNAL_FUNC) cmd_dcc);
|
||||
command_bind("dcc close", NULL, (SIGNAL_FUNC) cmd_dcc_close);
|
||||
signal_add("event 401", (SIGNAL_FUNC) event_no_such_nick);
|
||||
|
||||
dcc_chat_init();
|
||||
dcc_files_init();
|
||||
}
|
||||
|
||||
void dcc_deinit(void)
|
||||
{
|
||||
dcc_chat_deinit();
|
||||
dcc_files_deinit();
|
||||
|
||||
signal_remove("server connected", (SIGNAL_FUNC) dcc_server_connected);
|
||||
signal_remove("server disconnected", (SIGNAL_FUNC) dcc_server_disconnected);
|
||||
signal_remove("ctcp reply dcc", (SIGNAL_FUNC) dcc_ctcp_reply);
|
||||
|
|
|
|||
|
|
@ -217,11 +217,11 @@ int autoignore_remove(IRC_SERVER_REC *server, const char *mask, int level)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host, const char *levelstr)
|
||||
static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host, gpointer levelp)
|
||||
{
|
||||
int level, check_level;
|
||||
|
||||
level = level2bits(levelstr);
|
||||
level = GPOINTER_TO_INT(levelp);
|
||||
check_level = level2bits(settings_get_str("autoignore_levels"));
|
||||
|
||||
if (level & check_level)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
/*
|
||||
flood.c : Flood protection
|
||||
|
||||
flood.c : Flood protection (see also ctcp.c)
|
||||
|
||||
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
|
||||
|
|
@ -32,36 +31,59 @@
|
|||
#include "ignore.h"
|
||||
|
||||
typedef struct {
|
||||
char *nick;
|
||||
char *target;
|
||||
int level;
|
||||
|
||||
int msgcount;
|
||||
time_t first;
|
||||
} FLOOD_ITEM_REC;
|
||||
|
||||
typedef struct {
|
||||
char *nick;
|
||||
GSList *items;
|
||||
} FLOOD_REC;
|
||||
|
||||
static int flood_tag;
|
||||
static int flood_max_msgs;
|
||||
static int flood_max_msgs, flood_timecheck;
|
||||
|
||||
static int flood_hash_deinit(const char *key, FLOOD_REC *rec)
|
||||
static int flood_hash_deinit(const char *key, FLOOD_REC *flood, gpointer nowp)
|
||||
{
|
||||
g_return_val_if_fail(key != NULL, FALSE);
|
||||
g_return_val_if_fail(rec != NULL, FALSE);
|
||||
GSList *tmp, *next;
|
||||
time_t now;
|
||||
|
||||
g_free(rec->nick);
|
||||
g_free(rec);
|
||||
g_return_val_if_fail(key != NULL, FALSE);
|
||||
g_return_val_if_fail(flood != NULL, FALSE);
|
||||
|
||||
now = (time_t) GPOINTER_TO_INT(nowp);
|
||||
for (tmp = flood->items; tmp != NULL; tmp = next) {
|
||||
FLOOD_ITEM_REC *rec = tmp->data;
|
||||
|
||||
next = tmp->next;
|
||||
if (now-rec->first >= flood_timecheck)
|
||||
flood->items = g_slist_remove(flood->items, rec);
|
||||
}
|
||||
|
||||
if (flood->items != NULL)
|
||||
return FALSE;
|
||||
|
||||
g_free(flood->nick);
|
||||
g_free(flood);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* timeout function: flood protection */
|
||||
static int flood_timeout(void)
|
||||
{
|
||||
MODULE_SERVER_REC *mserver;
|
||||
GSList *tmp;
|
||||
time_t now;
|
||||
|
||||
/* remove everyone from flood list */
|
||||
/* remove the old people from flood lists */
|
||||
now = time(NULL);
|
||||
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
|
||||
IRC_SERVER_REC *rec = tmp->data;
|
||||
|
||||
mserver = MODULE_DATA(rec);
|
||||
g_hash_table_foreach_remove(mserver->floodlist, (GHRFunc) flood_hash_deinit, NULL);
|
||||
g_hash_table_foreach_remove(mserver->floodlist, (GHRFunc) flood_hash_deinit, GINT_TO_POINTER((int) now));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -88,6 +110,8 @@ static void flood_deinit_server(IRC_SERVER_REC *server)
|
|||
|
||||
mserver = MODULE_DATA(server);
|
||||
if (mserver != NULL && mserver->floodlist != NULL) {
|
||||
flood_timecheck = 0;
|
||||
|
||||
g_hash_table_freeze(mserver->floodlist);
|
||||
g_hash_table_foreach(mserver->floodlist, (GHFunc) flood_hash_deinit, NULL);
|
||||
g_hash_table_thaw(mserver->floodlist);
|
||||
|
|
@ -96,34 +120,55 @@ static void flood_deinit_server(IRC_SERVER_REC *server)
|
|||
g_free(mserver);
|
||||
}
|
||||
|
||||
static FLOOD_ITEM_REC *flood_find(FLOOD_REC *flood, int level, const char *target)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = flood->items; tmp != NULL; tmp = tmp->next) {
|
||||
FLOOD_ITEM_REC *rec = tmp->data;
|
||||
|
||||
if (rec->level == level && g_strcasecmp(rec->target, target) == 0)
|
||||
return rec;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* All messages should go through here.. */
|
||||
static void flood_newmsg(IRC_SERVER_REC *server, int level, const char *nick, const char *host, const char *target)
|
||||
{
|
||||
MODULE_SERVER_REC *mserver;
|
||||
FLOOD_REC *rec;
|
||||
char *levelstr;
|
||||
FLOOD_REC *flood;
|
||||
FLOOD_ITEM_REC *rec;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
g_return_if_fail(nick != NULL);
|
||||
|
||||
mserver = MODULE_DATA(server);
|
||||
rec = g_hash_table_lookup(mserver->floodlist, nick);
|
||||
flood = g_hash_table_lookup(mserver->floodlist, nick);
|
||||
|
||||
rec = flood == NULL ? NULL : flood_find(flood, level, target);
|
||||
if (rec != NULL) {
|
||||
if (++rec->msgcount > flood_max_msgs) {
|
||||
/* flooding! */
|
||||
levelstr = bits2level(rec->level);
|
||||
signal_emit("flood", 5, server, nick, host, levelstr, target);
|
||||
g_free(levelstr);
|
||||
signal_emit("flood", 5, server, nick, host, GINT_TO_POINTER(rec->level), target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rec = g_new(FLOOD_REC, 1);
|
||||
rec->level = level;
|
||||
rec->msgcount = 1;
|
||||
rec->nick = g_strdup(nick);
|
||||
if (flood == NULL) {
|
||||
flood = g_new0(FLOOD_REC, 1);
|
||||
flood->nick = g_strdup(nick);
|
||||
g_hash_table_insert(mserver->floodlist, flood->nick, flood);
|
||||
}
|
||||
|
||||
g_hash_table_insert(mserver->floodlist, rec->nick, rec);
|
||||
rec = g_new0(FLOOD_ITEM_REC, 1);
|
||||
rec->level = level;
|
||||
rec->first = time(NULL);
|
||||
rec->msgcount = 1;
|
||||
rec->target = g_strdup(target);
|
||||
|
||||
flood->items = g_slist_append(flood->items, rec);
|
||||
}
|
||||
|
||||
static void flood_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
|
||||
|
|
@ -141,7 +186,7 @@ static void flood_privmsg(const char *data, IRC_SERVER_REC *server, const char *
|
|||
|
||||
params = event_get_params(data, 2, &target, &text);
|
||||
|
||||
if (*text == 1) {
|
||||
if (*text == 1 && g_strncasecmp(text+1, "ACTION", 6) != 0) {
|
||||
/* CTCP */
|
||||
if (!ignore_check(server, nick, addr, target, text, MSGLEVEL_CTCPS))
|
||||
flood_newmsg(server, MSGLEVEL_CTCPS, nick, addr, target);
|
||||
|
|
@ -176,24 +221,37 @@ static void flood_notice(const char *data, IRC_SERVER_REC *server, const char *n
|
|||
|
||||
static void read_settings(void)
|
||||
{
|
||||
if (flood_tag != -1) g_source_remove(flood_tag);
|
||||
flood_tag = g_timeout_add(settings_get_int("flood_timecheck"), (GSourceFunc) flood_timeout, NULL);
|
||||
int time;
|
||||
|
||||
flood_timecheck = settings_get_int("flood_timecheck");
|
||||
flood_max_msgs = settings_get_int("flood_max_msgs");
|
||||
|
||||
time = flood_timecheck > 500 ? 500 :
|
||||
(flood_timecheck > 0 && flood_timecheck < 100) ? 100 :
|
||||
flood_timecheck;
|
||||
|
||||
if (flood_tag != -1) {
|
||||
g_source_remove(flood_tag);
|
||||
flood_tag = -1;
|
||||
}
|
||||
|
||||
if (time > 0 && flood_max_msgs > 0) {
|
||||
flood_tag = g_timeout_add(time, (GSourceFunc) flood_timeout, NULL);
|
||||
signal_add("event privmsg", (SIGNAL_FUNC) flood_privmsg);
|
||||
signal_add("event notice", (SIGNAL_FUNC) flood_notice);
|
||||
}
|
||||
}
|
||||
|
||||
void flood_init(void)
|
||||
{
|
||||
settings_add_int("flood", "flood_timecheck", 1000);
|
||||
settings_add_int("flood", "flood_max_msgs", 5);
|
||||
settings_add_int("flood", "flood_timecheck", 5000);
|
||||
settings_add_int("flood", "flood_max_msgs", 4);
|
||||
|
||||
flood_tag = -1;
|
||||
read_settings();
|
||||
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
signal_add_first("server connected", (SIGNAL_FUNC) flood_init_server);
|
||||
signal_add("server disconnected", (SIGNAL_FUNC) flood_deinit_server);
|
||||
signal_add("event privmsg", (SIGNAL_FUNC) flood_privmsg);
|
||||
signal_add("event notice", (SIGNAL_FUNC) flood_notice);
|
||||
|
||||
autoignore_init();
|
||||
}
|
||||
|
|
@ -202,11 +260,13 @@ void flood_deinit(void)
|
|||
{
|
||||
autoignore_deinit();
|
||||
|
||||
if (flood_tag != -1) g_source_remove(flood_tag);
|
||||
if (flood_tag != -1) {
|
||||
g_source_remove(flood_tag);
|
||||
signal_remove("event privmsg", (SIGNAL_FUNC) flood_privmsg);
|
||||
signal_remove("event notice", (SIGNAL_FUNC) flood_notice);
|
||||
}
|
||||
|
||||
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
||||
signal_remove("server connected", (SIGNAL_FUNC) flood_init_server);
|
||||
signal_remove("server disconnected", (SIGNAL_FUNC) flood_deinit_server);
|
||||
signal_remove("event privmsg", (SIGNAL_FUNC) flood_privmsg);
|
||||
signal_remove("event notice", (SIGNAL_FUNC) flood_notice);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static void cmd_notify(gchar *data)
|
|||
if (stristr(args, "-idle") == NULL)
|
||||
idle_check_time = 0;
|
||||
else {
|
||||
idle_check_time = is_numeric(idletime, 0) ? (atol(idletime)*60) :
|
||||
idle_check_time = is_numeric(idletime, 0) ? (atoi(idletime)*60) :
|
||||
(settings_get_int("notify_idle_time")*60);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static void event_whois_idle(const char *data, IRC_SERVER_REC *server)
|
|||
g_return_if_fail(data != NULL);
|
||||
|
||||
params = event_get_params(data, 3, NULL, &nick, &secstr);
|
||||
secs = atol(secstr);
|
||||
secs = atoi(secstr);
|
||||
|
||||
notify = notifylist_find(nick, server->connrec->ircnet);
|
||||
nickrec = notify_nick_find(server, nick);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue