diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/channel.h ircd-hybrid-6.0/include/channel.h
--- ircd-hybrid-6.0.orig/include/channel.h	Thu May 31 09:26:09 2001
+++ ircd-hybrid-6.0/include/channel.h	Thu May 31 08:46:06 2001
@@ -81,6 +81,8 @@
 #ifdef FLUD
   time_t          fludblock;
   struct fludbot* fluders;
+  char            lastmsg[32];
+  int             repeatcount, lastlen;
 #endif
 #if defined(PRESERVE_CHANNEL_ON_SPLIT) || defined(NO_JOIN_ON_SPLIT)
   struct Channel* last_empty_channel;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/client.h ircd-hybrid-6.0/include/client.h
--- ircd-hybrid-6.0.orig/include/client.h	Thu May 31 09:26:08 2001
+++ ircd-hybrid-6.0/include/client.h	Thu May 31 08:46:06 2001
@@ -241,6 +241,10 @@
   time_t            last_nick_change;
   int               number_of_nick_changes;
 #endif
+#ifdef FLUD
+  char              lastmsg[32];
+  int               repeatcount, lastlen;
+#endif
   time_t            last_knock; /* don't allow knock to flood */
   /*
    * client->sockhost contains the ip address gotten from the socket as a
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/config.h ircd-hybrid-6.0/include/config.h
--- ircd-hybrid-6.0.orig/include/config.h	Thu May 31 09:26:09 2001
+++ ircd-hybrid-6.0/include/config.h	Thu May 31 08:46:06 2001
@@ -921,6 +921,12 @@
  */
 #define FLUD
 
+/* DEATHFLUD - excess FLUD is lethal, resulting in KILL
+ */
+#ifdef FLUD
+#define DEATHFLUD
+#endif
+
 /* ANTI_DRONE_FLOOD - anti flooding code for drones
  * This code adds server side ignore for a client who gets
  * messaged more than drone_count times within drone_time seconds
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/flud.h ircd-hybrid-6.0/include/flud.h
--- ircd-hybrid-6.0.orig/include/flud.h	Fri Oct  6 04:00:56 2000
+++ ircd-hybrid-6.0/include/flud.h	Thu May 31 08:46:02 2001
@@ -52,6 +52,7 @@
                                                         struct Client *);
 
 extern struct SLink *remove_fludee_reference(struct SLink **,void *);
+extern int check_for_spam(struct Client *,struct Client *,struct Channel *,char *);
 extern int check_for_ctcp(char *);
 extern int check_for_flud(struct Client *,struct Client *,struct Channel *,int);
 extern void free_fluders(struct Client *,struct Channel *);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/ircd.h ircd-hybrid-6.0/include/ircd.h
--- ircd-hybrid-6.0.orig/include/ircd.h	Thu May 31 09:26:05 2001
+++ ircd-hybrid-6.0/include/ircd.h	Thu May 31 08:46:02 2001
@@ -49,6 +49,7 @@
   int fludnum;
   int fludtime;
   int fludblock;
+  int killnum;
 #endif
 
 #ifdef ANTI_DRONE_FLOOD
@@ -107,7 +108,7 @@
 #define SPLITDELAY GlobalSetOptions.server_split_recovery_time
 #define SPLITNUM   GlobalSetOptions.split_smallnet_size
 #define SPLITUSERS GlobalSetOptions.split_smallnet_users
-
+#define KILLNUM    GlobalSetOptions.killnum
 
 extern char*          debugmode;
 extern int            debuglevel;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/channel.c ircd-hybrid-6.0/src/channel.c
--- ircd-hybrid-6.0.orig/src/channel.c	Thu May 31 09:26:09 2001
+++ ircd-hybrid-6.0/src/channel.c	Thu May 31 08:46:06 2001
@@ -3232,7 +3232,7 @@
             {
               if(SPAMNUM && (sptr->join_leave_count >= SPAMNUM))
                 {
-                  sendto_ops_flags(FLAGS_BOTS,
+                  sendto_ops_flags_butone(NULL, FLAGS_BOTS,
                                      "User %s (%s@%s) is a possible spambot",
                                      sptr->name,
                                      sptr->username, sptr->host);
@@ -3328,7 +3328,7 @@
  
               if(sptr->oper_warn_count_down == 0)
                 {
-                  sendto_ops_flags(FLAGS_BOTS,
+                  sendto_ops_flags_butone(NULL, FLAGS_BOTS,
                     "User %s (%s@%s) trying to join %s is a possible spambot",
                              sptr->name,
                              sptr->username,
@@ -3552,7 +3552,7 @@
         {
           if(SPAMNUM && (sptr->join_leave_count >= SPAMNUM))
             {
-              sendto_ops_flags(FLAGS_BOTS,
+              sendto_ops_flags_butone(NULL, FLAGS_BOTS,
                                "User %s (%s@%s) is a possible spambot",
                                sptr->name,
                                sptr->username, sptr->host);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/flud.c ircd-hybrid-6.0/src/flud.c
--- ircd-hybrid-6.0.orig/src/flud.c	Sat Nov 18 19:11:11 2000
+++ ircd-hybrid-6.0/src/flud.c	Thu May 31 09:24:12 2001
@@ -54,9 +54,40 @@
   else
     fludee = chptr->chname;
 
+#ifdef DEATHFLUD
+  switch(type)
+    {
+    case 1: /* classic CTCP */
+      sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s (ctcp %i)",
+                       fluder->name, fluder->username, fluder->host,
+                       fluder->user->server, fludee, fluder->repeatcount);
+      break;
+    case 2: /* repeating channel traffic */
+      sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s (echo %i)",
+                       fluder->name, fluder->username, fluder->host,
+                       fluder->user->server, fludee, fluder->repeatcount);
+      break;
+    case 3: /* repeating oneself */
+      sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s (spam %i)",
+                       fluder->name, fluder->username, fluder->host,
+                       fluder->user->server, fludee, fluder->repeatcount);
+      break;
+    case 4: /* insane message lengths */
+      sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s (len %i)",
+                       fluder->name, fluder->username, fluder->host,
+                       fluder->user->server, fludee, fluder->lastlen);
+      break;
+    default:
+      sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s",
+                       fluder->name, fluder->username, fluder->host,
+                       fluder->user->server, fludee);
+      break;
+    }
+#else /* DEATHFLUD */
   sendto_ops_flags(FLAGS_BOTS, "Flooder %s [%s@%s] on %s target: %s",
                  fluder->name, fluder->username, fluder->host,
                  fluder->user->server, fludee);
