diff -uNr ircd-hybrid-7.0/contrib/m_operspy.c ircd-hybrid-7.0+umodeZ/contrib/m_operspy.c
--- ircd-hybrid-7.0/contrib/m_operspy.c	Tue Jun 10 16:21:47 2003
+++ ircd-hybrid-7.0+umodeZ/contrib/m_operspy.c	Sat Jun 21 01:06:02 2003
@@ -55,11 +55,11 @@
 /* enable this to log all local/remote operspy usage to a logfile */
 #define OPERSPY_LOGFILE
 
-/* enable this to send incoming operspy usage to active +y (FLAGS_SPY) opers */
+/* enable this to send incoming operspy usage to active +Z (FLAGS_SPYLOG) opers */
 #define OPERSPY_NOTICE
 
 /* enable OPERSPY version of LIST */
-#define OPERSPY_LIST
+#undef OPERSPY_LIST
 
 /* enable OPERSPY version of MODE */
 #define OPERSPY_MODE
@@ -74,17 +74,17 @@
 #define OPERSPY_WHOIS
 
 /* enable OPERSPY version of TOPIC */
-#define OPERSPY_TOPIC
+#undef OPERSPY_TOPIC
 
-#define IsOperspy(x) (IsOper(x) && MyClient(x) && IsAdmin(x))
+#define IsOperspy(x)		(IsOper(x) && MyClient(x) && IsOperSpy(x))
+#define IsConfOperator(x)	((x)->status & CONF_OPERATOR)
 
 /*
  * The commands we will add
  */
-static void m_operspy(struct Client *client_p, struct Client *source_p,
-                       int parc, char *parv[]);
-static void mo_operspy(struct Client *client_p, struct Client *source_p,
-                       int parc, char *parv[]);
+static void m_operspy(struct Client *, struct Client *, int, char **);
+static void ms_operspy(struct Client *, struct Client *, int, char **);
+static void mo_operspy(struct Client *, struct Client *, int, char **);
 
 /* extensions for OPERSPY WHO */
 #ifdef OPERSPY_WHO
@@ -118,7 +118,7 @@
 
 struct Message operspy_msgtab = {
   "OPERSPY", 0, 0, 0, 0, MFLG_SLOW|MFLG_HIDDEN, 0,
-  {m_ignore, m_operspy, m_operspy, mo_operspy}
+  {m_ignore, m_operspy, ms_operspy, mo_operspy}
 };
 
 #ifndef STATIC_MODULES
@@ -160,6 +160,15 @@
              operspy);
 }
 
+static void
+ms_operspy(struct Client *client_p, struct Client *source_p,
+           int parc, char *parv[])
+{
+#ifdef OPERSPY_LOG
+  operspy_log(source_p, parv[1], parv[2]);
+#endif
+}
+
 /*
  * mo_operspy
  *	parv[1] = operspy command
@@ -837,8 +846,17 @@
 #endif
 
 #ifdef OPERSPY_NOTICE
-  sendto_realops_flags(FLAGS_SPY, L_ALL, "OPERSPY %s %s %s",
+  sendto_realops_flags(FLAGS_SPYLOG, L_ALL, "OPERSPY %s %s %s",
                        get_oper_name(source_p), command, target);
 #endif
+
+  /*
+   * Only start logging propogation for local opers using the
+   * command.  ms_encap() will take care of propogating incoming
+   * remote requests.
+   */
+  if (MyClient(source_p))
+    sendto_match_servs(source_p, "*", CAP_ENCAP, "ENCAP * OPERSPY %s :%s",
+                       command, target);
 }
 #endif /* OPERSPY_LOG */
diff -uNr ircd-hybrid-7.0/include/client.h ircd-hybrid-7.0+umodeZ/include/client.h
--- ircd-hybrid-7.0/include/client.h	Sun Feb 16 16:54:35 2003
+++ ircd-hybrid-7.0+umodeZ/include/client.h	Tue Jun 17 11:47:33 2003
@@ -418,10 +418,11 @@
 #define FLAGS_CALLERID     0x4000 /* block unless caller id's */
 #define FLAGS_UNAUTH       0x8000 /* show unauth connects here */
 #define FLAGS_LOCOPS       0x10000 /* show locops */
