summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2000-11-04 16:54:58 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2000-11-04 16:54:58 +0000
commitcbcf1b07bc35bd2f6617db3c45cd8edefb4a93ca (patch)
treed0f6f22715e5dbee6661f966af765ef69e9d64a0
parent990e2741aa32d934546e369883ccad5fbd5c2bce (diff)
downloadirssi-cbcf1b07bc35bd2f6617db3c45cd8edefb4a93ca.zip
Fixed lag checking when nick was just being changed.
Support for DALnet event 437 "can't change nick while being banned in some channel" which conflicts with ircnet's "nick/channel temporarily unavailable" git-svn-id: http://svn.irssi.org/repos/irssi/trunk@806 dbcabf3a-b0e7-0310-adc4-f8d773084564
-rw-r--r--src/fe-common/irc/fe-events-numeric.c24
-rw-r--r--src/irc/core/channel-rejoin.c14
-rw-r--r--src/irc/core/irc-commands.c60
-rw-r--r--src/irc/core/irc-servers.h1
-rw-r--r--src/irc/core/lag.c11
5 files changed, 88 insertions, 22 deletions
diff --git a/src/fe-common/irc/fe-events-numeric.c b/src/fe-common/irc/fe-events-numeric.c
index fb506d68..7fdbdbbe 100644
--- a/src/fe-common/irc/fe-events-numeric.c
+++ b/src/fe-common/irc/fe-events-numeric.c
@@ -32,6 +32,8 @@
#include "printtext.h"
+static void event_received(const char *data, IRC_SERVER_REC *server);
+
static char *last_away_nick = NULL;
static char *last_away_msg = NULL;
@@ -547,16 +549,25 @@ static void event_end_of_whowas(const char *data, IRC_SERVER_REC *server)
static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
{
char *params, *channel;
+ IRC_CHANNEL_REC *chanrec;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2, NULL, &channel);
if (!ischannel(*channel)) {
/* nick unavailable */
- printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_NICK_UNAVAILABLE, channel);
+ printformat(server, NULL, MSGLEVEL_CRAP,
+ IRCTXT_NICK_UNAVAILABLE, channel);
} else {
- /* channel is unavailable. */
- printformat(server, NULL, MSGLEVEL_CRAP, IRCTXT_JOINERROR_UNAVAIL, channel);
+ chanrec = irc_channel_find(server, channel);
+ if (chanrec != NULL && chanrec->joined) {
+ /* dalnet - can't change nick while being banned */
+ event_received(data, server);
+ } else {
+ /* channel is unavailable. */
+ printformat(server, NULL, MSGLEVEL_CRAP,
+ IRCTXT_JOINERROR_UNAVAIL, channel);
+ }
}
g_free(params);
@@ -667,8 +678,7 @@ static void event_not_chanop(const char *data, IRC_SERVER_REC *server)
g_free(params);
}
-static void event_received(const char *data, IRC_SERVER_REC *server,
- const char *nick, const char *addr)
+static void event_received(const char *data, IRC_SERVER_REC *server)
{
char *params, *args, *ptr;
@@ -760,6 +770,8 @@ void fe_events_numeric_init(void)
signal_add("event 004", (SIGNAL_FUNC) event_received);
signal_add("event 364", (SIGNAL_FUNC) event_received);
signal_add("event 365", (SIGNAL_FUNC) event_received);
+ signal_add("event 432", (SIGNAL_FUNC) event_received);
+ signal_add("event 438", (SIGNAL_FUNC) event_received);
signal_add("event 465", (SIGNAL_FUNC) event_received);
}
@@ -820,5 +832,7 @@ void fe_events_numeric_deinit(void)
signal_remove("event 004", (SIGNAL_FUNC) event_received);
signal_remove("event 364", (SIGNAL_FUNC) event_received);
signal_remove("event 365", (SIGNAL_FUNC) event_received);
+ signal_remove("event 432", (SIGNAL_FUNC) event_received);
+ signal_remove("event 438", (SIGNAL_FUNC) event_received);
signal_remove("event 465", (SIGNAL_FUNC) event_received);
}
diff --git a/src/irc/core/channel-rejoin.c b/src/irc/core/channel-rejoin.c
index 7552efcc..e9b783ed 100644
--- a/src/irc/core/channel-rejoin.c
+++ b/src/irc/core/channel-rejoin.c
@@ -104,14 +104,22 @@ static void channel_rejoin(IRC_SERVER_REC *server, const char *channel)
static void event_target_unavailable(const char *data, IRC_SERVER_REC *server)
{
char *params, *channel;
+ IRC_CHANNEL_REC *chanrec;
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);
- signal_stop();
+ chanrec = irc_channel_find(server, channel);
+ if (chanrec != NULL && chanrec->joined) {
+ /* dalnet event - can't change nick while
+ banned in channel */
+ } else {
+ /* channel is unavailable - try to join again
+ a bit later */
+ channel_rejoin(server, channel);
+ signal_stop();
+ }
}
g_free(params);
diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c
index 12d21219..e1f73b7e 100644
--- a/src/irc/core/irc-commands.c
+++ b/src/irc/core/irc-commands.c
@@ -388,6 +388,46 @@ static void cmd_names(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *ite
irc_send_cmdv(server, "NAMES %s", data);
}
+/* SYNTAX: NICK <new nick> */
+static void cmd_nick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item)
+{
+ char *nick;
+ void *free_arg;
+
+ g_return_if_fail(data != NULL);
+
+ if (!IS_IRC_SERVER(server) || !server->connected)
+ cmd_return_error(CMDERR_NOT_CONNECTED);
+
+ if (!cmd_get_params(data, &free_arg, 1, &nick))
+ return;
+
+ server->nick_changing = TRUE;
+ irc_send_cmdv(server, "NICK %s", nick);
+ server_redirect_event(SERVER(server), nick, 1,
+ "event nick", "nickchange over", -1,
+ "event 433", "nickchange over", 1,
+ /* 437: ircnet = target unavailable,
+ dalnet = banned in channel,
+ can't change nick */
+ "event 437", "nickchange over", -1,
+ "event 432", "nickchange over", 1,
+ "event 438", "nickchange over", 1, NULL);
+ cmd_params_free(free_arg);
+}
+
+static void sig_nickchange_over(const char *data, IRC_SERVER_REC *server,
+ const char *nick, const char *addr)
+{
+ char *signal;
+
+ server->nick_changing = FALSE;
+
+ signal = g_strconcat("event ", current_server_event, NULL);
+ signal_emit(signal, 4, data, server, nick, addr);
+ g_free(signal);
+}
+
static char *get_redirect_nicklist(const char *nicks, int *free)
{
char *str, *ret;
@@ -452,7 +492,7 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server,
/* do automatic /WHOWAS if any of the nicks wasn't found */
query = get_redirect_nicklist(query, &free_nick);
- server_redirect_event((SERVER_REC *) server, query, 2,
+ server_redirect_event(SERVER(server), query, 2,
"event 318", "event 318", 1,
"event 402", event_402, -1,
"event 311", "whois event", 1,
@@ -461,7 +501,8 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server,
cmd_params_free(free_arg);
}
-static void event_whois(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr)
+static void event_whois(const char *data, IRC_SERVER_REC *server,
+ const char *nick, const char *addr)
{
server->whois_found = TRUE;
signal_emit("event 311", 4, data, server, nick, addr);
@@ -477,7 +518,7 @@ static void sig_whois_not_found(const char *data, IRC_SERVER_REC *server)
irc_send_cmdv(server, "WHOWAS %s 1", nick);
server->whowas_found = FALSE;
- server_redirect_event((SERVER_REC *) server, nick, 1,
+ server_redirect_event(SERVER(server), nick, 1,
"event 369", "whowas event end", 1,
"event 314", "whowas event", 1,
"event 406", "event empty", 1, NULL);
@@ -510,7 +551,7 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server)
"WHOWAS %s %s", nicks, count);
nicks = get_redirect_nicklist(nicks, &free_nick);
- server_redirect_event((SERVER_REC *) server, nicks, 1,
+ server_redirect_event(SERVER(server), nicks, 1,
"event 369", "event 369", 1,
"event 314", "whowas event", 1, NULL);
if (free_nick) g_free(nicks);
@@ -892,8 +933,8 @@ static void sig_connected(IRC_SERVER_REC *server)
/* gui-gnome can use server_redirect_event() in who/list commands so
we can't use "command who" or list here.. */
- server_redirect_init((SERVER_REC *) server, "bogus command who", 2, "event 401", "event 315", "event 352", NULL);
- server_redirect_init((SERVER_REC *) server, "bogus command list", 1, "event 321", "event 322", "event 323", NULL);
+ server_redirect_init(SERVER(server), "bogus command who", 2, "event 401", "event 315", "event 352", NULL);
+ server_redirect_init(SERVER(server), "bogus command list", 1, "event 321", "event 322", "event 323", NULL);
}
void irc_commands_init(void)
@@ -919,8 +960,7 @@ void irc_commands_init(void)
command_bind("list", NULL, (SIGNAL_FUNC) cmd_list);
command_bind("who", NULL, (SIGNAL_FUNC) cmd_who);
command_bind("names", NULL, (SIGNAL_FUNC) cmd_names);
- /* SYNTAX: NICK <new nick> */
- command_bind("nick", NULL, (SIGNAL_FUNC) command_self);
+ command_bind("nick", NULL, (SIGNAL_FUNC) cmd_nick);
/* SYNTAX: NOTE <command> [&<password>] [+|-<flags>] [<arguments>] */
command_bind("note", NULL, (SIGNAL_FUNC) command_self);
command_bind("whois", NULL, (SIGNAL_FUNC) cmd_whois);
@@ -990,6 +1030,7 @@ void irc_commands_init(void)
signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
+ signal_add("nickchange over", (SIGNAL_FUNC) sig_nickchange_over);
signal_add("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
signal_add("whois event", (SIGNAL_FUNC) event_whois);
signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
@@ -1018,7 +1059,7 @@ void irc_commands_deinit(void)
command_unbind("list", (SIGNAL_FUNC) cmd_list);
command_unbind("who", (SIGNAL_FUNC) cmd_who);
command_unbind("names", (SIGNAL_FUNC) cmd_names);
- command_unbind("nick", (SIGNAL_FUNC) command_self);
+ command_unbind("nick", (SIGNAL_FUNC) cmd_nick);
command_unbind("note", (SIGNAL_FUNC) command_self);
command_unbind("whois", (SIGNAL_FUNC) cmd_whois);
command_unbind("whowas", (SIGNAL_FUNC) cmd_whowas);
@@ -1060,6 +1101,7 @@ void irc_commands_deinit(void)
command_unbind("knockout", (SIGNAL_FUNC) cmd_knockout);
signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
+ signal_remove("nickchange over", (SIGNAL_FUNC) sig_nickchange_over);
signal_remove("whois not found", (SIGNAL_FUNC) sig_whois_not_found);
signal_remove("whois event", (SIGNAL_FUNC) event_whois);
signal_remove("whowas event", (SIGNAL_FUNC) event_whowas);
diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h
index 25b6f422..c35fb0c8 100644
--- a/src/irc/core/irc-servers.h
+++ b/src/irc/core/irc-servers.h
@@ -38,6 +38,7 @@ typedef struct {
char *usermode; /* The whole mode string .. */
char *userhost; /* /USERHOST <nick> - set when joined to first channel */
+ int nick_changing:1; /* We've sent nick change command to server */
int whois_coming:1; /* Mostly just to display away message right.. */
int whois_found:1; /* Did WHOIS return any entries? */
int whowas_found:1; /* Did WHOWAS return any entries? */
diff --git a/src/irc/core/lag.c b/src/irc/core/lag.c
index 3ab8b13b..2107801d 100644
--- a/src/irc/core/lag.c
+++ b/src/irc/core/lag.c
@@ -60,6 +60,11 @@ static void lag_get(IRC_SERVER_REC *server)
g_return_if_fail(server != NULL);
+ /* nick changes may fail this check, so we should never do this
+ while there's nick change request waiting for reply in server.. */
+ if (server->nick_changing)
+ return;
+
lag = g_new0(LAG_REC, 1);
lags = g_slist_append(lags, lag);
lag->server = server;
@@ -70,9 +75,6 @@ static void lag_get(IRC_SERVER_REC *server)
server->lag_sent = time(NULL);
server->lag_last_check = time(NULL);
- /* NOTE: this will fail if there's any nick changes in buffer -
- that's why this function should be called only when the buffer
- is empty */
irc_send_cmdv(server, "NOTICE %s :\001IRSSILAG %ld %ld\001",
server->nick, lag->time.tv_sec, lag->time.tv_usec);
}
@@ -141,8 +143,7 @@ static int sig_check_lag(void)
rec->connection_lost = TRUE;
server_disconnect((SERVER_REC *) rec);
}
- }
- else if (rec->lag_last_check+lag_check_time < now &&
+ } else if (rec->lag_last_check+lag_check_time < now &&
rec->cmdcount == 0 && rec->connected) {
/* no commands in buffer - get the lag */
lag_get(rec);