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	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/include/config.h	Tue Jul  3 19:36:34 2001
@@ -174,7 +174,7 @@
  * names for your services pseudo-users
   */
   
-#define SERVICES_NAME "services.openprojects.quiet"
+/*#define SERVICES_NAME "services.openprojects.quiet"*/
   
 #define CHANSERV "ChanServ"
 #define NICKSERV "NickServ"
@@ -869,6 +869,11 @@
  * Include the code and data to calculate TSDELTA on request
  */
 #define TSDELTA
+
+/*
+ * Use full-blown K:lines with timeouts in the hold field, rather than tKlines
+ */
+#define FULL_TIMEOUT_KLINES
 
 /*   STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP  */
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/m_kline.h ircd-hybrid-6.0/include/m_kline.h
--- ircd-hybrid-6.0.orig/include/m_kline.h	Fri Jul 30 07:48:11 1999
+++ ircd-hybrid-6.0/include/m_kline.h	Tue Jul  3 19:31:35 2001
@@ -21,6 +21,8 @@
 #ifndef INCLUDED_m_kline_h
 #define INCLUDED_m_kline_h
 
+#include <time.h>
+
 struct Client;
 
 struct PKDlines
@@ -33,6 +35,7 @@
   char*            reason; /* reason they are K/D lined */
   char*            when; /* when the K/D line was set */
   int              type;
+  time_t           until; /* expiry time */
 };
 
 typedef struct PKDlines aPendingLine;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/numeric.h ircd-hybrid-6.0/include/numeric.h
--- ircd-hybrid-6.0.orig/include/numeric.h	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/include/numeric.h	Mon Jul  2 22:27:08 2001
@@ -313,6 +313,7 @@
 #define ERR_TOOMANYTARGETS   407
 #define ERR_NOCOLORSTOCHAN   408
 #define ERR_NOORIGIN         409
+#define ERR_SERVICES_OFFLINE 410
 
 #define ERR_NORECIPIENT      411
 #define ERR_NOTEXTTOSEND     412
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/patchlevel.h ircd-hybrid-6.0/include/patchlevel.h
--- ircd-hybrid-6.0.orig/include/patchlevel.h	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/include/patchlevel.h	Tue Jul  3 10:19:35 2001
@@ -17,5 +17,5 @@
  */
 
 #ifndef PATCHLEVEL
-#define PATCHLEVEL    "dancer-ircd-0.9.3.4(rc1)"
+#define PATCHLEVEL    "dancer-ircd-0.9.3.5(rc2)"
 #endif
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/s_conf.h ircd-hybrid-6.0/include/s_conf.h
--- ircd-hybrid-6.0.orig/include/s_conf.h	Tue Jul  3 19:48:55 2001
+++ ircd-hybrid-6.0/include/s_conf.h	Tue Jul  3 15:29:06 2001
@@ -390,6 +390,7 @@
 extern struct ConfItem* find_conf_by_host(const char* host, unsigned int status);
 extern struct ConfItem* find_conf_by_abbrevname(const char* name, unsigned int status);
 extern struct ConfItem* find_kill (struct Client *);
+extern struct ConfItem* find_tkline(const char*, const char*, unsigned long);
 extern int conf_connect_allowed(struct in_addr addr);
 extern char *oper_flags_as_string(umode_t);
 extern int rehash_dump(struct Client *);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_kline.c ircd-hybrid-6.0/src/m_kline.c
--- ircd-hybrid-6.0.orig/src/m_kline.c	Tue Jul  3 19:48:54 2001
+++ ircd-hybrid-6.0/src/m_kline.c	Tue Jul  3 19:35:29 2001
@@ -71,6 +71,9 @@
 static void WritePendingLines(const char *);
 static void WriteKline(const char *, aClient *, aClient *,
                        const char *, const char *, const char *, 
+#ifdef FULL_TIMEOUT_KLINES
+		       time_t until,
+#endif
                        const char *);
 static void WriteDline(const char *, aClient *,
                        const char *, const char *, const char *);