+#endif
 }
 
 
@@ -125,6 +156,64 @@
 }
 
 
+/* This function checks to see if the given message is being repeated,
+** etc.  Returns type of flood (2 if repeating channel traffic, 3 if
+** repeating himself), or 0 if none. Message is truncated to TOPICLEN
+** if too long.  Unfortunately, this makes for a LOT of extra
+** processing in the server.  */
+
+int check_for_spam(struct Client *fluder, /* fluder */
+                   struct Client *cptr,   /* client being fluded, NULL for now */
+                   struct Channel *chptr, /* channel being fluded */
+                   char *message)
+{
+  int flud = 0;
+  int len;
+
+  if (!MyConnect(fluder) || IsPrivileged(fluder))
+    return 0;
+
+  if ((len = strlen(message)) > 160)
+    {
+      if (fluder->repeatcount++) /* ignore it the first time */
+        flud = 4;
+    }
+  else if (!strncmp(fluder->lastmsg, message, 31)
+           || ((len > 31) && (len == fluder->lastlen)))
+    {
+      flud = 3;
+      fluder->repeatcount++;
+    }
+  else
+    {
+      strncpy(fluder->lastmsg, message, 32);
+      fluder->lastmsg[31] = 0;
+      fluder->repeatcount = 0;
+    }
+  fluder->lastlen = len;
+
+  if (chptr)
+    {
+      if (!strncmp(chptr->lastmsg, message, 31)
+          || ((len > 31) && (len == chptr->lastlen)))
+        {
+          if (!flud)
+            flud = 2;
+          chptr->repeatcount++;
+        }
+      else
+        {
+          strncpy(chptr->lastmsg, message, 32);
+          chptr->lastmsg[31] = 0;
+          chptr->repeatcount = 0;
+        }
+      chptr->lastlen = len;
+    }
+
+  return flud;
+}
+
+
 /* This function checks to see if a CTCP message (other than ACTION) is
 ** contained in the passed string.  This might seem easier than I am doing it,
 ** but a CTCP message can be changed together, even after a normal message.
@@ -164,8 +253,8 @@
   /* It's either got to be a client or a channel being fluded */
   if((cptr == NULL) && (chptr == NULL))
     return 0;
