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	Tue Jun 26 20:05:22 2001
+++ ircd-hybrid-6.0/include/client.h	Tue Jun 26 18:33:56 2001
@@ -444,16 +444,14 @@
  * NOTICE *
  **********
  *
- * send_umodes and user_umodes are now defined in a roundabout way in
+ * user_umodes is now defined in a roundabout way in
  *  init_umodes() at the bottom of s_user.c. This is a compromise; the
  *  rest of the bitfield math works much neater this way. Suggestions of
  *  better ways to do it welcome.
  *   -- asuffield
  */
 
-/*extern umode_t send_umodes;*/
 extern umode_t user_umodes;
-extern umode_t all_umodes;
 
 #define FLAGS_ID     (FLAGS_NEEDID | FLAGS_GOTID)
 
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 Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/include/patchlevel.h	Tue Jun 26 20:04:04 2001
@@ -17,5 +17,5 @@
  */
 
 #ifndef PATCHLEVEL
-#define PATCHLEVEL    "dancer-ircd-0.9.1.9"
+#define PATCHLEVEL    "dancer-ircd-0.9.2.1"
 #endif
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/s_serv.h ircd-hybrid-6.0/include/s_serv.h
--- ircd-hybrid-6.0.orig/include/s_serv.h	Tue Jun 26 20:05:22 2001
+++ ircd-hybrid-6.0/include/s_serv.h	Tue Jun 26 18:48:08 2001
@@ -51,7 +51,9 @@
 					   This is used in m_whois to prevent services
 					   from being queried remotely, which it can't
 					   do anything with */
-#define CAP_OPN         0x10000000      /* Can do sethost, setident, setname,
+#define CAP_SERVICES    0x00000200      /* Is a services daemon. Used primarily to identify
+					   what is and is not a server jupe */
+#define CAP_DANCER      0x10000000      /* Can do sethost, setident, setname,
                                            allows opers to hack modes, accepts
                                            glines without vote, has nicklen 30
                                            and topiclen 450, etc. etc. */
@@ -74,6 +76,7 @@
  * extra argument to "PASS" takes care of checking that.  -orabidoo
  */
 extern struct Capability captab[];
+extern struct Capability other_captab[];
 
 extern int MaxClientCount;     /* GLOBAL - highest number of clients */
 extern int MaxConnectionCount; /* GLOBAL - highest number of connections */
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/s_user.h ircd-hybrid-6.0/include/s_user.h
--- ircd-hybrid-6.0.orig/include/s_user.h	Tue Jun 26 20:05:21 2001
+++ ircd-hybrid-6.0/include/s_user.h	Tue Jun 26 18:33:39 2001
@@ -40,7 +40,7 @@
 
 extern int   user_mode(struct Client *, struct Client *, int, char **);
 extern void  send_umode (struct Client *, struct Client *,
-                         umode_t, umode_t, char *);
+                         umode_t, char *);
 extern void  send_umode_out (struct Client*, struct Client *, umode_t);
 extern int   show_lusers(struct Client *, struct Client *, int, char **);
 extern void  show_opers(struct Client* client);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/send.h ircd-hybrid-6.0/include/send.h
--- ircd-hybrid-6.0.orig/include/send.h	Tue Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/include/send.h	Tue Jun 26 15:35:23 2001
@@ -74,6 +74,8 @@
 extern  void sendto_ops_flag_butone(struct Client *, int, const char *, ...);
 extern  void sendto_ops_flag_butone_from(struct Client *, int, struct Client*, const char *, ...);
 extern  void sendto_ops_flag_butone_hidefrom(struct Client *, int, const char *, ...);
-extern  void sendto_local_users(const char*, ...);
+extern  void sendto_local_ops_flag(int, const char*, ...);
+extern  void sendto_local_ops_flag_butone(struct Client *, int, const char *, ...);
+extern  void sendto_local_ops_flag_butone_from(struct Client *, int, struct Client*, const char *, ...);
 
 #endif /* INCLUDED_send_h */
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/include/umodes.h ircd-hybrid-6.0/include/umodes.h
--- ircd-hybrid-6.0.orig/include/umodes.h	Tue Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/include/umodes.h	Tue Jun 26 18:28:28 2001
@@ -86,7 +86,7 @@
   {UMODE_SEESTATST, '4'},
   {UMODE_SEESTATSSERV,'5'},
   {UMODE_TESTLINE, '9'},
