Index: src/channel.c
===================================================================
RCS file: /home/cmunk/ircsystems/cvsroot/unreal/src/channel.c,v
retrieving revision 1.1.1.1.6.1.2.319.2.27
diff -u -r1.1.1.1.6.1.2.319.2.27 channel.c
--- src/channel.c	26 Feb 2005 22:47:09 -0000	1.1.1.1.6.1.2.319.2.27
+++ src/channel.c	10 Nov 2005 20:35:54 -0000
@@ -528,6 +528,110 @@
 	return (tmp);
 }
 
+/** is_banned_with_nick - checks for bans is the users where to have the specified nick.
+ * Based entirely on the above function; For fixing that pesky /nick -> ban problem. -- Nazzy
+ * PARAMETERS:
+ * sptr:        the client to check (can be remote client)
+ * chptr:       the channel to check
+ * type:        one of BANCHK_*
+ * tnick:	the target nick
+ * RETURNS:
+ * a pointer to the ban structure if banned, else NULL.
+ */
+
+Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *tnick)
+{
+        Ban *tmp, *tmp2;
+        char *s;
+        static char realhost[NICKLEN + USERLEN + HOSTLEN + 6];
+        static char virthost[NICKLEN + USERLEN + HOSTLEN + 6];
+        static char     nuip[NICKLEN + USERLEN + HOSTLEN + 6];
+        int dovirt = 0, mine = 0;
+        Extban *extban;
+
+        if (!IsPerson(sptr))
+                return NULL; /* No peep, no ban */
+
+        ban_realhost = realhost;
+        ban_ip = ban_virthost = NULL;
+
+        /* If it's one of my clients, do an ip based comparison */
+        if (MyConnect(sptr)) {
+                mine = 1;
+                s = make_nick_user_host(tnick, sptr->user->username, GetIP(sptr));
+                strlcpy(nuip, s, sizeof nuip);
+                ban_ip = nuip;
+        }
+
+        /* If the user has a vhost, and it is different from their real host, do vhost comparison */
+        if (sptr->user->virthost)
+                if (strcmp(sptr->user->realhost, sptr->user->virthost))
+                {
+                        dovirt = 1;
+			s = make_nick_user_host(tnick, sptr->user->username,
+			    sptr->user->virthost);
+			strlcpy(virthost, s, sizeof virthost);
+			ban_virthost = virthost;
+                }
+
+        /* Finally, alway do real host check */
+        s = make_nick_user_host(tnick, sptr->user->username,
+            sptr->user->realhost);
+        strlcpy(realhost, s, sizeof realhost);
+
+          /* We now check +b first, if a +b is found we then see if there is a +e.
+           * If a +e was found we return NULL, if not, we return the ban.
+           */
+        for (tmp = chptr->banlist; tmp; tmp = tmp->next)
+        {
+		/* Since the extended bans use the masks we generated here,
+		 * we should be perfectly safe to simply call out to them as normal ...
+		 * obviously if that changes, we'd have a problem heh.
+		 *
+		 * Incidentally, only a check for ~n is needed, 
+		 * but doing all allows for expansion without having to update here.
+		 */
+                if (*tmp->banstr == '~')
+                {
+                        extban = findmod_by_bantype(tmp->banstr[1]);
+                        if (!extban)
+                                continue;
+                        if (!extban->is_banned(sptr, chptr, tmp->banstr, type))
+                                continue;
+                } else {
+                        if ((match(tmp->banstr, realhost) == 0) ||
+                            (dovirt && (match(tmp->banstr, virthost) == 0)) ||
+                            (mine && (match(tmp->banstr, nuip) == 0)))
+                        {
+                                /* matches.. do nothing */
+                        } else
+                                continue;
+                }
+
+                /* Ban found, now check for +e */
+                for (tmp2 = chptr->exlist; tmp2; tmp2 = tmp2->next)
+                {
+                        if (*tmp2->banstr == '~')
+                        {
+                                extban = findmod_by_bantype(tmp2->banstr[1]);
+                                if (!extban)
+                                        continue;
+                                if (extban->is_banned(sptr, chptr, tmp2->banstr, type))
+                                        return NULL;
+                        } else {
+                                if ((match(tmp2->banstr, realhost) == 0) ||
+                                        (dovirt && (match(tmp2->banstr, virthost) == 0)) ||
+                                        (mine && (match(tmp2->banstr, nuip) == 0)) )
+                                        return NULL;
+                        }
+                }
+                break; /* ban found and not on except */
+        }
+
+        return (tmp);
+}
+
+
 /*
  * Checks if the "user" IRC is banned, used by +mu.
  */