-  
-  if(cptr && !MyConnect(cptr))
+
+  if(cptr && !MyConnect(fluder))
     {
       sendto_realops("check_for_flud() called for non-local client");
       return 0;
@@ -293,14 +382,22 @@
       ** time to mention it to them. */
       if(cptr)
         sendto_one(cptr,     
-                   ":%s NOTICE %s :*** Notice -- Server flood protection activated for %s",
-                   me.name, cptr->name, cptr->name);
+                   ":%s NOTICE %s :*** Notice -- incoming %s flood from %s throttled at %s",
+                   me.name, cptr->name, cptr->name, fluder->name, me.name);
       else            
-        sendto_channel_butserv(chptr, &me,
-               ":%s NOTICE %s :*** Notice -- Server flood protection activated for %s",
+        sendto_channel_butone(NULL, &me, chptr,
+#ifdef DEATHFLUD
+               ":%s NOTICE %s :*** Notice -- %s throttling %s %s flood from %s",
+#else
+               ":%s NOTICE %s :*** Notice -- %s throttling %s flood from %s",
+#endif
                                me.name,
                                chptr->chname,
-                               chptr->chname);
+                               me.name, chptr->chname,
+#ifdef DEATHFLUD
+                               (type == 1) ? "CTCP" : "repeat",
+#endif
+                               fluder->name);
             
       /* Here we should go back through the existing list of
       ** fluders and announce that they were part of the game as 
@@ -324,7 +421,17 @@
       else
         chptr->fludblock = now;
     }               
- 
+
+#ifdef DEATHFLUD
+  if (blocking && fluder->repeatcount > KILLNUM)
+    {
+      sendto_ops_flags(FLAGS_SKILL, "Flood countermeasure, dumping user %s",
+                       fluder->name);
+      sendto_one(fluder, ":%s KILL %s :%s spam",
+                 me.name, fluder->name, cptr->name);
+      exit_client(fluder, fluder, &me, "Excessive spam");
+    }
+#endif
   return(blocking);
 }               
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/ircd.c ircd-hybrid-6.0/src/ircd.c
--- ircd-hybrid-6.0.orig/src/ircd.c	Thu May 31 09:26:06 2001
+++ ircd-hybrid-6.0/src/ircd.c	Thu May 31 08:46:03 2001
@@ -567,6 +567,7 @@
   FLUDNUM = FLUD_NUM;
   FLUDTIME = FLUD_TIME;
   FLUDBLOCK = FLUD_BLOCK;
+  KILLNUM = FLUD_NUM + 2;
 #endif
 
 #ifdef IDLE_CHECK
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_message.c ircd-hybrid-6.0/src/m_message.c
--- ircd-hybrid-6.0.orig/src/m_message.c	Thu May 31 09:26:09 2001
+++ ircd-hybrid-6.0/src/m_message.c	Thu May 31 08:46:06 2001
@@ -124,6 +124,9 @@
   char  *nick, *server, *cmd, *host;
   /* char *p; */
   int type=0, msgs=0;
+#ifdef FLUD
+  int flud;
+#endif
 
   cmd = notice ? MSG_NOTICE : MSG_PRIVATE;
 
@@ -181,9 +184,20 @@
         sptr->user->last = CurrentTime;
 #endif
 #ifdef FLUD
+#ifdef DEATHFLUD
+      if(!notice && check_for_ctcp(parv[2])
+         && check_for_flud(sptr, NULL, chptr, 1))
+        return 0;
+      if((flud = check_for_spam(sptr, NULL, chptr, parv[2])))
+        {
+          if (check_for_flud(sptr, NULL, chptr, flud))
+            return 0;
+        }
+#else /* DEATHFLUD */
       if(!notice)
-        if(check_for_ctcp(parv[2]))
-            check_for_flud(sptr, NULL, chptr, 1);
+	if(check_for_ctcp(parv[2]))
+	  check_for_flud(sptr, NULL, chptr, 1);
+#endif /* DEATHFLUD */
 #endif /* FLUD */
 
 #ifndef DISABLECHANMODEC
@@ -254,9 +268,20 @@
             sptr->user->last = CurrentTime;
 #endif
 #ifdef FLUD
+#ifdef DEATHFLUD
+          if(!notice && check_for_ctcp(parv[2])
+             && check_for_flud(sptr, NULL, chptr, 1))
+            return 0;
+          if((flud = check_for_spam(sptr, NULL, chptr, parv[2])))
+            {
+              if (check_for_flud(sptr, NULL, chptr, flud))
+                return 0;
+            }
+#else /* DEATHFLUD */
           if(!notice)
             if(check_for_ctcp(parv[2]))
               check_for_flud(sptr, NULL, chptr, 1);