-  /*  {UMODE_GRANT, '*'},*/
+  {UMODE_GRANT, '*'},
   {0, 0}
 };
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/client.c ircd-hybrid-6.0/src/client.c
--- ircd-hybrid-6.0.orig/src/client.c	Tue Jun 26 20:05:22 2001
+++ ircd-hybrid-6.0/src/client.c	Tue Jun 26 18:35:17 2001
@@ -57,8 +57,6 @@
 
 struct  bitfield_lookup_t bitfield_lookup[BITFIELD_SIZE];
 umode_t user_umodes;
-/*umode_t send_umodes;*/
-umode_t all_umodes;
 
 /* 
  * Number of struct Client structures to preallocate at a time
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_capab.c ircd-hybrid-6.0/src/m_capab.c
--- ircd-hybrid-6.0.orig/src/m_capab.c	Tue Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/src/m_capab.c	Tue Jun 26 18:49:37 2001
@@ -116,6 +116,14 @@
               break;
             }
          }
+      for (cap = other_captab; cap->name; cap++)
+        {
+          if (0 == strcmp(cap->name, s))
+            {
+              cptr->caps |= cap->cap;
+              break;
+            }
+         }
     }
   
   return 0;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_chall.c ircd-hybrid-6.0/src/m_chall.c
--- ircd-hybrid-6.0.orig/src/m_chall.c	Tue Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/src/m_chall.c	Tue Jun 26 19:01:22 2001
@@ -12,6 +12,7 @@
 #include "s_conf.h"      /* find_conf* */
 #include "s_log.h"
 #include "s_cr.h"
+#include "s_serv.h"
 
 #ifdef CHALLENGERESPONSE
 
@@ -78,6 +79,7 @@
   char* chall = parc > 2 ? parv[2] : "";
   char* host = parc > 1 ? parv[1] : "";
   struct ConfItem *n_conf, *c_conf;
+  struct Client* acptr;
 
   if (IsPerson(sptr))
     {
@@ -95,7 +97,20 @@
       return 0;
     }
 
-  sendto_ops_flag(UMODE_SEEROUTING, "CHALL received from %s, trying to use N:line for %s", get_client_name(cptr, SHOW_IP), host);
+  /* If we know this, we shouldn't be getting a chall */
+  if (IsPerson(cptr) || IsServer(cptr)) 
+    return 0;
+
+  if ((acptr = find_server(host)))
+    {
+      sendto_one(cptr,"ERROR :Server %s already exists", host);
+      if (!(acptr->from->caps & CAP_SERVICES)) /* If it's connected to services, it's actually a server jupe. Silently ignore. */
+	sendto_ops_flag(UMODE_SERVNOTICE, "Challenge for %s rejected, server already exists",
+			host);
+      return exit_client(cptr, cptr, &me, "Server already exists");
+    }
+
+  sendto_ops_flag(UMODE_SEEROUTING, "CHALL received, trying to use N:line for %s", host);
 
   if (parc < 5)
     {
@@ -103,10 +118,6 @@
       sendto_ops_flag(UMODE_SEEROUTING, "Invalid CHALL from remote host for %s", host);
       return 0;
     }
