diff options
Diffstat (limited to 'src/irc')
-rw-r--r-- | src/irc/core/Makefile.am | 1 | ||||
-rw-r--r-- | src/irc/core/channel-events.c | 2 | ||||
-rw-r--r-- | src/irc/core/channel-rejoin.c | 104 | ||||
-rw-r--r-- | src/irc/core/channels.c | 21 | ||||
-rw-r--r-- | src/irc/core/irc-log.c | 16 | ||||
-rw-r--r-- | src/irc/core/irc-server.h | 3 | ||||
-rw-r--r-- | src/irc/core/server-setup.c | 2 | ||||
-rw-r--r-- | src/irc/dcc/dcc-chat.c | 4 | ||||
-rw-r--r-- | src/irc/dcc/dcc-files.c | 4 |
9 files changed, 129 insertions, 28 deletions
diff --git a/src/irc/core/Makefile.am b/src/irc/core/Makefile.am index e0d49197..fa5f5f1f 100644 --- a/src/irc/core/Makefile.am +++ b/src/irc/core/Makefile.am @@ -12,6 +12,7 @@ libirc_core_la_SOURCES = \ channels-query.c \ channels-setup.c \ channel-events.c \ + channel-rejoin.c \ ignore.c \ irc.c \ irc-core.c \ diff --git a/src/irc/core/channel-events.c b/src/irc/core/channel-events.c index 8de80cbd..02af3c0f 100644 --- a/src/irc/core/channel-events.c +++ b/src/irc/core/channel-events.c @@ -54,7 +54,7 @@ static void event_target_unavailable(const char *data, IRC_SERVER_REC *server) params = event_get_params(data, 2, NULL, &channel); if (ischannel(*channel)) { - /* channel is unavailable. */ + /* channel is unavailable - try to join again a bit later */ event_cannot_join(data, server); } diff --git a/src/irc/core/channel-rejoin.c b/src/irc/core/channel-rejoin.c new file mode 100644 index 00000000..89abae0c --- /dev/null +++ b/src/irc/core/channel-rejoin.c @@ -0,0 +1,104 @@ +/* + channel-rejoin.c : rejoin to channel if it's "temporarily unavailable" + this has nothing to do with autorejoin if kicked + + Copyright (C) 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 "misc.h" +#include "channels.h" +#include "irc.h" + +#define REJOIN_TIMEOUT (1000*60*5) /* try to rejoin every 5 minutes */ + +static int rejoin_tag; + +static void channel_rejoin(IRC_SERVER_REC *server, const char *channel) +{ + 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); + + server->rejoin_channels = g_slist_append(server->rejoin_channels, str); +} + +static void event_target_unavailable(const char *data, IRC_SERVER_REC *server) +{ + char *params, *channel; + + g_return_if_fail(data != NULL); + + params = event_get_params(data, 2, NULL, &channel); + if (ischannel(*channel)) { + /* channel is unavailable - try to join again a bit later */ + channel_rejoin(server, channel); + } + + g_free(params); +} + +static void sig_disconnected(IRC_SERVER_REC *server) +{ + g_slist_foreach(server->rejoin_channels, (GFunc) g_free, NULL); + g_slist_free(server->rejoin_channels); +} + +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); + } +} + +static int sig_rejoin(void) +{ + GSList *tmp; + + for (tmp = servers; tmp != NULL; tmp = tmp->next) { + IRC_SERVER_REC *rec = tmp->data; + + if (irc_server_check(rec)) + server_rejoin_channels(rec); + } + + return TRUE; +} + +void channel_rejoin_init(void) +{ + 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); +} + +void channel_rejoin_deinit(void) +{ + g_source_remove(rejoin_tag); + + signal_remove("event 437", (SIGNAL_FUNC) event_target_unavailable); + signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected); +} diff --git a/src/irc/core/channels.c b/src/irc/core/channels.c index 4c50ab7b..6943952e 100644 --- a/src/irc/core/channels.c +++ b/src/irc/core/channels.c @@ -38,6 +38,9 @@ void channels_query_deinit(void); void channel_events_init(void); void channel_events_deinit(void); +void channel_rejoin_init(void); +void channel_rejoin_deinit(void); + void massjoin_init(void); void massjoin_deinit(void); @@ -159,7 +162,7 @@ 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 *params, *channels, *keys, *key; char **chanlist, **keylist, **tmp, **tmpkey, *channel; int use_keys; @@ -187,15 +190,17 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic) schannel = channels_setup_find(channel, server->connrec->ircnet); g_string_sprintfa(outchans, "%s,", channel); - if (schannel == NULL || schannel->password == NULL) - g_string_sprintfa(outkeys, "%s,", get_join_key(*tmpkey)); - else { + if (schannel == NULL || schannel->password == NULL) { + key = *tmpkey == NULL || **tmpkey == '\0' ? NULL : *tmpkey; + } else { /* get password from setup record */ use_keys = TRUE; - g_string_sprintfa(outkeys, "%s,", schannel->password); + key = schannel->password; } - channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic); + g_string_sprintfa(outkeys, "%s,", get_join_key(key)); + chanrec = channel_create(server, channel + (channel[0] == '!' && channel[1] == '!'), automatic); + if (key != NULL) chanrec->key = g_strdup(key); } g_free(channel); @@ -204,6 +209,8 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic) } if (outchans->len > 0) { + g_string_truncate(outchans, outchans->len-1); + g_string_truncate(outkeys, outkeys->len-1); irc_send_cmdv(server, use_keys ? "JOIN %s %s" : "JOIN %s", outchans->str, outkeys->str); } @@ -220,6 +227,7 @@ void channels_join(IRC_SERVER_REC *server, const char *data, int automatic) void channels_init(void) { channel_events_init(); + channel_rejoin_init(); channels_query_init(); channels_setup_init(); @@ -233,6 +241,7 @@ void channels_init(void) void channels_deinit(void) { channel_events_deinit(); + channel_rejoin_deinit(); channels_query_deinit(); channels_setup_deinit(); diff --git a/src/irc/core/irc-log.c b/src/irc/core/irc-log.c index 9871ee64..accf6014 100644 --- a/src/irc/core/irc-log.c +++ b/src/irc/core/irc-log.c @@ -26,20 +26,6 @@ #include "irc-server.h" -static void sig_log(SERVER_REC *server, const char *channel, gpointer level, const char *str) -{ - int loglevel; - - g_return_if_fail(str != NULL); - - loglevel = GPOINTER_TO_INT(level); - if (loglevel == MSGLEVEL_NEVER || logs == NULL) return; - - /* Check if line should be saved in logs */ - log_write(channel, loglevel, str); -} - - static void event_away(const char *data, IRC_SERVER_REC *server) { const char *fname, *levelstr; @@ -93,14 +79,12 @@ void irc_log_init(void) 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); signal_add("event 305", (SIGNAL_FUNC) event_unaway); } void irc_log_deinit(void) { - signal_remove("print text stripped", (SIGNAL_FUNC) sig_log); signal_remove("event 306", (SIGNAL_FUNC) event_away); signal_remove("event 305", (SIGNAL_FUNC) event_unaway); } diff --git a/src/irc/core/irc-server.h b/src/irc/core/irc-server.h index 11172bea..8d780e30 100644 --- a/src/irc/core/irc-server.h +++ b/src/irc/core/irc-server.h @@ -129,6 +129,9 @@ typedef struct { 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; } IRC_SERVER_REC; diff --git a/src/irc/core/server-setup.c b/src/irc/core/server-setup.c index 9c27c101..91bafd81 100644 --- a/src/irc/core/server-setup.c +++ b/src/irc/core/server-setup.c @@ -293,7 +293,7 @@ static void setupserver_destroy(SETUP_SERVER_REC *rec) g_free_not_null(rec->own_ip); g_free(rec->ircnet); g_free(rec->address); - g_free(rec->password); + g_free_not_null(rec->password); g_free(rec); } diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index c01077d3..6a38e93c 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -308,12 +308,12 @@ static void cmd_dcc_chat(gchar *data, IRC_SERVER_REC *server) cmd_return_error(CMDERR_NOT_CONNECTED); if (net_getsockname(server->handle, &addr, NULL) == -1) - cmd_return_error(CMDERR_GETSOCKNAME); + cmd_return_error(CMDERR_ERRNO); port = settings_get_int("dcc_port"); handle = net_listen(&addr, &port); if (handle == -1) - cmd_return_error(CMDERR_LISTEN); + cmd_return_error(CMDERR_ERRNO); dcc = dcc_create(DCC_TYPE_CHAT, handle, data, "chat", server, NULL); dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, diff --git a/src/irc/dcc/dcc-files.c b/src/irc/dcc/dcc-files.c index 8ccdb11a..5acd35c9 100644 --- a/src/irc/dcc/dcc-files.c +++ b/src/irc/dcc/dcc-files.c @@ -513,7 +513,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item) if (net_getsockname(chat != NULL ? chat->handle : server->handle, &addr, NULL) == -1) { close(fh); - cmd_param_error(CMDERR_GETSOCKNAME); + cmd_param_error(CMDERR_ERRNO); } /* start listening */ @@ -522,7 +522,7 @@ static void cmd_dcc_send(gchar *data, IRC_SERVER_REC *server, WI_IRC_REC *item) if (h == -1) { close(fh); - cmd_param_error(CMDERR_LISTEN); + cmd_param_error(CMDERR_ERRNO); } /* skip path */ |