+#define FLAGS_SPYLOG       0x20000  
 
 /* user information flags, only settable by remote mode or local oper */
-#define FLAGS_OPER         0x20000 /* Operator */
-#define FLAGS_ADMIN        0x40000 /* Admin on server */
+#define FLAGS_OPER         0x40000 /* Operator */
+#define FLAGS_ADMIN        0x80000 /* Admin on server */
 
 #define FLAGS_ALL	   FLAGS_SERVNOTICE
 
@@ -442,6 +443,7 @@
 #define FLAGS2_OPER_DIE         0x0800  /* oper can die */
 #define FLAGS2_OPER_REHASH      0x1000  /* oper can rehash */
 #define FLAGS2_OPER_ADMIN       0x2000  /* oper can set umode +a */
+#define FLAGS2_OPER_SPY		0x4000	/* oper can operspy */
 #define FLAGS2_OPER_FLAGS       (FLAGS2_OPER_GLOBAL_KILL | \
                                  FLAGS2_OPER_REMOTE | \
                                  FLAGS2_OPER_UNKLINE | \
@@ -449,8 +451,9 @@
                                  FLAGS2_OPER_N | \
                                  FLAGS2_OPER_K | \
                                  FLAGS2_OPER_DIE | \
-                                 FLAGS2_OPER_REHASH| \
-                                 FLAGS2_OPER_ADMIN)
+                                 FLAGS2_OPER_REHASH | \
+                                 FLAGS2_OPER_ADMIN | \
+                                 FLAGS2_OPER_SPY)
 
 #define FLAGS2_CBURST		0x10000  /* connection burst being sent */
 #define FLAGS2_PING_COOKIE	0x20000		/* PING Cookie */
@@ -465,7 +468,8 @@
                       FLAGS_REJ | FLAGS_SKILL | FLAGS_FULL | FLAGS_SPY | \
                       FLAGS_NCHANGE | FLAGS_OPERWALL | FLAGS_DEBUG | \
                       FLAGS_BOTS | FLAGS_EXTERNAL | FLAGS_LOCOPS | \
- 		      FLAGS_ADMIN | FLAGS_UNAUTH | FLAGS_CALLERID)
+ 		      FLAGS_ADMIN | FLAGS_UNAUTH | FLAGS_CALLERID | \
+                      FLAGS_SPYLOG )
 
 #define FLAGS_ID     (FLAGS_NEEDID | FLAGS_GOTID)
 
@@ -588,6 +592,8 @@
 #define SetOperRehash(x)        ((x)->flags2 |= FLAGS2_OPER_REHASH)
 #define IsOperAdmin(x)          ((x)->flags2 & FLAGS2_OPER_ADMIN)
 #define SetOperAdmin(x)         ((x)->flags2 |= FLAGS2_OPER_ADMIN)
+#define IsOperSpy(x)		((x)->flags2 & FLAGS2_OPER_SPY)
+#define SetOperSpy(x)		((x)->flags2 |= FLAGS2_OPER_SPY)
 
 #define IsFloodDone(x)          ((x)->flags2 & FLAGS2_FLOODDONE)
 #define SetFloodDone(x)         ((x)->flags2 |= FLAGS2_FLOODDONE)
diff -uNr ircd-hybrid-7.0/include/parse.h ircd-hybrid-7.0+umodeZ/include/parse.h
--- ircd-hybrid-7.0/include/parse.h	Mon Jun  9 21:16:52 2003
+++ ircd-hybrid-7.0+umodeZ/include/parse.h	Thu Jun 12 17:12:36 2003
@@ -38,6 +38,7 @@
 #define MAX_MSG_HASH  387
 
 extern  void           parse (struct Client *, char *, char *);
+extern  struct Message *hash_parse(char *);
 extern  void           clear_hash_parse (void);
 extern  void           mod_add_cmd(struct Message *msg);
 extern  void           mod_del_cmd(struct Message *msg);