-
-  /* If we know this, we shouldn't be getting a chall */
-  if (IsPerson(cptr) || IsServer(cptr)) 
-    return 0;
 
   /* See if we got c and n lines. */
   if (!(n_conf = find_conf_by_name(host, CONF_NOCONNECT_SERVER))) {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_setname.c ircd-hybrid-6.0/src/m_setname.c
--- ircd-hybrid-6.0.orig/src/m_setname.c	Tue Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/src/m_setname.c	Tue Jun 26 15:36:26 2001
@@ -148,10 +148,10 @@
   }
 
   if ((acptr = find_person(target, NULL))) {
-    sendto_ops_flag(UMODE_SPY,
-			   "%s is rehosting %s (%s@%s) to \"%s\" while whistling innocently",
-			   sptr->name, acptr->name,
-			   acptr->username, acptr->host, hostname);
+    sendto_local_ops_flag(UMODE_SPY,
+			  "%s is rehosting %s (%s@%s) to \"%s\" while whistling innocently",
+			  sptr->name, acptr->name,
+			  acptr->username, acptr->host, hostname);
       if (sptr == acptr) {
          if (MyClient(acptr))
          sendto_one(acptr, ":%s NOTICE %s :your hostname is now set to \"%s\"",
@@ -227,10 +227,10 @@
   }
 
   if ((acptr = find_person(target, NULL))) {
-    sendto_ops_flag(UMODE_SPY,
-			   "%s is identing %s (%s@%s) to \"%s\" while whistling innocently",
-			   sptr->name, acptr->name,
-			   acptr->username, acptr->host, username);
+    sendto_local_ops_flag(UMODE_SPY,
+			  "%s is identing %s (%s@%s) to \"%s\" while whistling innocently",
+			  sptr->name, acptr->name,
+			  acptr->username, acptr->host, username);
       if (sptr == acptr) {
          if (MyClient(acptr))
          sendto_one(acptr, ":%s NOTICE %s :your ident is now set to \"%s\"",
@@ -299,19 +299,19 @@
   }
 
   if ((acptr = find_server(target))) {
-    sendto_ops_flag(UMODE_SERVNOTICE,
-			   "%s is making %s be \"%s\" while whistling innocently",
-			   sptr->name, acptr->name, realname);
+    sendto_local_ops_flag(UMODE_SERVNOTICE,
+			  "%s is making %s be \"%s\" while whistling innocently",
+			  sptr->name, acptr->name, realname);
     sendto_serv_butone(cptr, ":%s SETNAME %s :%s",
                        sptr->name,
                        target,
                        realname);
     ircsprintf(acptr->info, "%s", realname);
   } else if ((acptr = find_person(target, NULL))) {
-    sendto_ops_flag(UMODE_SPY,
-			   "%s is naming %s (%s@%s) to \"%s\" while whistling innocently",
-			   sptr->name, acptr->name,
-			   acptr->username, acptr->host, realname);
+    sendto_local_ops_flag(UMODE_SPY,
+			  "%s is naming %s (%s@%s) to \"%s\" while whistling innocently",
+			  sptr->name, acptr->name,
+			  acptr->username, acptr->host, realname);
       if (sptr == acptr) {
          if (MyClient(acptr))
          sendto_one(acptr, ":%s NOTICE %s :your realname is now set to \"%s\"",
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_serv.c ircd-hybrid-6.0/src/s_serv.c
--- ircd-hybrid-6.0.orig/src/s_serv.c	Tue Jun 26 20:05:22 2001
+++ ircd-hybrid-6.0/src/s_serv.c	Tue Jun 26 18:51:09 2001
@@ -74,7 +74,7 @@
   { "EX",       CAP_EX },
   { "CHW",      CAP_CHW },
   { "DE",       CAP_DE },
-  { "OPN",      CAP_OPN },
+  { "DNCR",     CAP_DANCER },
   { "IE", 	CAP_IE }, 
 #ifdef QUIET_MODE
   { "QU",       CAP_QU },
@@ -83,6 +83,11 @@
   { 0,   0 }
 };
 
+/* Capabilities that I recognise, but which I do not posess */
+struct Capability other_captab[] = {
+  { "SRV",      CAP_SERVICES },
+  { 0, 0}
+};
 
 /*
  * my_name_for_link - return wildcard name of my server name 
@@ -479,7 +484,7 @@
 
   if (IsPerson(acptr))
     {
-      send_umode(NULL, acptr, 0, all_umodes, ubuf);
+      send_umode(NULL, acptr, 0, ubuf);
       if (!*ubuf)
         { /* trivial optimization - Dianora */
           
@@ -620,8 +625,8 @@
   /* Its got identd , since its a server */
   SetGotId(cptr);
 
-  if (!IsCapable(cptr, CAP_OPN)) {
-      sendto_ops_flag(UMODE_SERVNOTICE, "Access denied (not an OPN hax0red server) %s", inpath);
+  if (!IsCapable(cptr, CAP_DANCER)) {
+      sendto_ops_flag(UMODE_SERVNOTICE, "Access denied (not a dancer server) %s", inpath);
       return exit_client(cptr, cptr, cptr, "Insufficient Capabilities");
     }
 #ifndef HUB
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 Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/src/s_user.c	Tue Jun 26 19:35:46 2001
@@ -748,7 +748,7 @@
       Count.max_tot = Count.total;
       if ( (!(Count.max_tot % 2)) && (record_time < CurrentTime - 30) )
         {
-          sendto_local_users("New network record: %d users (%d local)", Count.max_tot, Count.max_loc);
+          sendto_local_ops_flag(UMODE_SERVNOTICE, "New network record: %d users (%d local)", Count.max_tot, Count.max_loc);
           record_time = CurrentTime;
       }
     }
@@ -857,7 +857,7 @@
         }
     }
 
-  send_umode(NULL, sptr, 0, all_umodes, ubuf);
+  send_umode(NULL, sptr, 0, ubuf);
   if (!*ubuf)
     {
       ubuf[0] = '+';
@@ -2036,7 +2036,8 @@
 			    if (CanGrantModes(sptr))
 			      {
 				/* OK, we have to check these against allowed_umodes here */
-				/* NYI */
+				if (TestBit(sptr->allowed_umodes, mode))
+				  *m2++ = *m;
 			      }
 			    else
 			      /* We're not doing any magic. Send it on. */
@@ -2046,8 +2047,8 @@
 			}
 		    *m2 = 0;
                   }
-              sendto_one(acptr->from, ":%s MODE %s %s", sptr->name,
-                         acptr->name, ((parc < 3) ? "" : parv[2]));
+              sendto_serv_butone(cptr, ":%s MODE %s %s", parv[0],
+				 parv[1], ((parc < 3) ? "" : parv[2]));
               return 0;
             }
         }
@@ -2209,20 +2210,28 @@
 		/* Grant a mode if we're supposed to, if it's not +* itself, and if we are either
 		 *  handling a remote grant or it's allowed locally
 		 */
-		if (CanGrantModes(sptr) && (flag != UMODE_GRANT) && ((sptr->from != cptr->from) || TestBit(sptr->allowed_umodes, flag)))
+		if (CanGrantModes(sptr) && (flag != UMODE_GRANT) && (!MyClient(sptr) || TestBit(sptr->allowed_umodes, flag)))
 		  {
 		    /* We're granting, rather than just normally changing */
-		    /* NYI */
-		    /*
-		      sendto_ops_flag(UMODE_SERVNOTICE, "%s has bestowed the power of +%c onto %s",
-		      sptr->name, acptr->name, *m);
-		      log(L_NOTICE, "%s has bestowed the power of +%c onto %s",
-		      sptr->name, acptr->name, *m);
-		      sendto_ops_flag(UMODE_SERVNOTICE, "%s has stripped %s of the power of +%c",
-		      sptr->name, acptr->name, *m);
-		      log(L_NOTICE, "%s has stripped %s of the power of +%c",
-		      sptr->name, acptr->name, *m);
-		    */
+		    if (what == MODE_ADD)
+		      {
+			SetBit(acptr->allowed_umodes, flag);
+			sendto_ops_flag(UMODE_SERVNOTICE, "%s has bestowed the power of +%c onto %s",
+					sptr->name, *m, acptr->name);
+			log(L_NOTICE, "%s bestowed the power of +%c onto %s",
+			    sptr->name, *m, acptr->name);
+		      }
+		    else
+		      {
+			if (!TestBit(user_umodes, flag))
+			  {
+			    ClearBit(acptr->allowed_umodes, flag);
+			    sendto_ops_flag(UMODE_SERVNOTICE, "%s has stripped %s of the power of +%c",
+					    sptr->name, acptr->name, *m);
+			    log(L_NOTICE, "%s stripped %s of the power of +%c",
+				sptr->name, acptr->name, *m);
+			  }
+		      }
 		  }
 		if (what == MODE_ADD)
 		  SetBit(acptr->umodes, flag);
@@ -2281,7 +2290,7 @@
  * send the MODE string for user (user) to connection cptr
  * -avalon
  */
-void send_umode(aClient *cptr, aClient *sptr, umode_t old, umode_t sendmask,
+void send_umode(aClient *cptr, aClient *sptr, umode_t old,
                 char *umode_buf)
 {
   int   i;
@@ -2300,8 +2309,6 @@
     {
       flag = user_modes[i].mode;
       
-      if (MyClient(sptr) && !TestBit(sendmask,flag))
-        continue;
       if (old && TestBit(old,flag) && !TestBit(sptr->umodes,flag))
         {
           if (what == MODE_DEL)
@@ -2347,7 +2354,7 @@
   aClient *acptr;
   char buf[BUFSIZE];
 
-  send_umode(NULL, sptr, old, all_umodes, buf);
+  send_umode(NULL, sptr, old, buf);
 
   for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client)
     {
@@ -2359,7 +2366,7 @@
     }
 
   if (cptr && MyClient(cptr))
-    send_umode(cptr, sptr, old, all_umodes, buf);
+    send_umode(cptr, sptr, old, buf);
 }
 
 /*
@@ -2373,19 +2380,21 @@
   aClient *acptr;
   char buf[BUFSIZE];
 
-  send_umode(NULL, sptr, old, all_umodes, buf);
+  send_umode(NULL, sptr, old, buf);
 
   if (*buf)
-    for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client)
-      {
-        if((acptr != cptr) && (acptr != sptr))
-          {
-            sendto_one(acptr, ":%s MODE %s :%s",
-                     ircop->name, sptr->name, buf);
-          }
-      }
+    sendto_serv_butone(cptr, ":%s MODE %s :%s",
+		       ircop->name, sptr->name, buf);
+/*     for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client) */
+/*       { */
+/*         if((acptr != cptr) && (apctr != cptr->from)) */
+/*           { */
+/*             sendto_one(acptr, ":%s MODE %s :%s", */
+/*                      ircop->name, sptr->name, buf); */
+/*           } */
+/*       } */
 
-  send_umode(NULL, sptr, old, all_umodes, buf);
+  send_umode(NULL, sptr, old, buf);
 
   if (MyClient(sptr) && *buf)
     sendto_one(sptr, ":%s MODE %s :%s",
@@ -2490,35 +2499,7 @@
 	bit = bit << 1;
     }
 
-  /* Here we fill in send_umodes and user_umodes */
-  /*  ClearBitfield(send_umodes);*/
-  ClearBitfield(user_umodes);
-  ClearBitfield(all_umodes);
-  NotUmodes(all_umodes, all_umodes);
-
-/* These are the umodes which are propogated. Note that most oper umodes are
- * checked at the source, so don't need to be propogated
- *  -- asuffield
- */
-/* I changed my mind; to have UMODE_GRANT and oper WHOIS sane, we need to
- * propogate the lot. Ah well. Network load is minimal while number of opers
- * isn't huge. server-server mode command should carry an unlimited number of
- * umodes to cut down on bandwidth usage.
- *  -- asuffield
- */
-/*  SetBit(send_umodes, UMODE_INVISIBLE);
-  SetBit(send_umodes, UMODE_OPER);
-  SetBit(send_umodes, UMODE_WALLOP);
-  SetBit(send_umodes, UMODE_IMMUNE);
-  SetBit(send_umodes, UMODE_IDENTIFIED);
-  SetBit(send_umodes, UMODE_NINVITE);
-  SetBit(send_umodes, UMODE_BLOCK_NOTID);
-  SetBit(send_umodes, UMODE_NCTCP);*/
-
-/*
- * Only opers can have modes outside USER_UMODES.  If you change this
- * set, then also change the explanatory NOTICE in user_mode(). -dark
- */
+  /* These are the umodes which any user can set */
   SetBit(user_umodes, UMODE_INVISIBLE);
   SetBit(user_umodes, UMODE_WALLOP);
   SetBit(user_umodes, UMODE_NINVITE);
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 Jun 26 20:05:23 2001
+++ ircd-hybrid-6.0/src/send.c	Tue Jun 26 15:37:34 2001
@@ -52,7 +52,9 @@
 
 static  void vsendto_prefix_one(register aClient *, register aClient *, const char *, va_list);
 static  void vsendto_one(aClient *, const char *, va_list);
-static  void vsendto_ops_flag_butone(aClient*, int, const char *, va_list);
+static  void vsendto_ops_flag_butone_from(aClient*, int, aClient*, const char *, va_list);
+static  void vsendto_local_ops_flag_butone_from(aClient*, int, aClient*, const char *, va_list);
+static  void vsendto_remote_ops_flag_butone_from(aClient*, int, aClient*, const char *, va_list);
 
 static  unsigned long sentalong[MAXCONNECTIONS];
 static unsigned long current_serial=0L;
@@ -1217,7 +1219,7 @@
       warnings = 0;
     }
 
-  vsendto_ops_flag_butone(NULL, UMODE_SERVNOTICE, pattern, args);
+  vsendto_ops_flag_butone_from(NULL, UMODE_SERVNOTICE, &me, pattern, args);
   vsprintf(buf, pattern, args);
   log(L_CRIT, "%s", buf);
 
@@ -1304,7 +1306,7 @@
 
   va_start(args, pattern);
 
-  vsendto_ops_flag_butone(NULL, flag, pattern, args);
+  vsendto_ops_flag_butone_from(NULL, flag, &me, pattern, args);
 
   va_end(args);
 }
@@ -1317,7 +1319,7 @@
 
   va_start(args, pattern);
 
-  vsendto_ops_flag_butone(one, flag, pattern, args);
+  vsendto_ops_flag_butone_from(one, flag, &me, pattern, args);
 
   va_end(args);
 }
