Index: irc.h
===================================================================
--- irc.h	(revision 69982f8361f8e75d768872fba0e1e94dd1d4e875)
+++ irc.h	(revision e3e2059c57f051d103645c120934a05ef5e35156)
@@ -299,4 +299,6 @@
 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);
Index: irc_channel.c
===================================================================
--- irc_channel.c	(revision 69982f8361f8e75d768872fba0e1e94dd1d4e875)
+++ irc_channel.c	(revision e3e2059c57f051d103645c120934a05ef5e35156)
@@ -556,4 +556,84 @@
 }
 
+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_)
 {
Index: irc_im.c
===================================================================
--- irc_im.c	(revision 69982f8361f8e75d768872fba0e1e94dd1d4e875)
+++ irc_im.c	(revision e3e2059c57f051d103645c120934a05ef5e35156)
@@ -696,59 +696,5 @@
 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);
 }
 
Index: nick.c
===================================================================
--- nick.c	(revision 69982f8361f8e75d768872fba0e1e94dd1d4e875)
+++ nick.c	(revision e3e2059c57f051d103645c120934a05ef5e35156)
@@ -214,4 +214,20 @@
 }
 
+/* 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])
 {
@@ -224,15 +240,6 @@
 	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) {
Index: nick.h
===================================================================
--- nick.h	(revision 69982f8361f8e75d768872fba0e1e94dd1d4e875)
+++ nick.h	(revision e3e2059c57f051d103645c120934a05ef5e35156)
@@ -28,4 +28,5 @@
 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);