+#endif /* DEATHFLUD */
 #endif /* FLUD */
 
           if (!is_chan_op(sptr,chptr))
@@ -301,11 +326,22 @@
         sptr->user->last = CurrentTime;
 #endif
 #ifdef FLUD
-      if(!notice && MyConnect(acptr))
-        if(check_for_ctcp(parv[2]))
-          if(check_for_flud(sptr, acptr, NULL, 1))
+#ifdef DEATHFLUD
+      if(!notice && check_for_ctcp(parv[2])
+         && check_for_flud(sptr, acptr, NULL, 1))
+        return 0;
+      if((flud = check_for_spam(sptr, acptr, NULL, parv[2])))
+        {
+          if (check_for_flud(sptr, acptr, NULL, flud))
             return 0;
-#endif
+        }
+#else /* DEATHFLUD */
+      if(!notice && MyConnect(acptr))
+	if(check_for_ctcp(parv[2]))
+	  if(check_for_flud(sptr, acptr, NULL, 1))
+	    return 0;
+#endif /* DEATHFLUD */
+#endif /* FLUD */
 #ifdef ANTI_DRONE_FLOOD
       if(MyConnect(acptr) && IsClient(sptr) && !IsAnOper(sptr) && DRONETIME)
         {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_set.c ircd-hybrid-6.0/src/m_set.c
--- ircd-hybrid-6.0.orig/src/m_set.c	Thu May 31 09:26:06 2001
+++ ircd-hybrid-6.0/src/m_set.c	Thu May 31 08:46:02 2001
@@ -126,7 +126,8 @@
 #define TOKEN_SPAMNUM 11
 #define TOKEN_SPAMTIME 12
 #define TOKEN_LOG 13
-#define TOKEN_BAD 14
+#define TOKEN_KILLNUM 14
+#define TOKEN_BAD 15
 
 static char *set_token_table[] = {
   "MAX",
@@ -143,6 +144,9 @@
   "SPAMNUM",
   "SPAMTIME",
   "LOG",
+#ifdef DEATHFLUD
+  "KILLNUM",
+#endif
   NULL
 };
 
@@ -271,6 +275,9 @@
                     return 0;
                   }       
                 FLUDNUM = newval;
+#ifdef DEATHFLUD
+                if (FLUDNUM >= KILLNUM) KILLNUM = FLUDNUM + 2;
+#endif
                 sendto_realops("%s has changed FLUDNUM to %i",
                                parv[0], FLUDNUM);
               }
@@ -335,6 +342,32 @@
               }
             return 0;       
             break;
+
+#ifdef DEATHFLUD
+          case TOKEN_KILLNUM:
+            if(parc > 2)
+              {
+                int newval = atoi(parv[2]);
+
+                if(newval <= FLUDNUM)
+                  {
+                    sendto_one(sptr, ":%s NOTICE %s :KILLNUM must be > FLUDNUM",
+                               me.name, parv[0]);
+                    return 0;
+                  }       
+                KILLNUM = newval;
+                sendto_realops("%s has changed KILLNUM to %i, fear",
+                               parv[0], KILLNUM);
+              }
+            else
+              {
+                sendto_one(sptr, ":%s NOTICE %s :KILLNUM is currently %i",
+                           me.name, parv[0], KILLNUM);
+              }
+            return 0;
+            break;
+#endif /* DEATHFLUD */
+
 #endif
 #ifdef ANTI_DRONE_FLOOD
           case TOKEN_DRONETIME:
@@ -581,10 +614,14 @@
           break;
         }
     }
-  sendto_one(sptr, ":%s NOTICE %s :Options: MAX AUTOCONN",
+  sendto_one(sptr, ":%s NOTICE %s :Options: MAX, AUTOCONN",
              me.name, parv[0]);
 #ifdef FLUD
+#ifdef DEATHFLUD
+  sendto_one(sptr, ":%s NOTICE %s :Options: FLUDNUM, FLUDTIME, FLUDBLOCK, KILLNUM",
+#else /* DEATHFLUD */
   sendto_one(sptr, ":%s NOTICE %s :Options: FLUDNUM, FLUDTIME, FLUDBLOCK",
+#endif /* DEATHFLUD */
              me.name, parv[0]);
 #endif
 #ifdef ANTI_DRONE_FLOOD