@@ -1328,23 +1330,38 @@
 */
 
 static void
-vsendto_ops_flag_butone(aClient *one, int flag, const char *pattern, va_list args)
+vsendto_ops_flag_butone_from(aClient *one, int flag, aClient* from, const char *pattern, va_list args)
+{
+  vsendto_local_ops_flag_butone_from(one, flag, from, pattern, args);
+  vsendto_remote_ops_flag_butone_from(one, flag, from, pattern, args);
+}
+
+static void
+vsendto_local_ops_flag_butone_from(aClient *one, int flag, aClient* from, const char *pattern, va_list args)
 {
   register aClient *cptr;
   char nbuf[1024];
-  
+
   for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
     {
       if (IsPerson(cptr) && TestBit(cptr->umodes,flag))
 	{
 	  (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
-			   me.name, cptr->name);
+			   from->name, cptr->name);
 	  (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
 	  vsendto_one(cptr, nbuf, args);
 	}
     }
+}
+
+static void
+vsendto_remote_ops_flag_butone_from(aClient *one, int flag, aClient* from, const char *pattern, va_list args)
+{
+  register aClient *cptr;
+  char nbuf[1024];
+
   (void)ircsprintf(nbuf, ":%s WALLOPS %i :",
-		   me.name, flag);
+		   from->name, flag);
   (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
   for(cptr = serv_cptr_list; cptr; cptr = cptr->next_server_client)
     {
@@ -1352,38 +1369,19 @@
 	continue;
       vsendto_one(cptr, nbuf, args);
     }
-} /* vsendto_realops() */
+}
+
 
 /* This one is used in the magic WALLOPS hack to propogate server notices */
 
 void
 sendto_ops_flag_butone_from(aClient *one, int flag, aClient* from, const char *pattern, ...)
 {
-  register aClient *cptr;
-  char nbuf[1024];
   va_list args;
 
   va_start(args, pattern);
 
-  for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
-    {
-      if (IsPerson(cptr) && TestBit(cptr->umodes,flag))
-	{
-	  (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
-			   from->name, cptr->name);
-	  (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
-	  vsendto_one(cptr, nbuf, args);
-	}
-    }
-  (void)ircsprintf(nbuf, ":%s WALLOPS %i :",
-		   from->name, flag);
-  (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
-  for(cptr = serv_cptr_list; cptr; cptr = cptr->next_server_client)
-    {
-      if (IsMe(cptr) || (one && (cptr == one->from)))
-	continue;
-      vsendto_one(cptr, nbuf, args);
-    }
+  vsendto_ops_flag_butone_from(one, flag, from, pattern, args);
 
   va_end(args);
 }
@@ -1399,16 +1397,8 @@
 
   va_start(args, pattern);
 
-  for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
-    {
-      if (IsPerson(cptr) && TestBit(cptr->umodes,flag))
-	{
-	  (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
-			   me.name, cptr->name);
-	  (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
-	  vsendto_one(cptr, nbuf, args);
-	}
-    }
+  vsendto_local_ops_flag_butone_from(one, flag, &me, pattern, args);
+
   (void)ircsprintf(nbuf, ":%s WALLOPS *%i :",
 		   me.name, flag);
   (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
@@ -1423,19 +1413,37 @@
 }
 
 void
-sendto_local_users(const char* pattern, ...)
+sendto_local_ops_flag(int flag, const char* pattern, ...)
 {
-  register aClient *cptr;
-  char nbuf[1024];
   va_list args;
+
   va_start(args, pattern);
-  for (cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
-    {
-      if (IsPerson(cptr))
-	(void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
-			 me.name, cptr->name);
-      (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
-      vsendto_one(cptr, nbuf, args);
-    }
+
+  vsendto_local_ops_flag_butone_from(NULL, flag, &me, pattern, args);
+
+  va_end(args);
+}
+
+void
+sendto_local_ops_flag_butone(aClient* one, int flag, const char* pattern, ...)
+{
+  va_list args;
+
+  va_start(args, pattern);
+
+  vsendto_local_ops_flag_butone_from(one, flag, &me, pattern, args);
+
+  va_end(args);
+}
+
+void
+sendto_local_ops_flag_butone_from(aClient* one, int flag, aClient* from, const char* pattern, ...)
+{
+  va_list args;
+
+  va_start(args, pattern);
+
+  vsendto_local_ops_flag_butone_from(one, flag, from, pattern, args);
+
   va_end(args);
 }
