diff -u include/m_commands.h include/m_commands.h
--- include/m_commands.h	Thu Jan  4 17:23:09 2001
+++ include/m_commands.h	Sun Jul  7 04:59:31 2002
@@ -33,6 +33,7 @@
 extern int m_kline(struct Client *,struct Client *,int,char **);
 extern int m_ungline(struct Client *,struct Client *,int,char **);
 extern int m_unkline(struct Client *,struct Client *,int,char **);
+extern int m_undline(struct Client *,struct Client *,int,char **);
 extern int m_dline(struct Client *,struct Client *,int,char **);
 
 extern int m_gline(struct Client *,struct Client *,int,char **);
diff -u include/msg.h include/msg.h
--- include/msg.h	Thu Jan  4 17:23:09 2001
+++ include/msg.h	Sun Jul  7 05:00:36 2002
@@ -114,6 +114,7 @@
 #define MSG_OPERWALL "OPERWALL" /* OPERWALL */
 #define MSG_KLINE    "KLINE"    /* KLINE */
 #define MSG_UNKLINE  "UNKLINE"  /* UNKLINE */
+#define MSG_UNDLINE  "UNDLINE"  /* UNDLINE */
 #define MSG_DLINE    "DLINE"    /* DLINE */
 #define MSG_HTM      "HTM"      /* HTM */
 #define MSG_SET      "SET"      /* SET */
@@ -241,6 +242,7 @@
   { MSG_CLOSE,   m_close,    0, MAXPARA, 1, 0, 0, 0L },
   { MSG_KLINE,   m_kline,    0, MAXPARA, 1, 0, 0, 0L },
   { MSG_UNKLINE, m_unkline,  0, MAXPARA, 1, 0, 0, 0L },
+  { MSG_UNDLINE, m_undline,  0, MAXPARA, 1, 0, 0, 0L },
   { MSG_DLINE,   m_dline,    0, MAXPARA, 1, 0, 0, 0L },
   { MSG_GLINE,   m_gline,    0, MAXPARA, 1, 0, 0, 0L },
   { MSG_UNGLINE, m_ungline,  0, MAXPARA, 1, 0, 0, 0L },
diff -u src/m_unkline.c src/m_unkline.c
--- src/m_unkline.c	Sat Nov 18 21:11:12 2000
+++ src/m_unkline.c	Sun Jul  7 04:56:46 2002
@@ -406,3 +406,215 @@
     }
   return NO;
 }
