--- src/modules/m_svsmode.c.orig	2006-06-16 14:29:17.000000000 -0400
+++ src/modules/m_svsmode.c	2006-07-27 23:53:54.216567399 -0400
@@ -87,6 +87,90 @@ DLLFUNC int MOD_UNLOAD(m_svsmode)(int mo
 	return MOD_SUCCESS;
 }
 
+int unban_user(aClient *sptr, aChannel *chptr, aClient *acptr, char chmode) {
+	Extban *extban;
+	Ban *ban, *bnext, *banlist;
+	char uhost[NICKLEN+USERLEN+HOSTLEN+6], vhost[NICKLEN+USERLEN+HOSTLEN+6];
+	char ihost[NICKLEN+USERLEN+HOSTLEN+6], chost[NICKLEN+USERLEN+HOSTLEN+6];
+
+	strlcpy(uhost, make_nick_user_host(acptr->name, 
+		acptr->user->username, acptr->user->realhost),
+		sizeof uhost);
+	strlcpy(vhost, make_nick_user_host(acptr->name,
+		acptr->user->username, GetHost(acptr)),
+		sizeof vhost);
+	strlcpy(ihost, make_nick_user_host(acptr->name,
+		acptr->user->username, GetIP(acptr)),
+		sizeof ihost);
+	strlcpy(chost, make_nick_user_host(acptr->name, 
+		acptr->user->username, acptr->user->cloakedhost),
+		sizeof chost);
+
+	switch (chmode) {
+		case 'b':
+			ban = banlist = chptr->banlist;
+			break;
+		case 'e':
+			ban = banlist = chptr->exlist;
+			break;
+		case 'I':
+			ban = banlist = chptr->invexlist;
+			break;
+	}
+	
+	while (ban) {
+		bnext = ban->next;
+		if (!match(ban->banstr, uhost) || !match(ban->banstr, vhost) || !match(ban->banstr, ihost) || !match(ban->banstr, chost)) {
+			add_send_mode_param(chptr, sptr, '-',  chmode, 
+				ban->banstr);
+			del_listmode(&banlist, chptr, ban->banstr);
+		}
+		else if (chmode != 'I' && *ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
+		{
+			if (extban->options & EXTBOPT_CHSVSMODE) 
+			{
+				if (extban->is_banned(acptr, chptr, ban->banstr, BANCHK_JOIN))
+				{
+					add_send_mode_param(chptr, acptr, '-', chmode, ban->banstr);
+					del_listmode(&banlist, chptr, ban->banstr);
+				}
+			}
+		}
+		ban = bnext;
+	}
+}
+
+int clear_bans(aClient *sptr, aChannel *chptr, char chmode) {
+	Extban *extban;
+	Ban *ban, *bnext, *banlist;
+
+	switch (chmode) {
+		case 'b':
+			ban = banlist = chptr->banlist;
+			break;
+		case 'e':
+			ban = banlist = chptr->exlist;
+			break;
+		case 'I':
+			ban = banlist = chptr->invexlist;
+			break;
+	}
+	while (ban) {
+		bnext = ban->next;
+		if (chmode != 'I' && *ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
+		{
+			if (!(extban->options & EXTBOPT_CHSVSMODE))							
+			{
+				ban = bnext;
+				continue;
+			}
+		}
+		add_send_mode_param(chptr, sptr, '-',  chmode, ban->banstr);
+		del_listmode(&banlist, chptr, ban->banstr);
+		ban = bnext;
+	}
+}
+
 int channel_svsmode(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 {
 	aChannel *chptr;
@@ -197,8 +281,6 @@ int channel_svsmode(aClient *cptr, aClie
 				Extban *extban;
 				Ban *ban, *bnext;
 				if (parc >= i) {
-					char uhost[NICKLEN+USERLEN+HOSTLEN+6], vhost[NICKLEN+USERLEN+HOSTLEN+6];
-					char ihost[NICKLEN+USERLEN+HOSTLEN+6];
 					if (!(acptr = find_person(parv[i-1], NULL))) {
 						i++;
 						break;
@@ -209,53 +291,10 @@ int channel_svsmode(aClient *cptr, aClie
 					}
 					i++;
 
-					strlcpy(uhost, make_nick_user_host(acptr->name, 
-						acptr->user->username, acptr->user->realhost),
-						sizeof uhost);
-					strlcpy(vhost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetHost(acptr)),
-						sizeof vhost);
-					strlcpy(ihost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetIP(acptr)),
-						sizeof ihost);
-					ban = chptr->banlist;
-					while (ban) {
-						bnext = ban->next;
-						if (*ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
-						{
-							if (extban->options & EXTBOPT_CHSVSMODE) 
-							{
-								if (extban->is_banned(acptr, chptr, ban->banstr, BANCHK_JOIN))
-								{
-									add_send_mode_param(chptr, acptr, '-', 'b', ban->banstr);
-									del_listmode(&chptr->banlist, chptr, ban->banstr);
-								}
-							}
-						}
-						else if (!match(ban->banstr, uhost) || !match(ban->banstr, vhost) || !match(ban->banstr, ihost)) {
-							add_send_mode_param(chptr, sptr, '-',  'b', 
-								ban->banstr);
-							del_listmode(&chptr->banlist, chptr, ban->banstr);
-						}
-						ban = bnext;
-					}
+					unban_user(sptr, chptr, acptr, 'b');
 				}
 				else {
-					ban = chptr->banlist;
-					while (ban) {
-						bnext = ban->next;
-						if (*ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
-						{
-							if (!(extban->options & EXTBOPT_CHSVSMODE))							
-							{
-								ban = bnext;
-								continue;
-							}
-						}
-						add_send_mode_param(chptr, sptr, '-',  'b', ban->banstr);
-						del_listmode(&chptr->banlist, chptr, ban->banstr);
-						ban = bnext;
-					}
+					clear_bans(sptr, chptr, 'b');
 				}
 			}
 			break;
@@ -263,8 +302,6 @@ int channel_svsmode(aClient *cptr, aClie
 				Extban *extban;
 				Ban *ban, *bnext;
 				if (parc >= i) {
-					char uhost[NICKLEN+USERLEN+HOSTLEN+6], vhost[NICKLEN+USERLEN+HOSTLEN+6];
-					char ihost[NICKLEN+USERLEN+HOSTLEN+6];
 					if (!(acptr = find_person(parv[i-1], NULL))) {
 						i++;
 						break;
@@ -275,62 +312,16 @@ int channel_svsmode(aClient *cptr, aClie
 					}
 					i++;
 
-					strlcpy(uhost, make_nick_user_host(acptr->name, 
-						acptr->user->username, acptr->user->realhost),
-						sizeof uhost);
-					strlcpy(vhost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetHost(acptr)),
-						sizeof vhost);
-					strlcpy(ihost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetIP(acptr)),
-						sizeof ihost);
-
-					ban = chptr->exlist;
-					while (ban) {
-						bnext = ban->next;
-						if (*ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
-						{
-							if (extban->options & EXTBOPT_CHSVSMODE) 
-							{
-								if (extban->is_banned(acptr, chptr, ban->banstr, BANCHK_JOIN))
-								{
-									add_send_mode_param(chptr, acptr, '-', 'b', ban->banstr);
-									del_listmode(&chptr->exlist, chptr, ban->banstr);
-								}
-							}
-						}
-						else if (!match(ban->banstr, uhost) || !match(ban->banstr, vhost) || !match(ban->banstr, ihost)) {
-							add_send_mode_param(chptr, sptr, '-',  'e', 
-								ban->banstr);
-							del_listmode(&chptr->exlist, chptr, ban->banstr);
-						}
-						ban = bnext;
-					}
+					unban_user(sptr, chptr, acptr, 'e');
 				}
 				else {
-					ban = chptr->exlist;
-					while (ban) {
-						bnext = ban->next;
-						if (*ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr[1])))
-						{
-							if (!(extban->options & EXTBOPT_CHSVSMODE))							
-							{
-								ban = bnext;
-								continue;
-							}
-						}
-						add_send_mode_param(chptr, sptr, '-',  'e', ban->banstr);
-						del_listmode(&chptr->exlist, chptr, ban->banstr);
-						ban = bnext;
-					}
+					clear_bans(sptr, chptr, 'e');
 				}
 			}
 			break;
 			case 'I': {
 				Ban *ban, *bnext;
 				if (parc >= i) {
-					char uhost[NICKLEN+USERLEN+HOSTLEN+6], vhost[NICKLEN+USERLEN+HOSTLEN+6];
-					char ihost[NICKLEN+USERLEN+HOSTLEN+6];
 					if (!(acptr = find_person(parv[i-1], NULL))) {
 						i++;
 						break;
@@ -341,35 +332,10 @@ int channel_svsmode(aClient *cptr, aClie
 					}
 					i++;
 
-					strlcpy(uhost, make_nick_user_host(acptr->name, 
-						acptr->user->username, acptr->user->realhost),
-						sizeof uhost);
-					strlcpy(vhost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetHost(acptr)),
-						sizeof vhost);
-					strlcpy(ihost, make_nick_user_host(acptr->name,
-						acptr->user->username, GetIP(acptr)),
-						sizeof ihost);
-
-					ban = chptr->invexlist;
-					while (ban) {
-						bnext = ban->next;
-						if (!match(ban->banstr, uhost) || !match(ban->banstr, vhost) || !match(ban->banstr, ihost)) {
-							add_send_mode_param(chptr, sptr, '-',  'I', 
-								ban->banstr);
-							del_listmode(&chptr->invexlist, chptr, ban->banstr);
-						}
-						ban = bnext;
-					}
+					unban_user(sptr, chptr, acptr, 'I');
 				}
 				else {
-					ban = chptr->invexlist;
-					while (ban) {
-						bnext = ban->next;
-						add_send_mode_param(chptr, sptr, '-',  'I', ban->banstr);
-						del_listmode(&chptr->invexlist, chptr, ban->banstr);
-						ban = bnext;
-					}
+					clear_bans(sptr, chptr, 'I');
 				}
 			}
 			break;