diff -uNr ircd-hybrid-7.0/include/s_conf.h ircd-hybrid-7.0+umodeZ/include/s_conf.h
--- ircd-hybrid-7.0/include/s_conf.h	Sat Feb 15 18:22:21 2003
+++ ircd-hybrid-7.0+umodeZ/include/s_conf.h	Tue Jun 17 11:45:53 2003
@@ -124,6 +124,7 @@
 #define CONF_FLAGS_EXEMPTGLINE          0x00001000
 #define CONF_FLAGS_RESTRICTED           0x00002000
 #define CONF_FLAGS_CAN_FLOOD            0x00100000
+#define CONF_FLAGS_OPER_SPY		0x00400000
 /* server flags */
 #define CONF_FLAGS_ALLOW_AUTO_CONN      0x00004000
 #define CONF_FLAGS_LAZY_LINK            0x00008000
@@ -139,6 +140,7 @@
 #define IsNeedIdentd(x)         ((x)->flags & CONF_FLAGS_NEED_IDENTD)
 #define IsPassIdentd(x)         ((x)->flags & CONF_FLAGS_PASS_IDENTD)
 #define IsNoMatchIp(x)          ((x)->flags & CONF_FLAGS_NOMATCH_IP)
+#define IsConfOperSpy(x)	((x)->flags & CONF_FLAGS_OPER_SPY)
 #define IsConfExemptKline(x)    ((x)->flags & CONF_FLAGS_EXEMPTKLINE)
 #define IsConfExemptLimits(x)   ((x)->flags & CONF_FLAGS_NOLIMIT)
 #define IsConfExemptGline(x)    ((x)->flags & CONF_FLAGS_EXEMPTGLINE)
@@ -163,6 +165,7 @@
 #define CONF_OPER_REHASH        0x0040
 #define CONF_OPER_DIE           0x0080
 #define CONF_OPER_ADMIN         0x0100
+#define CONF_OPER_SPY		0x0200
 
 struct config_file_entry
 {
diff -uNr ircd-hybrid-7.0/include/s_serv.h ircd-hybrid-7.0+umodeZ/include/s_serv.h
--- ircd-hybrid-7.0/include/s_serv.h	Mon Jun  9 21:16:52 2003
+++ ircd-hybrid-7.0+umodeZ/include/s_serv.h	Thu Jun 12 17:12:36 2003
@@ -74,12 +74,13 @@
 
 #define CAP_TBURST	0x00040000   /* supports TBURST */
 #define CAP_PARA	0x00080000   /* supports invite broadcasting for +p */
+#define CAP_ENCAP	0x00100000
 
 #define CAP_MASK        (CAP_QS  | CAP_EX   | CAP_CHW  | \
                          CAP_IE  | CAP_EOB  | CAP_KLN  | \
                          CAP_GLN | CAP_HOPS | CAP_AOPS | \
                          CAP_UID | CAP_ZIP  | CAP_ENC | \
-                         CAP_KNOCK  | CAP_PARA)
+                         CAP_KNOCK  | CAP_PARA | CAP_ENCAP )
 
 #ifdef HAVE_LIBZ
 #define CAP_ZIP_SUPPORTED       CAP_ZIP
diff -uNr ircd-hybrid-7.0/include/send.h ircd-hybrid-7.0+umodeZ/include/send.h
--- ircd-hybrid-7.0/include/send.h	Fri Feb 14 17:01:49 2003
+++ ircd-hybrid-7.0+umodeZ/include/send.h	Thu Jun 12 17:12:36 2003
@@ -78,6 +78,8 @@
                    int caps, int nocaps, struct Channel *chptr,
                    const char *pattern, ...) AFP(7, 8);
 
