Pārlūkot izejas kodu

Merge branch 'member-from'

* member-from:
  Use new memberlist->from instead of dynamically determining it
  Populate memberlist->fromip
  Populate memberlist->from when initiating new member and when they change nick
  Simplify lookup of from
  Mark my own member as 'me' when joining
  Remove useless victim check
  Pass member into detect_chan_flood() and cleanup surrounding code
Bryan Drewery 14 gadi atpakaļ
vecāks
revīzija
58570f8299

+ 2 - 1
src/chan.h

@@ -24,6 +24,8 @@ typedef struct memstruct {
   char nick[NICKLEN];
   char nick[NICKLEN];
   char userhost[UHOSTLEN];
   char userhost[UHOSTLEN];
   char userip[UHOSTLEN];
   char userip[UHOSTLEN];
+  char from[NICKLEN + UHOSTLEN];   /* nick!user@host */
+  char fromip[NICKLEN + UHOSTLEN]; /* nick!user@ip */
   bool is_me;
   bool is_me;
 } memberlist;
 } memberlist;
 
 
@@ -222,7 +224,6 @@ struct chanset_t {
   char topic[121];
   char topic[121];
   char added_by[HANDLEN + 1];	/* who added the channel? */
   char added_by[HANDLEN + 1];	/* who added the channel? */
   char floodwho[FLOOD_CHAN_MAX][128];
   char floodwho[FLOOD_CHAN_MAX][128];
-  char deopd[NICKLEN];		/* last person deop'd (must change	*/
   char dname[81];               /* what the users know the channel as like !eggdev */
   char dname[81];               /* what the users know the channel as like !eggdev */
   char name[81];                /* what the servers know the channel as, like !ABCDEeggdev */
   char name[81];                /* what the servers know the channel as, like !ABCDEeggdev */
 };
 };

+ 1 - 1
src/mod/channels.mod/channels.h

@@ -53,7 +53,7 @@ int channel_modify(char *, struct chanset_t *, int, char **, bool);
 int channel_add(char *, const char *, char *, bool = 0);
 int channel_add(char *, const char *, char *, bool = 0);
 void clear_channel(struct chanset_t *, bool);
 void clear_channel(struct chanset_t *, bool);
 int u_equals_mask(maskrec *, char *);
 int u_equals_mask(maskrec *, char *);
-bool u_match_mask(struct maskrec *, char *);
+bool u_match_mask(struct maskrec *, const char *);
 bool ismasked(masklist *, const char *);
 bool ismasked(masklist *, const char *);
 bool ismodeline(masklist *, const char *);
 bool ismodeline(masklist *, const char *);
 void channels_report(int, int);
 void channels_report(int, int);

+ 1 - 1
src/mod/channels.mod/userchan.c

@@ -219,7 +219,7 @@ int u_equals_mask(maskrec *u, char *mask)
   return 0;
   return 0;
 }
 }
 
 