@@ -198,12 +201,15 @@
     if (PendingLines->type == KLINE_TYPE)
     {
       WriteKline(filename,
-        PendingLines->sptr,
-        PendingLines->rcptr,
-        PendingLines->user,
-        PendingLines->host,
-        PendingLines->reason,
-        PendingLines->when);
+		 PendingLines->sptr,
+		 PendingLines->rcptr,
+		 PendingLines->user,
+		 PendingLines->host,
+		 PendingLines->reason,
+#ifdef FULL_TIMEOUT_KLINES
+		 PendingLines->until,
+#endif
+		 PendingLines->when);
     }
     else
     {
@@ -232,6 +238,9 @@
 static void
 WriteKline(const char *filename, aClient *sptr, aClient *rcptr,
            const char *user, const char *host, const char *reason, 
+#ifdef FULL_TIMEOUT_KLINES
+	   time_t until,
+#endif
            const char *when)
 
 {
@@ -242,12 +251,12 @@
     return;
 
   if ((out = open(filename, O_RDWR|O_APPEND|O_CREAT, 0644)) == (-1))
-  {
-    sendto_ops_flag(UMODE_DEBUG, "Error opening %s: %s",
-			   filename,
-			   strerror(errno));
-    return;
-  }
+    {
+      sendto_ops_flag(UMODE_DEBUG, "Error opening %s: %s",
+		      filename,
+		      strerror(errno));
+      return;
+    }
 
 #ifdef SEPARATE_QUOTE_KLINES_BY_DATE
   fchmod(out, 0660);
@@ -255,39 +264,59 @@
 
 #ifdef SLAVE_SERVERS
   if (IsServer(sptr))
-  {
-    if (rcptr)
-      ircsprintf(buffer,
-        "#%s!%s@%s from %s K'd: %s@%s:%s\n",
-        rcptr->name,
-        rcptr->username,
-        rcptr->host,
-        sptr->name,
-        user,
-        host,
-        reason);
-  }
+    {
+      if (rcptr)
+	{
+	  if (IsServer(rcptr))
+	    ircsprintf(buffer,
+		       "#%s propagated K: %s@%s:%s\n",
+		       rcptr->name,
+		       user,
+		       host,
+		       reason);
+	  else
+	    ircsprintf(buffer,
+		       "#%s!%s@%s from server %s K'd: %s@%s:%s\n",
+		       rcptr->name,
+		       rcptr->username,
+		       rcptr->host,
+		       sptr->name,
+		       user,
+		       host,
+		       reason);
+	}
+    }
   else
 #endif /* SLAVE_SERVERS */
-  {
-    ircsprintf(buffer,
-      "#%s!%s@%s K'd: %s@%s:%s\n",
-      sptr->name,
-      sptr->username,
-      sptr->host,
-      user,
-      host,
-      reason);
-  }
+    {
+      ircsprintf(buffer,
+		 "#%s!%s@%s K'd: %s@%s:%s\n",
+		 sptr->name,
+		 sptr->username,
+		 sptr->host,
+		 user,
+		 host,
+		 reason);
+    }
 
   if (safe_write(sptr, filename, out, buffer) == (-1))
     return;
 
-  ircsprintf(buffer, "K:%s:%s (%s):%s\n",
-    host,
-    reason,
-    when,
-    user);
+#ifdef FULL_TIMEOUT_KLINES
+  if (until)
+    ircsprintf(buffer, "K:%s:%s (%s):%s:::%d\n",
+	       host,
+	       reason,
+	       when,
+	       user,
+	       until);
+  else
+#endif
+    ircsprintf(buffer, "K:%s:%s (%s):%s\n",
+	       host,
+	       reason,
+	       when,
+	       user);
 
   if (safe_write(sptr, filename, out, buffer) == (-1))
     return;
@@ -399,8 +428,12 @@
 
       if ((rcptr = hash_find_client(slave_oper,(aClient *)NULL)))
         {
-          if(!IsPerson(rcptr))
-            return 0;
+	  /* Servers can send out KLINEs now, when they need to propagate a local
+	   * KLINE to a remote server which appears to be missing it
+	   *  -- asuffield
+	   */
+          if(!IsPerson(rcptr) && !IsServer(rcptr))
+	    return 0;
         }
       else
         return 0;
@@ -417,8 +450,6 @@
 
 #endif
       sendto_slaves(sptr,"KLINE",slave_oper,parc,parv);
-
-
     }
   else
 #endif
@@ -714,33 +745,37 @@
   DupString(aconf->user, user);
   aconf->port = 0;
 
+#ifndef FULL_TIMEOUT_KLINES
   if(temporary_kline_time)
     {
       ircsprintf(buffer,
-        "Temporary K-line %d min. - %s (%s)",
-        temporary_kline_time,
-        reason ? reason : "No reason",
-        current_date);
+		 "Temporary K-line %d min. - %s (%s)",
+		 temporary_kline_time,
+		 reason ? reason : "No reason",
+		 current_date);
       DupString(aconf->passwd, buffer );
+#endif
       aconf->hold = CurrentTime + temporary_kline_time_seconds;
       if(ip_kline)
         {
           aconf->ip = ip;
           aconf->ip_mask = ip_mask;
         }
+#ifndef FULL_TIMEOUT_KLINES
       add_temp_kline(aconf);
       rehashed = YES;
       dline_in_progress = NO;
       nextping = CurrentTime;
-      sendto_ops_flag(UMODE_SERVNOTICE, "%s added temporary %d min. K-Line for [%s@%s] [%s]",
-			     rcptr ? rcptr->name : parv[0],
-			     temporary_kline_time,
-			     user,
-			     host,
-			     reason ? reason : "No reason");
+      sendto_local_ops_flag(UMODE_SERVNOTICE, "%s added temporary %d min. K-Line for [%s@%s] [%s]",
+			    rcptr ? rcptr->name : parv[0],
+			    temporary_kline_time,
+			    user,
+			    host,
+			    reason ? reason : "No reason");
       return 0;
     }
   else