+extern void sendto_match_servs(struct Client *, const char *, int,
+                               const char *, ...);
 extern void sendto_server(struct Client *one, struct Client *source_p,
                           struct Channel *chptr, unsigned long caps,
                           unsigned long nocaps, unsigned long llflags,
diff -uNr ircd-hybrid-7.0/modules/Makefile.in ircd-hybrid-7.0+umodeZ/modules/Makefile.in
--- ircd-hybrid-7.0/modules/Makefile.in	Sun Jun 16 11:31:25 2002
+++ ircd-hybrid-7.0+umodeZ/modules/Makefile.in	Thu Jun 12 17:12:36 2003
@@ -61,6 +61,7 @@
   m_cryptlink.c \
   m_dmem.c \
   m_drop.c \
+  m_encap.c \
   m_eob.c \
   m_gline.c \
   m_help.c \
diff -uNr ircd-hybrid-7.0/modules/m_encap.c ircd-hybrid-7.0+umodeZ/modules/m_encap.c
--- ircd-hybrid-7.0/modules/m_encap.c	Wed Dec 31 18:00:00 1969
+++ ircd-hybrid-7.0+umodeZ/modules/m_encap.c	Thu Jun 12 17:12:36 2003
@@ -0,0 +1,134 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  m_encap.c: encapsulated command propogation and parsing
+ *
+ *  Copyright (C) 2003 by the past and present ircd coders, and others.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ *  $Id: m_encap.c,v 1.7 2003/06/09 23:24:01 bill Exp $
+ */
+
+#include "stdinc.h"
+#include "handlers.h"
+#include "client.h"
+#include "msg.h"
+#include "parse.h"
+#include "sprintf_irc.h"
+#include "s_serv.h"
+#include "send.h"
+#include "modules.h"
+#include "irc_string.h"
+#include "common.h"
+#include "numeric.h"
+
+static void ms_encap(struct Client *client_p, struct Client *source_p,
+                     int parc, char *parv[]);
+
+struct Message encap_msgtab = {
+  "ENCAP", 0, 0, 3, 0, MFLG_SLOW, 0,
+  {m_ignore, m_ignore, ms_encap, m_ignore}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&encap_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&encap_msgtab);
+}
+const char *_version = "$Revision: 1.7 $";
+#endif
+
+/*
+ * ms_encap()
+ *
+ * inputs	- destination server, subcommand, parameters
+ * outputs	- none
+ * side effects	- propogates subcommand to locally connected servers
+ */
+static void
+ms_encap(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
+{
+  char buffer[BUFSIZE], *ptr = buffer;
+  unsigned int cur_len = 0, len, i;
+  int paramcount, mpara = 0;
+  struct Message *mptr = NULL;
+  MessageHandler handler = 0;
+
+  for (i = 1; i < (unsigned int)parc - 1; i++)
+  {
+    len = strlen(parv[i]) + 1;
+
+    if ((cur_len + len) >= sizeof(buffer))
+      return;
+
+    ircsprintf(ptr, "%s ", parv[i]);
+    cur_len += len;
+    ptr += len;
+  }
+
+  len = strlen(parv[i]);
+
+  /*
+   * if the final parameter crosses our buffer size, should we bail, 
+   * like the rest, or should we truncate?  ratbox seems to think truncate,
+   * so i'll do that for now until i can talk to lee.  -bill
+   */
+
+  if (parc == 3)
+    ircsprintf(ptr, "%s", parv[2]);
+  else
+    ircsprintf(ptr, ":%s", parv[parc-1]);
+
+  if ((cur_len + len) >= sizeof(buffer))
+    buffer[sizeof(buffer)-1] = '\0';
+
+  sendto_match_servs(source_p, parv[1], CAP_ENCAP,
+                     "ENCAP %s", buffer);
+
+  if (!match(parv[1], me.name))
+    return;
+
+  mptr = hash_parse(parv[2]);
+  if ((mptr == NULL) || (mptr->cmd == NULL))
+    return;
+
+  paramcount = mptr->parameters;
+  mpara      = mptr->maxpara;
+
+  mptr->bytes += strlen(buffer);
+
+  /*
+   * yes this is an ugly hack, but it is quicker than copying the entire array again
+   * note: this hack wouldnt be needed if parv[0] were set to the command name, rather
+   * than being derived from the prefix, as it should have been from the beginning.
+   */
+  ptr = parv[0];
+  parv+=2;
+  parc-=2;
+  parv[0] = ptr;
+
+  if ((handler = mptr->handlers[2]) == NULL)
+    return;
+
+  (*handler)(client_p, source_p, parc, parv);
+}
diff -uNr ircd-hybrid-7.0/src/ircd_lexer.l ircd-hybrid-7.0+umodeZ/src/ircd_lexer.l
--- ircd-hybrid-7.0/src/ircd_lexer.l	Wed Oct 30 11:44:56 2002
+++ ircd-hybrid-7.0+umodeZ/src/ircd_lexer.l	Fri Jun 13 14:17:52 2003
@@ -227,6 +227,7 @@
 oper		{ return OPERATOR; }
 oper_log        { return OPER_LOG; }
 oper_pass_resv	{ return OPER_PASS_RESV; }
+oper_spy	{ return OPER_SPY; }
 operator	{ return OPERATOR; }
 passwd		{ return PASSWORD; }
 password	{ return PASSWORD; }
diff -uNr ircd-hybrid-7.0/src/ircd_parser.y ircd-hybrid-7.0+umodeZ/src/ircd_parser.y
--- ircd-hybrid-7.0/src/ircd_parser.y	Tue Nov 12 07:45:42 2002
+++ ircd-hybrid-7.0+umodeZ/src/ircd_parser.y	Fri Jun 13 14:16:01 2003
@@ -195,6 +195,7 @@
 %token  OPER_LOG
 %token  OPER_ONLY_UMODES
 %token	OPER_PASS_RESV
+%token	OPER_SPY
 %token  OPER_UMODES
 %token  PACE_WAIT
 %token	PACE_WAIT_SIMPLE
@@ -739,7 +740,7 @@
 oper_items:     oper_items oper_item |
                 oper_item;
 
-oper_item:      oper_name  | oper_user | oper_password |
+oper_item:      oper_name  | oper_user | oper_password | oper_spy |
                 oper_class | oper_global_kill | oper_remote |
                 oper_kline | oper_unkline | oper_gline | oper_nick_changes |
                 oper_die | oper_rehash | oper_admin | oper_rsa_public_key_file | error;
@@ -841,6 +842,16 @@
   {
     MyFree(yy_achead->className);
     DupString(yy_achead->className, yylval.string);
+  };
+
+oper_spy:         OPER_SPY '=' TYES ';'
+  {
+    yy_achead->port |= CONF_OPER_SPY;
+  }
+                  |
+                  OPER_SPY '=' TNO ';'
+  {
+    yy_achead->port &= ~CONF_OPER_SPY;
   };
 
 oper_global_kill: GLOBAL_KILL '=' TYES ';'
diff -uNr ircd-hybrid-7.0/src/parse.c ircd-hybrid-7.0+umodeZ/src/parse.c
--- ircd-hybrid-7.0/src/parse.c	Mon Jun  9 21:16:54 2003
+++ ircd-hybrid-7.0+umodeZ/src/parse.c	Thu Jun 12 17:12:36 2003
@@ -60,7 +60,7 @@
 
 static int hash(char *p);
 
-static struct Message *hash_parse(char *);
+struct Message *hash_parse(char *);
 
 struct MessageHash *msg_hash_table[MAX_MSG_HASH];
 
@@ -498,7 +498,7 @@
  * output	- pointer to struct Message
  * side effects - 
  */
-static struct Message *
+struct Message *
 hash_parse(char *cmd)
 {
   struct MessageHash *ptr;
diff -uNr ircd-hybrid-7.0/src/s_conf.c ircd-hybrid-7.0+umodeZ/src/s_conf.c
--- ircd-hybrid-7.0/src/s_conf.c	Sun Feb 16 16:06:46 2003
+++ ircd-hybrid-7.0+umodeZ/src/s_conf.c	Sat Jun 21 01:05:30 2003
@@ -1789,6 +1789,15 @@
     }
   else
     *privs_ptr++ = 'r';
+
+  if(port & CONF_OPER_SPY)
+    {
+      if(client_p)
+        SetOperSpy(client_p);
+      *privs_ptr++ = 'S';
+    }
+  else
+    *privs_ptr++ = 's';
   
   if(port & CONF_OPER_UNKLINE)
     {
diff -uNr ircd-hybrid-7.0/src/s_serv.c ircd-hybrid-7.0+umodeZ/src/s_serv.c
--- ircd-hybrid-7.0/src/s_serv.c	Sat May 31 02:30:34 2003
+++ ircd-hybrid-7.0+umodeZ/src/s_serv.c	Thu Jun 12 17:12:36 2003
@@ -104,6 +104,7 @@
   { "ZIP",   CAP_ZIP },
   { "TBURST", CAP_TBURST },
   { "PARA",  CAP_PARA },
+  { "ENCAP", CAP_ENCAP },
   { 0,           0 }
 };
 
diff -uNr ircd-hybrid-7.0/src/s_user.c ircd-hybrid-7.0+umodeZ/src/s_user.c
--- ircd-hybrid-7.0/src/s_user.c	Wed May 28 23:58:03 2003
+++ ircd-hybrid-7.0+umodeZ/src/s_user.c	Thu Jun 12 17:12:36 2003
@@ -91,6 +91,7 @@
   {FLAGS_EXTERNAL, 'x'},
   {FLAGS_SPY, 'y'},
   {FLAGS_OPERWALL, 'z'},
+  {FLAGS_SPYLOG, 'Z'},
   {0, 0}
 };
 