-bool u_match_mask(maskrec *rec, char *mask)
+bool u_match_mask(maskrec *rec, const char *mask)
 {
 {
   for (; rec; rec = rec->next)
   for (; rec; rec = rec->next)
     if (wild_match(rec->mask, mask) || match_cidr(rec->mask, mask))
     if (wild_match(rec->mask, mask) || match_cidr(rec->mask, mask))

+ 93 - 125
src/mod/irc.mod/chan.c

@@ -59,7 +59,7 @@ static void resolv_member_callback(int id, void *client_data, const char *host,
   }
   }
 
 
   memberlist *m = NULL;
   memberlist *m = NULL;
-  char *pe = NULL, s[UHOSTLEN + 1], user[15] = "";
+  char *pe = NULL, user[15] = "";
   bool matched_user = 0;
   bool matched_user = 0;
 
 
   /* Apply lookup results to all matching members by host */
   /* Apply lookup results to all matching members by host */
@@ -69,9 +69,9 @@ static void resolv_member_callback(int id, void *client_data, const char *host,
       if (pe && !strcmp(pe + 1, r->host)) {
       if (pe && !strcmp(pe + 1, r->host)) {
         strlcpy(user, m->userhost, pe - m->userhost + 1);
         strlcpy(user, m->userhost, pe - m->userhost + 1);
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, bd::String(ips[0]).c_str());
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, bd::String(ips[0]).c_str());
+        simple_snprintf(m->fromip, sizeof(m->fromip), "%s!%s", m->nick, m->userip);
         if (!m->user) {
         if (!m->user) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
-          m->user = get_user_by_host(s);
+          m->user = get_user_by_host(m->fromip);
 
 
           /* Act on this lookup */
           /* Act on this lookup */
           if (m->user)
           if (m->user)
@@ -286,13 +286,9 @@ static memberlist *newmember(struct chanset_t *chan, char *nick)
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
 static bool member_getuser(memberlist* m, bool act_on_lookup) {
   if (!m) return 0;
   if (!m) return 0;
   if (!m->user && !m->tried_getuser) {
   if (!m->user && !m->tried_getuser) {
-    static char s[UHOSTLEN] = "";
-
-    simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-    m->user = get_user_by_host(s);
+    m->user = get_user_by_host(m->from);
     if (!m->user && m->userip[0]) {
     if (!m->user && m->userip[0]) {
-      simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
-      m->user = get_user_by_host(s);
+      m->user = get_user_by_host(m->fromip);
     }
     }
     m->tried_getuser = 1;
     m->tried_getuser = 1;
 
 
@@ -363,7 +359,7 @@ static char *getchanmode(struct chanset_t *chan)
   return s;
   return s;
 }
 }
 
 
-static void check_exemptlist(struct chanset_t *chan, char *from)
+static void check_exemptlist(struct chanset_t *chan, const char *from)
 {
 {
   if (!use_exempts)
   if (!use_exempts)
     return;
     return;
@@ -542,30 +538,28 @@ static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode)
 /* This is a clone of detect_flood, but works for channel specificity now
 /* This is a clone of detect_flood, but works for channel specificity now
  * and handles kick & deop as well.
  * and handles kick & deop as well.
  */
  */
-static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
-			     struct chanset_t *chan, int which, char *victim)
+static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t *chan, int which, const char *msg)
 {
 {
-  if (!chan || (which < 0) || (which >= FLOOD_CHAN_MAX))
+  /* Do not punish non-existant channel members and IRC services like
+   * ChanServ
+   */
+  if (!chan || (which < 0) || (which >= FLOOD_CHAN_MAX) || !m)
     return 0;
     return 0;
 
 
   /* Okay, make sure i'm not flood-checking myself */
   /* Okay, make sure i'm not flood-checking myself */
-  if (match_my_nick(floodnick))
+  if (m->is_me) {
     return 0;
     return 0;
-  if (!strcasecmp(floodhost, botuserhost))
+  }
+  if (!strcasecmp(m->userhost, botuserhost))
     return 0;
     return 0;
   /* My user@host (?) */
   /* My user@host (?) */
 
 
-  /* Do not punish non-existant channel members and IRC services like
-   * ChanServ
-   */
-  memberlist *m = ismember(chan, floodnick);
-
-  if (!m && (which != FLOOD_JOIN) && (which != FLOOD_PART))
-    return 0;
-
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
+  struct userrec *u = NULL;
 
 
-  get_user_flagrec(get_user_by_host(from), &fr, chan->dname, chan);
+  member_getuser(m);
+  u = m->user;
+  get_user_flagrec(u, &fr, chan->dname, chan);
   if (glob_bot(fr) ||
   if (glob_bot(fr) ||
       ((which == FLOOD_DEOP) &&
       ((which == FLOOD_DEOP) &&
        (glob_master(fr) || chan_master(fr))) ||
        (glob_master(fr) || chan_master(fr))) ||
@@ -579,7 +573,6 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
     return 0;
     return 0;
 
 
   char h[UHOSTLEN] = "", ftype[12] = "", *p = NULL;
   char h[UHOSTLEN] = "", ftype[12] = "", *p = NULL;
-  struct userrec *u = NULL;
   int thr = 0;
   int thr = 0;
   time_t lapse = 0;
   time_t lapse = 0;
 
 
@@ -622,9 +615,9 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
     return 0;			/* no flood protection */
     return 0;			/* no flood protection */
 
 
   if ((which == FLOOD_KICK) || (which == FLOOD_DEOP))
   if ((which == FLOOD_KICK) || (which == FLOOD_DEOP))
-    p = floodnick;
+    p = m->nick;
   else {
   else {
-    p = strchr(floodhost, '@');
+    p = strchr(m->userhost, '@');
     if (p) {
     if (p) {
       p++;
       p++;
     }
     }
@@ -643,22 +636,12 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
     chan->floodnum[which] = 1;
     chan->floodnum[which] = 1;
     return 0;
     return 0;
   }
   }
-  /* Deop'n the same person, sillyness ;) - so just ignore it */
-  if (which == FLOOD_DEOP) {
-    if (!rfc_casecmp(chan->deopd, victim))
-      return 0;
-    else
-      strlcpy(chan->deopd, victim, sizeof(chan->deopd));
-  }
   chan->floodnum[which]++;
   chan->floodnum[which]++;
   if (chan->floodnum[which] >= thr) {	/* FLOOD */
   if (chan->floodnum[which] >= thr) {	/* FLOOD */
     /* Reset counters */
     /* Reset counters */
     chan->floodnum[which] = 0;
     chan->floodnum[which] = 0;
     chan->floodtime[which] = 0;
     chan->floodtime[which] = 0;
     chan->floodwho[which][0] = 0;
     chan->floodwho[which][0] = 0;
-    if (which == FLOOD_DEOP)
-      chan->deopd[0] = 0;
-    u = get_user_by_host(from);
     switch (which) {
     switch (which) {
     case FLOOD_PRIVMSG:
     case FLOOD_PRIVMSG:
     case FLOOD_NOTICE:
     case FLOOD_NOTICE:
@@ -666,14 +649,12 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       /* Flooding chan! either by public or notice */
       /* Flooding chan! either by public or notice */
       if (!chan_sentkick(m) && me_op(chan)) {
       if (!chan_sentkick(m) && me_op(chan)) {
         if (channel_floodban(chan)) {
         if (channel_floodban(chan)) {
-          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- banning", floodnick);
-          char s[UHOSTLEN] = "", *s1 = NULL;
-          simple_snprintf(s, sizeof(s), "%s!%s", floodnick, floodhost);
-          s1 = quickban(chan, s);
+          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- banning", m->nick);
+          char *s1 = quickban(chan, from);
           u_addmask('b', chan, s1, conf.bot->nick, "channel flood", now + (60 * chan->ban_time), 0);
           u_addmask('b', chan, s1, conf.bot->nick, "channel flood", now + (60 * chan->ban_time), 0);
         } else {
         } else {
-          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- kicking", floodnick);
-          dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, floodnick, kickprefix, response(RES_FLOOD));
+          putlog(LOG_MODES, chan->dname, "Channel flood from %s -- kicking", m->nick);
+          dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_FLOOD));
           m->flags |= SENTKICK;
           m->flags |= SENTKICK;
         }
         }
       }
       }
@@ -702,10 +683,8 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       if (which == FLOOD_PART)
       if (which == FLOOD_PART)
         add_mode(chan, '+', 'b', h);
         add_mode(chan, '+', 'b', h);
       if (!channel_enforcebans(chan) && me_op(chan)) {
       if (!channel_enforcebans(chan) && me_op(chan)) {
-	  char s[UHOSTLEN];
 	  for (m = chan->channel.member; m && m->nick[0]; m = m->next) {	  
 	  for (m = chan->channel.member; m && m->nick[0]; m = m->next) {	  
-	    simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-	    if (!chan_sentkick(m) && wild_match(h, s) &&
+	    if (!chan_sentkick(m) && wild_match(h, m->from) &&
 		(m->joined >= chan->floodtime[which]) &&
 		(m->joined >= chan->floodtime[which]) &&
 		!m->is_me && me_op(chan)) {
 		!m->is_me && me_op(chan)) {
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
@@ -719,8 +698,8 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       return 1;
       return 1;
     case FLOOD_KICK:
     case FLOOD_KICK:
       if (me_op(chan) && !chan_sentkick(m)) {
       if (me_op(chan) && !chan_sentkick(m)) {
-	putlog(LOG_MODES, chan->dname, "Kicking %s, for mass kick.", floodnick);
-        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, floodnick, kickprefix, response(RES_KICKFLOOD));
+	putlog(LOG_MODES, chan->dname, "Kicking %s, for mass kick.", m->nick);
+        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_KICKFLOOD));
 	m->flags |= SENTKICK;
 	m->flags |= SENTKICK;
       }
       }
       if (channel_protect(chan))
       if (channel_protect(chan))
@@ -730,7 +709,7 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
       if (me_op(chan) && !chan_sentkick(m)) {
       if (me_op(chan) && !chan_sentkick(m)) {
 	putlog(LOG_MODES, chan->dname,
 	putlog(LOG_MODES, chan->dname,
 	       "Mass deop on %s by %s", chan->dname, from);
 	       "Mass deop on %s by %s", chan->dname, from);
-        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, floodnick, kickprefix, response(RES_MASSDEOP));
+        dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix, response(RES_MASSDEOP));
 	m->flags |= SENTKICK;
 	m->flags |= SENTKICK;
       }
       }
       if (u) {
       if (u) {
@@ -748,23 +727,21 @@ static bool detect_chan_flood(char *floodnick, char *floodhost, char *from,
 }
 }
 
 
 /* Given a chan/m do all necesary exempt checks and ban. */
 /* Given a chan/m do all necesary exempt checks and ban. */
-static void refresh_ban_kick(struct chanset_t*, memberlist *, char *);
+static void refresh_ban_kick(struct chanset_t*, memberlist *, const char *);
 static void do_closed_kick(struct chanset_t *chan, memberlist *m)
 static void do_closed_kick(struct chanset_t *chan, memberlist *m)
 {
 {
   if (!chan || !m) return;
   if (!chan || !m) return;
 
 
-  char s[UHOSTLEN] = "", *s1 = NULL;
-
-  simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
+  char *s1 = NULL;
 
 
   if (!(use_exempts &&
   if (!(use_exempts &&
-        (u_match_mask(global_exempts,s) ||
-         u_match_mask(chan->exempts, s)))) {
-    if (u_match_mask(global_bans, s) || u_match_mask(chan->bans, s))
-      refresh_ban_kick(chan, m, s);
+        (u_match_mask(global_exempts, m->from) ||
+         u_match_mask(chan->exempts, m->from)))) {
+    if (u_match_mask(global_bans, m->from) || u_match_mask(chan->bans, m->from))
+      refresh_ban_kick(chan, m, m->from);
 
 
-    check_exemptlist(chan, s);
-    s1 = quickban(chan, s);
+    check_exemptlist(chan, m->from);
+    s1 = quickban(chan, m->from);
     u_addmask('b', chan, s1, conf.bot->nick, "joined closed chan", now + (60 * chan->ban_time), 0);
     u_addmask('b', chan, s1, conf.bot->nick, "joined closed chan", now + (60 * chan->ban_time), 0);
   }
   }
   return;
   return;
@@ -772,7 +749,7 @@ static void do_closed_kick(struct chanset_t *chan, memberlist *m)
 
 
 /* Given a nick!user@host, place a quick ban on them on a chan.
 /* Given a nick!user@host, place a quick ban on them on a chan.
  */
  */
-static char *quickban(struct chanset_t *chan, char *from)
+static char *quickban(struct chanset_t *chan, const char *from)
 {
 {
   static char s1[512] = "";
   static char s1[512] = "";
 
 
@@ -787,27 +764,21 @@ static char *quickban(struct chanset_t *chan, char *from)
 static void kick_all(struct chanset_t *chan, char *hostmask, const char *comment, int bantype)
 static void kick_all(struct chanset_t *chan, char *hostmask, const char *comment, int bantype)
 {
 {
   int flushed = 0;
   int flushed = 0;
-  char s[UHOSTLEN] = "", sip[UHOSTLEN] = "";
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
 
   for (memberlist *m = chan->channel.member; m && m->nick[0]; m = m->next) {
   for (memberlist *m = chan->channel.member; m && m->nick[0]; m = m->next) {
-    simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-    if (m->userip[0])
-      simple_snprintf(sip, sizeof(sip), "%s!%s", m->nick, m->userip);
-    else
-      sip[0] = 0;
     get_user_flagrec(m->user, &fr, chan->dname, chan);
     get_user_flagrec(m->user, &fr, chan->dname, chan);
-    if ((wild_match(hostmask, s) || match_cidr(hostmask, s) ||
-          (sip[0] && (wild_match(hostmask, sip) || match_cidr(hostmask, sip)))) &&
+    if ((wild_match(hostmask, m->from) || match_cidr(hostmask, m->from) ||
+          (m->userip[0] && (wild_match(hostmask, m->fromip) || match_cidr(hostmask, m->fromip)))) &&
         !chan_sentkick(m) &&
         !chan_sentkick(m) &&
 	!m->is_me && !chan_issplit(m) &&
 	!m->is_me && !chan_issplit(m) &&
 	!(use_exempts &&
 	!(use_exempts &&
-	  ((bantype && (isexempted(chan, s) || (chan->ircnet_status & CHAN_ASKED_EXEMPTS))) ||
-	   (u_match_mask(global_exempts, s) ||
-	    u_match_mask(chan->exempts, s) ||
-            (sip[0] &&
-             (u_match_mask(global_exempts, sip) ||
-              u_match_mask(chan->exempts, sip))))))) {
+	  ((bantype && (isexempted(chan, m->from) || (chan->ircnet_status & CHAN_ASKED_EXEMPTS))) ||
+	   (u_match_mask(global_exempts, m->from) ||
+	    u_match_mask(chan->exempts, m->from) ||
+            (m->userip[0] &&
+             (u_match_mask(global_exempts, m->fromip) ||
+              u_match_mask(chan->exempts, m->fromip))))))) {
       if (!flushed) {
       if (!flushed) {
 	/* We need to kick someone, flush eventual bans first */
 	/* We need to kick someone, flush eventual bans first */
 	flush_mode(chan, QUICK);
 	flush_mode(chan, QUICK);
@@ -823,7 +794,7 @@ static void kick_all(struct chanset_t *chan, char *hostmask, const char *comment
 
 
 /* If any bans match this wildcard expression, refresh them on the channel.
 /* If any bans match this wildcard expression, refresh them on the channel.
  */
  */
-static void refresh_ban_kick(struct chanset_t* chan, memberlist *m, char *user)
+static void refresh_ban_kick(struct chanset_t* chan, memberlist *m, const char *user)
 {
 {
   if (!m || chan_sentkick(m))
   if (!m || chan_sentkick(m))
     return;
     return;
@@ -879,7 +850,7 @@ static void refresh_exempt(struct chanset_t *chan, char *user)
   }
   }
 }
 }
 
 
-static void refresh_invite(struct chanset_t *chan, char *user)
+static void refresh_invite(struct chanset_t *chan, const char *user)
 {
 {
   maskrec *i = NULL;
   maskrec *i = NULL;
 
 
@@ -909,14 +880,11 @@ static void enforce_bans(struct chanset_t *chan)
   if ((chan->ircnet_status & CHAN_ASKED_EXEMPTS))
   if ((chan->ircnet_status & CHAN_ASKED_EXEMPTS))
     return;
     return;
 
 
-  char me[UHOSTLEN] = "", meip[UHOSTLEN] = "";
-
-  simple_snprintf(me, sizeof(me), "%s!%s", botname, botuserhost);
-  simple_snprintf(meip, sizeof(meip), "%s!%s", botname, botuserip);
+  const memberlist *me = ismember(chan, botname);
 
 
   /* Go through all bans, kicking the users. */
   /* Go through all bans, kicking the users. */
   for (masklist *b = chan->channel.ban; b && b->mask[0]; b = b->next) {
   for (masklist *b = chan->channel.ban; b && b->mask[0]; b = b->next) {
-    if (!(wild_match(b->mask, me) || match_cidr(b->mask, meip)) && !isexempted(chan, b->mask))
+    if (!(wild_match(b->mask, me->from) || match_cidr(b->mask, me->fromip)) && !isexempted(chan, b->mask))
       kick_all(chan, b->mask, "You are banned", 1);
       kick_all(chan, b->mask, "You are banned", 1);
   }
   }
 }
 }
@@ -1026,14 +994,14 @@ void check_this_ban(struct chanset_t *chan, char *banmask, bool sticky)
   if (!me_op(chan))
   if (!me_op(chan))
     return;
     return;
 
 
-  char user[UHOSTLEN] = "";
+  const char *user = NULL;
 
 
   for (memberlist *m = chan->channel.member; m && m->nick[0]; m = m->next) {
   for (memberlist *m = chan->channel.member; m && m->nick[0]; m = m->next) {
     for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
     for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
       if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
       if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
-        simple_snprintf(user, sizeof(user), "%s!%s", m->nick, m->userip);
+        user = m->fromip;
       else
       else
-        simple_snprintf(user, sizeof(user), "%s!%s", m->nick, m->userhost);
+        user = m->from;
       if ((wild_match(banmask, user)  || match_cidr(banmask, user)) &&
       if ((wild_match(banmask, user)  || match_cidr(banmask, user)) &&
           !(use_exempts &&
           !(use_exempts &&
             (u_match_mask(global_exempts, user) ||
             (u_match_mask(global_exempts, user) ||
@@ -1182,12 +1150,12 @@ static void check_this_member(struct chanset_t *chan, char *nick, struct flag_re
     }
     }
   }
   }
 
 
-  char s[UHOSTLEN] = "";
+  const char *s = NULL;
   for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
   for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
     if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
     if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
-      simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
+      s = m->fromip;
     else
     else
-      simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
+      s = m->from;
 
 
     /* check vs invites */
     /* check vs invites */
     if (use_invites &&
     if (use_invites &&
@@ -1239,11 +1207,12 @@ void check_this_user(char *hand, int del, char *host)
           u = NULL; // Pretend user doesn't exist when checking
           u = NULL; // Pretend user doesn't exist when checking
       } else if (0 && del == 2) { //-host, may now match on a diff user and need to act on them
       } else if (0 && del == 2) { //-host, may now match on a diff user and need to act on them
         /*
         /*
+        const char *s = NULL;
         for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
         for (int i = 0; i < (m->userip[0] ? 2 : 1); ++i) {
           if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
           if (i == 0 && m->userip[0]) // Check userip first in case userhost is already an ip
-            simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
+            s = m->fromip;
           else
           else
-            simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
+            s = m->from;
           if (wild_match(host, s) ||
           if (wild_match(host, s) ||
               (i == 0 && m->userip[0] && match_cidr(host, s))) {
               (i == 0 && m->userip[0] && match_cidr(host, s))) {
             check_member = 1;
             check_member = 1;
@@ -1897,12 +1866,14 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
 
 
     /* Store the userhost */
     /* Store the userhost */
     simple_snprintf(m->userhost, sizeof(m->userhost), "%s@%s", user, host);
     simple_snprintf(m->userhost, sizeof(m->userhost), "%s@%s", user, host);
+    simple_snprintf(m->from, sizeof(m->from), "%s!%s", m->nick, m->userhost);
 
 
     if (!m->userip[0]) {
     if (!m->userip[0]) {
       if (ip)
       if (ip)
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, ip);
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, ip);
       else if (is_dotted_ip(host))
       else if (is_dotted_ip(host))
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, host);
         simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, host);
+      simple_snprintf(m->fromip, sizeof(m->fromip), "%s!%s", m->nick, m->userip);
     }
     }
   }
   }
 
 
@@ -2604,8 +2575,6 @@ static int gotjoin(char *from, char *chname)
 
 
     chan->ircnet_status &= ~CHAN_STOP_CYCLE;
     chan->ircnet_status &= ~CHAN_STOP_CYCLE;
 
 
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_JOIN, NULL);
-
     if ((host = strchr(uhost, '@')))
     if ((host = strchr(uhost, '@')))
       ++host;
       ++host;
 
 
@@ -2639,6 +2608,7 @@ static int gotjoin(char *from, char *chname)
           if (!m->user && !m->userip[0] && doresolv(chan)) {
           if (!m->user && !m->userip[0] && doresolv(chan)) {
             if (is_dotted_ip(host)) {
             if (is_dotted_ip(host)) {
               strlcpy(m->userip, uhost, sizeof(m->userip));
               strlcpy(m->userip, uhost, sizeof(m->userip));
+              simple_snprintf(m->fromip, sizeof(m->fromip), "%s!%s", m->nick, m->userip);
               if (channel_rbl(chan))
               if (channel_rbl(chan))
                 resolve_to_rbl(chan, m->userip);
                 resolve_to_rbl(chan, m->userip);
             } else
             } else
@@ -2651,8 +2621,11 @@ static int gotjoin(char *from, char *chname)
 	m = newmember(chan, nick);
 	m = newmember(chan, nick);
 	m->joined = m->last = now;
 	m->joined = m->last = now;
 	strlcpy(m->userhost, uhost, sizeof(m->userhost));
 	strlcpy(m->userhost, uhost, sizeof(m->userhost));
-        if (is_dotted_ip(host))
+        simple_snprintf(m->from, sizeof(m->from), "%s!%s", m->nick, m->userhost);
+        if (is_dotted_ip(host)) {
           strlcpy(m->userip, uhost, sizeof(m->userip));
           strlcpy(m->userip, uhost, sizeof(m->userip));
+          simple_snprintf(m->fromip, sizeof(m->fromip), "%s!%s", m->nick, m->userip);
+        }
         m->user = get_user_by_host(from);
         m->user = get_user_by_host(from);
         m->tried_getuser = 1;
         m->tried_getuser = 1;
 
 
@@ -2664,6 +2637,7 @@ static int gotjoin(char *from, char *chname)
 //	m->flags |= STOPWHO;
 //	m->flags |= STOPWHO;
 
 
 	if (match_my_nick(nick)) {
 	if (match_my_nick(nick)) {
+          m->is_me = 1;
 	  /* It was me joining! Need to update the channel record with the
 	  /* It was me joining! Need to update the channel record with the
 	   * unique name for the channel (as the server see's it). <cybah>
 	   * unique name for the channel (as the server see's it). <cybah>
 	   */
 	   */
@@ -2682,6 +2656,7 @@ static int gotjoin(char *from, char *chname)
  	    reset_chan_info(chan);
  	    reset_chan_info(chan);
 	} else {
 	} else {
           irc_log(chan, "Join: %s (%s)", nick, uhost);
           irc_log(chan, "Join: %s (%s)", nick, uhost);
+          detect_chan_flood(m, from, chan, FLOOD_JOIN);
 	  set_handle_laston(chan->dname, m->user, now);
 	  set_handle_laston(chan->dname, m->user, now);
 	}
 	}
       }
       }
@@ -2834,7 +2809,7 @@ static int gotpart(char *from, char *msg)
     set_handle_laston(chan->dname, u, now);
     set_handle_laston(chan->dname, u, now);
 
 
     if (m) {
     if (m) {
-      detect_chan_flood(nick, m->userhost, from, chan, FLOOD_PART, NULL);
+      detect_chan_flood(m, from, chan, FLOOD_PART);
       killmember(chan, nick);
       killmember(chan, nick);
     }
     }
     if (msg[0])
     if (msg[0])
@@ -2878,7 +2853,6 @@ static int gotkick(char *from, char *origmsg)
     fixcolon(msg);
     fixcolon(msg);
     strlcpy(uhost, from, sizeof(buf));
     strlcpy(uhost, from, sizeof(buf));
     whodid = splitnick(&uhost);
     whodid = splitnick(&uhost);
-    detect_chan_flood(whodid, uhost, from, chan, FLOOD_KICK, nick);
 
 
     chan = findchan(chname);
     chan = findchan(chname);
     if (!chan)
     if (!chan)
@@ -2886,6 +2860,8 @@ static int gotkick(char *from, char *origmsg)
 
 
     m = ismember(chan, whodid);
     m = ismember(chan, whodid);
     if (m) {
     if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_KICK);
+
       m->last = now;
       m->last = now;
       member_getuser(m);
       member_getuser(m);
       if (m->user) {
       if (m->user) {
@@ -2970,6 +2946,7 @@ static int gotnick(char *from, char *msg)
       }
       }
 
 
       strlcpy(m->nick, msg, sizeof(m->nick));
       strlcpy(m->nick, msg, sizeof(m->nick));
+      strlcpy(m->from, s1, sizeof(m->from));
 
 
       /*
       /*
        * Banned?
        * Banned?
@@ -2977,7 +2954,7 @@ static int gotnick(char *from, char *msg)
 
 
       memberlist_reposition(chan, m);
       memberlist_reposition(chan, m);
 
 
-      detect_chan_flood(msg, uhost, from, chan, FLOOD_NICK, NULL);
+      detect_chan_flood(m, from, chan, FLOOD_NICK);
 
 
       /* don't fill the serverqueue with modes or kicks in a nickflood */
       /* don't fill the serverqueue with modes or kicks in a nickflood */
       if (chan_sentkick(m) || chan_sentdeop(m) || chan_sentop(m) ||
       if (chan_sentkick(m) || chan_sentdeop(m) || chan_sentop(m) ||
@@ -3149,8 +3126,9 @@ static int gotmsg(char *from, char *msg)
   memberlist *m = ismember(chan, nick);
   memberlist *m = ismember(chan, nick);
 
 
   /* Only check if flood-ctcp is active */
   /* Only check if flood-ctcp is active */
-  if (flood_ctcp.count && detect_avalanche(msg)) {
-    u = get_user_by_host(from);
+  if (m && flood_ctcp.count && detect_avalanche(msg)) {
+    member_getuser(m);
+    u = m->user;
     get_user_flagrec(u, &fr, chan->dname, chan);
     get_user_flagrec(u, &fr, chan->dname, chan);
     /* Discard -- kick user if it was to the channel */
     /* Discard -- kick user if it was to the channel */
     if (m && me_op(chan) && 
     if (m && me_op(chan) && 
@@ -3196,13 +3174,9 @@ static int gotmsg(char *from, char *msg)
       ctcp = buf2;
       ctcp = buf2;
       strlcpy(ctcp, p1, sizeof(buf2));
       strlcpy(ctcp, p1, sizeof(buf2));
       strcpy(p1 - 1, p + 1);
       strcpy(p1 - 1, p + 1);
-      detect_chan_flood(nick, uhost, from, chan,
-			strncmp(ctcp, "ACTION ", 7) ?
-			FLOOD_CTCP : FLOOD_PRIVMSG, NULL);
-
-      chan = findchan(realto);
-      if (!chan)
-        return 0;
+      if (m) {
+        detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+      }
 
 
       /* Respond to the first answer_ctcp */
       /* Respond to the first answer_ctcp */
       p = strchr(msg, 1);
       p = strchr(msg, 1);
@@ -3214,10 +3188,6 @@ static int gotmsg(char *from, char *msg)
 	  if (!ignoring || trigger_on_ignore) {
 	  if (!ignoring || trigger_on_ignore) {
 	    if (check_bind_ctcp(nick, uhost, u, to, code, ctcp) == BIND_RET_LOG) {
 	    if (check_bind_ctcp(nick, uhost, u, to, code, ctcp) == BIND_RET_LOG) {
 
 
-	      chan = findchan(realto); 
-	      if (!chan)
-		return 0;
-
 	      update_idle(chan->dname, nick);
 	      update_idle(chan->dname, nick);
             }
             }
 	      /* Log DCC, it's to a channel damnit! */
 	      /* Log DCC, it's to a channel damnit! */
@@ -3255,8 +3225,9 @@ static int gotmsg(char *from, char *msg)
       detect_offense(m, chan, msg);
       detect_offense(m, chan, msg);
 #endif
 #endif
 
 
-    /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_PRIVMSG, NULL);
+    if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_PRIVMSG);
+    }
     
     
     if (auth_chan) {
     if (auth_chan) {
       my_msg = my_ptr = strdup(msg);
       my_msg = my_ptr = strdup(msg);
@@ -3307,9 +3278,13 @@ static int gotnotice(char *from, char *msg)
   fixcolon(msg);
   fixcolon(msg);
   strlcpy(uhost, from, sizeof(buf));
   strlcpy(uhost, from, sizeof(buf));
   nick = splitnick(&uhost);
   nick = splitnick(&uhost);
-  u = get_user_by_host(from);
+  memberlist *m = ismember(chan, nick);
+  if (m) {
+    member_getuser(m);
+    u = m->user;
+  }
+
   if (flood_ctcp.count && detect_avalanche(msg)) {
   if (flood_ctcp.count && detect_avalanche(msg)) {
-    memberlist *m = ismember(chan, nick);
 
 
     get_user_flagrec(u, &fr, chan->dname, chan);
     get_user_flagrec(u, &fr, chan->dname, chan);
     /* Discard -- kick user if it was to the channel */
     /* Discard -- kick user if it was to the channel */
@@ -3346,13 +3321,9 @@ static int gotnotice(char *from, char *msg)
       strlcpy(ctcp, p1, sizeof(buf2));
       strlcpy(ctcp, p1, sizeof(buf2));
       strcpy(p1 - 1, p + 1);
       strcpy(p1 - 1, p + 1);
       p = strchr(msg, 1);
       p = strchr(msg, 1);
-      detect_chan_flood(nick, uhost, from, chan,
-			strncmp(ctcp, "ACTION ", 7) ?
-			FLOOD_CTCP : FLOOD_PRIVMSG, NULL);
-
-      chan = findchan(realto); 
-      if (!chan)
-	return 0;
+      if (m) {
+        detect_chan_flood(m, from, chan, strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
+      }
 
 
       if (ctcp[0] != ' ') {
       if (ctcp[0] != ' ') {
 	code = newsplit(&ctcp);
 	code = newsplit(&ctcp);
@@ -3369,12 +3340,9 @@ static int gotnotice(char *from, char *msg)
     }
     }
   }
   }
   if (msg[0]) {
   if (msg[0]) {
-    /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
-    detect_chan_flood(nick, uhost, from, chan, FLOOD_NOTICE, NULL);
-
-    chan = findchan(realto); 
-    if (!chan)
-      return 0;
+    if (m) {
+      detect_chan_flood(m, from, chan, FLOOD_NOTICE);
+    }
 
 
     update_idle(chan->dname, nick);
     update_idle(chan->dname, nick);
 
 

+ 15 - 28
src/mod/irc.mod/cmdsirc.c

@@ -284,8 +284,8 @@ static void cmd_kickban(int idx, char *par)
       dprintf(idx, "%s is not on %s\n", nick, chan->dname);
       dprintf(idx, "%s is not on %s\n", nick, chan->dname);
       return;
       return;
     }
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m->user;
     get_user_flagrec(u, &victim, chan->dname);
     get_user_flagrec(u, &victim, chan->dname);
   
   
     if ((chan_master(victim) || glob_master(victim)) &&
     if ((chan_master(victim) || glob_master(victim)) &&
@@ -484,7 +484,6 @@ static void cmd_op(int idx, char *par)
   if (!all && !chan)
   if (!all && !chan)
     return;
     return;
 
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   memberlist *m = NULL;
   struct userrec *u = NULL;
   struct userrec *u = NULL;
 
 
@@ -528,8 +527,8 @@ static void cmd_op(int idx, char *par)
     dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
     dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
     return;
     return;
   }
   }
-  simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  u = get_user_by_host(s);
+  member_getuser(m);
+  u = m->user;
   get_user_flagrec(u, &victim, chan->dname);
   get_user_flagrec(u, &victim, chan->dname);
   if (chk_deop(victim, chan)) {
   if (chk_deop(victim, chan)) {
     dprintf(idx, "%s is currently being auto-deopped  on %s.\n", m->nick, chan->dname);
     dprintf(idx, "%s is currently being auto-deopped  on %s.\n", m->nick, chan->dname);
@@ -976,7 +975,6 @@ static void cmd_deop(int idx, char *par)
   if (!all && !chan)
   if (!all && !chan)
     return;
     return;
 
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   memberlist *m = NULL;
   struct userrec *u = NULL;
   struct userrec *u = NULL;
 
 
@@ -1022,8 +1020,8 @@ static void cmd_deop(int idx, char *par)
       dprintf(idx, "I'm not going to deop myself.\n");
       dprintf(idx, "I'm not going to deop myself.\n");
       return;
       return;
     }
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m->user;
     get_user_flagrec(u, &victim, chan->dname);
     get_user_flagrec(u, &victim, chan->dname);
 
 
     if ((chan_master(victim) || glob_master(victim)) &&
     if ((chan_master(victim) || glob_master(victim)) &&
@@ -1080,7 +1078,6 @@ static void cmd_kick(int idx, char *par)
     return;
     return;
   }
   }
 
 
-  char s[UHOSTLEN] = "";
   memberlist *m = NULL;
   memberlist *m = NULL;
   struct userrec *u = NULL;
   struct userrec *u = NULL;
 
 
@@ -1117,8 +1114,8 @@ static void cmd_kick(int idx, char *par)
       dprintf(idx, "%s is not on %s\n", nick, chan->dname);
       dprintf(idx, "%s is not on %s\n", nick, chan->dname);
       return;
       return;
     }
     }
-    simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-    u = get_user_by_host(s);
+    member_getuser(m);
+    u = m->user;
     get_user_flagrec(u, &victim, chan->dname);
     get_user_flagrec(u, &victim, chan->dname);
     if (chk_op(victim, chan) && !(chan_master(user) || glob_master(user))) {
     if (chk_op(victim, chan) && !(chan_master(user) || glob_master(user))) {
       if (all) goto next;
       if (all) goto next;
@@ -1209,7 +1206,6 @@ static void cmd_mop(int idx, char *par)
   putlog(LOG_CMDS, "*", "#%s# (%s) mop %s", dcc[idx].nick, all ? "*" : chan->dname, par);
   putlog(LOG_CMDS, "*", "#%s# (%s) mop %s", dcc[idx].nick, all ? "*" : chan->dname, par);
 
 
   memberlist *m = NULL;
   memberlist *m = NULL;
-  char s[256] = "";
 
 
   while (chan) {
   while (chan) {
     get_user_flagrec(dcc[idx].user, &user, chan->dname);
     get_user_flagrec(dcc[idx].user, &user, chan->dname);
@@ -1230,14 +1226,7 @@ static void cmd_mop(int idx, char *par)
     }
     }
     if (channel_active(chan) && !channel_pending(chan)) {
     if (channel_active(chan) && !channel_pending(chan)) {
       for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
       for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
-        if (!m->user) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-          m->user = get_user_by_host(s);
-          if (!m->user && m->userip[0]) {
-            simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
-            m->user = get_user_by_host(s);
-          }
-        }
+        member_getuser(m);
         if (m->user && u_pass_match(m->user, "-"))
         if (m->user && u_pass_match(m->user, "-"))
           continue;		/* dont op users without a pass */
           continue;		/* dont op users without a pass */
         get_user_flagrec(m->user, &victim, chan->dname);
         get_user_flagrec(m->user, &victim, chan->dname);
@@ -1295,10 +1284,8 @@ static void cmd_find(int idx, char *par)
 
 
       for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
       for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
         member_getuser(m, 1);
         member_getuser(m, 1);
-        char s[UHOSTLEN] = "";
 
 
-        simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
-        if ((!lookup_user && wild_match(par, s)) || (lookup_user && m->user == u)) {
+        if ((!lookup_user && wild_match(par, m->from)) || (lookup_user && m->user == u)) {
           fcount++;
           fcount++;
           if (!found) {
           if (!found) {
             found = (memberlist **) my_calloc(1, sizeof(memberlist *) * 100);
             found = (memberlist **) my_calloc(1, sizeof(memberlist *) * 100);
@@ -1732,8 +1719,8 @@ static void cmd_adduser(int idx, char *par)
   }
   }
   if (strlen(hand) > HANDLEN)
   if (strlen(hand) > HANDLEN)
     hand[HANDLEN] = 0;
     hand[HANDLEN] = 0;
-  simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  if ((u = get_user_by_host(s))) {
+  member_getuser(m);
+  if ((u = m->user)) {
     dprintf(idx, "%s is already known as %s.\n", nick, u->handle);
     dprintf(idx, "%s is already known as %s.\n", nick, u->handle);
     return;
     return;
   }
   }
@@ -1787,7 +1774,7 @@ static void cmd_deluser(int idx, char *par)
     return;
     return;
   }
   }
 
 
-  char *nick = NULL, s[UHOSTLEN] = "", *added = NULL;
+  char *nick = NULL, *added = NULL;
   struct chanset_t *chan = NULL;
   struct chanset_t *chan = NULL;
   memberlist *m = NULL;
   memberlist *m = NULL;
   struct userrec *u = NULL;
   struct userrec *u = NULL;
@@ -1804,8 +1791,8 @@ static void cmd_deluser(int idx, char *par)
     return;
     return;
   }
   }
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
   get_user_flagrec(dcc[idx].user, &user, chan->dname);
-  simple_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-  if (!(u = get_user_by_host(s))) {
+  member_getuser(m);
+  if (!(u = m->user)) {
     dprintf(idx, "%s is not a valid user.\n", nick);
     dprintf(idx, "%s is not a valid user.\n", nick);
     return;
     return;
   }
   }

+ 0 - 2
src/mod/irc.mod/irc.c

@@ -1374,7 +1374,6 @@ check_expired_chanstuff(struct chanset_t *chan)
   if (channel_active(chan) && shouldjoin(chan)) {
   if (channel_active(chan) && shouldjoin(chan)) {
     masklist *b = NULL, *e = NULL;
     masklist *b = NULL, *e = NULL;
     memberlist *m = NULL, *n = NULL;
     memberlist *m = NULL, *n = NULL;
-    char s[UHOSTLEN] = "";
     struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
     struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
 
 
     if (me_op(chan)) {
     if (me_op(chan)) {
@@ -1434,7 +1433,6 @@ check_expired_chanstuff(struct chanset_t *chan)
       if (m->split) {
       if (m->split) {
         ++splitmembers;
         ++splitmembers;
         if (now - m->split > wait_split) {
         if (now - m->split > wait_split) {
-          simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userhost);
           putlog(LOG_JOIN, chan->dname, "%s (%s) got lost in the net-split.", m->nick, m->userhost);
           putlog(LOG_JOIN, chan->dname, "%s (%s) got lost in the net-split.", m->nick, m->userhost);
           --(chan->channel.splitmembers);
           --(chan->channel.splitmembers);
           killmember(chan, m->nick);
           killmember(chan, m->nick);

+ 2 - 3
src/mod/irc.mod/irc.h

@@ -82,11 +82,10 @@ static void do_protect(struct chanset_t* chan, const char* reason);
 static bool do_op(char *, struct chanset_t *, bool, bool);
 static bool do_op(char *, struct chanset_t *, bool, bool);
 static void request_op(struct chanset_t *);
 static void request_op(struct chanset_t *);
 static void request_in(struct chanset_t *);
 static void request_in(struct chanset_t *);
-static bool detect_chan_flood(char *, char *, char *, struct chanset_t *, int,
-			     char *);
+static bool detect_chan_flood(memberlist *m, const char* from, struct chanset_t *chan, int which, const char *msg = NULL);
 static bool new_mask(masklist *, char *, char *);
 static bool new_mask(masklist *, char *, char *);
 static void do_closed_kick(struct chanset_t *, memberlist *);
 static void do_closed_kick(struct chanset_t *, memberlist *);
-static char *quickban(struct chanset_t *, char *);
+static char *quickban(struct chanset_t *, const char *);
 static bool killmember(struct chanset_t *chan, char *nick);
 static bool killmember(struct chanset_t *chan, char *nick);
 static void check_lonely_channel(struct chanset_t *chan);
 static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
 static int gotmode(char *, char *);

+ 11 - 17
src/mod/irc.mod/mode.c

@@ -649,16 +649,12 @@ got_op(struct chanset_t *chan, memberlist *m, memberlist *mv)
 static void
 static void
 got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 {
 {
-  char s1[UHOSTLEN] = "";
   const bool was_op = chan_hasop(mv);
   const bool was_op = chan_hasop(mv);
 
 
   if (mdop_reversing && !was_op)
   if (mdop_reversing && !was_op)
     return;
     return;
 
 
   /* m is NULL if a server made the change */
   /* m is NULL if a server made the change */
-  if (m)
-    simple_snprintf(s1, sizeof(s1), "%s!%s", m->nick, m->userhost);
-
   if (mv->user) {
   if (mv->user) {
     get_user_flagrec(mv->user, &victim, chan->dname, chan);
     get_user_flagrec(mv->user, &victim, chan->dname, chan);
   }
   }
@@ -696,8 +692,9 @@ got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
   if (isserver[0])		/* !m */
   if (isserver[0])		/* !m */
     putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s", chan->dname, mv->nick, isserver);
     putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s", chan->dname, mv->nick, isserver);
   /* Check for mass deop */
   /* Check for mass deop */
-  else if (m)
-    detect_chan_flood(m->nick, m->userhost, s1, chan, FLOOD_DEOP, mv->nick);
+  else if (m) {
+    detect_chan_flood(m, m->from, chan, FLOOD_DEOP, mv->nick);
+  }
   /* Having op hides your +v and +h  status -- so now that someone's lost ops,
   /* Having op hides your +v and +h  status -- so now that someone's lost ops,
    * check to see if they have +v or +h
    * check to see if they have +v or +h
    */
    */
@@ -739,12 +736,11 @@ got_deop(struct chanset_t *chan, memberlist *m, memberlist *mv, char *isserver)
 static void
 static void
 got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
 got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
 {
 {
-  char me[UHOSTLEN] = "", meip[UHOSTLEN] = "", s[UHOSTLEN] = "";
+  const memberlist *me = ismember(chan, botname);
+  char s[UHOSTLEN] = "";
 
 
-  simple_snprintf(me, sizeof(me), "%s!%s", botname, botuserhost);
-  simple_snprintf(meip, sizeof(meip), "%s!%s", botname, botuserip);
   simple_snprintf(s, sizeof s, "%s!%s", m ? m->nick : "", m ? m->userhost : isserver);
   simple_snprintf(s, sizeof s, "%s!%s", m ? m->nick : "", m ? m->userhost : isserver);
-  if (newban(chan, mask, s))
+  if (m && newban(chan, mask, m->from))
     return; /* The ban was already set, don't bother with it */
     return; /* The ban was already set, don't bother with it */
 
 
   if (channel_pending(chan) || !me_op(chan))
   if (channel_pending(chan) || !me_op(chan))
@@ -753,17 +749,15 @@ got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
   // Make an array of all matching users
   // Make an array of all matching users
   bd::Array<memberlist*> matchedUserMembers;
   bd::Array<memberlist*> matchedUserMembers;
   bool matched_bot = false;
   bool matched_bot = false;
-  char s1[UHOSTLEN] = "";
 
 
   for (memberlist *mv = chan->channel.member; mv && mv->nick[0]; mv = mv->next) {
   for (memberlist *mv = chan->channel.member; mv && mv->nick[0]; mv = mv->next) {
     member_getuser(mv);
     member_getuser(mv);
     if (mv->user) {
     if (mv->user) {
-      simple_snprintf(s1, sizeof s1, "%s!%s", mv->nick, mv->userhost);
-      if ((wild_match(mask, s1) || match_cidr(mask, s1))) {
+      if ((wild_match(mask, mv->from) || match_cidr(mask, mv->from))) {
         if (!matched_bot && mv != m && mv->user->bot) {
         if (!matched_bot && mv != m && mv->user->bot) {
           matched_bot = true;
           matched_bot = true;
         }
         }
-        if (mv->user && !isexempted(chan, s1)) {
+        if (mv->user && !isexempted(chan, mv->from)) {
           matchedUserMembers << mv;
           matchedUserMembers << mv;
         }
         }
       }
       }
@@ -784,7 +778,7 @@ got_ban(struct chanset_t *chan, memberlist *m, char *mask, char *isserver)
     }
     }
   }
   }
 
 
-  if ((wild_match(mask, me) || match_cidr(mask, meip)) && !isexempted(chan, me)) {
+  if ((wild_match(mask, me->from) || match_cidr(mask, me->fromip)) && !isexempted(chan, me->from)) {
     add_mode(chan, '-', 'b', mask);
     add_mode(chan, '-', 'b', mask);
     reversing = 1;
     reversing = 1;
     return;
     return;
@@ -1243,7 +1237,7 @@ gotmode(char *from, char *msg)
                   const size_t len = simple_snprintf(tmp, sizeof(tmp), "KICK %s %s :%s%s\r\n", chan->name, m->nick, kickprefix, response(RES_BADOP));
                   const size_t len = simple_snprintf(tmp, sizeof(tmp), "KICK %s %s :%s%s\r\n", chan->name, m->nick, kickprefix, response(RES_BADOP));
                   dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                   dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                 }
                 }
-                simple_snprintf(tmp, sizeof(tmp), "%s!%s MODE %s %s", m->nick, m->userhost, chan->dname, modes[modecnt - 1]);
+                simple_snprintf(tmp, sizeof(tmp), "%s MODE %s %s", m->from, chan->dname, modes[modecnt - 1]);
                 deflag_user(u, DEFLAG_EVENT_BADCOOKIE, tmp, chan);
                 deflag_user(u, DEFLAG_EVENT_BADCOOKIE, tmp, chan);
               }
               }
               /* Do the logging last as it can slow down the KICK pushing */
               /* Do the logging last as it can slow down the KICK pushing */
@@ -1282,7 +1276,7 @@ gotmode(char *from, char *msg)
                     dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                     dprintf_real(DP_MODE_NEXT, tmp, len, sizeof(tmp));
                     m->flags |= SENTKICK;
                     m->flags |= SENTKICK;
                   }
                   }
-                  simple_snprintf(tmp, sizeof(tmp), "%s!%s MODE %s %s", m->nick, m->userhost, chan->dname, modes[modecnt - 1]);
+                  simple_snprintf(tmp, sizeof(tmp), "%s MODE %s %s", m->from, chan->dname, modes[modecnt - 1]);
                   deflag_user(u, DEFLAG_EVENT_MANUALOP, tmp, chan);
                   deflag_user(u, DEFLAG_EVENT_MANUALOP, tmp, chan);
                 }
                 }
                 break;
                 break;