+#endif
     {
       ircsprintf(buffer, "%s (%s)",
         reason ? reason : "No reason",
@@ -758,11 +793,21 @@
   else
     add_mtrie_conf_entry(aconf,CONF_KILL);
 
-  sendto_ops_flag(UMODE_SERVNOTICE, "%s added K-Line for [%s@%s] [%s]",
-			 rcptr ? rcptr->name : sptr->name,
-			 user,
-			 host,
-			 reason ? reason : "No reason");
+#ifdef FULL_TIMEOUT_KLINES
+  if(temporary_kline_time)
+    sendto_local_ops_flag(UMODE_SERVNOTICE, "%s added K-Line for [%s@%s] [%s], expiring at %d (%d minutes)",
+			  rcptr ? rcptr->name : sptr->name,
+			  user,
+			  host,
+			  reason ? reason : "No reason",
+			  aconf->hold, temporary_kline_time);
+  else
+#endif
+    sendto_local_ops_flag(UMODE_SERVNOTICE, "%s added K-Line for [%s@%s] [%s]",
+			  rcptr ? rcptr->name : sptr->name,
+			  user,
+			  host,
+			  reason ? reason : "No reason");
 
   log(L_TRACE, "%s added K-Line for [%s@%s] [%s]",
       sptr->name, user, host, reason ? reason : "No reason");
@@ -797,12 +842,16 @@
     pptr->rcptr = (aClient *) NULL;
 #endif
 
+#ifdef FULL_TIMEOUT_KLINES
+    pptr->until = aconf->hold;
+#endif
+
     sendto_one(sptr,
-      ":%s NOTICE %s :Added K-Line [%s@%s] (config file write delayed)",
-      me.name,
-      sptr->name,
-      user,
-      host);
+	       ":%s NOTICE %s :Added K-Line [%s@%s] (config file write delayed)",
+	       me.name,
+	       sptr->name,
+	       user,
+	       host);
 
     return 0;
   }
@@ -810,32 +859,38 @@
     WritePendingLines(kconf);
 
   sendto_one(sptr,
-    ":%s NOTICE %s :Added K-Line [%s@%s] to %s",
-    me.name,
-    sptr->name,
-    user,
-    host,
-    kconf ? kconf : "configuration file");
+	     ":%s NOTICE %s :Added K-Line [%s@%s] to %s",
+	     me.name,
+	     sptr->name,
+	     user,
+	     host,
+	     kconf ? kconf : "configuration file");
 
   /*
    * Write kline to configuration file
    */
 #ifdef SLAVE_SERVERS
   WriteKline(kconf,
-    sptr,
-    rcptr,
-    user,
-    host,
-    reason ? reason : "No reason",
-    current_date);
+	     sptr,
+	     rcptr,
+	     user,
+	     host,
+	     reason ? reason : "No reason",
+#ifdef FULL_TIMEOUT_KLINES
+	     aconf->hold,
+#endif
+	     current_date);
 #else
   WriteKline(kconf,
-    sptr,
-    (aClient *) NULL,
-    user,
-    host,
-    reason ? reason : "No reason",
-    current_date);
+	     sptr,
+	     (aClient *) NULL,
+	     user,
+	     host,
+	     reason ? reason : "No reason",
+#ifdef FULL_TIMEOUT_KLINES
+	     aconf->hold,
+#endif
+	     current_date);
 #endif
 
   rehashed = YES;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_services.c ircd-hybrid-6.0/src/m_services.c
--- ircd-hybrid-6.0.orig/src/m_services.c	Tue Jul  3 19:48:51 2001
+++ ircd-hybrid-6.0/src/m_services.c	Tue Jul  3 10:21:27 2001
@@ -95,18 +95,22 @@
  */
 int m_chanserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+
+  if (!(acptr = find_person(CHANSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+  /* OK, enough with the safety checks. The nick should be Q:lined anyway. */
                                                                 
-	if ((acptr = find_person (CHANSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], CHANSERV, SERVICES_NAME, parv[1]);        
-		return(0);
-	} else  {
-		return(-1);
-	}
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], CHANSERV, parv[1]);        
+  return(0);
 }
 
 
@@ -116,18 +120,21 @@
  */
 int m_nickserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (NICKSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], NICKSERV, SERVICES_NAME, parv[1]);        
-		return(0);
-	} else  {
-		return(-1);
-	}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+	
+  if (!(acptr = find_person(NICKSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], NICKSERV, parv[1]);        
+  return(0);
 }
 
 /*
@@ -136,18 +143,31 @@
  */
 int m_memoserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-                                                                