@@ -128,7 +129,7 @@
   0,            /* W */
   0,            /* X */
   0,            /* Y */
-  0,            /* Z 0x5A */
+  FLAGS_SPYLOG, /* Z 0x5A */
   0, 0, 0, 0, 0, /* 0x5F */ 
   /* 0x60 */       0,
   FLAGS_ADMIN,  /* a */
diff -uNr ircd-hybrid-7.0/src/send.c ircd-hybrid-7.0+umodeZ/src/send.c
--- ircd-hybrid-7.0/src/send.c	Wed Apr  2 19:29:04 2003
+++ ircd-hybrid-7.0+umodeZ/src/send.c	Thu Jun 12 17:12:36 2003
@@ -609,6 +609,63 @@
   }
 }
 
+/* sendto_match_servs()
+ *
+ * inputs       - source client
+ *              - mask to send to
+ *              - capab needed
+ *              - data
+ * outputs      - none
+ * side effects - data sent to servers matching with capab
+ */
+void
+sendto_match_servs(struct Client *source_p, const char *mask, int cap,
+                   const char *pattern, ...)
+{
+  va_list args;
+  struct Client *target_p;
+  dlink_node *ptr;
+  char buffer[BUFSIZE];
+  int found = 0;
+
+  va_start(args, pattern);
+  send_format(&buffer[0], pattern, args);
+  va_end(args);
+
+  current_serial++;
+
+  DLINK_FOREACH(ptr, global_serv_list.head)
+  {
+    target_p = ptr->data;
+                         
+    /* Do not attempt to send to ourselves, or the source */
+    if (IsMe(target_p) || target_p->from == source_p->from) 
+      continue;                                            
+               
+    if (target_p->from->serial == current_serial)
+      continue;                                  
+               
+    if (match(mask, target_p->name))
+    {
+      /*
+       * if we set the serial here, then we'll never do a
+       * match() again, if !IsCapable()                  
+       */                              
+      target_p->from->serial = current_serial;
+      found++;                                
+              
+      if (!IsCapable(target_p->from, cap))
+        continue;
+                 
+      sendto_anywhere(target_p, source_p, buffer);
+    }                                             
+  }
+
+  if (!found && IsClient(source_p) && !match(mask, me.name))
+    sendto_one(source_p, form_str(ERR_NOSUCHSERVER),        
+               me.name, source_p->name, mask);
+}
+
 /*
  * sendto_server
  * 
