diff options
author | dequis <dx@dxzone.com.ar> | 2015-04-06 09:30:30 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-04-06 09:35:57 -0300 |
commit | e3e2059c57f051d103645c120934a05ef5e35156 (patch) | |
tree | 14bbaa57556d7d64ba8a821eaeaf1b92bb1018fe | |
parent | 69982f8361f8e75d768872fba0e1e94dd1d4e875 (diff) |
irc: split bee_irc_chat_name_hint in a few functions
Also split underscore_dedupe from nick_dedupe.
-rw-r--r-- | irc.h | 2 | ||||
-rw-r--r-- | irc_channel.c | 80 | ||||
-rw-r--r-- | irc_im.c | 56 | ||||
-rw-r--r-- | nick.c | 29 | ||||
-rw-r--r-- | nick.h | 1 |
5 files changed, 102 insertions, 66 deletions
@@ -298,6 +298,8 @@ void irc_channel_printf(irc_channel_t *ic, char *format, ...); gboolean irc_channel_name_ok(const char *name); void irc_channel_name_strip(char *name); int irc_channel_name_cmp(const char *a_, const char *b_); +char *irc_channel_name_gen(bee_t *bee, const char *name); +gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name); void irc_channel_update_ops(irc_channel_t *ic, char *value); char *set_eval_irc_channel_ops(struct set *set, char *value); gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu); diff --git a/irc_channel.c b/irc_channel.c index b4257ba6..f66efabe 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -555,6 +555,86 @@ int irc_channel_name_cmp(const char *a_, const char *b_) return case_map[a[i]] - case_map[b[i]]; } +gboolean irc_channel_is_unused(bee_t *bee, char *name) +{ + char *type, *chat_type; + irc_channel_t *oic; + + if (!irc_channel_name_ok(name)) { + return FALSE; + } + + if (!(oic = irc_channel_by_name(bee->ui_data, name))) { + return TRUE; + } + + type = set_getstr(&oic->set, "type"); + chat_type = set_getstr(&oic->set, "chat_type"); + + if (type && chat_type && oic->data == FALSE && + strcmp(type, "chat") == 0 && + strcmp(chat_type, "groupchat") == 0) { + /* There's a channel with this name already, but it looks + like it's not in use yet. Most likely the IRC client + rejoined the channel after a reconnect. Remove it so + we can reuse its name. */ + irc_channel_free(oic); + return TRUE; + } + + return FALSE; +} + +char *irc_channel_name_gen(bee_t *bee, const char *hint) +{ + char name[MAX_NICK_LENGTH + 1] = { 0 }; + char *translit_name; + gsize bytes_written; + + translit_name = g_convert_with_fallback(hint, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, &bytes_written, NULL); + if (bytes_written > MAX_NICK_LENGTH) { + translit_name[MAX_NICK_LENGTH] = '\0'; + } + + name[0] = '#'; + strncpy(name + 1, translit_name, MAX_NICK_LENGTH - 1); + name[MAX_NICK_LENGTH] = '\0'; + + g_free(translit_name); + + irc_channel_name_strip(name); + + if (set_getbool(&bee->set, "lcnicks")) { + nick_lc(bee->ui_data, name + 1); + } + + while (!irc_channel_is_unused(bee, name)) { + underscore_dedupe(name); + } + + return g_strdup(name); +} + +gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name) +{ + irc_t *irc = ic->irc; + char *full_name; + + /* Don't rename a channel if the user's in it already. */ + if (ic->flags & IRC_CHANNEL_JOINED) { + return FALSE; + } + + if (!(full_name = irc_channel_name_gen(irc->b, name))) { + return FALSE; + } + + g_free(ic->name); + ic->name = full_name; + + return TRUE; +} + static gint irc_channel_user_cmp(gconstpointer a_, gconstpointer b_) { const irc_channel_user_t *a = a_, *b = b_; @@ -695,61 +695,7 @@ static gboolean bee_irc_chat_topic(bee_t *bee, struct groupchat *c, const char * static gboolean bee_irc_chat_name_hint(bee_t *bee, struct groupchat *c, const char *name) { - irc_t *irc = bee->ui_data; - irc_channel_t *ic = c->ui_data, *oic; - char *stripped, *full_name; - gsize bytes_written; - - if (ic == NULL) { - return FALSE; - } - - /* Don't rename a channel if the user's in it already. */ - if (ic->flags & IRC_CHANNEL_JOINED) { - return FALSE; - } - - stripped = g_convert_with_fallback(name, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, &bytes_written, NULL); - if (bytes_written > MAX_NICK_LENGTH) { - stripped[MAX_NICK_LENGTH] = '\0'; - } - - irc_channel_name_strip(stripped); - if (set_getbool(&bee->set, "lcnicks")) { - nick_lc(irc, stripped); - } - - if (stripped[0] == '\0') { - g_free(stripped); - return FALSE; - } - - full_name = g_strdup_printf("#%s", stripped); - g_free(stripped); - if ((oic = irc_channel_by_name(irc, full_name))) { - char *type, *chat_type; - - type = set_getstr(&oic->set, "type"); - chat_type = set_getstr(&oic->set, "chat_type"); - - if (type && chat_type && oic->data == FALSE && - strcmp(type, "chat") == 0 && - strcmp(chat_type, "groupchat") == 0) { - /* There's a channel with this name already, but it looks - like it's not in use yet. Most likely the IRC client - rejoined the channel after a reconnect. Remove it so - we can reuse its name. */ - irc_channel_free(oic); - } else { - g_free(full_name); - return FALSE; - } - } - - g_free(ic->name); - ic->name = full_name; - - return TRUE; + return irc_channel_name_hint(c->ui_data, name); } static gboolean bee_irc_chat_invite(bee_t *bee, bee_user_t *bu, const char *name, const char *msg) @@ -213,6 +213,22 @@ char *nick_gen(bee_user_t *bu) return NULL; } +/* Used for nicks and channel names too! */ +void underscore_dedupe(char nick[MAX_NICK_LENGTH + 1]) +{ + if (strlen(nick) < (MAX_NICK_LENGTH - 1)) { + nick[strlen(nick) + 1] = 0; + nick[strlen(nick)] = '_'; + } else { + /* We've got no more space for underscores, + so truncate it and replace the last three + chars with a random "_XX" suffix */ + int len = truncate_utf8(nick, MAX_NICK_LENGTH - 3); + nick[len] = '_'; + g_snprintf(nick + len + 1, 3, "%2x", rand()); + } +} + void nick_dedupe(bee_user_t *bu, char nick[MAX_NICK_LENGTH + 1]) { irc_t *irc = (irc_t *) bu->bee->ui_data; @@ -223,17 +239,8 @@ void nick_dedupe(bee_user_t *bu, char nick[MAX_NICK_LENGTH + 1]) subtle changes to make it unique. */ while (!nick_ok(irc, nick) || ((iu = irc_user_by_name(irc, nick)) && iu->bu != bu)) { - if (strlen(nick) < (MAX_NICK_LENGTH - 1)) { - nick[strlen(nick) + 1] = 0; - nick[strlen(nick)] = '_'; - } else { - /* We've got no more space for underscores, - so truncate it and replace the last three - chars with a random "_XX" suffix */ - int len = truncate_utf8(nick, MAX_NICK_LENGTH - 3); - nick[len] = '_'; - g_snprintf(nick + len + 1, 3, "%2x", rand()); - } + + underscore_dedupe(nick); if (inf_protection-- == 0) { g_snprintf(nick, MAX_NICK_LENGTH + 1, "xx%x", rand()); @@ -27,6 +27,7 @@ void nick_set_raw(account_t *acc, const char *handle, const char *nick); void nick_set(bee_user_t *bu, const char *nick); char *nick_get(bee_user_t *bu); char *nick_gen(bee_user_t *bu); +void underscore_dedupe(char nick[MAX_NICK_LENGTH + 1]); void nick_dedupe(bee_user_t * bu, char nick[MAX_NICK_LENGTH + 1]); int nick_saved(bee_user_t *bu); void nick_del(bee_user_t *bu); |