-	if ((acptr = find_person (MEMOSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], MEMOSERV, SERVICES_NAME, parv[1]);        
-		return(0);
-	} else {
-		return(-1);
-	}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+
+  if (!(acptr = find_person(MEMOSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+  if (!(a2cptr = find_server(acptr->user->server)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+  if (!(a2cptr->caps & CAP_SERVICES))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], MEMOSERV, parv[1]);        
+  return(0);
 }
 
 /*
@@ -156,18 +176,21 @@
  */
 int m_operserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (OPERSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], OPERSERV, SERVICES_NAME, parv[1]);
-		return(0);
-	} else  {
-		return(-1);
-		}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+
+  if (!(acptr = find_person(OPERSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+	
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], OPERSERV, parv[1]);
+  return(0);
 }
 /*
  * m_seenserv
@@ -175,18 +198,21 @@
  */
 int m_seenserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (SEENSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], SEENSERV, SERVICES_NAME, parv[1]);
-		return(0);
-	} else  {
-		return(-1);
-		}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+	
+  if (!(acptr = find_person(SEENSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], SEENSERV, parv[1]);
+  return(0);
 }
 /*
  * m_statserv
@@ -194,18 +220,21 @@
  */
 int m_statserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (STATSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], STATSERV, SERVICES_NAME, parv[1]);
-		return(0);
-	} else  {
-		return(-1);
-		}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+	
+  if (!(acptr = find_person(STATSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], STATSERV, parv[1]);
+  return(0);
 }
 /*
  * m_helpserv
@@ -213,18 +242,21 @@
  */
 int m_helpserv(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (HELPSERV, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], HELPSERV, SERVICES_NAME, parv[1]);
-		return(0);
-	} else  {
-		return(-1);
-		}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+	
+  if (!(acptr = find_person(HELPSERV, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], HELPSERV, parv[1]);
+  return(0);
 }
 
 /*
@@ -233,18 +265,21 @@
  */
 int m_global(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
-	struct Client       *acptr;
-	if (parc < 2 || *parv[1] == '\0') {
-		sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
-		return(-1);
-	}
-	
-	if ((acptr = find_person (GLOBALNOTICE, NULL))) {
-		sendto_one(acptr, ":%s PRIVMSG %s@%s :%s", parv[0], GLOBALNOTICE, SERVICES_NAME, parv[1]);
-		return(0);
-	} else  {
-		return(-1);
-		}
+  struct Client       *acptr;
+  struct Client* a2cptr;
+  if (parc < 2 || *parv[1] == '\0') {
+    sendto_one (sptr, form_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
+    return(-1);
+  }
+
+  if (!(acptr = find_person(GLOBALNOTICE, NULL)))
+    {
+      sendto_one(sptr, form_str(ERR_SERVICES_OFFLINE), me.name, parv[0]);
+      return 0;
+    }
+	
+  sendto_one(acptr, ":%s PRIVMSG %s :%s", parv[0], GLOBALNOTICE, parv[1]);
+  return(0);
 }
 
 #endif /* USE_SERVICES */
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_spingtime.c ircd-hybrid-6.0/src/m_spingtime.c
--- ircd-hybrid-6.0.orig/src/m_spingtime.c	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/src/m_spingtime.c	Mon Jul  2 22:05:41 2001
@@ -116,7 +116,6 @@
   acptr->ping_time.tv_sec = 0;
   acptr->ping_time.tv_usec = atoi(parv[2]);
 
-  sendto_ops_flag(UMODE_DEBUG, "Using SPINGTIME for %s from %s", parv[1], parv[0]);
   sendto_serv_butone(cptr, ":%s SPINGTIME %s %s", parv[0], parv[1], parv[2]);
 
   return 0;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_unkline.c ircd-hybrid-6.0/src/m_unkline.c
--- ircd-hybrid-6.0.orig/src/m_unkline.c	Tue Jul  3 19:48:53 2001
+++ ircd-hybrid-6.0/src/m_unkline.c	Tue Jul  3 17:41:54 2001
@@ -81,13 +81,13 @@
   mode_t oldumask;
 
   ircsprintf(temppath, "%s.tmp", ConfigFileEntry.klinefile);
-  
-  if (check_registered(sptr))
+
+  if (!IsMe(sptr) && check_registered(sptr))
     {
       return -1;
     }
 
-  if (!(IsServer(sptr) || IsSetOperUnkline(sptr)))  
+  if (!(IsMe(sptr) || IsServer(sptr) || IsSetOperUnkline(sptr)))  
     {
       if (SeesOperMessages(sptr))
 	sendto_one(sptr,":%s NOTICE %s :You have no U umode",me.name,parv[0]);
@@ -99,10 +99,10 @@
 
   if ( parc < 2 )
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
                    me.name, parv[0], "UNKLINE");
-      return 0;
+      return -1;
     }
 
   sendto_serv_butone(sptr, ":%s UNKLINE %s", parv[0], parv[1]);
@@ -124,24 +124,24 @@
     }
   else
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :Invalid parameters",
                    me.name, parv[0]);
-      return 0;
+      return -1;
     }
 
   if( (user[0] == '*') && (user[1] == '\0')
       && (host[0] == '*') && (host[1] == '\0') )
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :Cannot UNK-Line everyone",
                    me.name, parv[0]);
