diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2012-08-22 19:28:19 +0200 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2012-08-22 19:28:19 +0200 |
commit | 7f3d7e5f29eadd0e805131b768efe5faa656d903 (patch) | |
tree | 5b7d92882001d6a58ded9bc3c47bec5571d8de6a /src/plugins | |
parent | 7aaac8d6981a6a54179c7ae7dec1a479638278de (diff) | |
download | weechat-7f3d7e5f29eadd0e805131b768efe5faa656d903.zip |
irc: generate alternate nicks dynamically when all nicks are already in use (task #12209)
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 54 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 99 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.h | 4 |
3 files changed, 120 insertions, 37 deletions
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 067a992e6..709ef9caf 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -4082,7 +4082,7 @@ IRC_PROTOCOL_CALLBACK(368) IRC_PROTOCOL_CALLBACK(432) { - int nick_index; + const char *alternate_nick; struct t_gui_buffer *ptr_buffer; /* @@ -4099,13 +4099,8 @@ IRC_PROTOCOL_CALLBACK(432) ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL, command, NULL, NULL); - nick_index = irc_server_get_nick_index (server); - if (nick_index < 0) - nick_index = 0; - else - nick_index = (nick_index + 1) % server->nicks_count; - - if (nick_index == server->nick_first_tried) + alternate_nick = irc_server_get_alternate_nick (server); + if (!alternate_nick) { weechat_printf (ptr_buffer, _("%s%s: all declared nicknames are " @@ -4119,12 +4114,11 @@ IRC_PROTOCOL_CALLBACK(432) weechat_printf (ptr_buffer, _("%s%s: nickname \"%s\" is invalid, " - "trying nickname #%d (\"%s\")"), + "trying nickname \"%s\""), weechat_prefix ("error"), - IRC_PLUGIN_NAME, server->nick, nick_index + 1, - server->nicks_array[nick_index]); + IRC_PLUGIN_NAME, server->nick, alternate_nick); - irc_server_set_nick (server, server->nicks_array[nick_index]); + irc_server_set_nick (server, alternate_nick); irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } @@ -4138,7 +4132,7 @@ IRC_PROTOCOL_CALLBACK(432) IRC_PROTOCOL_CALLBACK(433) { - int nick_index; + const char *alternate_nick; struct t_gui_buffer *ptr_buffer; /* @@ -4151,13 +4145,8 @@ IRC_PROTOCOL_CALLBACK(433) ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL, command, NULL, NULL); - nick_index = irc_server_get_nick_index (server); - if (nick_index < 0) - nick_index = 0; - else - nick_index = (nick_index + 1) % server->nicks_count; - - if (nick_index == server->nick_first_tried) + alternate_nick = irc_server_get_alternate_nick (server); + if (!alternate_nick) { weechat_printf (ptr_buffer, _("%s%s: all declared nicknames are " @@ -4171,11 +4160,10 @@ IRC_PROTOCOL_CALLBACK(433) weechat_printf (ptr_buffer, _("%s: nickname \"%s\" is already in use, " - "trying nickname #%d (\"%s\")"), - IRC_PLUGIN_NAME, server->nick, nick_index + 1, - server->nicks_array[nick_index]); + "trying nickname \"%s\""), + IRC_PLUGIN_NAME, server->nick, alternate_nick); - irc_server_set_nick (server, server->nicks_array[nick_index]); + irc_server_set_nick (server, alternate_nick); irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } @@ -4196,7 +4184,7 @@ IRC_PROTOCOL_CALLBACK(433) IRC_PROTOCOL_CALLBACK(437) { - int nick_index; + const char *alternate_nick; struct t_gui_buffer *ptr_buffer; /* @@ -4216,13 +4204,8 @@ IRC_PROTOCOL_CALLBACK(437) ptr_buffer = irc_msgbuffer_get_target_buffer (server, NULL, command, NULL, NULL); - nick_index = irc_server_get_nick_index (server); - if (nick_index < 0) - nick_index = 0; - else - nick_index = (nick_index + 1) % server->nicks_count; - - if (nick_index == server->nick_first_tried) + alternate_nick = irc_server_get_alternate_nick (server); + if (!alternate_nick) { weechat_printf (ptr_buffer, _("%s%s: all declared nicknames are " @@ -4236,12 +4219,11 @@ IRC_PROTOCOL_CALLBACK(437) weechat_printf (ptr_buffer, _("%s%s: nickname \"%s\" is unavailable, " - "trying nickname #%d (\"%s\")"), + "trying nickname \"%s\""), weechat_prefix ("error"), - IRC_PLUGIN_NAME, server->nick, nick_index + 1, - server->nicks_array[nick_index]); + IRC_PLUGIN_NAME, server->nick, alternate_nick); - irc_server_set_nick (server, server->nicks_array[nick_index]); + irc_server_set_nick (server, alternate_nick); irc_server_sendf (server, 0, NULL, "NICK %s", server->nick); } diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 1ae2f0347..8db5f9150 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -486,6 +486,100 @@ irc_server_get_nick_index (struct t_irc_server *server) } /* + * irc_server_get_alternate_nick: get an alternate nick when the nick is + * already used on server + * We first try all declared nicks, then we + * build nicks by adding "_", until length of 9. + * If all nicks are still used, build 99 + * alternate nicks by using number at the end. + * Example: nicks = "abcde,fghi,jkl" + * Nicks tried: abcde + * fghi + * jkl + * abcde_ + * abcde__ + * abcde___ + * abcde____ + * abcde___1 + * abcde___2 + * ... + * abcde__99 + * Return NULL if no more alternate nick is + * available + */ + +const char * +irc_server_get_alternate_nick (struct t_irc_server *server) +{ + static char nick[64]; + char str_number[64]; + int nick_index, length_nick, length_number; + + nick[0] = '\0'; + + /* we are still trying nicks from option "nicks" */ + if (server->nick_alternate_number < 0) + { + nick_index = irc_server_get_nick_index (server); + if (nick_index < 0) + nick_index = 0; + else + { + nick_index = (nick_index + 1) % server->nicks_count; + /* stop loop if first nick tried was not in the list of nicks */ + if ((nick_index == 0) && (server->nick_first_tried < 0)) + server->nick_first_tried = 0; + } + + if (nick_index != server->nick_first_tried) + { + snprintf (nick, sizeof (nick), + "%s", server->nicks_array[nick_index]); + return nick; + } + + /* + * we have tried all nicks in list, then use main nick + * and we will add "_" and then number if needed + */ + server->nick_alternate_number = 0; + snprintf (nick, sizeof (nick), "%s", server->nicks_array[0]); + } + else + snprintf (nick, sizeof (nick), "%s", server->nick); + + /* if length is < 9, just add a "_" */ + if (strlen (nick) < 9) + { + strcat (nick, "_"); + return nick; + } + + server->nick_alternate_number++; + + /* number is max 99 */ + if (server->nick_alternate_number > 99) + return NULL; + + /* be sure the nick has 9 chars max */ + nick[9] = '\0'; + + /* generate number */ + snprintf (str_number, sizeof (str_number), + "%d", server->nick_alternate_number); + + /* copy number in nick */ + length_nick = strlen (nick); + length_number = strlen (str_number); + if (length_number > length_nick) + return NULL; + memcpy (nick + length_nick - length_number, str_number, length_number); + + /* return alternate nick */ + return nick; +} + +/* * irc_server_get_isupport_value: return value of an item in "isupport" (copy * of IRC message 005) * if feature is found but has no value, empty @@ -782,6 +876,7 @@ irc_server_alloc (const char *name) new_server->nicks_count = 0; new_server->nicks_array = NULL; new_server->nick_first_tried = 0; + new_server->nick_alternate_number = -1; new_server->nick = NULL; new_server->nick_modes = NULL; new_server->isupport = NULL; @@ -2811,6 +2906,8 @@ irc_server_login (struct t_irc_server *server) else server->nick_first_tried = irc_server_get_nick_index (server); + server->nick_alternate_number = -1; + if (irc_server_sasl_enabled (server) || (capabilities && capabilities[0])) { irc_server_sendf (server, 0, NULL, "CAP LS"); @@ -4290,6 +4387,7 @@ irc_server_hdata_server_cb (void *data, const char *hdata_name) WEECHAT_HDATA_VAR(struct t_irc_server, nicks_count, INTEGER, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, nicks_array, STRING, "nicks_count", NULL); WEECHAT_HDATA_VAR(struct t_irc_server, nick_first_tried, INTEGER, NULL, NULL); + WEECHAT_HDATA_VAR(struct t_irc_server, nick_alternate_number, INTEGER, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, nick, STRING, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, nick_modes, STRING, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, isupport, STRING, NULL, NULL); @@ -4800,6 +4898,7 @@ irc_server_print_log () weechat_log_printf (" nicks_count. . . . . : %d", ptr_server->nicks_count); weechat_log_printf (" nicks_array. . . . . : 0x%lx", ptr_server->nicks_array); weechat_log_printf (" nick_first_tried . . : %d", ptr_server->nick_first_tried); + weechat_log_printf (" nick_alternate_number: %d", ptr_server->nick_alternate_number); weechat_log_printf (" nick . . . . . . . . : '%s'", ptr_server->nick); weechat_log_printf (" nick_modes . . . . . : '%s'", ptr_server->nick_modes); weechat_log_printf (" isupport . . . . . . : '%s'", ptr_server->isupport); diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h index 32bebe921..09856a160 100644 --- a/src/plugins/irc/irc-server.h +++ b/src/plugins/irc/irc-server.h @@ -161,6 +161,8 @@ struct t_irc_server char **nicks_array; /* nicknames (after split) */ int nick_first_tried; /* first nick tried in list of nicks */ /* when (re-)connecting to server */ + int nick_alternate_number; /* number used to build alternate nicks */ + /* (nick____1, nick____2, ...) */ char *nick; /* current nickname */ char *nick_modes; /* nick modes */ char *isupport; /* copy of message 005 (ISUPPORT) */ @@ -237,7 +239,7 @@ extern void irc_server_set_addresses (struct t_irc_server *server, const char *addresses); extern void irc_server_set_nicks (struct t_irc_server *server, const char *nicks); extern void irc_server_set_nick (struct t_irc_server *server, const char *nick); -extern int irc_server_get_nick_index (struct t_irc_server *server); +extern const char *irc_server_get_alternate_nick (struct t_irc_server *server); extern const char *irc_server_get_isupport_value (struct t_irc_server *server, const char *feature); extern void irc_server_set_prefix_modes_chars (struct t_irc_server *server, |