aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-04-06 09:30:30 -0300
committerdequis <dx@dxzone.com.ar>2015-04-06 09:35:57 -0300
commite3e2059c57f051d103645c120934a05ef5e35156 (patch)
tree14bbaa57556d7d64ba8a821eaeaf1b92bb1018fe
parent69982f8361f8e75d768872fba0e1e94dd1d4e875 (diff)
irc: split bee_irc_chat_name_hint in a few functions
Also split underscore_dedupe from nick_dedupe.
-rw-r--r--irc.h2
-rw-r--r--irc_channel.c80
-rw-r--r--irc_im.c56
-rw-r--r--nick.c29
-rw-r--r--nick.h1
5 files changed, 102 insertions, 66 deletions
diff --git a/irc.h b/irc.h
index e5a34daa..bdc7a9b6 100644
--- a/irc.h
+++ b/irc.h
@@ -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_;
diff --git a/irc_im.c b/irc_im.c
index 2a956c44..58cf2667 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -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)
diff --git a/nick.c b/nick.c
index 1ace448a..fb84f986 100644
--- a/nick.c
+++ b/nick.c
@@ -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());
diff --git a/nick.h b/nick.h
index 093fcaa2..1b546be2 100644
--- a/nick.h
+++ b/nick.h
@@ -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);