-      return 0;
+      return -1;
     }
 
   if(remove_tkline_match(host,user))
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :Un-klined [%s@%s] from temporary k-lines",
                    me.name, parv[0],user, host);
       sendto_ops_flag(UMODE_SERVNOTICE, "%s has removed the temporary K-Line for: [%s@%s]",
@@ -156,21 +156,21 @@
 
   if( (in = fbopen(filename, "r")) == 0)
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :Cannot open %s",
                    me.name,parv[0],filename);
-      return 0;
+      return -1;
     }
 
   oldumask = umask(0);                  /* ircd is normally too paranoid */
   if( (out = fbopen(temppath, "w")) == 0)
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :Cannot open %s",
                    me.name,parv[0],temppath);
       fbclose(in);
       umask(oldumask);                  /* Restore the old umask */
-      return 0;
+      return -1;
     }
     umask(oldumask);                    /* Restore the old umask */
 
@@ -198,7 +198,7 @@
           p = strchr(found_host,':');
           if(p == (char *)NULL)
             {
-	      if (!IsServer(cptr)) {		 
+	      if (!IsServer(cptr) && !IsMe(cptr)) {		 
               sendto_one(sptr, ":%s NOTICE %s :K-Line file corrupted",
                          me.name, parv[0]);
               sendto_one(sptr, ":%s NOTICE %s :Couldn't find host",
@@ -216,13 +216,14 @@
           p = strchr(found_comment,':');
           if(p == (char *)NULL)
             {
-	      if (!IsServer(cptr)) { 
-              sendto_one(sptr, ":%s NOTICE %s :K-Line file corrupted",
-                         me.name, parv[0]);
-              sendto_one(sptr, ":%s NOTICE %s :Couldn't find comment",
-                         me.name, parv[0]);
-              log(L_ERROR, "K-Line file corrupted (couldn't find comment)");
-	      }
+	      if (!IsServer(cptr) && !IsMe(cptr))
+		{ 
+		  sendto_one(sptr, ":%s NOTICE %s :K-Line file corrupted",
+			     me.name, parv[0]);
+		  sendto_one(sptr, ":%s NOTICE %s :Couldn't find comment",
+			     me.name, parv[0]);
+		  log(L_ERROR, "K-Line file corrupted (couldn't find comment)");
+		}
               if(!error_on_write)
                 error_on_write = flush_write(sptr, out, buf, temppath);
               continue;         /* This K line is corrupted ignore */
@@ -231,6 +232,11 @@
           p++;
           found_user = p;
 
+	  /* If I have more fields, clip here */
+          p = strchr(found_user,':');
+	  if (p)
+	    *p = '\0';
+
 /*
  * Ok, if its not an exact match on either the user or the host
  * then, write the K: line out, and I add it back to the K line
@@ -324,7 +330,7 @@
     }
   else
     {
-       if (!IsServer(cptr))
+       if (!IsServer(cptr) && !IsMe(cptr))
          sendto_one(sptr,":%s NOTICE %s :Couldn't write temp kline file, aborted",
         me.name,parv[0]);
       return -1;
@@ -332,12 +338,12 @@
 
   if(!pairme)
     {
-      if (!IsServer(cptr))
+      if (!IsServer(cptr) && !IsMe(cptr))
         sendto_one(sptr, ":%s NOTICE %s :No K-Line for %s@%s",
                  me.name, parv[0],user,host);
-      return 0;
+      return -1;
     }
-  if (!IsServer(cptr))
+  if (!IsServer(cptr) && !IsMe(cptr))
     sendto_one(sptr, ":%s NOTICE %s :K-Line for [%s@%s] is removed", 
              me.name, parv[0], user,host);
   sendto_ops_flag(UMODE_SERVNOTICE, "%s has removed the K-Line for: [%s@%s]",
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/messages_cust.tab ircd-hybrid-6.0/src/messages_cust.tab
--- ircd-hybrid-6.0.orig/src/messages_cust.tab	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/src/messages_cust.tab	Mon Jul  2 22:26:14 2001
@@ -451,7 +451,7 @@
                 ":%s 407 %s %s :Too many recipients. Only %d processed",
 /* 408 ERR_NOCOLORSTOCHAN, */   ":%s 408 %s %s :Cannot send messages with color highlighting to this channel",
 /* 409 ERR_NOORIGIN, */         ":%s 409 %s :No origin specified",
-/* 410 */       (char *)NULL,
+/* 410 ERR_SERVICES_OFFLINE */  ":%s 410 %s :No services can currently be detected",
 /* 411 ERR_NORECIPIENT, */      ":%s 411 %s :No recipient given (%s)",
 /* 412 ERR_NOTEXTTOSEND, */     ":%s 412 %s :No text to send",
 /* 413 ERR_NOTOPLEVEL, */       ":%s 413 %s %s :No toplevel domain specified",
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/mtrie_conf.c ircd-hybrid-6.0/src/mtrie_conf.c
--- ircd-hybrid-6.0.orig/src/mtrie_conf.c	Tue Jul  3 19:48:54 2001
+++ ircd-hybrid-6.0/src/mtrie_conf.c	Tue Jul  3 19:20:00 2001
@@ -56,6 +56,7 @@
 #include "s_conf.h"
 #include "send.h"
 #include "struct.h"
+#include "m_commands.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -702,125 +703,154 @@
 aConfItem* find_matching_mtrie_conf(const char* host, const char* user,
                                     unsigned long ip)
 {
-  aConfItem *iline_aconf_unsortable = NULL;
-  aConfItem *iline_aconf = NULL;
-  aConfItem *kline_aconf = NULL;
-  char tokenized_host[HOSTLEN + 1];
-  int top_of_stack = 0;
+  for(;;) /* Fake loop so I can retry if I expire a K:line */
+    {
+      aConfItem *iline_aconf_unsortable = NULL;
+      aConfItem *iline_aconf = NULL;
+      aConfItem *kline_aconf = NULL;
+      char tokenized_host[HOSTLEN + 1];
+      int top_of_stack = 0;
 
-  last_found_iline_aconf = NULL;
+      last_found_iline_aconf = NULL;
 
-  /* Look in the unsortable i line list first, to find
-   * special cases like *@*ppp* first.
-   */
+      /* Look in the unsortable i line list first, to find
+       * special cases like *@*ppp* first.
+       */
 
-  iline_aconf_unsortable = look_in_unsortable_ilines(host,user);
+      iline_aconf_unsortable = look_in_unsortable_ilines(host,user);
 
-  if(iline_aconf_unsortable &&
-     (iline_aconf_unsortable->flags & CONF_FLAGS_E_LINED))
-    return(iline_aconf_unsortable);
+      if(iline_aconf_unsortable &&
+	 (iline_aconf_unsortable->flags & CONF_FLAGS_E_LINED))
+	return(iline_aconf_unsortable);
 
-  if(trie_list)
-    {
-      stack_pointer = 0;
-      tokenize_and_stack(tokenized_host, host);
-      top_of_stack = stack_pointer;
-      saved_stack_pointer = -1;
-      first_kline_trie_list = (DOMAIN_LEVEL *)NULL;
+      if(trie_list)
+	{
+	  stack_pointer = 0;
+	  tokenize_and_stack(tokenized_host, host);
+	  top_of_stack = stack_pointer;
+	  saved_stack_pointer = -1;
+	  first_kline_trie_list = (DOMAIN_LEVEL *)NULL;
 
-      iline_aconf = find_sub_mtrie(trie_list, host, user, CONF_CLIENT);
-    }
+	  iline_aconf = find_sub_mtrie(trie_list, host, user, CONF_CLIENT);
+	}
 
-  if(iline_aconf)
-    {
-      if(iline_aconf->flags & CONF_FLAGS_E_LINED)
-	return(iline_aconf);
-    }
-  else
-    {
-      if(ip)
+      if(iline_aconf)
 	{
-	  iline_aconf= find_matching_ip_i_line(ip);
-	  
-	  if(iline_aconf)
+	  if(iline_aconf->flags & CONF_FLAGS_E_LINED)
+	    return(iline_aconf);
+	}
+      else
+	{
+	  if(ip)
 	    {
-	      if(iline_aconf->flags & CONF_FLAGS_E_LINED)
-		return(iline_aconf);
+	      iline_aconf= find_matching_ip_i_line(ip);
+	  
+	      if(iline_aconf)
+		{
+		  if(iline_aconf->flags & CONF_FLAGS_E_LINED)
+		    return(iline_aconf);
+		}
 	    }
 	}
-    }
 
-  /* always default to an I line found in the unsortable list */
+      /* always default to an I line found in the unsortable list */
 
-  if(iline_aconf_unsortable)
-    iline_aconf = iline_aconf_unsortable;
+      if(iline_aconf_unsortable)
+	iline_aconf = iline_aconf_unsortable;
 
-  if(!iline_aconf)
-    iline_aconf = find_wild_card_iline(user);
+      if(!iline_aconf)
+	iline_aconf = find_wild_card_iline(user);
 
-  /* If there is no I line, there is no point checking for a K line now
-   * is there? -Dianora
-   */
+      /* If there is no I line, there is no point checking for a K line now
+       * is there? -Dianora
+       */
 
-  if(!iline_aconf)
-    return((aConfItem *)NULL);
-  else
-    {
-      if(iline_aconf->flags & CONF_FLAGS_E_LINED)
-	return(iline_aconf);
-    }
+      if(!iline_aconf)
+	return((aConfItem *)NULL);
+      else
+	{
+	  if(iline_aconf->flags & CONF_FLAGS_E_LINED)
+	    return(iline_aconf);
+	}
 
-  /* I have an I line, now I have to see if it gets
-   * over-ruled by a K line somewhere else in the tree.
-   * Note, that if first_kline_trie_list is non NULL
-   * then trie_list had to have been non NULL as well.
-   * call me paranoid.
-   * Remember again, if any of the I lines
-   * found also had an E line, I've already returned it
-   * and not bothering with the K line search - Dianora
-   */
+      /* I have an I line, now I have to see if it gets
+       * over-ruled by a K line somewhere else in the tree.
+       * Note, that if first_kline_trie_list is non NULL
+       * then trie_list had to have been non NULL as well.
+       * call me paranoid.
+       * Remember again, if any of the I lines
+       * found also had an E line, I've already returned it
+       * and not bothering with the K line search - Dianora
+       */
 
-  /* ok, if there is a trie to use...
-   * and if a possible branch was found the first time
-   * I'll have a first_kline_trie_list saved.
-   * its possible there won't be a branch of possible klines
-   * in which case, I will have to start from the top of the tree again.
-   * - Dianora
-   */
+      /* ok, if there is a trie to use...
+       * and if a possible branch was found the first time
+       * I'll have a first_kline_trie_list saved.
+       * its possible there won't be a branch of possible klines
+       * in which case, I will have to start from the top of the tree again.
+       * - Dianora
+       */
 
-  kline_aconf = (aConfItem *)NULL;
+      kline_aconf = (aConfItem *)NULL;
 
-  if(trie_list)
-    {
-      if(first_kline_trie_list)
-        {
-          stack_pointer = saved_stack_pointer;
-          kline_aconf = find_sub_mtrie(first_kline_trie_list,host,user,
-                                       CONF_KILL);
-        }
-      else
-        {
-          stack_pointer = top_of_stack;
-          kline_aconf = find_sub_mtrie(trie_list,host,user,CONF_KILL);
-        }
-    }
+      if(trie_list)
+	{
+	  if(first_kline_trie_list)
+	    {
+	      stack_pointer = saved_stack_pointer;
+	      kline_aconf = find_sub_mtrie(first_kline_trie_list,host,user,
+					   CONF_KILL);
+	    }
+	  else
+	    {
+	      stack_pointer = top_of_stack;
+	      kline_aconf = find_sub_mtrie(trie_list,host,user,CONF_KILL);
+	    }
+	}
 
-  /* I didn't find a kline in the mtrie, I'll try the unsortable list */
+      /* I didn't find a kline in the mtrie, I'll try the unsortable list */
 
-  if(!kline_aconf)
-    kline_aconf = look_in_unsortable_klines(host,user);
+      if(!kline_aconf)
+	kline_aconf = look_in_unsortable_klines(host,user);
 
-  /* Try an IP hostname ban */
+      /* Try an IP hostname ban */
 
-  if(!kline_aconf)
-    kline_aconf = match_ip_Kline(ip,user);
+      if(!kline_aconf)
+	kline_aconf = match_ip_Kline(ip,user);
 
-  /* If this client isn't k-lined return the I line found */
+      /* If this client isn't k-lined return the I line found */
 
-  if(kline_aconf)
-    return(kline_aconf);
-  else
-    return(iline_aconf);
+      if(kline_aconf)
+	{
+#ifdef FULL_TIMEOUT_KLINES
+	  if(kline_aconf->hold)
+	    {
+	      /* Hello. One of the new timeout K:lines. */
+	      if(kline_aconf->hold <= CurrentTime)
+		{
+		  /* And it's expired. Remove it and return the I:line instead */
+		  char *parv[2];
+		  char buf[USERLEN + HOSTLEN + 1 + 1];
+		  parv[0] = me.name;
+		  ircsprintf(buf, "%s@%s", kline_aconf->user, kline_aconf->host);
+		  parv[1] = buf;
+		  sendto_ops_flag(UMODE_SERVNOTICE, "Expiring K:line on %s", buf);
+		  if (m_unkline(&me, &me, 2, parv) != 0)
+		    {
+		      sendto_ops_flag(UMODE_SERVNOTICE, "Cannot remove timed K:line for %s! Rejecting connection instead", buf);
+		      return ((aConfItem*) NULL);
+		    }
+		  /* OK, I expired a K:line. Go around and try again */
+		  continue;
+		}
+	    }
+#endif
+	  return(kline_aconf);
+	}
+      else
+	return(iline_aconf);
+      /* NOT REACHED */
+    }
 }
 
 /*
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_conf.c ircd-hybrid-6.0/src/s_conf.c
--- ircd-hybrid-6.0.orig/src/s_conf.c	Tue Jul  3 19:48:56 2001
+++ ircd-hybrid-6.0/src/s_conf.c	Tue Jul  3 17:07:55 2001
@@ -85,7 +85,6 @@
 static void add_q_line(struct ConfItem *);
 static void clear_q_lines(void);
 static void clear_special_conf(struct ConfItem **);
-static struct ConfItem* find_tkline(const char*, const char*, unsigned long);
 
 struct ConfItem *temporary_klines = NULL;
 struct ConfItem *temporary_ip_klines = NULL;
@@ -322,7 +321,7 @@
                          sptr->name,
                          p->conf_char,
                          user, host, name,
-                         oper_flags_as_string(tmp->allowed_umodes),
+                         SeesOperPrivs(sptr) ? oper_flags_as_string(tmp->allowed_umodes) : "",
                          get_conf_class(tmp),
                          ""); /* can't make two calls to oper_flags_as_string in one statement, it's a static buffer */
             else
@@ -2133,6 +2132,12 @@
                 break;
               oper_flags_from_string(&(aconf->default_umodes), tmp);
             }
+	  else if(aconf->status & CONF_KILL)
+	    {
+              if ((tmp = getfield(NULL)) == NULL)
+                break;
+              aconf->hold = atoi(tmp);
+	    }
 
           break;
           /* NOTREACHED */
@@ -2764,7 +2769,7 @@
  * thats expected to be done by caller.... *sigh* -Dianora
  */
 
-static struct ConfItem* find_tkline(const char* host, const char* user, unsigned long ip)
+struct ConfItem* find_tkline(const char* host, const char* user, unsigned long ip)
 {
   struct ConfItem *kill_list_ptr;        /* used for the link list only */
   struct ConfItem *last_list_ptr;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_user.c ircd-hybrid-6.0/src/s_user.c
--- ircd-hybrid-6.0.orig/src/s_user.c	Tue Jul  3 19:48:55 2001
+++ ircd-hybrid-6.0/src/s_user.c	Tue Jul  3 16:28:10 2001
@@ -48,6 +48,7 @@
 #include "whowas.h"
 #include "flud.h"
 #include "umodes.h"
+#include "mtrie_conf.h"
 
 #ifdef ANTI_DRONE_FLOOD
 #include "dbuf.h"
@@ -486,9 +487,9 @@
         case I_LINE_FULL:
         case I_LINE_FULL2:
           sendto_ops_flag(UMODE_FULL, "%s for %s (%s).",
-			      "I-line is full",
-			      get_client_host(sptr),
-			      inetntoa((char*) &sptr->ip));
+			  "I-line is full",
+			  get_client_host(sptr),
+			  inetntoa((char*) &sptr->ip));
           log(L_INFO,"Too many connections from %s.", get_client_host(sptr));
           ServerStats->is_ref++;
           return exit_client(cptr, sptr, &me, 
@@ -720,7 +721,43 @@
         }
     }
   else
-    strncpy_irc(sptr->username, username, USERLEN);
+    {
+      struct ConfItem* aconf;
+      struct ConfItem* tklineconf;
+      struct Client* acptr = find_server(user->server);
+
+      strncpy_irc(sptr->username, username, USERLEN);
+      if (acptr)
+	{
+	  /* OK, it's from a remote server. I'm going to check against *MY* K:lines. */
+	  aconf = find_matching_mtrie_conf(sptr->host, sptr->username, ntohl(sptr->ip.s_addr));
+	  tklineconf = find_tkline(sptr->host, sptr->username, ntohl(sptr->ip.s_addr));
+	  
+	  if (aconf && (aconf->status & CONF_KILL))
+	    {
+	      /* Propagate the K:line */
+	      sendto_ops_flag(UMODE_SKILL, "Remote user %s K:lined here (%s), propagating K:line to %s", 
+			      sptr->name, me.name, sptr->user->server);
+	      sendto_one(acptr, ":%s KLINE %s %s@%s :%s", me.name, me.name, aconf->user, aconf->host, aconf->passwd);
+	    }
+	  else if (tklineconf)
+	    {
+	      /* Don't propagate temporary K:lines (yet, because it's complex), but do kill the target */
+/* 	      sendto_ops_flag(UMODE_SKILL, "Remote tKline kill: %s on server %s", sptr->name, sptr->user->server); */
+/* 	      sendto_one(cptr, ":%s KILL %s :tKlined on %s", */
+/* 			 me.name, sptr->name, me.name); */
+/* 	      sptr->flags |= FLAGS_KILLED; */
+/* 	      return exit_client(sptr, sptr, &me, "tKlined"); */
+	      long int time_remaining = (tklineconf->hold - CurrentTime) / 60;
+
+	      sendto_ops_flag(UMODE_SKILL, "Remote user %s tK:lined here (%s) until %d, propagating tK:line to %s with %d minutes left",
+			      sptr->name, me.name, tklineconf->hold, sptr->user->server, time_remaining);
+	      /* Well, now we can try to propagate it */
+	      sendto_one(cptr, ":%s KLINE %s %d %s@%s :%s", me.name, me.name,
+			 time_remaining, tklineconf->user, tklineconf->host, tklineconf->passwd);
+	    }
+	}
+    }
 
   SetClient(sptr);
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/send.c ircd-hybrid-6.0/src/send.c
--- ircd-hybrid-6.0.orig/src/send.c	Tue Jul  3 19:48:55 2001
+++ ircd-hybrid-6.0/src/send.c	Tue Jul  3 16:58:42 2001
@@ -425,7 +425,8 @@
 
   va_start(args, pattern);
 
-  vsendto_one(to, pattern, args);
+  if (to)
+    vsendto_one(to, pattern, args);
 
   va_end(args);
 } /* sendto_one() */