+/*
+** m_undline
+** added May 28th 2000 by Toby Verrall <toot@melnet.co.uk>
+** based totally on m_unkline
+**
+**      parv[0] = sender nick
+**      parv[1] = dline to remove
+*/
+int m_undline (aClient *cptr,aClient *sptr,int parc,char *parv[])
+{
+  FBFILE* in;
+  FBFILE* out;
+  int   pairme = NO;
+  char  buf[BUFSIZE];
+  char  buff[BUFSIZE];  /* matches line definition in s_conf.c */
+  char  temppath[256];
+
+  const char  *filename;                /* filename to use for undline */
+
+  char  *cidr;
+  char  *p;
+  unsigned long ip_host;
+  unsigned long ip_mask;
+  int   error_on_write = NO;
+  mode_t oldumask;
+
+  ircsprintf(temppath, "%s.tmp", ConfigFileEntry.dlinefile);
+
+  if (check_registered(sptr))
+    {
+      return -1;
+    }
+
+  if (!IsAnOper(sptr))
+    {
+      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name,
+                 parv[0]);
+      return 0;
+    }
+
+  if (!IsSetOperUnkline(sptr))
+    {
+      sendto_one(sptr,":%s NOTICE %s :You have no U flag",me.name,
+                 parv[0]);
+      return 0;
+    }
+
+  if ( parc < 2 )
+    {
+      sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "UNDLINE");
+      return 0;
+    }
+  
+  cidr = parv[1];
+
+  if (!is_address(cidr,&ip_host,&ip_mask))
+    {
+      sendto_one(sptr, ":%s NOTICE %s :Invalid parameters",
+                 me.name, parv[0]);
+      return 0;
+    }
+
+  filename = get_conf_name(DLINE_TYPE);
+
+  if( (in = fbopen(filename, "r")) == 0)
+    {
+      sendto_one(sptr, ":%s NOTICE %s :Cannot open %s",
+        me.name,parv[0],filename);
+      return 0;
+    }
+
+  oldumask = umask(0);                  /* ircd is normally too paranoid */
+  if( (out = fbopen(temppath, "w")) == 0)
+    {
+      sendto_one(sptr, ":%s NOTICE %s :Cannot open %s",
+        me.name,parv[0],temppath);
+      fbclose(in);
+      umask(oldumask);                  /* Restore the old umask */
+      return 0;
+    }
+  umask(oldumask);                    /* Restore the old umask */
+
+
+/*
+#toot!~toot@127.0.0.1 D'd: 123.4.5.0/24:test (2000/05/28 12.48)
+D:123.4.5.0/24:test (2000/05/28 12.48)
+*/
+
+  while(fbgets(buf, sizeof(buf), in))
+    {
+      if((buf[1] == ':') && ((buf[0] == 'd') || (buf[0] == 'D')))
+        {
+          /* its a D: line */
+          char *found_cidr;
+
+          strncpy_irc(buff, buf, BUFSIZE);      /* extra paranoia */
+
+          p = strchr(buff,'\n');
+          if(p)
+            *p = '\0';
+
+          found_cidr = buff + 2;        /* point past the D: */
+          p = strchr(found_cidr,':');
+          if(p == (char *)NULL)
+            {
+              sendto_one(sptr, ":%s NOTICE %s :D-Line file corrupted",
+                         me.name, parv[0]);
+              sendto_one(sptr, ":%s NOTICE %s :Couldn't find CIDR",
+                         me.name, parv[0]);
+              if(!error_on_write)
+                error_on_write = flush_write(sptr, out, buf, temppath);
+              continue;         /* This D line is corrupted ignore */
+            }
+         *p = '\0';   
+         
+         if(irccmp(cidr,found_cidr))
+            {
+              if(!error_on_write)
+                error_on_write = flush_write(sptr, out, buf, temppath);
+            }
+          else
+            pairme++;
+
+        } 
+      else if(buf[0] == '#')
+        {
+          char *found_cidr;
+
+          strncpy_irc(buff, buf, BUFSIZE);
+
+/*
+#toot!~toot@127.0.0.1 D'd: 123.4.5.0/24:test (2000/05/28 12.48)
+D:123.4.5.0/24:test (2000/05/28 12.48)
+
+If its a comment coment line, i.e.
+#ignore this line
+Then just ignore the line
+*/
+
+          p = strchr(buff,':');
+          if(p == (char *)NULL)
+            {
+              if(!error_on_write)
+                error_on_write = flush_write(sptr, out, buf, temppath);
+              continue;
+            }
+          *p = '\0';
+          p++;
+
+          found_cidr = p;
+          p = strchr(found_cidr,':');
+
+          if(p == (char *)NULL)
+            {
+              if(!error_on_write)
+                error_on_write = flush_write(sptr, out, buf, temppath);
+              continue;
+            }
+          *p = '\0';
+
+          while(*found_cidr == ' ')
+            found_cidr++;
+
+
+          if( (irccmp(found_cidr,cidr)))
+            {
+              if(!error_on_write)
+                error_on_write = flush_write(sptr, out, buf, temppath);
+            }
+        }
+
+      else      /* its the ircd.conf file, and not a D line or comment */
+        {
+          if(!error_on_write)
+            error_on_write = flush_write(sptr, out, buf, temppath);
+        }
+    }
+
+  fbclose(in);
+
+
+  if(!error_on_write)
+    {
+      fbclose(out);
+      (void)rename(temppath, filename);
+      rehash(cptr,sptr,0);
+    }
+  else
+    {
+      sendto_one(sptr,":%s NOTICE %s :Couldn't write D-line file, aborted",
+        me.name,parv[0]);
+      return -1;
+    }
+
+  if(!pairme)
+    {
+      sendto_one(sptr, ":%s NOTICE %s :No D-Line for %s",
+                 me.name, parv[0],cidr);
+      return 0;
+    }
+
+  sendto_one(sptr, ":%s NOTICE %s :D-Line for [%s] is removed",
+             me.name, parv[0], cidr);
+  sendto_ops("%s has removed the D-Line for: [%s]",
+             parv[0], cidr);
+
+  log(L_NOTICE, "%s removed D-Line for [%s]", parv[0], cidr);
+  return 0;
+}
+
+
