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	Fri Jun  8 18:03:39 2001
+++ ircd-hybrid-6.0/include/client.h	Fri Jun  8 16:07:44 2001
@@ -105,6 +105,37 @@
   struct Client*   users;       /* Users on this server */
 };
 
+/* DO NOT change this without changing the bitfield macros */
+typedef u_int32_t umode_t[2];
+
+/* Support stuff for the umode bitfields */
+#define BITFIELD_SIZE 64
+
+struct bitfield_lookup_t {
+  int field;
+  u_int32_t bit;
+};
+
+/* This is initialised in init_umodes() in s_user.c, based on the value of BITFIELD_SIZE */
+extern struct bitfield_lookup_t bitfield_lookup[];
+
+#define SetBit(f,b)   (((f)[bitfield_lookup[b].field]) |=  bitfield_lookup[b].bit)
+#define ClearBit(f,b) (((f)[bitfield_lookup[b].field]) &= ~bitfield_lookup[b].bit)
+#define TestBit(f,b)  (((f)[bitfield_lookup[b].field]) &  bitfield_lookup[b].bit)
+
+/* Written out in full for speed.
+ * I never thought I would actually use the , operator. You live and learn.
+ *  -- asuffield
+ */
+#define CopyUmodes(d,s) ((d[0] = s[0]), (d[1] = s[1]))
+#define AndUmodes(d,a,b) ((d[0] = a[0] & b[0]), (d[1] = a[1] & b[1]))
+#define OrUmodes(d,a,b) ((d[0] = a[0] | b[0]), (d[1] = a[1] | b[1]))
+#define AndNotUmodes(d,a,b) ((d[0] = a[0] & ~b[0]), (d[1] = a[1] & ~b[1]))
+#define NotUmodes(d,s) ((d[0] = ~s[0]), (d[1] = ~s[1]))
+#define AnyBits(d) (d[0] | d[1])
+
+#define ClearBitfield(b) ((b[0] = 0), (b[1] = 0))
+
 struct Client
 {
   struct Client*    next;
@@ -139,7 +170,8 @@
   time_t            firsttime;  /* time client was created */
   time_t            since;      /* last time we parsed something */
   time_t            tsinfo;     /* TS on the nick, SVINFO on server */
-  u_int32_t         umodes;     /* opers, normal users subset */
+  umode_t           umodes;     /* opers, normal users subset. DO NOT change this number without editing the bitfield macros below */
+  umode_t   allowed_umodes;     /* umodes which may be set outside of USER_UMODES */
   u_int32_t         flags;      /* client flags */
   u_int32_t         flags2;     /* ugh. overflow */
   int               fd;         /* >= 0, for local clients */
@@ -320,33 +352,62 @@
 #define FLAGS_IPHASH       0x1000 /* iphashed this client */
 
 /* umodes, settable flags */
-#define FLAGS_SERVNOTICE   0x00001 /* server notices such as kill */
-#define FLAGS_CCONN        0x00002 /* Client Connections */
-#define FLAGS_REJ          0x00004 /* Bot Rejections */
-#define FLAGS_SKILL        0x00008 /* Server Killed */
-#define FLAGS_FULL         0x00010 /* Full messages */
-#define FLAGS_SPY          0x00020 /* see STATS / LINKS */
-#define FLAGS_DEBUG        0x00040 /* 'debugging' info */
-#define FLAGS_NCHANGE      0x00080 /* Nick change notice */
-#define FLAGS_WALLOP       0x00100 /* send wallops to them */
-#define FLAGS_OPERWALL     0x00200 /* Operwalls */
-#define FLAGS_INVISIBLE    0x00400 /* makes user invisible */
-#define FLAGS_BOTS         0x00800 /* shows bots */
-#define FLAGS_EXTERNAL     0x01000 /* show servers introduced */
-#define FLAGS_NINVITE      0x40000 /* Don't send or receive INVITE messages -- PMA */
-#define FLAGS_NCTCP        0x200000 /* Don't receive CTCP messages or notices -- PMA */
+/* Nice, flashy new bitfield math. These are just indexes into the lookup. Fun :)
+ *  -- asuffield */
+#define UMODE_INVALID         0 /* Used as a delimeter in lists */
+#define UMODE_SERVNOTICE      1 /* server notices such as kill */
+#define UMODE_CCONN           2 /* Client Connections */
+#define UMODE_REJ             3 /* Bot Rejections */
+#define UMODE_SKILL           4 /* Server Killed */
+#define UMODE_FULL            5 /* Full messages */
+#define UMODE_SPY             6 /* see STATS / LINKS */
+#define UMODE_DEBUG           7 /* 'debugging' info */
+#define UMODE_NCHANGE         8 /* Nick change notice */
+#define UMODE_WALLOP          9 /* send wallops to them */
+#define UMODE_OPERWALL       10 /* Operwalls */
+#define UMODE_INVISIBLE      11 /* makes user invisible */
+#define UMODE_BOTS           12 /* shows bots */
+#define UMODE_EXTERNAL       13 /* show servers introduced */
+#define UMODE_NINVITE        14 /* Don't send or receive INVITE messages -- PMA */
+#define UMODE_NCTCP          15 /* Don't receive CTCP messages or notices -- PMA */
 
 /* user information flags, only settable by remote mode or local oper */
-#define FLAGS_IMMUNE       0x02000 /* immune from kick/deop */
-#define FLAGS_OPER         0x04000 /* Operator */
-#define FLAGS_LOCOP        0x08000 /* Local operator -- SRB */
-#define FLAGS_AUSPEX       0x10000 /* See the invisible. */
-#define FLAGS_IDENTIFIED   0x20000 /* Registered and identified with NickServ -- MGS */
-#define FLAGS_CHCREATE    0x80000 /* Channel Creation Notices */
-#define FLAGS_BLOCK_NOTID   0x100000 /* Block messages from non-identified users */
-
-#define FLAGS_GOD          0x400000 /* greater deity */
-/* Last flag is 0x80000000 for 32-bit unsigned int */
+/* No longer; these are now privileges proper. You can only gain them
+ * if your O:line says you can.
+ *  -- asuffield
+ */
+#define UMODE_IMMUNE         16 /* immune from kick/deop */
+#define UMODE_OPER           17 /* Operator */
+#define UMODE_LOCOP          18 /* Local operator -- SRB */
+#define UMODE_AUSPEX         19 /* See the invisible. */
+#define UMODE_IDENTIFIED     20 /* Registered and identified with NickServ -- MGS */
+#define UMODE_CHCREATE       21 /* Channel Creation Notices */
+#define UMODE_BLOCK_NOTID    22 /* Block messages from non-identified users */
+
+#define UMODE_GOD            23 /* greater deity */
+#define UMODE_GLOBAL_KILL    24
+#define UMODE_REMOTE         25 /* CONNECT, SQUIT */
+#define UMODE_GLINE          26
+#define UMODE_KILL           27 /* KILL, KLINE */
+#define UMODE_DIE            28
+#define UMODE_REHASH         29
+#define UMODE_UNKLINE        30
+#define UMODE_SEESOPERS      31
+#define UMODE_FLUDPROOF      32
+#define UMODE_MASSNOTICE     33
+#define UMODE_SEEILINES      34
+#define UMODE_SEEKLINES      35
+#define UMODE_SEEQLINES      36
+#define UMODE_SEESTATST      37
+#define UMODE_SEESTATSSERV   38
+#define UMODE_TESTLINE       39
+#define UMODE_FORCELUSERS    40
+#define UMODE_ANYNICK        41
+#define UMODE_SENDWALLOPS    42
+#define UMODE_SETNAME        43
+#define UMODE_HIGHPRIORITY   44
+#define UMODE_GRANT          45
+#define UMODE_SENDOPERWALL   46
 
 /* *sigh* overflow flags */
 #define FLAGS2_RESTRICTED   0x0001      /* restricted client */
@@ -356,32 +417,6 @@
 #define FLAGS2_F_LINED      0x0010      /* client is graced with F line */
 #define FLAGS2_EXEMPTGLINE  0x2000      /* client can't be G-lined */
 
-/* oper priv flags */
-#define FLAGS2_OPER_GLOBAL_KILL 0x0020  /* oper can global kill */
-#define FLAGS2_OPER_REMOTE      0x0040  /* oper can do squits/connects */
-#define FLAGS2_OPER_UNKLINE     0x0080  /* oper can use unkline */
-#define FLAGS2_OPER_GLINE       0x0100  /* oper can use gline */
-#define FLAGS2_OPER_N           0x0200  /* oper can umode n */
-#define FLAGS2_OPER_K           0x0400  /* oper can kill/kline */
-#define FLAGS2_OPER_DIE         0x0800  /* oper can die */
-#define FLAGS2_OPER_REHASH      0x1000  /* oper can rehash */
-#define FLAGS2_OPER_IMMUNE	0x2000	/* oper can umode m */
-#define FLAGS2_OPER_AUSPEX	0x800000 /* oper can see the invisible */
-#define FLAGS2_OPER_CHCREATE	0x2000000 /* oper sees local chan creations */
-					 /* Careful of the numbering if you add another flag... */
-#define FLAGS2_OPER_GOD         0x4000000 /* oper can have an apotheosis */
-#define FLAGS2_OPER_FLAGS       (FLAGS2_OPER_GLOBAL_KILL | \
-                                 FLAGS2_OPER_GOD | \
-                                 FLAGS2_OPER_REMOTE | \
-                                 FLAGS2_OPER_UNKLINE | \
-                                 FLAGS2_OPER_GLINE | \
-                                 FLAGS2_OPER_N | \
-                                 FLAGS2_OPER_K | \
-                                 FLAGS2_OPER_DIE | \
-                                 FLAGS2_OPER_REHASH | \
-                                 FLAGS2_OPER_IMMUNE | \
-                                 FLAGS2_OPER_AUSPEX | \
-                                 FLAGS2_OPER_CHCREATE)
 /* ZIP_LINKS */
 
 #define FLAGS2_ZIP           0x4000  /* (server) link is zipped */
@@ -398,33 +433,20 @@
                                                    from non opers */
 #define FLAGS2_SENDQ_POP  0x400000  /* sendq exceeded (during list) */
 
-
-#define SEND_UMODES  (FLAGS_INVISIBLE | FLAGS_OPER | FLAGS_WALLOP | \
-                      FLAGS_IMMUNE | FLAGS_IDENTIFIED | FLAGS_NINVITE | \
-                      FLAGS_BLOCK_NOTID | FLAGS_NCTCP)
-/*
- * Only opers can have modes outside USER_UMODES.  If you change this
- * set, then also change the explanatory NOTICE in user_mode(). -dark
+/**********
+ * NOTICE *
+ **********
+ *
+ * send_umodes and user_umodes are 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
  */
-#define USER_UMODES  (FLAGS_INVISIBLE | FLAGS_WALLOP | FLAGS_NINVITE | \
-                      FLAGS_BLOCK_NOTID | FLAGS_NCTCP)
-#define ALL_UMODES   (SEND_UMODES | FLAGS_SERVNOTICE | FLAGS_CCONN | \
-                      FLAGS_REJ | FLAGS_SKILL | FLAGS_FULL | FLAGS_SPY | \
-                      FLAGS_NCHANGE | FLAGS_OPERWALL | FLAGS_DEBUG | \
-                      FLAGS_BOTS | FLAGS_EXTERNAL | FLAGS_LOCOP | \
-                      FLAGS_GOD | FLAGS_IMMUNE | FLAGS_AUSPEX | \
-                      FLAGS_IDENTIFIED | FLAGS_CHCREATE | FLAGS_BLOCK_NOTID)
-
-#ifndef OPER_UMODES
-#define OPER_UMODES  (FLAGS_OPER | FLAGS_WALLOP | FLAGS_SERVNOTICE | \
-                      FLAGS_SPY | FLAGS_OPERWALL | FLAGS_DEBUG | FLAGS_BOTS \
-                      FLAGS_CHCREATE)
-#endif /* OPER_UMODES */
-
-#ifndef LOCOP_UMODES
-#define LOCOP_UMODES (FLAGS_LOCOP | FLAGS_WALLOP | FLAGS_SERVNOTICE | \
-                      FLAGS_SPY | FLAGS_DEBUG | FLAGS_BOTS)
-#endif /* LOCOP_UMODES */
+
+extern umode_t send_umodes;
+extern umode_t user_umodes;
+extern umode_t all_umodes;
 
 #define FLAGS_ID     (FLAGS_NEEDID | FLAGS_GOTID)
 
@@ -443,53 +465,78 @@
 
 /* oper flags */
 #define MyOper(x)               (MyConnect(x) && IsOper(x))
-#define IsOper(x)               ((x)->umodes & FLAGS_OPER)
+#define IsOper(x)               (TestBit((x)->umodes,UMODE_OPER))
 #ifdef GODOPERS
-#define IsGodOper(x)            ((x)->umodes & FLAGS_GOD)
+#define IsGodOper(x)            (TestBit((x)->umodes,UMODE_GOD))
 #else
 #define IsGodOper(x)            0
 #endif
-#define IsLocOp(x)              ((x)->umodes & FLAGS_LOCOP)
-#define IsAnOper(x)             ((x)->umodes & (FLAGS_OPER|FLAGS_LOCOP))
-#define SetOper(x)              ((x)->umodes |= FLAGS_OPER)
-#define SetLocOp(x)             ((x)->umodes |= FLAGS_LOCOP)
-#define ClearOper(x)            ((x)->umodes &= ~FLAGS_OPER)
-#define ClearLocOp(x)           ((x)->umodes &= ~FLAGS_LOCOP)
+#define IsLocOp(x)              (TestBit((x)->umodes,UMODE_LOCOP))
+#define IsAnOper(x)             (IsOper(x) || IsLocOp(x))
+#define SetOper(x)              (SetBit((x)->umodes,UMODE_OPER))
+#define SetLocOp(x)             (SetBit((x)->umodes,UMODE_LOCOP))
+#define ClearOper(x)            (ClearBit((x)->umodes,UMODE_OPER))
+#define ClearLocOp(x)           (ClearBit((x)->umodes,UMODE_LOCOP))
 #define IsPrivileged(x)         (IsAnOper(x) || IsServer(x))
 
 /* umode flags */
-#define IsInvisible(x)          ((x)->umodes & FLAGS_INVISIBLE)
-#define SetInvisible(x)         ((x)->umodes |= FLAGS_INVISIBLE)
-#define ClearInvisible(x)       ((x)->umodes &= ~FLAGS_INVISIBLE)
-#define BlocksInvites(x)        ((x)->umodes & FLAGS_NINVITE)
-#define SetNoInvites(x)         ((x)->umodes |= FLAGS_NINVITE)
-#define ClearNoInvites(x)       ((x)->umodes &= ~FLAGS_NINVITE)
-#define DoesNotCTCP(x)          ((x)->umodes & FLAGS_NCTCP)
-#define SendWallops(x)          (((x)->umodes & FLAGS_WALLOP) && IsAnOper(x))
-#define ClearWallops(x)         ((x)->umodes &= ~FLAGS_WALLOP)
-#define SendServNotice(x)       (((x)->umodes & FLAGS_SERVNOTICE) && IsAnOper(x))
-#define SendOperwall(x)         ((x)->umodes & FLAGS_OPERWALL)
-#define SendCConnNotice(x)      ((x)->umodes & FLAGS_CCONN)
-#define SendRejNotice(x)        ((x)->umodes & FLAGS_REJ)
-#define SendSkillNotice(x)      ((x)->umodes & FLAGS_SKILL)
-#define SendFullNotice(x)       ((x)->umodes & FLAGS_FULL)
-#define SendSpyNotice(x)        ((x)->umodes & FLAGS_SPY)
-#define SendDebugNotice(x)      ((x)->umodes & FLAGS_DEBUG)
-#define SendNickChange(x)       ((x)->umodes & FLAGS_NCHANGE)
-#define SetWallops(x)           ((x)->umodes |= FLAGS_WALLOP)
-#define IsImmune(x)             ((x)->umodes & FLAGS_IMMUNE)
+#define IsInvisible(x)          (TestBit((x)->umodes,UMODE_INVISIBLE))
+#define BlocksInvites(x)        (TestBit((x)->umodes,UMODE_NINVITE))
+#define DoesNotCTCP(x)          (TestBit((x)->umodes,UMODE_NCTCP))
+#define SendOperwall(x)         (TestBit((x)->umodes,UMODE_SENDOPERWALL))
+#define ReceiveOperwall(x)      (TestBit((x)->umodes,UMODE_OPERWALL))
+#define SendCConnNotice(x)      (TestBit((x)->umodes,UMODE_CCONN))
+#define SendRejNotice(x)        (TestBit((x)->umodes,UMODE_REJ))
+#define SendSkillNotice(x)      (TestBit((x)->umodes,UMODE_SKILL))
+#define SendFullNotice(x)       (TestBit((x)->umodes,UMODE_FULL))
+#define SendSpyNotice(x)        (TestBit((x)->umodes,UMODE_SPY))
+#define IsDebugger(x)           (TestBit((x)->umodes,UMODE_DEBUG))
+#define SendNickChange(x)       (TestBit((x)->umodes,UMODE_NCHANGE))
+#define IsImmune(x)             (TestBit((x)->umodes,UMODE_IMMUNE))
 
 #ifdef CHANNEL_CREATION_NOTICE
-#define SeesChannelCreations(x) ((x)->umodes & FLAGS_CHCREATE)
+#define SeesChannelCreations(x) (TestBit((x)->umodes,UMODE_CHCREATE))
 #endif
 
-#define SeesAllConnections(x)	((x)->umodes & FLAGS_AUSPEX)
-#define IsIdentifiedNick(x)     ((x)->umodes & FLAGS_IDENTIFIED)
-#define SetIdentifiedNick(x)    ((x)->umodes |= FLAGS_IDENTIFIED)
-#define ClearIdentifiedNick(x)  ((x)->umodes &= ~FLAGS_IDENTIFIED)
-#define IsBlockingUnidented(x)  ((x)->umodes & FLAGS_BLOCK_NOTID)
-#define SetBlockingUnidented(x) ((x)->umodes |= FLAGS_BLOCK_NOTID)
-#define ClearBlockingUnidented(x) ((x)->umodes &= ~FLAGS_BLOCK_NOTID)
+#define SeesOperMessages(x)     (TestBit((x)->umodes,UMODE_OPER))
+#define SeesOpers(x)            (TestBit((x)->umodes,UMODE_SEESOPERS))
+#define SendWhileLifeSucks(x)   (TestBit((x)->umodes,UMODE_HIGHPRIORITY))
+#define IsAlwaysBusy(x)         (TestBit((x)->umodes,UMODE_HIGHPRIORITY))
+/* This one means no protection against *this* client flooding */
+#define NoFloodProtection(x)    (TestBit((x)->umodes,UMODE_FLUDPROOF))
+#define CanSendMassNotice(x)    (TestBit((x)->umodes,UMODE_MASSNOTICE))
+#define CanSeeBlines(x)         (TestBit((x)->umodes,UMODE_SEEILINES))
+#define CanSeeDlines(x)         (TestBit((x)->umodes,UMODE_SEEKLINES))
+#define CanSeeElines(x)         (TestBit((x)->umodes,UMODE_SEEILINES))
+#define CanSeeFlines(x)         (TestBit((x)->umodes,UMODE_SEEILINES))
+#define CanSeeGlines(x)         (TestBit((x)->umodes,UMODE_SEEKLINES))
+#define CanSeeIlines(x)         (TestBit((x)->umodes,UMODE_SEEILINES))
+#define CanSeeKlines(x)         (TestBit((x)->umodes,UMODE_SEEKLINES))
+#define CanSeeOlines(x)         (TestBit((x)->umodes,UMODE_SEESOPERS))
+#define CanSeeQlines(x)         (TestBit((x)->umodes,UMODE_SEEQLINES))
+#define CanSeeStatsT(x)         (TestBit((x)->umodes,UMODE_SEESTATST))
+#define CanSeeXlines(x)         (TestBit((x)->umodes,UMODE_SEEQLINES))
+#define CanSeeYlines(x)         (TestBit((x)->umodes,UMODE_SEEILINES))
+#define CanSeeStatsServinfo(x)  (TestBit((x)->umodes,UMODE_SEESTATSSERV))
+#define CanDoTestline(x)        (TestBit((x)->umodes,UMODE_TESTLINE))
+#define CanForceLusers(x)       (TestBit((x)->umodes,UMODE_FORCELUSERS))
+#define CannotBeQlined(x)       (TestBit((x)->umodes,UMODE_ANYNICK))
+#define CannotBeXlined(x)       (TestBit((x)->umodes,UMODE_ANYNICK))
+#define SendWallops(x)          (TestBit((x)->umodes,UMODE_SENDWALLOPS))
+#define SendServNotice(x)       (TestBit((x)->umodes,UMODE_SERVNOTICE))
+#define CanConnect(x)           (TestBit((x)->umodes,UMODE_REMOTE))
+#define CanDoSetname(x)         (TestBit((x)->umodes,UMODE_SETNAME))
+/* Changing another user's umode */
+#define CanChangeModes(x)       (TestBit((x)->umodes,UMODE_SETNAME))
+#define CanGrantModes(x)        (TestBit((x)->umodes,UMODE_GRANT))
+
+#define SeesAllConnections(x)	(TestBit((x)->umodes,UMODE_AUSPEX))
+#define IsIdentifiedNick(x)     (TestBit((x)->umodes,UMODE_IDENTIFIED))
+#define SetIdentifiedNick(x)    (SetBit((x)->umodes,UMODE_IDENTIFIED))
+#define ClearIdentifiedNick(x)  (ClearBit((x)->umodes,UMODE_IDENTIFIED))
+#define IsBlockingUnidented(x)  (TestBit((x)->umodes,UMODE_BLOCK_NOTID))
+/* #define SetBlockingUnidented(x) (SetBit((x)->umodes,UMODE_BLOCK_NOTID)) */
+/* #define ClearBlockingUnidented(x) (ClearBit((x)->umodes,UMODE_BLOCK_NOTID)) */
 
 #ifdef REJECT_HOLD
 #define IsRejectHeld(x)         ((x)->flags & FLAGS_REJECT_HOLD)
@@ -536,33 +583,20 @@
 #endif
 
 #ifdef GODOPERS
-#define SetOperGod(x)           ((x)->flags2 |= FLAGS2_OPER_GOD)
-#define IsSetOperGod(x)         ((x)->flags2 & FLAGS2_OPER_GOD)
+#define IsSetOperGod(x)         (TestBit((x)->umodes,UMODE_GOD))
 #endif
-#define SetOperGlobalKill(x)    ((x)->flags2 |= FLAGS2_OPER_GLOBAL_KILL)
-#define IsOperGlobalKill(x)     ((x)->flags2 & FLAGS2_OPER_GLOBAL_KILL)
-#define SetOperRemote(x)        ((x)->flags2 |= FLAGS2_OPER_REMOTE)
-#define IsOperRemote(x)         ((x)->flags2 & FLAGS2_OPER_REMOTE)
-#define SetOperUnkline(x)       ((x)->flags2 |= FLAGS2_OPER_UNKLINE)
-#define IsSetOperUnkline(x)     ((x)->flags2 & FLAGS2_OPER_UNKLINE)
-#define SetOperGline(x)         ((x)->flags2 |= FLAGS2_OPER_GLINE)
-#define IsSetOperGline(x)       ((x)->flags2 & FLAGS2_OPER_GLINE)
-#define SetOperN(x)             ((x)->flags2 |= FLAGS2_OPER_N)
-#define IsSetOperN(x)           ((x)->flags2 & FLAGS2_OPER_N)
-#define SetOperK(x)             ((x)->flags2 |= FLAGS2_OPER_K)
-#define IsSetOperK(x)           ((x)->flags2 & FLAGS2_OPER_K)
-#define SetOperDie(x)           ((x)->flags2 |= FLAGS2_OPER_DIE)
-#define IsOperDie(x)            ((x)->flags2 & FLAGS2_OPER_DIE)
-#define SetOperRehash(x)        ((x)->flags2 |= FLAGS2_OPER_REHASH)
-#define IsOperRehash(x)         ((x)->flags2 & FLAGS2_OPER_REHASH)
-#define IsSetOperM(x)           ((x)->flags2 & FLAGS2_OPER_IMMUNE)
-#define SetOperM(x)             ((x)->flags2 |= FLAGS2_OPER_IMMUNE)
-#define IsSetOperAuspex(x)	((x)->flags2 & FLAGS2_OPER_AUSPEX)
-#define SetOperAuspex(x)	((x)->flags2 |= FLAGS2_OPER_AUSPEX)
+#define IsSetOperGlobalKill(x)  (TestBit((x)->umodes,UMODE_GLOBAL_KILL))
+#define IsSetOperRemote(x)      (TestBit((x)->umodes,UMODE_REMOTE))
+#define IsSetOperUnkline(x)     (TestBit((x)->umodes,UMODE_UNKLINE))
+#define IsSetOperGline(x)       (TestBit((x)->umodes,UMODE_GLINE))
+#define IsSetOperK(x)           (TestBit((x)->umodes,UMODE_KILL))
+#define IsSetOperDie(x)         (TestBit((x)->umodes,UMODE_DIE))
+#define IsSetOperRehash(x)      (TestBit((x)->umodes,UMODE_REHASH))
+#define IsSetOperM(x)           (TestBit((x)->umodes,UMODE_IMMUNE))
+#define IsSetOperAuspex(x)	(TestBit((x)->umodes,UMODE_AUSPEX))
 
 #ifdef CHANNEL_CREATION_NOTICE
-#define IsSetOperChanCreate(x)	((x)->flags2 & FLAGS2_OPER_CHCREATE)
-#define SetOperChanCreate(x)	((x)->flags2 |= FLAGS2_OPER_CHCREATE)
+#define IsSetOperChanCreate(x)	(TestBit((x)->umodes,UMODE_CHCREATE))
 #endif
 
 #define CBurst(x)               ((x)->flags2 & FLAGS2_CBURST)
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	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/include/config.h	Fri Jun  8 17:30:27 2001
@@ -747,10 +747,17 @@
  *
  * OPER_IDLE allows operators to remain idle when they idle
  * beyond the idle limit
+ *
+ * OPER_IDLE is fundamentally opposed to the objective of
+ * removing all special powers from O:lines and moving to
+ * capabilities. Don't use it.
+ *  -- asuffield
  */
 #undef  IDLE_CHECK
 #define IDLE_TIME 20160
-#define OPER_IDLE
+/* (deprecated)
+ * #undef OPER_IDLE
+ */
 
 /* SEND_FAKE_KILL_TO_CLIENT - make the client think it's being /KILL'ed
  * 
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	Fri Jun  8 18:03:39 2001
+++ ircd-hybrid-6.0/include/s_conf.h	Wed Jun  6 18:30:41 2001
@@ -201,6 +201,7 @@
 #ifndef INCLUDED_motd_h
 #include "motd.h"               /* MessageFile */
 #endif
+#include "client.h"
 
 struct Client;
 struct SLink;
@@ -224,6 +225,8 @@
   time_t           hold;     /* Hold action until this time (calendar time) */
   struct Class*    c_class;     /* Class of connection */
   int              dns_pending; /* 1 if dns query pending, 0 otherwise */
+  umode_t          allowed_umodes;
+  umode_t          default_umodes;
 };
 
 typedef struct QlineItem {
@@ -317,21 +320,6 @@
 #define IsConfLittleI(x)        ((x)->flags & CONF_FLAGS_LITTLE_I_LINE)
 #endif
 
-/* port definitions for Opers */
-
-#define CONF_OPER_GLOBAL_KILL 1
-#define CONF_OPER_REMOTE      2
-#define CONF_OPER_UNKLINE     4
-#define CONF_OPER_GLINE       8
-#define CONF_OPER_N          16
-#define CONF_OPER_K          32
-#define CONF_OPER_REHASH     64
-#define CONF_OPER_DIE       128
-#define CONF_OPER_M         256
-#define CONF_OPER_AUSPEX    512
-#define CONF_OPER_CHCREATE 1024
-#define CONF_OPER_GOD      2048
-
 typedef struct
 {
   char *dpath;          /* DPATH if set from command line */
@@ -403,8 +391,7 @@
 extern struct ConfItem* find_conf_by_abbrevname(const char* name, int status);
 extern struct ConfItem* find_kill (struct Client *);
 extern int conf_connect_allowed(struct in_addr addr);
-extern char *oper_flags_as_string(int);
-extern char *oper_privs_as_string(struct Client *, int);
+extern char *oper_flags_as_string(umode_t);
 extern int rehash_dump(struct Client *);
 extern int find_q_line(char*, char*, char *);
 extern struct ConfItem* find_special_conf(char *,int );
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	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/include/s_user.h	Wed Jun  6 18:40:36 2001
@@ -31,20 +31,21 @@
 #include <sys/types.h>      /* time_t */
 #define INCLUDED_sys_types_h
 #endif
+#include "client.h"
 
 struct Client;
 #ifdef PACE_WALLOPS
 extern time_t LastUsedWallops;
 #endif
 
-
 extern int   user_mode(struct Client *, struct Client *, int, char **);
 extern void  send_umode (struct Client *, struct Client *,
-                         int, int, char *);
-extern void  send_umode_out (struct Client*, struct Client *, int);
+                         umode_t, 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);
 extern int   del_silence(struct Client *, char *);
 extern int   is_silenced(struct Client *, struct Client *);
+extern void  init_umodes();
 
 #endif
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	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/include/send.h	Wed Jun  6 17:39:42 2001
@@ -55,10 +55,10 @@
 extern  void sendto_match_butone(struct Client *, struct Client *, 
                                  char *, int, const char *, ...);
 
-extern  void sendto_ops_flags(int, const char *, ...);
+extern  void sendto_ops_flag(int, const char *, ...);
 
 extern  void sendto_realops(const char *, ...);
-extern  void sendto_realops_flags(int, const char *, ...);
+extern  void sendto_realops_flag(int, const char *, ...);
 
 extern  void sendto_ops(const char *, ...);
 extern  void sendto_ops_butone(struct Client *, struct Client *, 
@@ -78,6 +78,6 @@
 #define MATCH_SERVER  1
 #define MATCH_HOST    2
 
-extern  void sendto_ops_flags_butone(struct Client *, int, const char *, ...);
+extern  void sendto_ops_flag_butone(struct Client *, int, 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	Thu Jan  1 01:00:00 1970
+++ ircd-hybrid-6.0/include/umodes.h	Fri Jun  8 16:07:21 2001
@@ -0,0 +1,94 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, include/s_user.h
+ *   This file is copyright (C) 2001 Andrew Suffield
+ *                                    <asuffield@users.sourceforge.net>
+ *
+ *   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
+ *
+ */
+#ifndef INCLUDED_s_umodes_h
+#define INCLUDED_s_umodes_h
+#ifndef INCLUDED_config_h
+#include "config.h"
+#endif
+#ifndef INCLUDED_sys_types_h
+#include <sys/types.h>      /* time_t */
+#define INCLUDED_sys_types_h
+#endif
+
+#include "common.h"
+#include "client.h"
+
+/* table of ascii char letters to corresponding bitmask */
+
+static FLAG_ITEM user_modes[] =
+{ 
+  {UMODE_AUSPEX, 'a'},
+  {UMODE_BOTS,  'b'},
+  {UMODE_CCONN, 'c'},
+  {UMODE_NCTCP, 'C'},
+  {UMODE_DEBUG, 'd'},
+  {UMODE_DIE, 'D'},
+  {UMODE_IDENTIFIED, 'e'},
+  {UMODE_BLOCK_NOTID, 'E'},
+  {UMODE_FULL,  'f'},
+  {UMODE_FLUDPROOF, 'F'},
+  {UMODE_GLINE, 'g'},
+  {UMODE_GLOBAL_KILL, 'G'},
+  {UMODE_HIGHPRIORITY, 'h'},
+  {UMODE_REHASH, 'H'},
+  {UMODE_INVISIBLE, 'i'},
+  {UMODE_NINVITE, 'I'},
+  {UMODE_SKILL, 'k'},
+  {UMODE_KILL, 'K'},
+#ifdef CHANNEL_CREATION_NOTICE
+  {UMODE_CHCREATE, 'l'},
+#endif
+  {UMODE_FORCELUSERS, 'L'},
+  {UMODE_IMMUNE, 'm'},
+  {UMODE_MASSNOTICE, 'M'},
+  {UMODE_NCHANGE, 'n'},
+  {UMODE_ANYNICK, 'N'},
+  {UMODE_OPER, 'o'},
+  {UMODE_LOCOP, 'O'},
+#ifdef GODOPERS
+  {UMODE_GOD,   'p'},
+#endif
+  {UMODE_SETNAME, 'P'},
+  {UMODE_REJ, 'r'},
+  {UMODE_REMOTE, 'R'},
+  {UMODE_SERVNOTICE, 's'},
+  {UMODE_UNKLINE, 'U'},
+  {UMODE_WALLOP, 'w'},
+  {UMODE_SENDWALLOPS, 'W'},
+  {UMODE_EXTERNAL, 'x'},
+  {UMODE_SPY, 'y'},
+  {UMODE_OPERWALL, 'z'},
+  {UMODE_SENDOPERWALL, 'Z'},
+  {UMODE_SEESOPERS, '0'},
+  {UMODE_SEEILINES, '1'},
+  {UMODE_SEEKLINES, '2'},
+  {UMODE_SEEQLINES, '3'},
+  {UMODE_SEESTATST, '4'},
+  {UMODE_SEESTATSSERV,'5'},
+  {UMODE_TESTLINE, '9'},
+  {UMODE_GRANT, '*'},
+  {0, 0}
+};
+
+/* There is no reason why this cannot be calculated at runtime -- asuffield */
+extern int user_modes_from_c_to_bitmask[];
+
+#endif
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	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/src/channel.c	Wed Jun  6 17:39:09 2001
@@ -443,9 +443,9 @@
     if (match(BANSTR(tmp), s) ||
 	match(BANSTR(tmp), s2))
       {
-        if (tmp->value.banptr->can_join) /* really banned? or just quieted? */
+	if (tmp->value.banptr->can_join) /* really banned? or just quieted? */
 	  return CHFL_QUIET;
-        else
+	else
 	  break;
       }
 #else
@@ -1289,7 +1289,7 @@
             }
 
           /* Immune users */
-          if ((c == 'o') && whatt == MODE_DEL && !IsPrivileged(sptr)
+          if ((c == 'o') && whatt == MODE_DEL && !(IsServer(sptr) || IsSetOperGod(sptr))
               && IsImmune(who))
             {
               sendto_one(sptr, form_str(ERR_USERISIMMUNE),
@@ -2073,7 +2073,7 @@
           /* Un documented for now , I have no idea how this got here ;-) */
 #ifdef JUPE_CHANNEL
         case 'j':
-          if(IsAnOper(sptr))
+          if(IsSetOperGod(sptr))
             {
               if (whatt == MODE_ADD)
                 {
@@ -2519,10 +2519,10 @@
 #ifdef JUPE_CHANNEL
   if( chptr->mode.mode & MODE_JUPED )
     {
-      sendto_ops_flags(FLAGS_SPY,
-             "User %s (%s@%s) is attempting to join juped channel %s",
-                     sptr->name,
-                     sptr->username, sptr->host,chptr->chname);
+      sendto_ops_flag(UMODE_SPY,
+		      "User %s (%s@%s) is attempting to join juped channel %s",
+		      sptr->name,
+		      sptr->username, sptr->host,chptr->chname);
       return (ERR_BADCHANNAME);
     }
 #endif
@@ -2626,8 +2626,8 @@
 
 #ifdef CHANNEL_CREATION_NOTICE
       if(IsPerson(cptr) && !IsServer(cptr)) {
-        sendto_ops_flags_butone(NULL, FLAGS_CHCREATE, "Channel %s created by %s!%s@%s on %s", chptr->chname, cptr->name, 
-		       cptr->username, cptr->host, me.name);
+        sendto_ops_flag_butone(NULL, UMODE_CHCREATE, "Channel %s created by %s!%s@%s on %s", chptr->chname, cptr->name, 
+			       cptr->username, cptr->host, me.name);
       }
 #endif /* CHANNEL_CREATION_NOTICE */
     }
@@ -3042,7 +3042,7 @@
            * -Dianora
            */
           server_was_split = NO;
-          sendto_ops_flags(FLAGS_SERVNOTICE, "Net rejoined, split-mode deactivated, whew");
+          sendto_ops_flag(UMODE_SERVNOTICE, "Net rejoined, split-mode deactivated, whew");
           cold_start = NO;
 #if defined(PRESERVE_CHANNEL_ON_SPLIT) || defined(NO_JOIN_ON_SPLIT)
           remove_empty_channels();
@@ -3232,7 +3232,7 @@
 
 
 #ifdef NO_JOIN_ON_SPLIT_SIMPLE
-      if (server_was_split && MyClient(sptr) && !IsAnOper(sptr))
+      if (server_was_split && MyClient(sptr) && !IsSetOperGod(sptr))
         {
               sendto_one(sptr, form_str(ERR_UNAVAILRESOURCE),
                          me.name, parv[0], name);
@@ -3248,7 +3248,7 @@
        * cold_start is set to NO if SPLITDELAY is set to 0 in m_set()
        */
 
-      if(cold_start && MyClient(sptr) && !IsAnOper(sptr))
+      if(cold_start && MyClient(sptr) && !IsSetOperGod(sptr))
         {
               sendto_one(sptr, form_str(ERR_UNAVAILRESOURCE),
                          me.name, parv[0], name);
@@ -3288,14 +3288,14 @@
 
 #ifdef ANTI_SPAMBOT       /* Dianora */
 
-          if( MyConnect(sptr) && !IsAnOper(sptr) )
+          if( MyConnect(sptr) && !IsImmune(sptr) )
             {
               if(SPAMNUM && (sptr->join_leave_count >= SPAMNUM))
                 {
-                  sendto_ops_flags_butone(NULL, FLAGS_BOTS,
-                                     "User %s (%s@%s) is a possible spambot",
-                                     sptr->name,
-                                     sptr->username, sptr->host);
+                  sendto_ops_flag_butone(NULL, UMODE_BOTS,
+					 "User %s (%s@%s) is a possible spambot",
+					 sptr->name,
+					 sptr->username, sptr->host);
                   sptr->oper_warn_count_down = OPER_SPAM_COUNTDOWN;
                 }
               else
@@ -3350,7 +3350,7 @@
             */
 
 #ifdef NO_CHANOPS_WHEN_SPLIT
-          if(!IsAnOper(sptr) && server_was_split)
+          if(!IsSetOperGod(sptr) && server_was_split)
             {
               allow_op = NO;
 
@@ -3362,7 +3362,7 @@
 #endif
 
           if ((sptr->user->joined >= MAXCHANNELSPERUSER) &&
-             (!IsAnOper(sptr) || (sptr->user->joined >= MAXCHANNELSPERUSER*3)))
+             (!IsSetOperGod(sptr) || (sptr->user->joined >= MAXCHANNELSPERUSER*3)))
             {
               sendto_one(sptr, form_str(ERR_TOOMANYCHANNELS),
                          me.name, parv[0], name);
@@ -3388,12 +3388,12 @@
  
               if(sptr->oper_warn_count_down == 0)
                 {
-                  sendto_ops_flags_butone(NULL, FLAGS_BOTS,
-                    "User %s (%s@%s) trying to join %s is a possible spambot",
-                             sptr->name,
-                             sptr->username,
-                             sptr->host,
-                             name);     
+                  sendto_ops_flag_butone(NULL, UMODE_BOTS,
+					 "User %s (%s@%s) trying to join %s is a possible spambot",
+					 sptr->name,
+					 sptr->username,
+					 sptr->host,
+					 name);     
                   sptr->oper_warn_count_down = OPER_SPAM_COUNTDOWN;
                 }
 #ifndef ANTI_SPAMBOT_WARN_ONLY
@@ -3423,7 +3423,7 @@
                 continue;
 
               /* allow local joins to this channel */
-              if( (chptr->users == 0) && !IsAnOper(sptr) )
+              if( (chptr->users == 0) && !IsSetOperGod(sptr) )
                 {
                   sendto_one(sptr, form_str(ERR_UNAVAILRESOURCE),
                              me.name, parv[0], name);
@@ -3612,14 +3612,14 @@
 #ifdef ANTI_SPAMBOT     /* Dianora */
       /* if its my client, and isn't an oper */
 
-      if (name && MyConnect(sptr) && !IsAnOper(sptr))
+      if (name && MyConnect(sptr) && !IsImmune(sptr))
         {
           if(SPAMNUM && (sptr->join_leave_count >= SPAMNUM))
             {
-              sendto_ops_flags_butone(NULL, FLAGS_BOTS,
-                               "User %s (%s@%s) is a possible spambot",
-                               sptr->name,
-                               sptr->username, sptr->host);
+              sendto_ops_flag_butone(NULL, UMODE_BOTS,
+				     "User %s (%s@%s) is a possible spambot",
+				     sptr->name,
+				     sptr->username, sptr->host);
               sptr->oper_warn_count_down = OPER_SPAM_COUNTDOWN;
             }
           else
@@ -3853,7 +3853,7 @@
   if (IsMember(who, chptr))
     {
       /* Immune users */
-      if( !IsPrivileged(sptr) && IsImmune(who) )
+      if( !(IsServer(sptr) || IsSetOperGod(sptr)) && IsImmune(who) )
         {
           sendto_one(sptr, form_str(ERR_USERISIMMUNE),
                      me.name, parv[0], user, name);
@@ -3880,10 +3880,10 @@
       remove_user_from_channel(who, chptr, 1);
       if (MyClient(sptr))
 #ifdef GODOPERS
-        sendto_ops_flags_butone(NULL, FLAGS_BOTS,
-                                "Kick from %s by %s on %s (%s@%s) [%s]",
-                                 name, sptr->name, who->name,
-                                 who->username, who->host, who->user->server);
+        sendto_ops_flag_butone(NULL, UMODE_BOTS,
+			       "Kick from %s by %s on %s (%s@%s) [%s]",
+			       name, sptr->name, who->name,
+			       who->username, who->host, who->user->server);
 #endif
     }
   else
@@ -3994,9 +3994,11 @@
 
   /* flood control server wide, clients on KNOCK
    * opers are not flood controlled.
+   *
+   * sure they are, just not godopers -- asuffield
    */
 
-  if(!IsAnOper(sptr))
+  if(!IsSetOperGod(sptr))
     {
       if((last_used + PACE_WAIT) > CurrentTime)
         return 0;
@@ -4012,7 +4014,8 @@
    */
 
   /* opers are not flow controlled here */
-  if( !IsAnOper(sptr) && (sptr->last_knock + KNOCK_DELAY) > CurrentTime)
+  /* <ahem> *god*opers are not flow controlled -- asuffield */
+  if( !IsSetOperGod(sptr) && (sptr->last_knock + KNOCK_DELAY) > CurrentTime)
     {
       sendto_one(sptr,":%s NOTICE %s :*** Notice -- Wait %d seconds before another knock",
                  me.name,
@@ -4184,11 +4187,13 @@
     }
 
 #ifdef SERVERHIDE
-  if (!IsAnOper(sptr) && parv[2][0] == '&') {
+#ifdef LOCAL_CHANNELS
+  if (!IsSetOperGod(sptr) && parv[2][0] == '&') {
     sendto_one(sptr, ":%s NOTICE %s :INVITE to local channels is disabled in this server",
                me.name, parv[0]);
     return 0;
   }
+#endif
 #endif
 
   /* A little sanity test here */
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	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/client.c	Wed Jun  6 18:59:44 2001
@@ -55,6 +55,10 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
+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
@@ -325,8 +329,8 @@
                       continue;
                     }
 
-		      sendto_ops_flags_butone(NULL, FLAGS_SKILL, "%s confirms D-line of %s", me.name,
-                                 get_client_name(cptr, FALSE));
+		      sendto_ops_flag_butone(NULL, UMODE_SKILL, "%s confirms D-line of %s", me.name,
+					     get_client_name(cptr, FALSE));
 
                   dying_clients[die_index] = cptr;
 /* Wintrhawk */
@@ -368,7 +372,7 @@
 #ifdef GLINES
                   if( (aconf = find_gkill(cptr,cptr->username)) )
                     {
-		      sendto_ops_flags_butone(NULL, FLAGS_SKILL, "%s confirms G-line of %s", me.name,
+		      sendto_ops_flag_butone(NULL, UMODE_SKILL, "%s confirms G-line of %s", me.name,
                                  get_client_name(cptr, FALSE));
 
                       dying_clients[die_index] = cptr;
@@ -406,7 +410,7 @@
                                      continue;
                         }
 
-		      sendto_ops_flags_butone(NULL, FLAGS_SKILL, "%s confirms kill of %s", me.name,
+		      sendto_ops_flag_butone(NULL, UMODE_SKILL, "%s confirms kill of %s", me.name,
                                  get_client_name(cptr, FALSE));
                       dying_clients[die_index] = cptr;
 
@@ -673,7 +677,7 @@
         {
           if (!server_was_split)
             {
-              sendto_ops_flags(FLAGS_SERVNOTICE, "Netsplit detected, split-mode activated, hope for the best");
+              sendto_ops_flag(UMODE_SERVNOTICE, "Netsplit detected, split-mode activated, hope for the best");
               server_was_split = YES;
             }
           server_split_time = CurrentTime;
@@ -1492,15 +1496,15 @@
       sptr->flags |= FLAGS_CLOSING;
       if (IsPerson(sptr))
         {
-          sendto_ops_flags_butone(NULL, FLAGS_CCONN,
-                               "Client exiting: %s (%s@%s) [%s] [%s] [%s]",
-                               sptr->name, sptr->username, sptr->host,
+          sendto_ops_flag_butone(NULL, UMODE_CCONN,
+				 "Client exiting: %s (%s@%s) [%s] [%s] [%s]",
+				 sptr->name, sptr->username, sptr->host,
 #ifdef WINTRHAWK
-                               comment,
+				 comment,
 #else
-               (sptr->flags & FLAGS_NORMALEX) ?  "Client Quit" : comment,
+				 (sptr->flags & FLAGS_NORMALEX) ?  "Client Quit" : comment,
 #endif /* WINTRHAWK */
-                               sptr->sockhost, me.name);
+				 sptr->sockhost, me.name);
         }
 #ifdef FNAME_USERLOG
           on_for = CurrentTime - sptr->firsttime;
@@ -1605,9 +1609,9 @@
 
       if (sptr->servptr == &me)
         {
-          sendto_ops_flags_butone(NULL, FLAGS_SERVNOTICE, "%s was connected to %s for %d seconds.  %d/%d sendK/recvK.",
-                     sptr->name, &me.name, CurrentTime - sptr->firsttime,
-                     sptr->sendK, sptr->receiveK);
+          sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE, "%s was connected to %s for %d seconds.  %d/%d sendK/recvK.",
+				 sptr->name, &me.name, CurrentTime - sptr->firsttime,
+				 sptr->sendK, sptr->receiveK);
           log(L_NOTICE, "%s was connected for %d seconds.  %d/%d sendK/recvK.",
               sptr->name, CurrentTime - sptr->firsttime, 
               sptr->sendK, sptr->receiveK);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/fdlist.c ircd-hybrid-6.0/src/fdlist.c
--- ircd-hybrid-6.0.orig/src/fdlist.c	Sat Jul 24 08:58:57 1999
+++ ircd-hybrid-6.0/src/fdlist.c	Tue Jun  5 13:19:46 2001
@@ -62,7 +62,7 @@
 
       if (!(cptr = local[i])) 
         continue;
-      if (IsServer(cptr) || IsAnOper(cptr))
+      if (IsServer(cptr) || IsAlwaysBusy(cptr))
           continue;
 
       GlobalFDList[i] &= ~FDL_BUSY;
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	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/flud.c	Wed Jun  6 17:40:16 2001
@@ -58,27 +58,27 @@
   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);
+      sendto_ops_flag_butone(NULL, UMODE_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)",
+      sendto_ops_flag_butone(NULL, UMODE_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)",
+      sendto_ops_flag_butone(NULL, UMODE_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)",
+      sendto_ops_flag_butone(NULL, UMODE_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",
+      sendto_ops_flag_butone(NULL, UMODE_BOTS, "Flooder %s [%s@%s] on %s target: %s",
                        fluder->name, fluder->username, fluder->host,
                        fluder->user->server, fludee);
       break;
@@ -170,7 +170,7 @@
   int flud = 0;
   int len;
 
-  if (!MyConnect(fluder) || IsPrivileged(fluder))
+  if (!MyConnect(fluder) || IsServer(fluder) || NoFloodProtection(fluder))
     return 0;
 
   if ((len = strlen(message)) > 160)
@@ -425,8 +425,8 @@
 #ifdef DEATHFLUD
   if (blocking && fluder->repeatcount > KILLNUM)
     {
-      sendto_ops_flags(FLAGS_SKILL, "Flood countermeasure, dumping user %s",
-                       fluder->name);
+      sendto_ops_flag(UMODE_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");
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/hash.c ircd-hybrid-6.0/src/hash.c
--- ircd-hybrid-6.0.orig/src/hash.c	Tue Feb  1 00:44:11 2000
+++ ircd-hybrid-6.0/src/hash.c	Tue Jun  5 11:32:02 2001
@@ -460,7 +460,7 @@
   char  hash_log_file[256];
   char  timebuffer[MAX_DATE_STRING];
 
-  if (!MyClient(sptr) || !IsOper(sptr))
+  if (!MyClient(sptr) || !IsDebugger(sptr))
     {
       sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
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	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/ircd.c	Tue Jun  5 11:17:25 2001
@@ -51,6 +51,7 @@
 #include "send.h"
 #include "struct.h"
 #include "whowas.h"
+#include "s_user.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -662,7 +663,9 @@
   uid_t       euid;
   time_t      delay = 0;
   aConfItem*  aconf;
+#ifndef OPN_DEBUG
   struct passwd *pass;
+#endif
 #ifdef SAVE_MAXCLIENT
   FBFILE* file;
   char mline[20];
@@ -852,6 +855,7 @@
   initwhowas();
   init_stats();
   init_tree_parse(msgtab);      /* tree parse code (orabidoo) */
+  init_umodes();                /* fill in the umode lookup table -- asuffield */
 
   fdlist_init();
   init_netio();
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/listener.c ircd-hybrid-6.0/src/listener.c
--- ircd-hybrid-6.0.orig/src/listener.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/listener.c	Tue Jun  5 13:20:30 2001
@@ -118,7 +118,7 @@
        flags[i] = '\0';
        
        /* Don't send hidden ports */
-       if (!listener->hidden_port || IsAnOper(sptr))
+       if (!listener->hidden_port || SeesAllConnections(sptr))
 	 sendto_one(sptr, form_str(RPL_STATSPLINE),
 		    me.name,
 		    sptr->name,
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_admin.c ircd-hybrid-6.0/src/m_admin.c
--- ircd-hybrid-6.0.orig/src/m_admin.c	Sat Nov 11 02:30:23 2000
+++ ircd-hybrid-6.0/src/m_admin.c	Wed Jun  6 17:36:21 2001
@@ -97,7 +97,7 @@
   struct ConfItem *aconf;
   static time_t last_used=0L;
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       if((last_used + PACE_WAIT) > CurrentTime)
         {
@@ -114,9 +114,9 @@
     return 0;
 
   if (IsPerson(sptr))
-    sendto_realops_flags(FLAGS_SPY,
-                         "ADMIN requested by %s (%s@%s) [%s]", sptr->name,
-                         sptr->username, sptr->host, sptr->user->server);
+    sendto_realops_flag(UMODE_SPY,
+			"ADMIN requested by %s (%s@%s) [%s]", sptr->name,
+			sptr->username, sptr->host, sptr->user->server);
   if ((aconf = find_admin()))
     {
       sendto_one(sptr, form_str(RPL_ADMINME),
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_away.c ircd-hybrid-6.0/src/m_away.c
--- ircd-hybrid-6.0.orig/src/m_away.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_away.c	Wed Jun  6 17:36:28 2001
@@ -115,8 +115,8 @@
   /* make sure the user exists */
   if (!(sptr->user))
     {
-      sendto_realops_flags(FLAGS_DEBUG,
-                           "Got AWAY from nil user, from %s (%s)\n",cptr->name,sptr->name);
+      sendto_realops_flag(UMODE_DEBUG,
+			  "Got AWAY from nil user, from %s (%s)\n",cptr->name,sptr->name);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_connect.c ircd-hybrid-6.0/src/m_connect.c
--- ircd-hybrid-6.0.orig/src/m_connect.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_connect.c	Wed Jun  6 17:36:50 2001
@@ -112,9 +112,12 @@
   struct ConfItem* aconf;
   struct Client*   acptr;
 
-  if (!IsPrivileged(sptr))
+  if (!(IsServer(sptr) || CanConnect(sptr)))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no R umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return -1;
     }
 
@@ -125,9 +128,9 @@
     return 0;
   }
 
-  if (MyConnect(sptr) && !IsOperRemote(sptr) && parc > 3)
+  if (MyConnect(sptr) && !IsSetOperRemote(sptr) && parc > 3)
     {
-      sendto_one(sptr,":%s NOTICE %s :You have no R flag", me.name, parv[0]);
+      sendto_one(sptr,":%s NOTICE %s :You have no R umode", me.name, parv[0]);
       return 0;
     }
 
@@ -186,12 +189,12 @@
   /*
    * Notify all operators about remote connect requests
    */
-  if (!IsAnOper(cptr))
+  if (IsServer(cptr))
     {
-      sendto_ops_butone(NULL, &me,
-                        ":%s WALLOPS :Remote CONNECT %s %s from %s",
-                        me.name, parv[1], parv[2] ? parv[2] : "",
-                        get_client_name(sptr, FALSE));
+      sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE,
+			     "Remote CONNECT %s %s from %s",
+			     parv[1], parv[2] ? parv[2] : "",
+			     get_client_name(sptr, FALSE));
 
       log(L_TRACE, "CONNECT From %s : %s %s", 
           parv[0], parv[1], parv[2] ? parv[2] : "");
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_die.c ircd-hybrid-6.0/src/m_die.c
--- ircd-hybrid-6.0.orig/src/m_die.c	Fri Jun  8 18:03:35 2001
+++ ircd-hybrid-6.0/src/m_die.c	Tue Jun  5 14:35:12 2001
@@ -96,15 +96,12 @@
   struct Client* acptr;
   int      i;
 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !IsSetOperDie(sptr))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-      return 0;
-    }
-
-  if (!IsOperDie(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :You have no D flag", me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no D umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
@@ -130,7 +127,7 @@
         continue;
       if (IsClient(acptr))
         {
-          if(IsAnOper(acptr))
+          if(IsSetOperAuspex(acptr))
             sendto_one(acptr,
                        ":%s NOTICE %s :Server Terminating. %s",
                        me.name, acptr->name,
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_gline.c ircd-hybrid-6.0/src/m_gline.c
--- ircd-hybrid-6.0.orig/src/m_gline.c	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/m_gline.c	Tue Jun  5 12:22:06 2001
@@ -118,15 +118,12 @@
     {
 #ifdef GLINES
       /* Only globals can apply Glines */
-      if (!IsOper(sptr))
-        {
-          sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-          return 0;
-        }
-
       if (!IsSetOperGline(sptr))
         {
-          sendto_one(sptr,":%s NOTICE %s :You have no G flag",me.name,parv[0]);
+	  if (!SeesOperMessages(sptr))
+	    sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+	  else
+	    sendto_one(sptr,":%s NOTICE %s :You have no G umode",me.name,parv[0]);
           return 0;
         }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_help.c ircd-hybrid-6.0/src/m_help.c
--- ircd-hybrid-6.0.orig/src/m_help.c	Thu Jul 29 08:11:48 1999
+++ ircd-hybrid-6.0/src/m_help.c	Tue Jun  5 14:38:33 2001
@@ -97,7 +97,7 @@
   int i;
   static time_t last_used = 0;
 
-  if (!IsAnOper(sptr))
+  if (!NoFloodProtection(sptr))
     {
       /* HELP is always local */
       if ((last_used + PACE_WAIT) > CurrentTime)
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_htm.c ircd-hybrid-6.0/src/m_htm.c
--- ircd-hybrid-6.0.orig/src/m_htm.c	Fri Jul 30 07:40:14 1999
+++ ircd-hybrid-6.0/src/m_htm.c	Tue Jun  5 12:22:30 2001
@@ -98,7 +98,7 @@
 {
   char *command;
 
-  if (!MyClient(sptr) || !IsOper(sptr))
+  if (!MyClient(sptr) || !SeesOperMessages(sptr))
     {
       sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
@@ -110,6 +110,11 @@
           LRV, currlife);
   if (parc > 1)
     {
+      if (!IsSetOperRemote(sptr))
+	{
+	  sendto_one(sptr,":%s NOTICE %s :You have no R umode",me.name,parv[0]);
+	  return 0;
+	}
       command = parv[1];
       if (!irccmp(command,"TO"))
         {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_info.c ircd-hybrid-6.0/src/m_info.c
--- ircd-hybrid-6.0.orig/src/m_info.c	Tue Nov 21 06:49:29 2000
+++ ircd-hybrid-6.0/src/m_info.c	Wed Jun  6 17:36:56 2001
@@ -36,11 +36,11 @@
 
   if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME)
   {
-    sendto_realops_flags(FLAGS_SPY, "info requested by %s (%s@%s) [%s]",
+    sendto_realops_flag(UMODE_SPY, "info requested by %s (%s@%s) [%s]",
       sptr->name, sptr->username, sptr->host,
       sptr->user->server);
 
-    if (!IsAnOper(sptr))
+    if (!NoFloodProtection(sptr))
     {
       /* reject non local requests */
       if (!MyConnect(sptr))
@@ -53,7 +53,7 @@
       }
       else
         last_used = CurrentTime;
-    } /* if (!IsAnOper(sptr)) */
+    }
 
     while (*text)
       sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], *text++);
@@ -64,7 +64,7 @@
      * Now send them a list of all our configuration options
      * (mostly from config.h)
      */
-    if (IsAnOper(sptr))
+    if (IsDebugger(sptr))
     {
       for (infoptr = MyInformation; infoptr->name; infoptr++)
       {
@@ -95,7 +95,7 @@
         parv[0],
         platform);
 #endif
-    } /* if (IsAnOper(sptr)) */
+    }
 
     sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_ison.c ircd-hybrid-6.0/src/m_ison.c
--- ircd-hybrid-6.0.orig/src/m_ison.c	Thu Oct 14 07:14:43 1999
+++ ircd-hybrid-6.0/src/m_ison.c	Tue Jun  5 12:27:41 2001
@@ -125,8 +125,10 @@
   len = strlen(buf);
   current_insert_point = buf + len;
 
-  if (!IsOper(cptr))
-    cptr->priority +=20; /* this keeps it from moving to 'busy' list */
+  /* opers get no special treatment now, ISON will always decrease your priority
+   *  -- asuffield
+   */
+  cptr->priority +=20; /* this keeps it from moving to 'busy' list */
 
   current_nick = parv[1];
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_kill.c ircd-hybrid-6.0/src/m_kill.c
--- ircd-hybrid-6.0.orig/src/m_kill.c	Tue Nov 21 06:49:29 2000
+++ ircd-hybrid-6.0/src/m_kill.c	Wed Jun  6 17:37:20 2001
@@ -125,13 +125,13 @@
       return 0;
     }
 
-  if (MyClient(sptr) && IsAnOper(sptr) && !IsSetOperK(sptr))
+  if (MyClient(sptr) && !IsSetOperK(sptr))
     {
-      sendto_one(sptr,":%s NOTICE %s :You have no K flag",me.name,parv[0]);
+      sendto_one(sptr,":%s NOTICE %s :You have no K umode",me.name,parv[0]);
       return 0;
     }
 
-  if (IsAnOper(cptr))
+  if (!IsServer(cptr)) /* It originated here; parv[2] is a reason, so clip it's length */
     {
       if (!BadPtr(path))
         if (strlen(path) > (size_t) KILLLEN)
@@ -167,7 +167,7 @@
       return 0;
     }
 
-  if (MyOper(sptr) && !MyConnect(acptr) && (!IsOperGlobalKill(sptr)))
+  if (MyOper(sptr) && !MyConnect(acptr) && !IsSetOperGlobalKill(sptr))
     {
       sendto_one(sptr, ":%s NOTICE %s :Nick %s isnt on your server",
                  me.name, parv[0], acptr->name);
@@ -189,7 +189,7 @@
         {
           ircsprintf(buf, "%s!%s%s (%s)",
                      cptr->username, cptr->name,
-                     IsOper(sptr) ? "" : "(L)", path);
+                     IsLocOp(sptr) ? "(L)" : "", path);
           path = buf;
           reason = path;
         }
@@ -218,7 +218,7 @@
     }
   else
     {
-      if(IsAnOper(cptr))
+      if(!IsServer(cptr))
         {
           reason = parv[2];
         }
@@ -232,7 +232,7 @@
 	}
     }
 
-  if (IsAnOper(sptr)) /* send it normally */
+  if (!IsServer(sptr)) /* send it normally */
     {
       sendto_realops("Received KILL message for %s. From %s Path: %s!%s", 
                acptr->name, parv[0], inpath, path);
@@ -247,12 +247,12 @@
        */
     }
   else
-    sendto_realops_flags(FLAGS_SKILL,
-                     "Received KILL message for %s. From %s",
-                     acptr->name, parv[0]);
+    sendto_realops_flag(UMODE_SKILL,
+			"Received KILL message for %s. From %s",
+			acptr->name, parv[0]);
 
 #if defined(USE_SYSLOG) && defined(SYSLOG_KILL)
-  if (IsOper(sptr))
+  if (!IsServer(sptr))
     log(L_INFO,"KILL From %s For %s Path %s!%s",
                         parv[0], acptr->name, inpath, path);
 #endif
@@ -262,7 +262,7 @@
   ** back.
   ** Suicide kills are NOT passed on --SRB
   */
-  if (!MyConnect(acptr) || !MyConnect(sptr) || !IsAnOper(sptr))
+  if (!MyConnect(acptr) || !MyConnect(sptr) || IsServer(sptr))
     {
       sendto_serv_butone(cptr, ":%s KILL %s :%s!%s",
                          parv[0], acptr->name, inpath, path);
@@ -293,7 +293,7 @@
   ** the unnecessary QUIT for this. (This flag should never be
   ** set in any other place)
   */
-  if (MyConnect(acptr) && MyConnect(sptr) && IsAnOper(sptr))
+  if (MyConnect(acptr) && MyConnect(sptr) && !IsServer(sptr))
 #ifdef SERVERHIDE
     ircsprintf(buf2, "Killed (%s): %s",
 #else
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	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_kline.c	Tue Jun  5 16:56:19 2001
@@ -423,15 +423,12 @@
   else
 #endif
     {
-      if (!MyClient(sptr) || !IsAnOper(sptr))
+      if (!MyClient(sptr) || !IsSetOperK(sptr))
         {
-          sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-          return 0;
-        }
-
-      if(!IsSetOperK(sptr))
-        {
-          sendto_one(sptr,":%s NOTICE %s :You have no K flag",me.name,parv[0]);
+	  if (!SeesOperMessages(sptr))
+	    sendto_one(sptr,":%s NOTICE %s :You have no K umode",me.name,parv[0]);
+	  else
+	    sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
           return 0;
         }
 
@@ -1022,15 +1019,12 @@
   const char* current_date;
   const char *dconf;
 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !IsSetOperK(sptr))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-      return 0;
-    }
-
-  if(!IsSetOperK(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :You have no K flag",me.name,parv[0]);
+      if (!SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no K umode",me.name,parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_links.c ircd-hybrid-6.0/src/m_links.c
--- ircd-hybrid-6.0.orig/src/m_links.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_links.c	Wed Jun  6 17:40:30 2001
@@ -121,7 +121,7 @@
 
   assert(0 != mask);
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       /* reject non local requests */
       if(!MyClient(sptr))
@@ -157,11 +157,11 @@
 
   if (bogus_server)
     {
-      sendto_realops_flags(FLAGS_SPY,
-                         "BOGUS LINKS '%s' requested by %s (%s@%s) [%s]",
-                         clean_string(clean_mask, (const unsigned char *) mask, 2 * HOSTLEN),
-                         sptr->name, sptr->username,
-                         sptr->host, sptr->user->server);
+      sendto_realops_flag(UMODE_SPY,
+			  "BOGUS LINKS '%s' requested by %s (%s@%s) [%s]",
+			  clean_string(clean_mask, (const unsigned char *) mask, 2 * HOSTLEN),
+			  sptr->name, sptr->username,
+			  sptr->host, sptr->user->server);
       return 0;
     }
 
@@ -169,10 +169,10 @@
     mask = collapse(clean_string(clean_mask, (const unsigned char *) mask, 2 * HOSTLEN));
 
   if (MyConnect(sptr))
-    sendto_realops_flags(FLAGS_SPY,
-                       "LINKS '%s' requested by %s (%s@%s) [%s]",
-                       mask, sptr->name, sptr->username,
-                       sptr->host, sptr->user->server);
+    sendto_realops_flag(UMODE_SPY,
+			"LINKS '%s' requested by %s (%s@%s) [%s]",
+			mask, sptr->name, sptr->username,
+			sptr->host, sptr->user->server);
   
   for (acptr = GlobalClientList; acptr; acptr = acptr->next) 
     {
@@ -180,7 +180,7 @@
         continue;
       if (*mask && !match(mask, acptr->name))
         continue;
-      if(IsAnOper(sptr))
+      if(SeesAllConnections(sptr))
          sendto_one(sptr, form_str(RPL_LINKS),
                     me.name, parv[0], acptr->name, acptr->serv->up,
                     acptr->hopcount, (acptr->info[0] ? acptr->info :
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_list.c ircd-hybrid-6.0/src/m_list.c
--- ircd-hybrid-6.0.orig/src/m_list.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_list.c	Tue Jun  5 19:01:50 2001
@@ -59,7 +59,7 @@
   if(!MyConnect(sptr))
     return 0;
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       if(((last_used + PACE_WAIT) > CurrentTime) && (!IsDoingList(sptr)))
         {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_locops.c ircd-hybrid-6.0/src/m_locops.c
--- ircd-hybrid-6.0.orig/src/m_locops.c	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/m_locops.c	Wed Jun  6 11:39:18 2001
@@ -110,7 +110,7 @@
         {
 #ifdef NEED_ULINES
           sendto_realops("received Unauthorized locops from %s",sptr->name);
- #endif
+#endif
           return 0;
         }
 
@@ -159,7 +159,7 @@
       return 0;
     }
 
-  if(MyConnect(sptr) && IsAnOper(sptr))
+  if(MyConnect(sptr) && SendWallops(sptr))
     {
 
 #ifdef SLAVE_SERVERS
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_ltrace.c ircd-hybrid-6.0/src/m_ltrace.c
--- ircd-hybrid-6.0.orig/src/m_ltrace.c	Fri Nov 24 18:51:17 2000
+++ ircd-hybrid-6.0/src/m_ltrace.c	Fri Jun  8 12:24:55 2001
@@ -117,8 +117,14 @@
     return 0;
 
 #ifdef SERVERHIDE
-  if (!IsAnOper(sptr))
-    return 0;
+  if (!SeesAllConnections(sptr))
+    {
+      if (!SeesOperMessages(sptr))
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+      else
+	sendto_one(sptr,":%s NOTICE %s :You have no a umode",me.name,parv[0]);
+      return 0;
+    }
 #endif
 
   if (parc > 2)
@@ -154,17 +160,17 @@
 
 
   if(MyClient(sptr))
-    sendto_realops_flags(FLAGS_SPY, "ltrace requested by %s (%s@%s) [%s]",
-                       sptr->name, sptr->username, sptr->host,
-                       sptr->user->server);
+    sendto_realops_flag(UMODE_SPY, "ltrace requested by %s (%s@%s) [%s]",
+			sptr->name, sptr->username, sptr->host,
+			sptr->user->server);
 
 
   doall = (parv[1] && (parc > 1)) ? match(tname, me.name): TRUE;
   wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
   dow = wilds || doall;
 
-  if(!IsAnOper(sptr) || !dow) /* non-oper traces must be full nicks */
-                              /* lets also do this for opers tracing nicks */
+  if(!IsSetOperAuspex(sptr) || !dow) /* non-oper traces must be full nicks */
+                                     /* lets also do this for opers tracing nicks */
     { 
       const char* name;
       const char* ip;
@@ -184,12 +190,12 @@
 
       c_class = get_client_class(acptr);
 
-      if (IsAnOper(acptr))
+      if (SeesOpers(sptr) && IsAnOper(acptr))
         { 
           sendto_one(sptr, form_str(RPL_TRACEOPERATOR),
                      me.name, parv[0], c_class,
                      name,
-                     IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
+                     IsSetOperAuspex(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
                      now - acptr->lasttime,
                      (acptr->user)?(now - acptr->user->last):0);
         }
@@ -201,7 +207,7 @@
   for (i = 0; i < MAXCONNECTIONS; i++)
     link_s[i] = 0, link_u[i] = 0;
                         
-  if (dow && LIFESUX && !IsOper(sptr))
+  if (dow && LIFESUX && !SendWhileLifeSucks(sptr))
     {
       sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0]);
       return 0;
@@ -228,8 +234,8 @@
       if (!(acptr = local[i])) /* Local Connection? */
         continue;
       if (IsInvisible(acptr) && dow &&
-          !(MyConnect(sptr) && IsAnOper(sptr)) &&
-          !IsAnOper(acptr) && (acptr != sptr))
+          !SeesAllConnections(sptr) &&
+          (acptr != sptr))
         continue;
       if (!doall && wilds && !match(tname, acptr->name))
         continue;
@@ -251,16 +257,17 @@
           break;
         case STAT_CLIENT:
           /* Well, most servers don't have a LOT of OPERs... let's show them too */
-          if ((IsAnOper(sptr) &&
+
+          if ((IsSetOperAuspex(sptr) &&
               (MyClient(sptr) || !(dow && IsInvisible(acptr))))
-              || !dow || IsAnOper(acptr))
+              || !dow || (IsAnOper(acptr) && SeesOpers(sptr)))
             {
               if (IsAnOper(acptr))
                 sendto_one(sptr,
                            form_str(RPL_TRACEOPERATOR),
                            me.name, parv[0], c_class,
                            name, 
-                           IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip), 
+                           IsSetOperAuspex(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip), 
                            now - acptr->lasttime,
                            (acptr->user)?(now - acptr->user->last):0);
               cnt++;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_lusers.c ircd-hybrid-6.0/src/m_lusers.c
--- ircd-hybrid-6.0.orig/src/m_lusers.c	Thu Jul 29 08:11:48 1999
+++ ircd-hybrid-6.0/src/m_lusers.c	Tue Jun  5 20:25:44 2001
@@ -100,7 +100,7 @@
 {
   static time_t last_used = 0;
 
-  if (!IsAnOper(sptr))
+  if (!NoFloodProtection(sptr))
     {
       if ((last_used + PACE_WAIT) > CurrentTime)
         {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_makepass.c ircd-hybrid-6.0/src/m_makepass.c
--- ircd-hybrid-6.0.orig/src/m_makepass.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_makepass.c	Tue Jun  5 20:25:56 2001
@@ -113,7 +113,7 @@
       return 0;
     }
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       if((last_used + PACE_WAIT) > CurrentTime)
         {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_map.c ircd-hybrid-6.0/src/m_map.c
--- ircd-hybrid-6.0.orig/src/m_map.c	Fri Jun  8 18:03:39 2001
+++ ircd-hybrid-6.0/src/m_map.c	Tue Jun  5 20:32:18 2001
@@ -87,7 +87,7 @@
 {
   static time_t   last_used = 0;
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       /* reject non local requests */
       if(!MyClient(sptr))
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	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/src/m_message.c	Wed Jun  6 17:40:38 2001
@@ -206,7 +206,7 @@
        * - Andre Guibert de Bruet <webdev@cheetah.properkernel.com>
        */
       if(chptr->mode.mode & MODE_NOCOLOR)
-        if(strchr(parv[2], 3) && !IsAnOper(sptr))
+        if(strchr(parv[2], 3) && !IsSetOperGod(sptr))
           { 
             sendto_one(sptr, form_str(ERR_NOCOLORSTOCHAN),
                        me.name, parv[0], nick);
@@ -343,7 +343,7 @@
 #endif /* DEATHFLUD */
 #endif /* FLUD */
 #ifdef ANTI_DRONE_FLOOD
-      if(MyConnect(acptr) && IsClient(sptr) && !IsAnOper(sptr) && DRONETIME)
+      if(MyConnect(acptr) && IsClient(sptr) && !NoFloodProtection(sptr) && DRONETIME)
         {
           if((acptr->first_received_message_time+DRONETIME) < CurrentTime)
             {
@@ -357,11 +357,11 @@
                 {
                   if(acptr->drone_noticed == 0) /* tiny FSM */
                     {
-                      sendto_ops_flags(FLAGS_BOTS,
-                             "Possible Drone Flooder %s [%s@%s] on %s target: %s",
-                                     sptr->name, sptr->username,
-                                     sptr->host,
-                                     sptr->user->server, acptr->name);
+                      sendto_ops_flag(UMODE_BOTS,
+				      "Possible Drone Flooder %s [%s@%s] on %s target: %s",
+				      sptr->name, sptr->username,
+				      sptr->host,
+				      sptr->user->server, acptr->name);
                       acptr->drone_noticed = 1;
                     }
                   /* heuristic here, if target has been getting a lot
@@ -375,12 +375,12 @@
                     {
                       if(acptr->drone_noticed == 1) /* tiny FSM */
                         {
-                          sendto_ops_flags(FLAGS_BOTS,
-                         "ANTI_DRONE_FLOOD SendQ protection activated for %s",
-                                         acptr->name);
+                          sendto_ops_flag(UMODE_BOTS,
+					  "ANTI_DRONE_FLOOD SendQ protection activated for %s",
+					  acptr->name);
 
                           sendto_one(acptr,     
- ":%s NOTICE %s :*** Notice -- Server drone flood protection activated for %s",
+				     ":%s NOTICE %s :*** Notice -- Server drone flood protection activated for %s",
                                      me.name, acptr->name, acptr->name);
                           acptr->drone_noticed = 2;
                         }
@@ -470,7 +470,7 @@
   if ((*nick == '$' || *nick == '>'))
     {
 
-      if(!IsAnOper(sptr))
+      if(!CanSendMassNotice(sptr))
         {
           sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                      me.name, parv[0], nick);
@@ -519,7 +519,7 @@
        * -Dianora
        */
 
-      if( (char *)strchr(nick,'%') && !IsAnOper(sptr))
+      if( (char *)strchr(nick,'%') /* && !Is??????(sptr) disabled until we figure out what this is for -- asuffield */)
         {
           sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                      me.name, parv[0], nick);
@@ -541,12 +541,15 @@
       *server = '\0';
 
       /* special case opers@server */
-      if(!irccmp(nick,"opers") && IsAnOper(sptr))
+      /* We don't want this on OPN -- asuffield */
+#if 0
+      if(!irccmp(nick,"opers") && SendWallops(sptr))
         {
           sendto_realops("To opers: From %s: %s",sptr->name,parv[2]);
           msgs++;
           continue;
         }
+#endif
         
       if ((host = (char *)strchr(nick, '%')))
         *host++ = '\0';
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_oper.c ircd-hybrid-6.0/src/m_oper.c
--- ircd-hybrid-6.0.orig/src/m_oper.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_oper.c	Fri Jun  8 17:13:14 2001
@@ -109,12 +109,17 @@
 #ifdef CRYPT_OPER_PASSWORD
   extern char * libshadow_md5_crypt(const char *pw, const char *salt);
 #endif /* CRYPT_OPER_PASSWORD */
-  char *operprivs;
   static char buf[BUFSIZE];
 
   password = parc > 2 ? parv[2] : (parc > 1 ? parv[1] : (char *)NULL);
   name = parc > 2 ? parv[1] : (parc > 1 ? sptr->name : (char *)NULL);
 
+  if (cptr != sptr)
+    {
+      sendto_ops_flag(UMODE_DEBUG, "Somebody tried to OPER but cptr != sptr (OPER %s from %s)", name, parv[0]);
+      return 0;
+    }
+
   if (!IsServer(cptr) && (EmptyString(name) || EmptyString(password)))
     {
       sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
@@ -123,15 +128,22 @@
     }
         
   /* if message arrived from server, trust it, and set to oper */
-  
-  if ((IsServer(cptr) || IsMe(cptr)) && !IsOper(sptr))
+  /* uhh.... not unless somebody can give me a damn good reason why OPER messages
+   * should ever come from a server
+   *  -- asuffield
+   */
+  if ((IsServer(cptr) || IsMe(cptr)))
     {
-      sptr->flags |= FLAGS_OPER;
-      Count.oper++;
-      sendto_serv_butone(cptr, ":%s MODE %s :+o", parv[0], parv[0]);
-      if (IsMe(cptr))
-        sendto_one(sptr, form_str(RPL_YOUREOPER),
-                   me.name, parv[0]);
+      sendto_ops_flag(UMODE_DEBUG, "WTF: %s received OPER message for %s from server %s", 
+		      me.name, sptr->name, cptr->name);
+      /* This doesn't work properly; it doesn't add them to the oper list locally.
+	SetBit(sptr->umodes,UMODE_OPER);
+	Count.oper++;
+	sendto_serv_butone(cptr, ":%s MODE %s :+o", parv[0], parv[0]);
+	if (IsMe(cptr))
+	sendto_one(sptr, form_str(RPL_YOUREOPER),
+	me.name, parv[0]);
+      */
       return 0;
     }
   else if (IsAnOper(sptr))
@@ -176,77 +188,59 @@
   if ((aconf->status & CONF_OPS) &&
       0 == strcmp(encr, aconf->passwd) && !attach_conf(sptr, aconf))
     {
-      int old = (sptr->umodes & ALL_UMODES);
-      
+      umode_t old;
+      CopyUmodes(old, sptr->umodes);
+
+      OrUmodes(sptr->allowed_umodes, aconf->allowed_umodes, user_umodes);
+      OrUmodes(sptr->umodes, sptr->umodes, aconf->default_umodes);
+      AndUmodes(sptr->umodes, sptr->umodes, sptr->allowed_umodes);
+
       if (aconf->status == CONF_LOCOP)
         {
           SetLocOp(sptr);
-          if((int)aconf->hold)
-            {
-              sptr->umodes |= ((int)aconf->hold & ALL_UMODES); 
-              sendto_one(sptr, ":%s NOTICE %s :*** Oper flags set from conf",
-                         me.name,parv[0]);
-            }
-          else
-            {
-              sptr->umodes |= (LOCOP_UMODES);
-            }
+	  SetBit(sptr->allowed_umodes,UMODE_LOCOP);
         }
       else
         {
           SetOper(sptr);
-          if((int)aconf->hold)
-            {
-              sptr->umodes |= ((int)aconf->hold & ALL_UMODES); 
-              if( !IsSetOperN(sptr) )
-                sptr->umodes &= ~FLAGS_NCHANGE;
-              if( !IsSetOperGod(sptr) )
-                sptr->umodes &= ~FLAGS_GOD;
-              if( !IsSetOperM(sptr) )
-                sptr->umodes &= ~FLAGS_IMMUNE;
-              if( !IsSetOperAuspex(sptr) )
-                sptr->umodes &= ~FLAGS_AUSPEX;
-              
-              sendto_one(sptr, ":%s NOTICE %s :*** Oper flags set from conf",
-                         me.name,parv[0]);
-            }
-          else
-            {
-              sptr->umodes |= (OPER_UMODES);
-            }
+	  SetBit(sptr->allowed_umodes,UMODE_OPER);
         }
-      SetIPHidden(sptr);
+      /*      SetIPHidden(sptr); */
       Count.oper++;
 
-      SetElined(cptr);
-      SetExemptGline(cptr);
+      /* No more of this oper-magic. If you're supposed to be exempt from
+       * G:lines/E:lined, you need an E:line/G:line exception in ircd.conf
+       *  -- asuffield
+       */
+      /*
+	SetElined(cptr);
+	SetExemptGline(cptr);
+      */
       
       /* LINKLIST */  
       /* add to oper link list -Dianora */
       cptr->next_oper_client = oper_cptr_list;
       oper_cptr_list = cptr;
 
-      if(cptr->confs)
-        {
-          struct ConfItem *aconf;
-          aconf = cptr->confs->value.aconf;
-          operprivs = oper_privs_as_string(cptr,aconf->port);
-        }
+      if (IsAlwaysBusy(sptr))
+	fdlist_add(sptr->fd, FDL_OPER | FDL_BUSY);
       else
-        operprivs = "";
-
-      fdlist_add(sptr->fd, FDL_OPER | FDL_BUSY);
+	fdlist_add(sptr->fd, FDL_OPER);
 #ifdef CUSTOM_ERR
       sendto_ops("%s (%s@%s) just activated an %c-line, hmmm.", parv[0],
 #else
       sendto_ops("%s (%s@%s) is now operator (%c)", parv[0],
 #endif /* CUSTOM_ERR */
                  sptr->username, sptr->host,
-                 IsOper(sptr) ? 'O' : 'o');
+                 IsLocOp(sptr) ? 'o' : 'O');
       send_umode_out(cptr, sptr, old);
       sendto_one(sptr, form_str(RPL_YOUREOPER), me.name, parv[0]);
-      sendto_one(sptr, ":%s NOTICE %s :*** Oper privs are %s",me.name,parv[0],
-                 operprivs);
+      {
+	umode_t privs;
+	AndNotUmodes(privs, sptr->allowed_umodes, user_umodes);
+	sendto_one(sptr, ":%s NOTICE %s :*** Oper privs are %s",me.name,parv[0],
+		   oper_flags_as_string(privs));
+      }
 
       SendMessageFile(sptr, &ConfigFileEntry.opermotd);
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_operwall.c ircd-hybrid-6.0/src/m_operwall.c
--- ircd-hybrid-6.0.orig/src/m_operwall.c	Tue Aug 10 03:46:24 1999
+++ ircd-hybrid-6.0/src/m_operwall.c	Wed Jun  6 11:43:14 2001
@@ -101,7 +101,7 @@
 
   if (check_registered_user(sptr))
     return 0;
-  if (!IsAnOper(sptr) || IsServer(sptr))
+  if (!SendOperwall(sptr) || IsServer(sptr))
     {
       if (MyClient(sptr) && !IsServer(sptr))
         sendto_one(sptr, form_str(ERR_NOPRIVILEGES),
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_pong.c ircd-hybrid-6.0/src/m_pong.c
--- ircd-hybrid-6.0.orig/src/m_pong.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_pong.c	Wed Jun  6 18:30:19 2001
@@ -123,7 +123,7 @@
     {
       if (!got_server_pong)
         {
-          sendto_ops_flags_butone(cptr, FLAGS_SERVNOTICE, "%s acknowledged end of %s burst (%i sec)",
+          sendto_ops_flag_butone(cptr, UMODE_SERVNOTICE, "%s acknowledged end of %s burst (%i sec)",
                      sptr->name, &me.name, CurrentTime - sptr->firsttime);
         }
       got_server_pong = 1;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_quit.c ircd-hybrid-6.0/src/m_quit.c
--- ircd-hybrid-6.0.orig/src/m_quit.c	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/src/m_quit.c	Mon Jun  4 18:36:45 2001
@@ -28,6 +28,7 @@
 #include "numeric.h"
 #include "s_serv.h"
 #include "send.h"
+#include "ctype.h"
 
 /*
  * m_functions execute protocol messages on this server:
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_rehash.c ircd-hybrid-6.0/src/m_rehash.c
--- ircd-hybrid-6.0.orig/src/m_rehash.c	Fri Jun  8 18:03:35 2001
+++ ircd-hybrid-6.0/src/m_rehash.c	Wed Jun  6 11:43:19 2001
@@ -100,15 +100,12 @@
 {
   int found = NO;
 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !IsSetOperRehash(sptr))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-      return 0;
-    }
-
-  if ( !IsOperRehash(sptr) )
-    {
-      sendto_one(sptr,":%s NOTICE %s :You have no H flag", me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no H umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_restart.c ircd-hybrid-6.0/src/m_restart.c
--- ircd-hybrid-6.0.orig/src/m_restart.c	Fri Jun  9 02:59:07 2000
+++ ircd-hybrid-6.0/src/m_restart.c	Tue Jun  5 21:16:24 2001
@@ -99,15 +99,12 @@
                   char *parv[])
 {
   char buf[BUFSIZE]; 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !IsSetOperDie(sptr))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
-      return 0;
-    }
-
-  if ( !IsOperDie(sptr) )
-    {
-      sendto_one(sptr,":%s NOTICE %s :You have no D flag", me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no D umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_server.c ircd-hybrid-6.0/src/m_server.c
--- ircd-hybrid-6.0.orig/src/m_server.c	Fri Nov 24 18:24:37 2000
+++ ircd-hybrid-6.0/src/m_server.c	Wed Jun  6 18:34:20 2001
@@ -376,8 +376,8 @@
                          
         }
       
-      sendto_realops_flags(FLAGS_EXTERNAL, "Server %s being introduced by %s",
-                           acptr->name, sptr->name);
+      sendto_realops_flag(UMODE_EXTERNAL, "Server %s being introduced by %s",
+			  acptr->name, sptr->name);
       return 0;
     }
 
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	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/m_set.c	Wed Jun  6 18:34:26 2001
@@ -171,9 +171,12 @@
   char *command;
   int cnum;
 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !IsSetOperRehash(sptr))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no H umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
@@ -450,7 +453,7 @@
                       if (server_was_split)
                         {
                           server_was_split = NO;
-                          sendto_ops_flags(FLAGS_SERVNOTICE, "split-mode deactived by manual override");
+                          sendto_ops_flag(UMODE_SERVNOTICE, "split-mode deactived by manual override");
                         }
 #if defined(PRESERVE_CHANNEL_ON_SPLIT) || defined(NO_JOIN_ON_SPLIT)
                       remove_empty_channels();
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	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_setname.c	Wed Jun  6 18:34:49 2001
@@ -39,6 +39,7 @@
 #include "channel.h"
 #include "irc_string.h"
 #include "s_debug.h"
+#include "client.h"
 
 extern int valid_hostname(const char* hostname);
 extern int valid_username(const char* username);
@@ -117,7 +118,7 @@
   target = parv[1];
   hostname = parv[2];
 
-  if (!IsPrivileged(cptr))
+  if (!(IsServer(cptr) || CanDoSetname(cptr)))
     {
       sendto_one(cptr, form_str(ERR_UNKNOWNCOMMAND),
                  me.name, parv[0], "SETHOST");
@@ -145,10 +146,10 @@
   }
 
   if ((acptr = find_person(target, NULL))) {
-    sendto_ops_flags(FLAGS_SPY,
-                     "%s is rehosting %s (%s@%s) to \"%s\" while whistling innocently",
-                     sptr->name, acptr->name,
-                     acptr->username, acptr->host, hostname);
+    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);
       if (sptr == acptr) {
          if (MyClient(acptr))
          sendto_one(acptr, ":%s NOTICE %s :your hostname is now set to \"%s\"",
@@ -196,7 +197,7 @@
   target = parv[1];
   username = parv[2];
 
-  if (!IsPrivileged(cptr))
+  if (!(IsServer(cptr) || CanDoSetname(cptr)))
     {
       sendto_one(cptr, form_str(ERR_UNKNOWNCOMMAND),
                  me.name, parv[0], "SETIDENT");
@@ -224,10 +225,10 @@
   }
 
   if ((acptr = find_person(target, NULL))) {
-    sendto_ops_flags(FLAGS_SPY,
-                     "%s is identing %s (%s@%s) to \"%s\" while whistling innocently",
-                     sptr->name, acptr->name,
-                     acptr->username, acptr->host, username);
+    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);
       if (sptr == acptr) {
          if (MyClient(acptr))
          sendto_one(acptr, ":%s NOTICE %s :your ident is now set to \"%s\"",
@@ -282,7 +283,7 @@
       return 0;
     }
 
-  if (!IsPrivileged(cptr) && (find_person(target, NULL) != sptr))
+  if (!(IsServer(cptr) || CanDoSetname(cptr)) && (find_person(target, NULL) != sptr))
     {
       sendto_one(sptr, form_str(ERR_USERSDONTMATCH), me.name, parv[0]);
       return 0;
@@ -296,19 +297,19 @@
   }
 
   if ((acptr = find_server(target))) {
-    sendto_ops_flags(FLAGS_SERVNOTICE,
-                     "%s is making %s be \"%s\" while whistling innocently",
-                     sptr->name, acptr->name, realname);
+    sendto_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_flags(FLAGS_SPY,
-                     "%s is naming %s (%s@%s) to \"%s\" while whistling innocently",
-                     sptr->name, acptr->name,
-                     acptr->username, acptr->host, realname);
+    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);
       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/m_squit.c ircd-hybrid-6.0/src/m_squit.c
--- ircd-hybrid-6.0.orig/src/m_squit.c	Sat Jul 31 09:23:00 1999
+++ ircd-hybrid-6.0/src/m_squit.c	Wed Jun  6 18:34:56 2001
@@ -106,9 +106,12 @@
   struct Client*   acptr;
   char  *comment = (parc > 2 && parv[2]) ? parv[2] : cptr->name;
 
-  if (!IsPrivileged(sptr))
+  if (!(IsServer(sptr) || IsSetOperRemote(sptr)))
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no R umode", me.name, parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
     }
 
@@ -210,20 +213,20 @@
       return 0;
     }
 
-  if (MyClient(sptr) && !IsOperRemote(sptr) && !MyConnect(acptr))
+  if (MyClient(sptr) && !IsSetOperRemote(sptr) && !MyConnect(acptr))
     {
-      sendto_one(sptr,":%s NOTICE %s :You have no R flag",me.name,parv[0]);
+      sendto_one(sptr,":%s NOTICE %s :You have no R umode",me.name,parv[0]);
       return 0;
     }
 
   /*
   **  Notify all opers, if my local link is remotely squitted
   */
-  if (MyConnect(acptr) && !IsAnOper(cptr))
+  if (MyConnect(acptr) && IsServer(cptr))
     {
-      sendto_ops_butone(NULL, &me,
-                        ":%s WALLOPS :Received SQUIT %s from %s (%s)",
-                        me.name, server, get_client_name(sptr,FALSE), comment);
+      sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE,
+			     "%s received SQUIT %s from %s (%s)",
+			     me.name, server, get_client_name(sptr,FALSE), comment);
       log(L_TRACE, "SQUIT From %s : %s (%s)", parv[0], server, comment);
     }
   else if (MyConnect(acptr))
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_stats.c ircd-hybrid-6.0/src/m_stats.c
--- ircd-hybrid-6.0.orig/src/m_stats.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_stats.c	Fri Jun  8 17:11:51 2001
@@ -144,12 +144,14 @@
     }
 
 #ifdef SERVERHIDE
-  if (!IsAnOper(sptr))
+  /* We do this on a per-stats basis -- asuffield
+    if (!IsSetOperAuspex(sptr))
     {
-      ignore_request++;
-      valid_stats++;
-      return 0;
+    ignore_request++;
+    valid_stats++;
+    return 0;
     }
+  */
 #endif
 
   if (hunt_server(cptr,sptr,":%s STATS %s :%s",2,parc,parv)!=HUNTED_ISME)
@@ -183,12 +185,12 @@
             continue;
 
           if (IsPerson(acptr) &&
-              !IsAnOper(acptr) && !IsAnOper(sptr) &&
+              !SeesAllConnections(sptr) &&
               (acptr != sptr))
             continue;
           if (IsInvisible(acptr) && (doall || wilds) &&
-              !(MyConnect(sptr) && IsOper(sptr)) &&
-              !IsAnOper(acptr) && (acptr != sptr))
+              !SeesAllConnections(sptr) &&
+              (acptr != sptr))
             continue;
           if (!doall && wilds && !match(name, acptr->name))
             continue;
@@ -207,7 +209,7 @@
           /* if(IsAnOper(sptr)) */
 
           /* Don't trust opers not on this server */
-          if(MyClient(sptr) && IsAnOper(sptr))
+          if(MyClient(sptr) && IsSetOperAuspex(sptr))
             {
               sendto_one(sptr, Lformat, me.name,
                      RPL_STATSLINKINFO, parv[0],
@@ -251,7 +253,7 @@
       break;
     case 'C' : case 'c' :
 #ifdef SERVERHIDE
-      if (!IsAnOper(sptr))
+      if (!IsSetOperAuspex(sptr))
         {
           ignore_request++;
           valid_stats++;
@@ -268,7 +270,7 @@
       break;
 
     case 'D': case 'd':
-      if (!IsAnOper(sptr))
+      if (!CanSeeDlines(sptr))
         {
           sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
           break;
@@ -287,6 +289,11 @@
 
     case 'G': case 'g' :
 #ifdef GLINES
+      if (!CanSeeGlines(sptr))
+        {
+          sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+          break;
+        }
       report_glines(sptr);
       valid_stats++;
 #else
@@ -297,7 +304,7 @@
 
     case 'H' : case 'h' :
 #ifdef SERVERHIDE
-      if (!IsAnOper(sptr))
+      if (!IsSetOperAuspex(sptr))
         {
           ignore_request++;
           valid_stats++;
@@ -311,7 +318,7 @@
 
     case 'I' : case 'i' :
 #ifdef I_LINES_OPER_ONLY
-      if (!IsAnOper(sptr))
+      if (!CanSeeIlines(sptr))
         {
           ignore_request++;
           valid_stats++;
@@ -324,7 +331,7 @@
 
     case 'k' :
 #ifdef K_LINES_OPER_ONLY
-      if (!IsAnOper(sptr)) 
+      if (!CanSeeKlines(sptr)) 
         {
           ignore_request++;
           valid_stats++;
@@ -337,7 +344,7 @@
 
     case 'K' :
 #ifdef K_LINES_OPER_ONLY
-      if (!IsAnOper(sptr))
+      if (!CanSeeKlines(sptr))
         {
           ignore_request++;
           valid_stats++;
@@ -347,7 +354,7 @@
       if(parc > 3)
         report_matching_host_klines(sptr,parv[3]);
       else
-        if (IsAnOper(sptr))
+        if (CanSeeKlines(sptr))
           report_mtrie_conf_links(sptr, CONF_KILL);
         else
           report_matching_host_klines(sptr,sptr->host);
@@ -364,7 +371,7 @@
 
     case 'o' : case 'O' :
 #ifdef O_LINES_OPER_ONLY
-      if (!IsAnOper(sptr))
+      if (!CanSeeOlines(sptr))
         {
           ignore_request++;
           valid_stats++;
@@ -377,7 +384,7 @@
 
     case 'P' :
 #ifdef P_LINES_OPER_ONLY
-      if (!IsAnOper(sptr)) 
+      if (!IsSetOperAuspex(sptr)) 
         {
           ignore_request++;
           valid_stats++;
@@ -394,7 +401,7 @@
       break;
 
     case 'Q' : case 'q' :
-      if(!IsAnOper(sptr))
+      if(!CanSeeQlines(sptr))
         sendto_one(sptr,":%s NOTICE %s :This server does not support Q lines",
                    me.name, parv[0]);
       else
@@ -410,7 +417,7 @@
       break;
 
     case 'S' : case 's':
-      if (IsAnOper(sptr))
+      if (IsDebugger(sptr))
         list_scache(cptr,sptr,parc,parv);
       else
         sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
@@ -418,7 +425,7 @@
       break;
 
     case 'T' : case 't' :
-      if (!IsAnOper(sptr))
+      if (!CanSeeStatsT(sptr))
         {
           sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
           break;
@@ -452,7 +459,7 @@
       break;
 
     case 'x' : case 'X' :
-      if(IsAnOper(sptr))
+      if(CanSeeXlines(sptr))
         {
           report_specials(sptr,CONF_XLINE,RPL_STATSXLINE);
           valid_stats++;
@@ -460,7 +467,7 @@
       break;;
 
     case 'Y' : case 'y' :
-      if(IsAnOper(sptr))
+      if(CanSeeYlines(sptr))
         { 
           report_classes(sptr);
           valid_stats++;
@@ -468,7 +475,7 @@
       break;
 
     case 'Z' : case 'z' :
-      if (IsAnOper(sptr))
+      if (IsDebugger(sptr))
         {
           count_memory(sptr, parv[0]);
         }
@@ -478,7 +485,7 @@
       break;
 
     case '?':
-      if (IsAnOper(sptr))
+      if (CanSeeStatsServinfo(sptr))
       {
         serv_info(sptr, parv[0]);
       }
@@ -505,28 +512,28 @@
     {
       if ( (stat == 'L') || (stat == 'l') )
         {
-          sendto_realops_flags(FLAGS_SPY,
-                "STATS %c requested by %s (%s@%s) [%s] on %s%s",
-                stat,
-                sptr->name,
-                sptr->username,
-                sptr->host,
-                sptr->user->server,
-                parc > 2 ? parv[2] : "<no recipient>",
-                ignore_request > 0 ? " [request ignored]" : "\0"
-                );
+          sendto_realops_flag(UMODE_SPY,
+			      "STATS %c requested by %s (%s@%s) [%s] on %s%s",
+			      stat,
+			      sptr->name,
+			      sptr->username,
+			      sptr->host,
+			      sptr->user->server,
+			      parc > 2 ? parv[2] : "<no recipient>",
+			      ignore_request > 0 ? " [request ignored]" : "\0"
+			      );
         }
       else
         {
-          sendto_realops_flags(FLAGS_SPY,
-                "STATS %c requested by %s (%s@%s) [%s]%s",
-                stat,
-                sptr->name,
-                sptr->username,
-                sptr->host,
-                sptr->user->server,
-                ignore_request > 0 ? " [request ignored]" : "\0"
-                );
+          sendto_realops_flag(UMODE_SPY,
+			      "STATS %c requested by %s (%s@%s) [%s]%s",
+			      stat,
+			      sptr->name,
+			      sptr->username,
+			      sptr->host,
+			      sptr->user->server,
+			      ignore_request > 0 ? " [request ignored]" : "\0"
+			      );
         }
     }
 #endif
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_stopic.c ircd-hybrid-6.0/src/m_stopic.c
--- ircd-hybrid-6.0.orig/src/m_stopic.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_stopic.c	Wed Jun  6 11:34:31 2001
@@ -119,7 +119,7 @@
                  me.name, parv[0], "STOPIC");
       return 0;
     }
-  if (!IsPrivileged(sptr))
+  if (!IsServer(sptr))
     {
       sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return(0);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_trace.c ircd-hybrid-6.0/src/m_trace.c
--- ircd-hybrid-6.0.orig/src/m_trace.c	Tue Nov 21 06:49:30 2000
+++ ircd-hybrid-6.0/src/m_trace.c	Fri Jun  8 12:23:44 2001
@@ -115,7 +115,7 @@
   static time_t now;
 
 #ifdef SERVERHIDE
-  if (!IsAnOper(sptr))
+  if (!IsSetOperAuspex(sptr))
     return 0;
 #endif
 
@@ -152,7 +152,7 @@
       return 0;
     }
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       /* pacing for /trace is problemmatical */
 #if PACE_TRACE
@@ -168,9 +168,11 @@
           last_used = CurrentTime;
         }
 #endif
-
+    }
+  if (!IsSetOperAuspex(sptr))
+    {
       if (parv[1] && !strchr(parv[1],'.') && (strchr(parv[1], '*')
-          || strchr(parv[1], '?'))) /* bzzzt, no wildcard nicks for nonopers */
+          || strchr(parv[1], '?'))) /* bzzzt, no wildcard nicks for non(auspex)opers */
         {
           sendto_one(sptr, form_str(RPL_ENDOFTRACE),me.name,
                      parv[0], parv[1]);
@@ -179,17 +181,17 @@
     }
 
   if(MyClient(sptr))
-    sendto_realops_flags(FLAGS_SPY, "trace requested by %s (%s@%s) [%s]",
-                       sptr->name, sptr->username, sptr->host,
-                       sptr->user->server);
+    sendto_realops_flag(UMODE_SPY, "trace requested by %s (%s@%s) [%s]",
+			sptr->name, sptr->username, sptr->host,
+			sptr->user->server);
 
 
   doall = (parv[1] && (parc > 1)) ? match(tname, me.name): TRUE;
   wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
   dow = wilds || doall;
   
-  if(!IsAnOper(sptr) || !dow) /* non-oper traces must be full nicks */
-                              /* lets also do this for opers tracing nicks */
+  if(!IsSetOperAuspex(sptr) || !dow) /* non-oper traces must be full nicks */
+                                     /* lets also do this for opers tracing nicks */
     {
       const char* name;
       const char* ip;
@@ -209,7 +211,7 @@
 
       c_class = get_client_class(acptr);
 
-      if (IsAnOper(acptr))
+      if (SeesOpers(sptr) && IsAnOper(acptr))
         {
           sendto_one(sptr, form_str(RPL_TRACEOPERATOR),
                      me.name, parv[0], c_class,
@@ -217,7 +219,7 @@
 #ifdef SERVERHIDE
                      "255.255.255.255",
 #else
-                     IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
+                     SeesAllConnections(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
 #endif
                      now - acptr->lasttime,
                      (acptr->user)?(now - acptr->user->last):0);
@@ -230,7 +232,7 @@
 #ifdef SERVERHIDE
                      "255.255.255.255",
 #else
-                     IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
+                     SeesAllConnections(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
 #endif
                      now - acptr->lasttime,
                      (acptr->user)?(now - acptr->user->last):0);
@@ -240,7 +242,7 @@
       return 0;
     }
 
-  if (dow && LIFESUX && !IsOper(sptr))
+  if (dow && LIFESUX && !SendWhileLifeSucks(sptr))
     {
       sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0]);
       return 0;
@@ -263,7 +265,7 @@
         }
 #else
       if (IsPerson(acptr) &&
-        (!IsInvisible(acptr) || IsAnOper(sptr)))
+        (!IsInvisible(acptr) || SeesAllConnections(sptr)))
         {
           link_u[acptr->from->fd]++;
         }
@@ -287,8 +289,8 @@
       if (!(acptr = local[i])) /* Local Connection? */
         continue;
       if (IsInvisible(acptr) && dow &&
-          !(MyConnect(sptr) && IsAnOper(sptr)) &&
-          !IsAnOper(acptr) && (acptr != sptr))
+          !SeesAllConnections(sptr) &&
+          (acptr != sptr))
         continue;
       if (!doall && wilds && !match(tname, acptr->name))
         continue;
@@ -323,10 +325,12 @@
         case STAT_CLIENT:
           /* Only opers see users if there is a wildcard
            * but anyone can see all the opers.
+	   *
+	   * Or at least, those who SeesOpers() -- asuffield
            */
-          if ((IsAnOper(sptr) &&
+          if ((IsSetOperAuspex(sptr) &&
               (MyClient(sptr) || !(dow && IsInvisible(acptr))))
-              || !dow || IsAnOper(acptr))
+              || !dow || (IsAnOper(acptr) && SeesOpers(sptr)))
             {
               if (IsAnOper(acptr))
                 sendto_one(sptr,
@@ -337,7 +341,7 @@
 #ifdef SERVERHIDE
                            "255.255.255.255",
 #else
-                           IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
+                           IsSetOperAuspex(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
 #endif
                            now - acptr->lasttime,
                            (acptr->user)?(now - acptr->user->last):0);
@@ -348,7 +352,7 @@
 #ifdef SERVERHIDE
                            "255.255.255.255",
 #else
-                           IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
+                           IsSetOperAuspex(sptr)?ip:(IsIPHidden(acptr)?"127.0.0.1":ip),
 #endif
                            now - acptr->lasttime,
                            (acptr->user)?(now - acptr->user->last):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	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/m_unkline.c	Wed Jun  6 11:35:32 2001
@@ -87,16 +87,13 @@
       return -1;
     }
 
-  if (!IsPrivileged(sptr))  
+  if (!(IsServer(sptr) || IsSetOperUnkline(sptr)))  
     {
-      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, 
-                 parv[0]);
-      return 0;
-    }
-
-  if (!IsServer(cptr) && !IsSetOperUnkline(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :You have no U flag",me.name,parv[0]);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr,":%s NOTICE %s :You have no U umode",me.name,parv[0]);
+      else
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, 
+		   parv[0]);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_userhost.c ircd-hybrid-6.0/src/m_userhost.c
--- ircd-hybrid-6.0.orig/src/m_userhost.c	Tue Jan  2 05:48:18 2001
+++ ircd-hybrid-6.0/src/m_userhost.c	Wed Jun  6 00:24:09 2001
@@ -133,14 +133,14 @@
           if (acptr == sptr) /* show real IP for USERHOST on yourself */
             rl = ircsprintf(response, "%s%s=%c%s@%s ",
 		       acptr->name,
-		       IsAnOper(acptr) ? "*" : "",
+		       IsAnOper(acptr) && SeesOpers(sptr) ? "*" : "",
 		       (acptr->user->away) ? '-' : '+',
 		       acptr->username,
 		       acptr->sockhost);
           else
             rl = ircsprintf(response, "%s%s=%c%s@%s ",
 		       acptr->name,
-		       IsAnOper(acptr) ? "*" : "",
+		       IsAnOper(acptr) && SeesOpers(sptr) ? "*" : "",
 		       (acptr->user->away) ? '-' : '+',
 		       acptr->username,
 		       acptr->host);
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_version.c ircd-hybrid-6.0/src/m_version.c
--- ircd-hybrid-6.0.orig/src/m_version.c	Sat Jul 31 05:48:04 1999
+++ ircd-hybrid-6.0/src/m_version.c	Wed Jun  6 00:41:10 2001
@@ -93,7 +93,7 @@
  */
 int m_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
-  if (IsAnOper(sptr))
+  if (IsSetOperRemote(sptr))
      {
        if (hunt_server(cptr, sptr, ":%s VERSION :%s", 
                        1, parc, parv) == HUNTED_ISME)
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_wallops.c ircd-hybrid-6.0/src/m_wallops.c
--- ircd-hybrid-6.0.orig/src/m_wallops.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_wallops.c	Wed Jun  6 17:27:04 2001
@@ -98,11 +98,11 @@
 int m_wallops(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 { 
   char* message;
-  int flags=0;
+  int flag=0;
 
   if (parc == 3)
     {
-      flags = atoi(parv[1]);
+      flag = atoi(parv[1]);
       message = parv[2];
     }
   else
@@ -115,7 +115,7 @@
       return 0;
     }
 
-  if (!IsServer(sptr) && MyConnect(sptr) && !IsAnOper(sptr))
+  if (!IsServer(sptr) && MyConnect(sptr) && !SendWallops(sptr))
     {
       sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return(0);
@@ -129,7 +129,7 @@
 
   if (parc == 3)
     {
-      sendto_ops_flags_butone(cptr, flags, "%s", message);
+      sendto_ops_flag_butone(cptr, flag, "%s", message);
       return 0;
     }
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_who.c ircd-hybrid-6.0/src/m_who.c
--- ircd-hybrid-6.0.orig/src/m_who.c	Fri Jun  8 18:03:38 2001
+++ ircd-hybrid-6.0/src/m_who.c	Wed Jun  6 01:10:57 2001
@@ -107,7 +107,7 @@
     *p++ = 'H';
   if (IsAnOper(acptr) 
 #ifdef OPERHIDE
-      && IsAnOper(sptr)
+      && SeesOpers(sptr)
 #endif
      )
     *p++ = '*';
@@ -131,7 +131,7 @@
              acptr->username,
              acptr->host,
 #ifdef SERVERHIDE
-             IsAnOper(sptr) ? acptr->user->server : NETWORK_NAME,
+             IsSetOperAuspex(sptr) ? acptr->user->server : NETWORK_NAME,
 #else
              acptr->user->server,
 #endif
@@ -210,24 +210,27 @@
       /*
        * List all users on a given channel
        */
-      chptr = hash_find_channel(channame, NULL);
-      if (chptr)
-        {
-          member = IsMember(sptr, chptr) || SeesAllConnections(sptr);
-          if (member || !SecretChannel(chptr))
-            for (lp = chptr->members; lp; lp = lp->next)
-              {
-                if (oper && !IsAnOper(lp->value.cptr))
-                  continue;
-                if (IsInvisible(lp->value.cptr) && !member)
-                  continue;
-                do_who(sptr, lp->value.cptr, chptr, lp);
-              }
-        }
+      if (!oper || SeesOpers(sptr)) /* If you're doing an oper search, you need SeesOpers() */
+	{
+	  chptr = hash_find_channel(channame, NULL);
+	  if (chptr)
+	    {
+	      member = IsMember(sptr, chptr) || SeesAllConnections(sptr);
+	      if (member || !SecretChannel(chptr))
+		for (lp = chptr->members; lp; lp = lp->next)
+		  {
+		    if (oper && !IsAnOper(lp->value.cptr))
+		      continue;
+		    if (IsInvisible(lp->value.cptr) && !member)
+		      continue;
+		    do_who(sptr, lp->value.cptr, chptr, lp);
+		  }
+	    }
+	}
     }
   else if (mask && 
            ((acptr = find_client(mask, NULL)) != NULL) &&
-           IsPerson(acptr) && (!oper || IsAnOper(acptr)))
+           IsPerson(acptr) && (!oper || (IsAnOper(acptr) && SeesOpers(sptr))))
     {
       int isinvis = 0;
       struct Channel *ch2ptr = NULL;
@@ -247,7 +250,8 @@
         }
       do_who(sptr, acptr, ch2ptr, NULL);
     }
-  else for (acptr = GlobalClientList; acptr; acptr = acptr->next)
+  else if (!oper || SeesOpers(sptr))
+    for (acptr = GlobalClientList; acptr; acptr = acptr->next)
     {
       struct Channel *ch2ptr = NULL;
       int       showperson, isinvis;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/m_whois.c ircd-hybrid-6.0/src/m_whois.c
--- ircd-hybrid-6.0.orig/src/m_whois.c	Fri Jun  8 18:03:39 2001
+++ ircd-hybrid-6.0/src/m_whois.c	Wed Jun  6 10:49:18 2001
@@ -144,7 +144,7 @@
       parv[1] = parv[2];
     }
 
-  if(!IsAnOper(sptr) && !MyConnect(sptr)) /* pace non local requests */
+  if(!NoFloodProtection(sptr) && !MyConnect(sptr)) /* pace non local requests */
     {
       if((last_used + WHOIS_WAIT) > CurrentTime)
         {
@@ -271,7 +271,7 @@
                        me.name, parv[0], name, buf);
          
 #ifdef SERVERHIDE
-          if (!(IsAnOper(sptr) || acptr == sptr))
+          if (!(IsSetOperAuspex(sptr) || acptr == sptr))
             sendto_one(sptr, form_str(RPL_WHOISSERVER),
                        me.name, parv[0], name, NETWORK_NAME,
                        NETWORK_DESC);
@@ -287,7 +287,7 @@
 
           if (IsAnOper(acptr)
 #ifdef OPERHIDE
-               && IsAnOper(sptr)
+               && SeesOpers(sptr)
 #endif
               )
             sendto_one(sptr, form_str(RPL_WHOISOPERATOR),
@@ -309,7 +309,7 @@
 
           if ((acptr->user
 #ifdef SERVERHIDE
-              && IsAnOper(sptr)
+              && IsSetOperAuspex(sptr)
 #endif
               && MyConnect(acptr)))
             sendto_one(sptr, form_str(RPL_WHOISIDLE),
@@ -426,7 +426,7 @@
                        me.name, parv[0], name, buf);
          
 #ifdef SERVERHIDE
-          if (!(IsAnOper(sptr) || acptr == sptr))
+          if (!(IsSetOperAuspex(sptr) || acptr == sptr))
             sendto_one(sptr, form_str(RPL_WHOISSERVER),
                        me.name, parv[0], name, NETWORK_NAME,
                        NETWORK_DESC);
@@ -442,7 +442,7 @@
 
           if (IsAnOper(acptr)
 #ifdef OPERHIDE
-               && IsAnOper(sptr)
+               && SeesOpers(sptr)
 #endif
               )
             sendto_one(sptr, form_str(RPL_WHOISOPERATOR),
@@ -458,7 +458,7 @@
 
           if ((acptr->user
 #ifdef SERVERHIDE
-              && IsAnOper(sptr) 
+              && IsSetOperAuspex(sptr) 
 #endif                 
               && MyConnect(acptr)))
             sendto_one(sptr, form_str(RPL_WHOISIDLE),
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/motd.c ircd-hybrid-6.0/src/motd.c
--- ircd-hybrid-6.0.orig/src/motd.c	Fri Jun  8 18:03:36 2001
+++ ircd-hybrid-6.0/src/motd.c	Wed Jun  6 18:35:27 2001
@@ -51,7 +51,7 @@
 {
   static time_t last_used = 0;
 
-  if(!IsAnOper(sptr))
+  if(!NoFloodProtection(sptr))
     {
       if((last_used + PACE_WAIT) > CurrentTime)
         {
@@ -67,9 +67,9 @@
   if (hunt_server(cptr, sptr, ":%s MOTD :%s", 1,parc,parv)!=HUNTED_ISME)
     return 0;
 
-  sendto_realops_flags(FLAGS_SPY, "motd requested by %s (%s@%s) [%s]",
-                     sptr->name, sptr->username, sptr->host,
-                     sptr->user->server);
+  sendto_realops_flag(UMODE_SPY, "motd requested by %s (%s@%s) [%s]",
+		      sptr->name, sptr->username, sptr->host,
+		      sptr->user->server);
 
   return(SendMessageFile(sptr,&ConfigFileEntry.motd));
 }
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	Fri Dec  1 06:28:49 2000
+++ ircd-hybrid-6.0/src/mtrie_conf.c	Wed Jun  6 10:56:58 2001
@@ -1235,7 +1235,7 @@
       if(match(host,need_host))
         {
           p = (char *)NULL;
-          if(!IsAnOper(sptr))
+          if(!CanSeeKlines(sptr))
             {
               p = strchr(pass,'|');
               if(p)
@@ -1279,7 +1279,7 @@
           /* Non local opers do not need to know about
            * I lines that do spoofing 
            */
-          if(!(MyConnect(sptr) && IsAnOper(sptr)) &&
+          if(!(MyConnect(sptr) && IsSetOperAuspex(sptr)) &&
              IsConfDoSpoofIp(found_conf))
             continue;
 
@@ -1354,7 +1354,7 @@
 
           /* Hide any comment following a '|' seen in the password field */
           p = (char *)NULL;
-          if(!IsAnOper(sptr))
+          if(!CanSeeKlines(sptr))
             {
               p = strchr(pass,'|');
               if(p)
@@ -1402,32 +1402,32 @@
     *prefix_ptr++ = '=';
 
 #ifdef E_LINES_OPER_ONLY
-  if(IsAnOper(sptr))
+  if(CanSeeElines(sptr))
 #endif
     if (IsConfExemptGline(aconf))
       *prefix_ptr++ = '_';
 
 #ifdef E_LINES_OPER_ONLY
-  if(IsAnOper(sptr))
+  if(CanSeeElines(sptr))
 #endif
     if (IsConfElined(aconf))
       *prefix_ptr++ = '^';
 
 #ifdef B_LINES_OPER_ONLY
-  if(IsAnOper(sptr))
+  if(CanSeeBlines(sptr))
 #endif
     if (IsConfBlined(aconf))
       *prefix_ptr++ = '&';
 
 #ifdef F_LINES_OPER_ONLY
-  if(IsAnOper(sptr))
+  if(CanSeeFlines(sptr))
 #endif
     if (IsConfFlined(aconf))
       *prefix_ptr++ = '>';
 
 #ifdef IDLE_CHECK  
 #ifdef E_LINES_OPER_ONLY
-  if(IsAnOper(sptr))
+  if(CanSeeElines(sptr))
 #endif
     if (IsConfIdlelined(aconf))
       *prefix_ptr++ = '<';
@@ -1479,7 +1479,7 @@
                        * password field
                        */
                       p = (char *)NULL;
-                      if(!IsAnOper(sptr))
+                      if(!CanSeeKlines(sptr))
                         {
                           p = strchr(pass,'|');
                           if(p)
@@ -1500,7 +1500,7 @@
                       /* Non local opers do not need to know about
                        * I lines that do spoofing
                        */
-                      if(!(MyConnect(sptr) && IsAnOper(sptr))
+                      if(!(MyConnect(sptr) && IsSetOperAuspex(sptr))
                          && IsConfDoSpoofIp(aconf))
                         continue;
 
@@ -1534,7 +1534,7 @@
                   if (aconf->status == CONF_KILL)
                     {
                       p = (char *)NULL;
-                      if(!IsAnOper(sptr))
+                      if(!CanSeeKlines(sptr))
                         {
                           p = strchr(pass,'|');
                           if(p)
@@ -1555,7 +1555,7 @@
                       /* Non local opers do not need to know about
                        * I lines that do spoofing
                        */
-                      if(!(MyConnect(sptr) && IsAnOper(sptr))
+                      if(!(MyConnect(sptr) && IsSetOperAuspex(sptr))
                          && IsConfDoSpoofIp(aconf))
                         continue;
                       c = 'I';
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/parse.c ircd-hybrid-6.0/src/parse.c
--- ircd-hybrid-6.0.orig/src/parse.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/parse.c	Wed Jun  6 18:40:21 2001
@@ -235,7 +235,7 @@
       if ((mptr->flags & 1) && !(IsServer(cptr)))
         {
 #ifdef NO_OPER_FLOOD
-          if (IsAnOper(cptr))
+          if (NoFloodProtection(cptr))
             /* "randomly" (weighted) increase the since */
             cptr->since += (cptr->receiveM % 5) ? 1 : 0;
           else
@@ -520,22 +520,22 @@
    */
   if (IsServer(sptr) || IsMe(sptr))
     {
-      sendto_realops_flags(FLAGS_DEBUG, "Message for %s[%s] from %s",
-                         sptr->name, sptr->from->name,
-                         get_client_name(cptr, TRUE));
+      sendto_realops_flag(UMODE_SERVNOTICE, "Message for %s[%s] from %s",
+			  sptr->name, sptr->from->name,
+			  get_client_name(cptr, TRUE));
       if (IsServer(cptr))
         {
-          sendto_realops_flags(FLAGS_DEBUG,
-                             "Not dropping server %s (%s) for Fake Direction",
-                             cptr->name, sptr->name);
+          sendto_realops_flag(UMODE_SERVNOTICE,
+			      "Not dropping server %s (%s) for Fake Direction",
+			      cptr->name, sptr->name);
           return -1;
         }
 
       if (IsClient(cptr))
-        sendto_realops_flags(FLAGS_DEBUG,
-                           "Would have dropped client %s (%s@%s) [%s from %s]",
-                           cptr->name, cptr->username, cptr->host,
-                           cptr->user->server, cptr->from->name);
+        sendto_realops_flag(UMODE_SERVNOTICE,
+			    "Would have dropped client %s (%s@%s) [%s from %s]",
+			    cptr->name, cptr->username, cptr->host,
+			    cptr->user->server, cptr->from->name);
       return -1;
 
       /*
@@ -556,20 +556,20 @@
     if (DoesTS(cptr))
       {
         if (sptr->user)
-          sendto_realops_flags(FLAGS_DEBUG,
-              "Message for %s[%s@%s!%s] from %s (TS, ignored)",
-                             sptr->name, sptr->username, sptr->host,
-                           sptr->from->name, get_client_name(cptr, TRUE));
+          sendto_realops_flag(UMODE_DEBUG,
+			      "Message for %s[%s@%s!%s] from %s (TS, ignored)",
+			      sptr->name, sptr->username, sptr->host,
+			      sptr->from->name, get_client_name(cptr, TRUE));
         return 0;
       }
     else
       {
         if (sptr->user)
           {
-            sendto_realops_flags(FLAGS_DEBUG,
-                             "Message for %s[%s@%s!%s] from %s",
-                           sptr->name, sptr->username, sptr->host,
-                           sptr->from->name, get_client_name(cptr, TRUE));
+            sendto_realops_flag(UMODE_DEBUG,
+				"Message for %s[%s@%s!%s] from %s",
+				sptr->name, sptr->username, sptr->host,
+				sptr->from->name, get_client_name(cptr, TRUE));
           }
         sendto_serv_butone(NULL,
                            ":%s KILL %s :%s (%s[%s] != %s, Fake Prefix)",
@@ -592,10 +592,10 @@
 
   if (IsClient(cptr))
     {
-      sendto_realops_flags(FLAGS_DEBUG,
-                 "Weirdness: Unknown client prefix (%s) from %s, Ignoring %s",
-                         buffer,
-                         get_client_name(cptr, FALSE), sender);
+      sendto_realops_flag(UMODE_DEBUG,
+			  "Weirdness: Unknown client prefix (%s) from %s, Ignoring %s",
+			  buffer,
+			  get_client_name(cptr, FALSE), sender);
       return;
     }
 
@@ -615,8 +615,8 @@
                get_client_name(cptr, FALSE));
   else
     {
-      sendto_realops_flags(FLAGS_DEBUG,
-        "Unknown prefix (%s) from %s, Squitting %s", buffer, get_client_name(cptr, FALSE), sender);
+      sendto_realops_flag(UMODE_DEBUG,
+			  "Unknown prefix (%s) from %s, Squitting %s", buffer, get_client_name(cptr, FALSE), sender);
       sendto_one(cptr, ":%s SQUIT %s :(Unknown prefix (%s) from %s)",
                  me.name, sender, buffer, get_client_name(cptr, FALSE));
     }
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/res.c ircd-hybrid-6.0/src/res.c
--- ircd-hybrid-6.0.orig/src/res.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/res.c	Wed Jun  6 10:58:51 2001
@@ -1684,8 +1684,14 @@
   int     i;
   struct hostent* hp;
 
-  if (!IsAnOper(sptr))
-    return 0;
+  if (!IsSetOperAuspex(sptr))
+    {
+      if (!SeesOperMessages(sptr))
+	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+      else
+	sendto_one(sptr,":%s NOTICE %s :You have no a umode",me.name,parv[0]);
+      return 0;
+    }
 
   if (parv[1] && *parv[1] == 'l') {
     for(cp = cacheTop; cp; cp = cp->list_next) {
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_bsd.c ircd-hybrid-6.0/src/s_bsd.c
--- ircd-hybrid-6.0.orig/src/s_bsd.c	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/s_bsd.c	Wed Jun  6 18:36:40 2001
@@ -170,7 +170,7 @@
 {
   who = (who) ? who : "";
 
-  sendto_realops_flags(FLAGS_DEBUG, text, who, strerror(error));
+  sendto_realops_flag(UMODE_DEBUG, text, who, strerror(error));
 
   log(L_ERROR, text, who, strerror(error));
 }
@@ -887,7 +887,7 @@
     
     if (IsPerson(cptr) &&
 #ifdef NO_OPER_FLOOD
-        !IsAnOper(cptr) &&
+        !NoFloodProtection(cptr) &&
 #endif
         DBufLength(&cptr->recvQ) > CLIENT_FLOOD) {
       return exit_client(cptr, cptr, cptr, "Excess Flood");
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	Fri Jun  8 18:03:39 2001
+++ ircd-hybrid-6.0/src/s_conf.c	Fri Jun  8 17:30:17 2001
@@ -40,6 +40,7 @@
 #include "send.h"
 #include "struct.h"
 #include "s_debug.h"
+#include "umodes.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -90,8 +91,7 @@
 struct ConfItem *temporary_ip_klines = NULL;
 
 static  char *set_conf_flags(struct ConfItem *,char *);
-static  int  oper_privs_from_string(int,char *);
-static  int  oper_flags_from_string(char *);
+static  void oper_flags_from_string(umode_t*, char *);
 
 /* externally defined functions */
 extern  void    outofmemory(void);        /* defined in list.c */
@@ -294,7 +294,7 @@
               c = 'c';
 
             /* Don't allow non opers to see actual ips */
-            if(IsAnOper(sptr))
+            if(IsSetOperAuspex(sptr))
               sendto_one(sptr, form_str(p->rpl_stats), me.name,
                          sptr->name, c,
 #ifdef SERVERHIDE
@@ -305,7 +305,7 @@
                          name,
                          port,
                          get_conf_class(tmp),
-                         oper_flags_as_string((int)tmp->hold));
+                         oper_flags_as_string(tmp->default_umodes));
             else
               sendto_one(sptr, form_str(p->rpl_stats), me.name,
                          sptr->name, c,
@@ -318,21 +318,21 @@
         else if(mask & (CONF_OPERATOR|CONF_LOCOP))
           {
             /* Don't allow non opers to see oper privs */
-            if(IsAnOper(sptr))
+            if(SeesOpers(sptr))
               sendto_one(sptr, form_str(p->rpl_stats), me.name,
                          sptr->name,
                          p->conf_char,
                          user, host, name,
-                         oper_privs_as_string((struct Client *)NULL,port),
+                         oper_flags_as_string(tmp->allowed_umodes),
                          get_conf_class(tmp),
-                         oper_flags_as_string((int)tmp->hold));
+                         oper_flags_as_string(tmp->default_umodes));
             else
               sendto_one(sptr, form_str(p->rpl_stats), me.name,
                          sptr->name,
                          p->conf_char,
                          user,
 #ifdef SERVERHIDE
-                         IsAnOper(sptr) ? host : "255.255.255.255",
+                         IsSetOperAuspex(sptr) ? host : "255.255.255.255",
 #else
                          host,
 #endif
@@ -2075,29 +2075,20 @@
 	  /* user field */
           if ((tmp = getfield(NULL)) == NULL)
             break;
-          /*from comstud */
-
+          /*from comstud*/
           if(aconf->status & CONF_CLIENT)
             tmp = set_conf_flags(aconf, tmp);
           DupString(aconf->user, tmp);
 
 	  /* port field */
-          if(aconf->status & CONF_OPERATOR)
+          if((aconf->status & CONF_OPERATOR) | (aconf->status & CONF_LOCOP))
             {
               /* defaults */
-              aconf->port = 
-                CONF_OPER_GLOBAL_KILL|CONF_OPER_REMOTE|CONF_OPER_UNKLINE|
-                CONF_OPER_K|CONF_OPER_GLINE|CONF_OPER_REHASH;
-              if ((tmp = getfield(NULL)) == NULL)
-                break;
-              aconf->port = oper_privs_from_string(aconf->port,tmp);
-            }
-          else if(aconf->status & CONF_LOCOP)
-            {
-              aconf->port = CONF_OPER_UNKLINE|CONF_OPER_K;
+	      log(L_NOTICE, "Reading allowed umodes for %s", aconf->user);
+	      ClearBitfield(aconf->allowed_umodes);
               if ((tmp = getfield(NULL)) == NULL)
                 break;
-              aconf->port = oper_privs_from_string(aconf->port,tmp);
+              oper_flags_from_string(&(aconf->allowed_umodes),tmp);
             }
           else
             {
@@ -2135,9 +2126,11 @@
 
           if(aconf->status & (CONF_LOCOP|CONF_OPERATOR))
             {
+	      log(L_NOTICE, "Reading default umodes for %s", aconf->user);
+	      ClearBitfield(aconf->default_umodes);
               if ((tmp = getfield(NULL)) == NULL)
                 break;
-              aconf->hold = oper_flags_from_string(tmp);
+              oper_flags_from_string(&(aconf->default_umodes), tmp);
             }
 
           break;
@@ -2590,7 +2583,7 @@
         sendto_realops("Can't open %s include file",include_list->name);
       else
         {
-          sendto_realops_flags(FLAGS_DEBUG, "Hashing in %s include file",include_list->name);
+          sendto_realops_flag(UMODE_DEBUG, "Hashing in %s include file",include_list->name);
           initconf(file, NO);
         }
       free_conf(include_list);
@@ -2928,7 +2921,7 @@
           else
             reason = "No Reason";
 
-          if(!IsAnOper(sptr))
+          if(!CanSeeKlines(sptr))
             {
               if( (p = strchr(reason,'|')) )
                 *p = '\0';
@@ -2948,212 +2941,6 @@
     }
 }
 
-/* oper_privs_from_string
- *
- * inputs        - default privs
- *               - privs as string
- * output        - default privs as modified by privs string
- * side effects -
- *
- */
-
-static int oper_privs_from_string(int int_privs,char *privs)
-{
-  while(*privs)
-    {
-      if(*privs == 'O')                     /* allow global kill */
-        int_privs |= CONF_OPER_GLOBAL_KILL;
-      else if(*privs == 'o')                /* disallow global kill */
-        int_privs &= ~CONF_OPER_GLOBAL_KILL;
-      else if(*privs == 'U')                /* allow unkline */
-        int_privs |= CONF_OPER_UNKLINE;
-      else if(*privs == 'u')                /* disallow unkline */
-        int_privs &= ~CONF_OPER_UNKLINE;
-      else if(*privs == 'R')                /* allow remote squit/connect etc.*/
-        int_privs |= CONF_OPER_REMOTE;        
-      else if(*privs == 'r')                /* disallow remote squit/connect etc.*/
-        int_privs &= ~CONF_OPER_REMOTE;
-      else if(*privs == 'N')                /* allow +n see nick changes */
-        int_privs |= CONF_OPER_N;
-      else if(*privs == 'n')                /* disallow +n see nick changes */
-        int_privs &= ~CONF_OPER_N;
-      else if(*privs == 'K')                /* allow kill and kline privs */
-        int_privs |= CONF_OPER_K;
-      else if(*privs == 'k')                /* disallow kill and kline privs */
-        int_privs &= ~CONF_OPER_K;
-#ifdef GLINES
-      else if(*privs == 'G')                /* allow gline */
-        int_privs |= CONF_OPER_GLINE;
-      else if(*privs == 'g')                /* disallow gline */
-        int_privs &= ~CONF_OPER_GLINE;
-#endif
-#ifdef GODOPERS
-      else if(*privs == 'P')                /* allow apotheosis */
-        int_privs |= CONF_OPER_GOD;
-      else if(*privs == 'p')                /* disallow apotheosis */
-        int_privs &= ~CONF_OPER_GOD;
-#endif
-      else if(*privs == 'H')                /* allow rehash */
-        int_privs |= CONF_OPER_REHASH;
-      else if(*privs == 'h')                /* disallow rehash */
-        int_privs &= ~CONF_OPER_REHASH;
-      else if(*privs == 'D')
-        int_privs |= CONF_OPER_DIE;         /* allow die */
-      else if(*privs == 'd')
-        int_privs &= ~CONF_OPER_DIE;        /* disallow die */
-      else if(*privs == 'M')
-        int_privs |= CONF_OPER_M;           /* allow immunity */
-      else if(*privs == 'm')
-        int_privs &= ~CONF_OPER_M;          /* disallow immunity */
-      else if(*privs == 'A')
-        int_privs |= CONF_OPER_AUSPEX;      /* allow seeing the invisible */
-      else if(*privs == 'a')
-        int_privs &= ~CONF_OPER_AUSPEX;     /* disallow seeing the invisible */
-#ifdef CHANNEL_CREATION_NOTICE
-      else if(*privs == 'L')
-        int_privs |= CONF_OPER_CHCREATE;    /* allow seeing new chans */
-      else if(*privs == 'l')
-        int_privs &= ~CONF_OPER_CHCREATE;   /* disallow seeing new  chans */
-#endif /* CHANNEL_CREATION_NOTICE */
-
-      privs++;
-    }
-
-  return(int_privs);
-}
-
-/*
- * oper_privs_as_string
- *
- * inputs        - pointer to cptr or NULL
- * output        - pointer to static string showing oper privs
- * side effects  -
- * return as string, the oper privs as derived from port
- * also, set the oper privs if given cptr non NULL
- */
-
-char *oper_privs_as_string(aClient *cptr,int port)
-{
-  static char privs_out[16];
-  char *privs_ptr;
-
-  privs_ptr = privs_out;
-  *privs_ptr = '\0';
-
-  if(port & CONF_OPER_GLINE)
-    {
-      if(cptr)
-        SetOperGline(cptr);
-      *privs_ptr++ = 'G';
-    }
-  else
-    *privs_ptr++ = 'g';
-
-  if(port & CONF_OPER_K)
-    {
-      if(cptr)
-        SetOperK(cptr);
-      *privs_ptr++ = 'K';
-    }
-  else
-    *privs_ptr++ = 'k';
-
-  if(port & CONF_OPER_M)
-    {
-      if(cptr)
-        SetOperM(cptr);
-      *privs_ptr++ = 'M';
-    }
-  else
-    *privs_ptr++ = 'm';
-  
-  if(port & CONF_OPER_AUSPEX)
-    {
-      if(cptr)
-        SetOperAuspex(cptr);
-      *privs_ptr++ = 'A';
-    }
-  else
-    *privs_ptr++ = 'a';
-  
-  if(port & CONF_OPER_N)
-    {
-      if(cptr)
-        SetOperN(cptr);
-      *privs_ptr++ = 'N';
-    }
-
-  if(port & CONF_OPER_GLOBAL_KILL)
-    {
-      if(cptr)
-        SetOperGlobalKill(cptr);
-      *privs_ptr++ = 'O';
-    }
-  else
-    *privs_ptr++ = 'o';
-
-  if(port & CONF_OPER_REMOTE)
-    {
-      if(cptr)
-        SetOperRemote(cptr);
-      *privs_ptr++ = 'R';
-    }
-  else
-    *privs_ptr++ = 'r';
-  
-  if(port & CONF_OPER_UNKLINE)
-    {
-      if(cptr)
-        SetOperUnkline(cptr);
-      *privs_ptr++ = 'U';
-    }
-  else
-    *privs_ptr++ = 'u';
-
-  if(port & CONF_OPER_REHASH)
-    {
-      if(cptr)
-        SetOperRehash(cptr);
-      *privs_ptr++ = 'H';
-    }
-  else
-    *privs_ptr++ = 'h';
-
-#ifdef GODOPERS
-  if(port & CONF_OPER_GOD)
-    {
-      if(cptr)
-        SetOperGod(cptr);
-      *privs_ptr++ = 'P';
-    }
-  else
-    *privs_ptr++ = 'p';
-#endif
-  if(port & CONF_OPER_DIE)
-    {
-      if(cptr)
-        SetOperDie(cptr);
-      *privs_ptr++ = 'D';
-    }
-  else
-    *privs_ptr++ = 'd';
-
-#ifdef CHANNEL_CREATION_NOTICE
-  if(port & CONF_OPER_CHCREATE)
-    {
-      if(cptr)
-        SetOperChanCreate(cptr);
-      *privs_ptr++ = 'L';
-    }
-  else
-    *privs_ptr++ = 'l';
-#endif
-
-  *privs_ptr = '\0';
-
-  return(privs_out);
-}
-
 /* oper_flags_from_string
  *
  * inputs        - flags as string
@@ -3163,44 +2950,13 @@
  * -Dianora
  */
 
-static int oper_flags_from_string(char *flags)
+static void oper_flags_from_string(umode_t* u, char *flags)
 {
-  int int_flags=0;
-
   while(*flags)
     {
-      if(*flags == 'i')                        /* invisible */
-        int_flags |= FLAGS_INVISIBLE;
-      else if(*flags == 'w')                /* see wallops */
-        int_flags |= FLAGS_WALLOP;
-      else if(*flags == 's')
-        int_flags |= FLAGS_SERVNOTICE;
-      else if(*flags == 'c')
-        int_flags |= FLAGS_CCONN;
-      else if(*flags == 'r')
-        int_flags |= FLAGS_REJ;
-      else if(*flags == 'k')
-        int_flags |= FLAGS_SKILL;
-      else if(*flags == 'f')
-        int_flags |= FLAGS_FULL;
-      else if(*flags == 'y')
-        int_flags |= FLAGS_SPY;
-#ifdef GODOPERS
-      else if(*flags == 'p')
-        int_flags |= FLAGS_GOD;
-#endif
-      else if(*flags == 'd')
-        int_flags |= FLAGS_DEBUG;
-      else if(*flags == 'n')
-        int_flags |= FLAGS_NCHANGE;
-      else if(*flags == 'm')
-        int_flags |= FLAGS_IMMUNE;
-      else if(*flags == 'a')
-        int_flags |= FLAGS_AUSPEX;
+      SetBit((*u), user_modes_from_c_to_bitmask[(unsigned char)*flags]);
       flags++;
     }
-
-  return(int_flags);
 }
 
 /* oper_flags_as_string
@@ -3212,44 +2968,21 @@
  * -Dianora
  */
 
-char *oper_flags_as_string(int flags)
+char *oper_flags_as_string(umode_t flags)
 {
-  static char flags_out[16];
+  static char flags_out[BITFIELD_SIZE]; /* we need more flags -- asuffield */
   char *flags_ptr;
+  int i;
 
   flags_ptr = flags_out;
   *flags_ptr = '\0';
 
-  if(flags & FLAGS_INVISIBLE)
-    *flags_ptr++ = 'i';
-  if(flags & FLAGS_WALLOP)
-    *flags_ptr++ = 'w';
-  if(flags & FLAGS_SERVNOTICE)
-    *flags_ptr++ = 's';
-  if(flags & FLAGS_CCONN)
-    *flags_ptr++ = 'c';
-  if(flags & FLAGS_REJ)
-    *flags_ptr++ = 'r';
-  if(flags & FLAGS_SKILL)
-    *flags_ptr++ = 'k';
-  if(flags & FLAGS_FULL)
-    *flags_ptr++ = 'f';
-  if(flags & FLAGS_SPY)
-    *flags_ptr++ = 'y';
-#ifdef GODOPERS
-  if(flags & FLAGS_GOD)
-    *flags_ptr++ = 'p';
-#endif
-  if(flags & FLAGS_DEBUG)
-    *flags_ptr++ = 'd';
-  if(flags & FLAGS_NCHANGE)
-    *flags_ptr++ = 'n';
-  if(flags & FLAGS_IMMUNE)
-    *flags_ptr++ = 'm';
-  if(flags & FLAGS_AUSPEX)
-    *flags_ptr++ = 'a';
+  for (i = 0; user_modes[i].letter; i++ )
+    {
+      if (TestBit(flags, user_modes[i].mode))
+	*flags_ptr++ = user_modes[i].letter;
+    }
   *flags_ptr = '\0';
-
   return(flags_out);
 }
 
@@ -3436,7 +3169,7 @@
   char *host, *pass, *user, *name, *given_host, *given_name, *p;
   int port;
 
-  if (!MyClient(sptr) || !IsAnOper(sptr))
+  if (!MyClient(sptr) || !CanDoTestline(sptr))
     {
       sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
       return 0;
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/s_misc.c ircd-hybrid-6.0/src/s_misc.c
--- ircd-hybrid-6.0.orig/src/s_misc.c	Tue Nov 21 06:49:32 2000
+++ ircd-hybrid-6.0/src/s_misc.c	Fri Jun  8 16:10:55 2001
@@ -158,7 +158,7 @@
        * been removed. Also, do not allow non opers to see the IP's of servers
        * on stats ?
        */
-      if(IsAnOper(cptr))
+      if(IsSetOperAuspex(cptr))
         sendto_one(cptr, Lformat, me.name, RPL_STATSLINKINFO, name,
 #ifdef SERVERHIDE
                    get_client_name(acptr, HIDEME),
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	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/src/s_serv.c	Wed Jun  6 18:38:29 2001
@@ -149,7 +149,7 @@
    * non-matching lookups.
    */
 #ifdef SERVERHIDE
-  if ( !(MyClient(sptr) && !IsOper(sptr))
+  if ( !(MyClient(sptr) && !SeesAllConnections(sptr))
       && (acptr = find_client(parv[server], NULL)) )
 #else
   if ((acptr = find_client(parv[server], NULL)))
@@ -171,7 +171,7 @@
   if (!acptr)
     {
 #ifdef SERVERHIDE
-      if ((!wilds || (MyClient(sptr) && !IsOper(sptr))))
+      if ((!wilds || (MyClient(sptr) && !SeesAllConnections(sptr))))
 #else
       if (!wilds)
 #endif
@@ -474,7 +474,7 @@
 
   if (IsPerson(acptr))
     {
-      send_umode(NULL, acptr, 0, SEND_UMODES, ubuf);
+      send_umode(NULL, acptr, 0, send_umodes, ubuf);
       if (!*ubuf)
         { /* trivial optimization - Dianora */
           
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	Fri Jun  8 18:03:40 2001
+++ ircd-hybrid-6.0/src/s_user.c	Fri Jun  8 16:25:06 2001
@@ -47,6 +47,7 @@
 #include "struct.h"
 #include "whowas.h"
 #include "flud.h"
+#include "umodes.h"
 
 #ifdef ANTI_DRONE_FLOOD
 #include "dbuf.h"
@@ -73,126 +74,11 @@
 int valid_username(const char* username);
 static void report_and_set_user_flags( aClient *, aConfItem * );
 static int tell_user_off(aClient *,char **);
-static void send_umode_out_oper (struct Client*, struct Client*, int,
+static void send_umode_out_oper (struct Client*, struct Client*, umode_t,
                                  struct Client*);
 int add_silence(struct Client *, char *);
 
-/* table of ascii char letters to corresponding bitmask */
-
-static FLAG_ITEM user_modes[] =
-{ 
-  {FLAGS_AUSPEX, 'a'},
-  {FLAGS_BOTS,  'b'},
-  {FLAGS_CCONN, 'c'},
-  {FLAGS_NCTCP, 'C'},
-  {FLAGS_DEBUG, 'd'},
-  {FLAGS_FULL,  'f'},
-  {FLAGS_INVISIBLE, 'i'},
-  {FLAGS_SKILL, 'k'},
-  {FLAGS_IMMUNE, 'm'},
-  {FLAGS_NCHANGE, 'n'},
-#ifdef CHANNEL_CREATION_NOTICE
-  {FLAGS_CHCREATE, 'l'},
-#endif
-  {FLAGS_NINVITE, 'I'},
-  {FLAGS_OPER, 'o'},
-  {FLAGS_LOCOP, 'O'},
-#ifdef GODOPERS
-  {FLAGS_GOD,   'p'},
-#endif
-  {FLAGS_REJ, 'r'},
-  {FLAGS_SERVNOTICE, 's'},
-  {FLAGS_WALLOP, 'w'},
-  {FLAGS_EXTERNAL, 'x'},
-  {FLAGS_SPY, 'y'},
-  {FLAGS_OPERWALL, 'z'},
-  {FLAGS_IDENTIFIED, 'e'},
-  {FLAGS_BLOCK_NOTID, 'E'},
-  {0, 0}
-};
-
-/* memory is cheap. map 0-255 to equivalent mode */
-
-static int user_modes_from_c_to_bitmask[] =
-{ 
-  /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x0F */
-  /* 0x10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1F */
-  /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2F */
-  /* 0x30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x3F */
-  0,            /* @ */
-  0,            /* A */
-  0,            /* B */
-  FLAGS_NCTCP,  /* C */
-  0,            /* D */
-  FLAGS_BLOCK_NOTID, /* E */
-  0,            /* F */
-  0,            /* G */
-  0,            /* H */
-  FLAGS_NINVITE, /* I */
-  0,            /* J */
-  0,            /* K */
-  0,            /* L */
-  0,            /* M */
-  0,            /* N */
-  FLAGS_LOCOP,  /* O */
-  0,            /* P */
-  0,            /* Q */
-  0,            /* R */
-  0,            /* S */
-  0,            /* T */
-  0,            /* U */
-  0,            /* V */
-  0,            /* W */
-  0,            /* X */
-  0,            /* Y */
-  0,            /* Z 0x5A */
-  0, 0, 0, 0, 0, /* 0x5F */ 
-  /* 0x60 */       0,
-  FLAGS_AUSPEX, /* a */
-  FLAGS_BOTS,   /* b */
-  FLAGS_CCONN,  /* c */
-  FLAGS_DEBUG,  /* d */
-  FLAGS_IDENTIFIED, /* e */
-  FLAGS_FULL,   /* f */
-  0,            /* g */
-  0,            /* h */
-  FLAGS_INVISIBLE, /* i */
-  0,            /* j */
-  FLAGS_SKILL,  /* k */
-#ifdef CHANNEL_CREATION_NOTICE
-  FLAGS_CHCREATE, /* l */
-#else
-  0,		/* l */
-#endif
-  FLAGS_IMMUNE, /* m */
-  FLAGS_NCHANGE, /* n */
-  FLAGS_OPER,   /* o */
-#ifdef GODOPERS
-  FLAGS_GOD,    /* p */
-#else
-  0,            /* p */
-#endif
-  0,            /* q */
-  FLAGS_REJ,    /* r */
-  FLAGS_SERVNOTICE, /* s */
-  0,            /* t */
-  0,            /* u */
-  0,            /* v */
-  FLAGS_WALLOP, /* w */
-  FLAGS_EXTERNAL, /* x */
-  FLAGS_SPY,    /* y */
-  FLAGS_OPERWALL, /* z 0x7A */
-  0,0,0,0,0,     /* 0x7B - 0x7F */
-
-  /* 0x80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9F */
-  /* 0x90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9F */
-  /* 0xA0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xAF */
-  /* 0xB0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xBF */
-  /* 0xC0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xCF */
-  /* 0xD0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xDF */
-  /* 0xE0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xEF */
-  /* 0xF0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 0xFF */
-};
+int user_modes_from_c_to_bitmask[256];
 
 /* internally defined functions */
 #ifdef BOTCHECK
@@ -226,13 +112,12 @@
   for(cptr2 = oper_cptr_list; cptr2; cptr2 = cptr2->next_oper_client)
     {
       ++j;
-      if (MyClient(cptr) && IsAnOper(cptr))
+      if (MyClient(cptr) && SeesOpers(cptr))
         {
           sendto_one(cptr, ":%s %d %s :[%c][%s] %s (%s@%s) Idle: %d",
                      me.name, RPL_STATSDEBUG, cptr->name,
-                     IsOper(cptr2) ? 'O' : 'o',
-                     oper_privs_as_string(cptr2,
-                                          cptr2->confs->value.aconf->port),
+                     IsLocOp(cptr2) ? 'o' : 'O',
+                     oper_flags_as_string(cptr2->confs->value.aconf->allowed_umodes),
                      cptr2->name,
                      cptr2->username, cptr2->host,
                      CurrentTime - cptr2->user->last);
@@ -241,7 +126,7 @@
         {
           sendto_one(cptr, ":%s %d %s :[%c] %s (%s@%s) Idle: %d",
                      me.name, RPL_STATSDEBUG, cptr->name,
-                     IsOper(cptr2) ? 'O' : 'o',
+                     IsLocOp(cptr2) ? 'o' : 'O',
                      cptr2->name,
                      cptr2->username, cptr2->host,
                      CurrentTime - cptr2->user->last);
@@ -269,7 +154,7 @@
 #endif
 
 /*  forced = (parc >= 2); */
-  forced = (IsAnOper(sptr) && (parc > 3));
+  forced = (CanForceLusers(sptr) && (parc > 3));
 
 /* (void)collapse(parv[1]); */
 
@@ -341,42 +226,42 @@
         {
           if (m_server != Count.myserver)
             {
-              sendto_realops_flags(FLAGS_DEBUG, 
-                                 "Local server count off by %d",
-                                 Count.myserver - m_server);
+              sendto_realops_flag(UMODE_DEBUG,
+                                  "Local server count off by %d ",
+				  Count.myserver - m_server);
               Count.myserver = m_server;
             }
           if (s_count != Count.server)
             {
-              sendto_realops_flags(FLAGS_DEBUG,
-                                 "Server count off by %d",
-                                 Count.server - s_count);
+              sendto_realops_flag(UMODE_DEBUG,
+				  "Server count off by %d",
+				  Count.server - s_count);
               Count.server = s_count;
             }
           if (i_count != Count.invisi)
             {
-              sendto_realops_flags(FLAGS_DEBUG,
-                                 "Invisible client count off by %d",
-                                 Count.invisi - i_count);
+              sendto_realops_flag(UMODE_DEBUG,
+				  "Invisible client count off by %d",
+				  Count.invisi - i_count);
               Count.invisi = i_count;
             }
           if ((c_count+i_count) != Count.total)
             {
-              sendto_realops_flags(FLAGS_DEBUG, "Total client count off by %d",
-                                 Count.total - (c_count+i_count));
+              sendto_realops_flag(UMODE_DEBUG, "Total client count off by %d",
+				  Count.total - (c_count+i_count));
               Count.total = c_count+i_count;
             }
           if (m_client != Count.local)
             {
-              sendto_realops_flags(FLAGS_DEBUG,
-                                 "Local client count off by %d",
-                                 Count.local - m_client);
+              sendto_realops_flag(UMODE_DEBUG,
+				  "Local client count off by %d",
+				  Count.local - m_client);
               Count.local = m_client;
             }
           if (o_count != Count.oper)
             {
-              sendto_realops_flags(FLAGS_DEBUG,
-                                 "Oper count off by %d", Count.oper - o_count);
+              sendto_realops_flag(UMODE_DEBUG,
+				  "Oper count off by %d", Count.oper - o_count);
               Count.oper = o_count;
             }
           Count.unknown = u_count;
@@ -392,7 +277,7 @@
 #endif
   
 #ifndef SHOW_INVISIBLE_LUSERS
-  if (IsAnOper(sptr) && i_count)
+  if (SeesAllConnections(sptr) && i_count)
 #endif
     sendto_one(sptr, form_str(RPL_LUSERCLIENT), me.name, parv[0],
                c_count, i_count, s_count);
@@ -596,10 +481,10 @@
 
         case I_LINE_FULL:
         case I_LINE_FULL2:
-          sendto_realops_flags(FLAGS_FULL, "%s for %s (%s).",
-                               "I-line is full",
-                               get_client_host(sptr),
-                               inetntoa((char*) &sptr->ip));
+          sendto_realops_flag(UMODE_FULL, "%s for %s (%s).",
+			      "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, 
@@ -624,14 +509,14 @@
               ServerStats->is_ref++;
 	/* jdc - lists server name & port connections are on */
 	/*       a purely cosmetical change */
-              sendto_realops_flags(FLAGS_CCONN,
-				 "%s from %s [%s] on [%s/%u].",
-                                 "Unauthorized client connection",
-                                 get_client_host(sptr),
-                                 inetntoa((char *)&sptr->ip),
-				 sptr->listener->name,
-				 sptr->listener->port
-				 );
+              sendto_realops_flag(UMODE_CCONN,
+				  "%s from %s [%s] on [%s/%u].",
+				  "Unauthorized client connection",
+				  get_client_host(sptr),
+				  inetntoa((char *)&sptr->ip),
+				  sptr->listener->name,
+				  sptr->listener->port
+				  );
               log(L_INFO,
 		  "Unauthorized client connection from %s on [%s/%u].",
                   get_client_host(sptr),
@@ -741,7 +626,7 @@
           ((Count.local + 1) >= (MAXCLIENTS+MAX_BUFFER))) ||
             (((Count.local +1) >= (MAXCLIENTS - 5)) && !(IsFlined(sptr))))
         {
-          sendto_realops_flags(FLAGS_FULL,
+          sendto_realops_flag(UMODE_FULL,
                                "Too many clients, rejecting %s[%s].",
                                nick, sptr->host);
           ServerStats->is_ref++;
@@ -754,16 +639,16 @@
         {
           if(IsBlined(sptr))
             {
-              sendto_ops_flags_butone(NULL, FLAGS_BOTS,
-                                 "Possible %s: %s (%s@%s) [B-lined]",
-                                 type_of_bot[sptr->isbot],
-                                 sptr->name, sptr->username, sptr->host);
+              sendto_ops_flag_butone(NULL, UMODE_BOTS,
+				     "Possible %s: %s (%s@%s) [B-lined]",
+				     type_of_bot[sptr->isbot],
+				     sptr->name, sptr->username, sptr->host);
             }
           else
             {
-              sendto_realops_flags(FLAGS_BOTS, "Rejecting %s: %s",
-                                 type_of_bot[sptr->isbot],
-                                 get_client_name(sptr,FALSE));
+              sendto_realops_flag(UMODE_BOTS, "Rejecting %s: %s",
+				  type_of_bot[sptr->isbot],
+				  get_client_name(sptr,FALSE));
               ServerStats->is_ref++;
               return exit_client(cptr, sptr, sptr, type_of_bot[sptr->isbot] );
             }
@@ -775,15 +660,15 @@
 
       if (!valid_username(sptr->username))
         {
-          sendto_realops_flags(FLAGS_REJ,"Invalid username: %s (%s@%s)",
-                             nick, sptr->username, sptr->host);
+          sendto_realops_flag(UMODE_REJ,"Invalid username: %s (%s@%s)",
+			      nick, sptr->username, sptr->host);
           ServerStats->is_ref++;
           ircsprintf(tmpstr2, "Invalid username [%s]", sptr->username);
           return exit_client(cptr, sptr, &me, tmpstr2);
         }
       /* end of valid user name check */
 
-      if(!IsAnOper(sptr))
+      if(!CannotBeXlined(sptr))
         {
           char *reason;
 
@@ -798,29 +683,29 @@
                 {
                   if (aconf->port == 1)
                     {
-                      sendto_realops_flags(FLAGS_REJ,
-                                           "X-line Rejecting [%s] [%s], user %s",
-                                           sptr->info,
-                                           reason,
-                                           get_client_name(cptr, FALSE));
+                      sendto_realops_flag(UMODE_REJ,
+					  "X-line Rejecting [%s] [%s], user %s",
+					  sptr->info,
+					  reason,
+					  get_client_name(cptr, FALSE));
                     }
                   ServerStats->is_ref++;      
                   return exit_client(cptr, sptr, &me, "Bad user info");
                 }
               else
-                sendto_ops_flags_butone(NULL, FLAGS_REJ,
-                                   "X-line Warning [%s] [%s], user %s",
-                                   sptr->info,
-                                   reason,
-                                   get_client_name(cptr, FALSE));
+                sendto_ops_flag_butone(NULL, UMODE_REJ,
+				       "X-line Warning [%s] [%s], user %s",
+				       sptr->info,
+				       reason,
+				       get_client_name(cptr, FALSE));
             }
          }
 
-      sendto_ops_flags_butone(NULL, FLAGS_CCONN,
-                         "Client connecting: %s (%s@%s) [%s] {%d} [%s]",
-                         nick, sptr->username, sptr->host,
-                         inetntoa((char *)&sptr->ip),
-                         get_client_class(sptr), me.name);
+      sendto_ops_flag_butone(NULL, UMODE_CCONN,
+			     "Client connecting: %s (%s@%s) [%s] {%d} [%s]",
+			     nick, sptr->username, sptr->host,
+			     inetntoa((char *)&sptr->ip),
+			     get_client_class(sptr), me.name);
 
       if ((++Count.local) > Count.max_loc)
         {
@@ -848,18 +733,18 @@
   add_client_to_llist(&(sptr->servptr->serv->users), sptr);
 
   if (MyConnect(sptr) && (sptr->username[0] == '~' || isdigit(sptr->host[0])))
-    sendto_ops_flags_butone(NULL, FLAGS_CCONN,
-                            "Auth warning on %s (%s@%s) %s%s",
-                            sptr->name, sptr->username, sptr->host,
-                            (sptr->username[0] == '~') ? "[ident fail] " : "",
-                            (isdigit(sptr->host[0])) ? "[dns fail] " : "");
+    sendto_ops_flag_butone(NULL, UMODE_CCONN,
+			   "Auth warning on %s (%s@%s) %s%s",
+			   sptr->name, sptr->username, sptr->host,
+			   (sptr->username[0] == '~') ? "[ident fail] " : "",
+			   (isdigit(sptr->host[0])) ? "[dns fail] " : "");
 /* Increment our total user count here */
   if (++Count.total > Count.max_tot)
     {
       Count.max_tot = Count.total;
       if ( (!(Count.max_tot % 2)) && (record_time < CurrentTime - 30) )
         {
-          sendto_ops_flags(FLAGS_SERVNOTICE, "New network record: %d users (%d local)", Count.max_tot, Count.max_loc);
+          sendto_ops_flag(UMODE_SERVNOTICE, "New network record: %d users (%d local)", Count.max_tot, Count.max_loc);
           record_time = CurrentTime;
       }
     }
@@ -935,11 +820,11 @@
       aClient *acptr;
       if ((acptr = find_server(user->server)) && acptr->from != sptr->from)
         {
-          sendto_realops_flags(FLAGS_DEBUG, 
-                             "Bad User [%s] :%s USER %s@%s %s, != %s[%s]",
-                             cptr->name, nick, sptr->username,
-                             sptr->host, user->server,
-                             acptr->name, acptr->from->name);
+          sendto_realops_flag(UMODE_DEBUG, 
+			      "Bad User [%s] :%s USER %s@%s %s, != %s[%s]",
+			      cptr->name, nick, sptr->username,
+			      sptr->host, user->server,
+			      acptr->name, acptr->from->name);
           sendto_one(cptr,
                      ":%s KILL %s :%s (%s != %s[%s] USER from wrong direction)",
                      me.name, sptr->name, me.name, user->server,
@@ -968,7 +853,7 @@
         }
     }
 
-  send_umode(NULL, sptr, 0, SEND_UMODES, ubuf);
+  send_umode(NULL, sptr, 0, send_umodes, ubuf);
   if (!*ubuf)
     {
       ubuf[0] = '+';
@@ -1215,7 +1100,8 @@
                  char *parv[], time_t newts,char *nick)
 {
   Link* channels;
-  int setflags = sptr->umodes;
+  umode_t setflags;
+  CopyUmodes(setflags, sptr->umodes);
 
   if (IsServer(sptr))
     {
@@ -1247,15 +1133,16 @@
           while (*m)
             {
               flag = user_modes_from_c_to_bitmask[(unsigned char)*m];
-              if( flag & FLAGS_INVISIBLE )
+              if( flag == UMODE_INVISIBLE )
                 {
                   Count.invisi++;
                 }
-              if( flag & FLAGS_OPER )
+              if( flag == UMODE_OPER )
                 {
                   Count.oper++;
                 }
-              sptr->umodes |= flag & SEND_UMODES;
+	      if (TestBit(send_umodes, flag))
+		SetBit(sptr->umodes, flag);
               m++;
             }
           
@@ -1298,10 +1185,10 @@
           if(sptr->number_of_nick_changes <= MAX_NICK_CHANGES)
             {
 #endif
-              sendto_realops_flags(FLAGS_NCHANGE,
-                                 "Nick change: From %s to %s [%s@%s]",
-                                 parv[0], nick, sptr->username,
-                                 sptr->host);
+              sendto_realops_flag(UMODE_NCHANGE,
+				  "Nick change: From %s to %s [%s@%s]",
+				  parv[0], nick, sptr->username,
+				  sptr->host);
 
               ClearIdentifiedNick(sptr);
               send_umode_out(cptr, sptr, setflags);
@@ -1323,8 +1210,8 @@
                          me.name,
                          sptr->name,
                          MAX_NICK_TIME);
-              sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Flooder %s [%s@%s] on %s (nick)",
-                                      sptr->name, sptr->username, sptr->host, me.name);
+              sendto_ops_flag_butone(NULL, UMODE_BOTS, "Flooder %s [%s@%s] on %s (nick)",
+				     sptr->name, sptr->username, sptr->host, me.name);
 
               return 0;
             }
@@ -1340,16 +1227,17 @@
               add_history(sptr,1);
               sendto_serv_butone(cptr, ":%s NICK %s :%lu",
                                  parv[0], nick, sptr->tsinfo);
-              sendto_realops_flags(FLAGS_NCHANGE,
-                                 "Nick change: From %s to %s [%s@%s]",
-                                 parv[0], nick, sptr->username,
-                                 sptr->host);
+              sendto_realops_flag(UMODE_NCHANGE,
+				  "Nick change: From %s to %s [%s@%s]",
+				  parv[0], nick, sptr->username,
+				  sptr->host);
             }
         }
     }
   else
     {
       /* Client setting NICK the first time */
+      CopyUmodes(sptr->allowed_umodes, user_umodes);
       
 
       /* This had to be copied here to avoid problems.. */
@@ -1485,9 +1373,9 @@
       if (IsServer(cptr))
         {
           ServerStats->is_kill++;
-          sendto_realops_flags(FLAGS_DEBUG, "Bad Nick: %s From: %s %s",
-                             parv[1], parv[0],
-                             get_client_name(cptr, FALSE));
+          sendto_realops_flag(UMODE_DEBUG, "Bad Nick: %s From: %s %s",
+			      parv[1], parv[0],
+			      get_client_name(cptr, FALSE));
           sendto_one(cptr, ":%s KILL %s :%s (%s <- %s[%s])",
                      me.name, parv[1], me.name, parv[1],
                      nick, cptr->name);
@@ -1506,18 +1394,18 @@
             }
         }
       else
-        sendto_ops_flags_butone(NULL, FLAGS_BOTS, "Illegal nick \"%s\" from: %s %s",
-                                parv[1], parv[0],
-                                get_client_name(cptr, FALSE));
+        sendto_ops_flag_butone(NULL, UMODE_BOTS, "Illegal nick \"%s\" from: %s %s",
+			       parv[1], parv[0],
+			       get_client_name(cptr, FALSE));
       return 0;
     }
 
-  if(MyConnect(sptr) && !IsServer(sptr) && !IsAnOper(sptr) &&
+  if(MyConnect(sptr) && !IsServer(sptr) && !CannotBeQlined(sptr) &&
      find_q_line(nick, sptr->username, sptr->host)) 
     {
-      sendto_realops_flags(FLAGS_REJ,
-                         "Quarantined nick [%s] from user %s",
-                         nick,get_client_name(cptr, FALSE));
+      sendto_realops_flag(UMODE_REJ,
+			  "Quarantined nick [%s] from user %s",
+			  nick,get_client_name(cptr, FALSE));
       sendto_one(sptr, form_str(ERR_ERRONEUSNICKNAME),
                  me.name, parv[0], parv[1]);
       return 0;
@@ -2053,15 +1941,7 @@
       sptr->flags |= FLAGS_INVISIBLE;
 #endif
 
-#if 0
-      /* Undocumented lame extension to the protocol
-       * if user provides a number, the bits set are
-       * used to set the umode flags. arghhhhh -db
-       */
-      sptr->flags |= (UFLAGS & atoi(host));
-#endif
-
-      if (!(oflags & FLAGS_INVISIBLE) && IsInvisible(sptr))
+      if (IsInvisible(sptr))
         Count.invisi++;
       /*
        * don't take the clients word for it, ever
@@ -2100,11 +1980,12 @@
   int   i;
   char  **p, *m;
   aClient *acptr;
-  int   what, setflags;
+  int   what;
   char  *m2;
   int   ircophack, restrictedmodes;
   int   badflag = NO;   /* Only send one bad flag notice -Dianora */
   char  buf[BUFSIZE];
+  umode_t bad_umodes, old_umodes;
 
   what = MODE_ADD;
   ircophack = 0;
@@ -2127,7 +2008,7 @@
 
   if (IsServer(sptr) || sptr != acptr || acptr->from != sptr->from)
     {
-      if (sptr != acptr && IsGodOper(sptr))
+      if (sptr != acptr && CanChangeModes(sptr))
         {
           ircophack = 1;
           
@@ -2138,31 +2019,50 @@
                 for (p = &parv[2]; p && *p; p++ )
                   {
                     for (m = *p, m2 = *p; *m; m++)
-                      switch(user_modes_from_c_to_bitmask[(unsigned char)*m])
-                        {
-			  case FLAGS_NCHANGE:
-                            if (IsSetOperN(sptr))
-                              *(m2++) = *m;
-                            break;
-                          case FLAGS_IMMUNE:
-                            if (IsSetOperM(sptr))
-                              *(m2++) = *m;
-                            break;
-#ifdef GODOPERS
-			  case FLAGS_GOD:
-			    if (IsSetOperGod(sptr))
-			      *(m2++) = *m;
-			    break;
-#endif
-			  case FLAGS_AUSPEX:
-                            if (IsSetOperAuspex(sptr))
-                              *(m2++) = *m;
-                            break;
-                          default:
-                            *(m2++) = *m;
-                            break;
-                        }
-                    *m2 = 0;
+		      switch(*m)
+			{
+			case '+':
+			  what = MODE_ADD;
+			  break;
+			case '-' :
+			  what = MODE_DEL;
+			  break;
+			default:
+			  if (CanGrantModes(sptr))
+			    {
+			      if ((what == MODE_ADD)
+				  && TestBit(sptr->allowed_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]))
+				{
+				  *(m2++) = *m; /* remove the umodes the originators's O:line doesn't allow them to have */
+				  /* But add them to the target's allowed umodes */
+				  SetBit(acptr->allowed_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]);
+				}
+			      else if ((what == MODE_DEL) && !IsAnOper(acptr))
+				{
+				  /* If they are not an operator, remove that umode from their allowed_umodes 
+				   *  if it is not in user_umodes
+				   */
+				  if (!TestBit(user_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]))
+				    ClearBit(acptr->allowed_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]);
+				}
+			    }
+			  else
+			    {
+			      if ((what == MODE_ADD) &&
+				  TestBit(acptr->allowed_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]))
+				*(m2++) = *m; /* remove the umodes the target's O:line doesn't allow them to have */
+			      else if ((what == MODE_DEL) && !IsAnOper(acptr))
+				{
+				  /* If they are not an operator, remove that umode from their allowed_umodes 
+				   *  if it is not in user_umodes
+				   */
+				  if (!TestBit(user_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]))
+				    ClearBit(acptr->allowed_umodes, user_modes_from_c_to_bitmask[(unsigned char)*m]);
+				}
+			    }
+			  break;
+			}
+		    *m2 = 0;
                   }
               sendto_one(acptr->from, ":%s MODE %s %s", sptr->name,
                          acptr->name, ((parc < 3) ? "" : parv[2]));
@@ -2170,10 +2070,10 @@
             }
         }
       else if (IsServer(cptr))
-        sendto_ops_butone(NULL, &me,
-                          ":%s WALLOPS :MODE for User %s From %s!%s",
-                          me.name, parv[1],
-                          get_client_name(cptr, FALSE), sptr->name);
+        sendto_ops_flag_butone(NULL, UMODE_SERVNOTICE,
+			       "%s issuing MODE for User %s From %s!%s",
+			       me.name, parv[1],
+			       get_client_name(cptr, FALSE), sptr->name);
       else
         sendto_one(sptr, form_str(ERR_USERSDONTMATCH),
                    me.name, parv[0]);
@@ -2181,14 +2081,14 @@
       if (!ircophack)
         return 0;
     }
- 
+
   if (parc < 3)
     {
       m = buf;
       *m++ = '+';
 
       for (i = 0; user_modes[i].letter && (m - buf < BUFSIZE - 4);i++)
-        if (acptr->umodes & user_modes[i].mode)
+        if (TestBit(acptr->umodes, user_modes[i].mode))
           *m++ = user_modes[i].letter;
       *m = '\0';
 
@@ -2201,201 +2101,162 @@
       return 0;
     }
 
-  /* find flags already set for user */
-  setflags = acptr->umodes;
-  
+  CopyUmodes(old_umodes, acptr->umodes);
+
   /*
    * parse mode change string(s)
    */
   for (p = &parv[2]; p && *p; p++ )
     for (m = *p; *m; m++)
-      switch(*m)
-        {
-        case '+' :
-          what = MODE_ADD;
-          break;
-        case '-' :
-          what = MODE_DEL;
-          break;        
-
-        case 'O': case 'o' :
-          if(what == MODE_ADD)
-            {
-              if((IsServer(cptr) || ircophack) && !IsOper(acptr))
-                {
-                  ++Count.oper;
-                  SetOper(acptr);
-
-                  if (ircophack && MyClient(acptr))
-                    {
-                      sendto_ops_flags_butone(sptr, FLAGS_SERVNOTICE,
-                        "%s just made %s (%s@%s) an operator",
-                        sptr->name, acptr->name,
-                        acptr->username, acptr->host);
-
-                      acptr->next_oper_client = oper_cptr_list;
-                      oper_cptr_list = acptr;
-
-                      sendto_one(acptr, form_str(RPL_YOUREOPER), me.name,
-                                 acptr->name);
-
-                      SendMessageFile(acptr, &ConfigFileEntry.opermotd);
-                    }
-                }
-            }
-          else
-            {
-	      /* Only decrement the oper counts if an oper to begin with
-               * found by Pat Szuta, Perly , perly@xnet.com 
-               */
-
-              if(!IsAnOper(acptr))
-                break;
-
-              acptr->umodes &= ~(FLAGS_OPER|FLAGS_LOCOP);
-
-              Count.oper--;
-
-#ifdef USE_USER_UMODES 
-	      acptr->umodes &= USER_UMODES | ~ALL_UMODES;
-#endif
-              if (MyConnect(acptr))
-                {
-                  aClient *prev_cptr = (aClient *)NULL;
-                  aClient *cur_cptr = oper_cptr_list;
-
-                  fdlist_delete(acptr->fd, FDL_OPER | FDL_BUSY);
-                  if (acptr->confs->value.aconf->status &
-                      (CONF_OPERATOR|CONF_LOCOP))
-                    detach_conf(acptr,acptr->confs->value.aconf);
-                  acptr->flags2 &= ~(FLAGS2_OPER_GLOBAL_KILL|
-                                    FLAGS2_OPER_REMOTE|
-                                    FLAGS2_OPER_UNKLINE|
-                                    FLAGS2_OPER_GLINE|
-                                    FLAGS2_OPER_N|
-#ifdef GODOPERS
-  			            FLAGS2_OPER_GOD|
-#endif
-                                    FLAGS2_OPER_K|
-                                    FLAGS2_OPER_IMMUNE|
-                                    FLAGS2_OPER_AUSPEX);
-                  while(cur_cptr)
-                    {
-                      if(acptr == cur_cptr) 
-                        {
-                          if(prev_cptr)
-                            prev_cptr->next_oper_client = cur_cptr->next_oper_client;
-                          else
-                            oper_cptr_list = cur_cptr->next_oper_client;
-                          cur_cptr->next_oper_client = (aClient *)NULL;
-                          break;
-                        }
-                      else
-                        prev_cptr = cur_cptr;
-                      cur_cptr = cur_cptr->next_oper_client;
-                    }
-                }
-            }
-          break;
-	case 'e' :
-          if(!IsServer(cptr))
-            break;
-
-          SetIdentifiedNick(sptr);
-          break;
-
-          /* we may not get these,
-           * but they shouldnt be in default
-           */
-        case ' ' :
-        case '\n' :
-        case '\r' :
-        case '\t' :
-          break;
-        default :
-          if( (flag = user_modes_from_c_to_bitmask[(unsigned char)*m]))
-            {
-              if (what == MODE_ADD)
-                acptr->umodes |= flag;
-              else
-                acptr->umodes &= ~flag;  
-            }
-          else
-            {
-              if ( MyConnect(sptr))
-                badflag = YES;
-            }
-          break;
-        }
+      {
+	switch(*m)
+	  {
+	  case '+' :
+	    what = MODE_ADD;
+	    break;
+	  case '-' :
+	    what = MODE_DEL;
+	    break;        
+
+	  case 'O': case 'o' :
+	    if(what == MODE_ADD)
+	      {
+		/* I'm going to disable this for now, we do things differently
+		 *  --asuffield
+		 */
+		break;
+
+		if((IsServer(cptr) || ircophack) && !IsOper(acptr))
+		  {
+		    ++Count.oper;
+		    SetOper(acptr);
+		    SetBit(acptr->allowed_umodes, UMODE_OPER);
+
+		    if (ircophack && MyClient(acptr))
+		      {
+			sendto_ops_flag_butone(sptr, UMODE_SERVNOTICE,
+					       "%s just made %s (%s@%s) an operator",
+					       sptr->name, acptr->name,
+					       acptr->username, acptr->host);
+
+			acptr->next_oper_client = oper_cptr_list;
+			oper_cptr_list = acptr;
+
+			sendto_one(acptr, form_str(RPL_YOUREOPER), me.name,
+				   acptr->name);
+
+			SendMessageFile(acptr, &ConfigFileEntry.opermotd);
+		      }
+		  }
+	      }
+	    else
+	      {
+		/* Only decrement the oper counts if an oper to begin with
+		 * found by Pat Szuta, Perly , perly@xnet.com 
+		 */
+
+		if(!IsAnOper(acptr))
+		  break;
+
+		ClearBit(acptr->umodes, UMODE_OPER);
+		ClearBit(acptr->umodes, UMODE_LOCOP);
+
+		Count.oper--;
+
+		CopyUmodes(acptr->allowed_umodes, user_umodes);
+		AndUmodes(acptr->umodes, acptr->umodes, acptr->allowed_umodes);
+
+		if (MyConnect(acptr))
+		  {
+		    aClient *prev_cptr = (aClient *)NULL;
+		    aClient *cur_cptr = oper_cptr_list;
+
+		    fdlist_delete(acptr->fd, FDL_OPER | FDL_BUSY);
+		    if (acptr->confs->value.aconf->status &
+			(CONF_OPERATOR|CONF_LOCOP))
+		      detach_conf(acptr,acptr->confs->value.aconf);
+		    while(cur_cptr)
+		      {
+			if(acptr == cur_cptr) 
+			  {
+			    if(prev_cptr)
+			      prev_cptr->next_oper_client = cur_cptr->next_oper_client;
+			    else
+			      oper_cptr_list = cur_cptr->next_oper_client;
+			    cur_cptr->next_oper_client = (aClient *)NULL;
+			    break;
+			  }
+			else
+			  prev_cptr = cur_cptr;
+			cur_cptr = cur_cptr->next_oper_client;
+		      }
+		  }
+	      }
+	    break;
+	    /* This needs no magic. -- asuffield
+	      case 'e' :
+	      if(!IsServer(cptr))
+	      break;
+	      
+	      SetIdentifiedNick(sptr);
+	      break; */
+
+	    /* we may not get these,
+	     * but they shouldnt be in default
+	     */
+	  case ' ' :
+	  case '\n' :
+	  case '\r' :
+	  case '\t' :
+	    break;
+	  default :
+	    if((flag = user_modes_from_c_to_bitmask[(unsigned char)*m]))
+	      {
+		if ((flag == UMODE_OPER) || (flag == UMODE_LOCOP))
+		  break;
+		if (what == MODE_ADD)
+		  SetBit(acptr->umodes, flag);
+		else
+		  ClearBit(acptr->umodes, flag);
+	      }
+	    else
+	      {
+		if (MyConnect(sptr))
+		  badflag = YES;
+	      }
+	    break;
+	  }
+      }
 
-#ifdef USE_USER_UMODES
-  /* Use ALL_UMODES to make sure we don't mess with special server flags. 
-   * And (acptr->umodes ~setflags) to prevent umodes set by an oper from
-   * being removed */
-  if (((acptr->umodes & ~setflags) & ALL_UMODES & ~USER_UMODES) && !IsAnOper(sptr))
-    {
-      acptr->umodes &= USER_UMODES | ~ALL_UMODES;
-      badflag = YES;
+  /* Find which ones shouldn't have been set, and unset them (and warn) */
+  AndNotUmodes(bad_umodes, acptr->umodes, acptr->allowed_umodes);
+  if (AnyBits(bad_umodes))
+    {
+      AndUmodes(acptr->umodes, acptr->umodes, acptr->allowed_umodes);
+      if (SeesOperMessages(sptr))
+	sendto_one(sptr, ":%s NOTICE %s :*** The privilege(s) +%s is not granted", me.name, parv[0],
+		   oper_flags_as_string(bad_umodes));
+      else
+	badflag = YES;
     }
-#endif
 
   if(badflag)
-    sendto_one(sptr, form_str(ERR_UMODEUNKNOWNFLAG), me.name, parv[0]);
-
-#ifdef CHANNEL_CREATION_NOTICE
-  if (acptr->umodes & FLAGS_CHCREATE && !IsSetOperChanCreate(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :*** You need oper and L flag for +l",
-                     me.name,parv[0]);
-      acptr->umodes &= ~FLAGS_CHCREATE;
-    }
-#endif /* CHANNEL_CREATION_NOTICE */
-
-  if ((acptr->umodes & FLAGS_NCHANGE) && !IsSetOperN(sptr))
     {
-      sendto_one(sptr,":%s NOTICE %s :*** You need oper and N flag for +n",
-                 me.name,parv[0]);
-      acptr->umodes &= ~FLAGS_NCHANGE; /* only tcm's really need this */
+      sendto_one(sptr, form_str(ERR_UMODEUNKNOWNFLAG), me.name, parv[0]);
     }
 
-
-  if ((acptr->umodes & FLAGS_IMMUNE) && !IsSetOperM(sptr) && MyClient(sptr) && !IsServer(cptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :*** You need oper and M flag for +m",
-                 me.name,parv[0]);
-      acptr->umodes &= ~FLAGS_IMMUNE; /* only services really need this,
-                                        though it could be useful for
-                                        opers once in a while */
-    }
-
-  if ((acptr->umodes & FLAGS_AUSPEX) && !IsSetOperAuspex(sptr) && MyClient(sptr) && !IsServer(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :*** You need oper and A flag for +a",
-		 me.name,parv[0]);
-      acptr->umodes &= ~FLAGS_AUSPEX;
-    }
-
-#ifdef GODOPERS
-  if ((acptr->umodes & FLAGS_GOD) && !IsSetOperGod(sptr) && MyClient(sptr) && !IsServer(sptr))
-    {
-      sendto_one(sptr,":%s NOTICE %s :*** You need oper and P flag for +p",
-		 me.name,parv[0]);
-      acptr->umodes &= ~FLAGS_GOD;
-    }
-#endif
-
-  if (!(setflags & FLAGS_INVISIBLE) && IsInvisible(acptr))
+  if (!TestBit(old_umodes, UMODE_INVISIBLE) && IsInvisible(acptr))
     ++Count.invisi;
-  if ((setflags & FLAGS_INVISIBLE) && !IsInvisible(acptr))
+  if (TestBit(old_umodes, UMODE_INVISIBLE) && !IsInvisible(acptr))
     --Count.invisi;
   /*
    * compare new flags with old flags and send string which
    * will cause servers to update correctly.
    */
   if(ircophack)
-    send_umode_out_oper(cptr, sptr, setflags, acptr);
+    send_umode_out_oper(cptr, sptr, old_umodes, acptr);
   else
-    send_umode_out(cptr, sptr, setflags);
+    send_umode_out(cptr, sptr, old_umodes);
 
   return 0;
 }
@@ -2405,7 +2266,7 @@
  * send the MODE string for user (user) to connection cptr
  * -avalon
  */
-void send_umode(aClient *cptr, aClient *sptr, int old, int sendmask,
+void send_umode(aClient *cptr, aClient *sptr, umode_t old, umode_t sendmask,
                 char *umode_buf)
 {
   int   i;
@@ -2423,10 +2284,10 @@
   for (i = 0; user_modes[i].letter; i++ )
     {
       flag = user_modes[i].mode;
-
-      if (MyClient(sptr) && !(flag & sendmask))
+      
+      if (MyClient(sptr) && !TestBit(sendmask,flag))
         continue;
-      if ((flag & old) && !(sptr->umodes & flag))
+      if (old && TestBit(old,flag) && !TestBit(sptr->umodes,flag))
         {
           if (what == MODE_DEL)
             *m++ = user_modes[i].letter;
@@ -2437,7 +2298,7 @@
               *m++ = user_modes[i].letter;
             }
         }
-      else if (!(flag & old) && (sptr->umodes & flag))
+      else if ((!old || !TestBit(old,flag)) && TestBit(sptr->umodes,flag))
         {
           if (what == MODE_ADD)
             *m++ = user_modes[i].letter;
@@ -2465,25 +2326,25 @@
  * server -Dianora
  */
 void send_umode_out(aClient *cptr,
-                       aClient *sptr,
-                       int old)
+		    aClient *sptr,
+                    umode_t old)
 {
   aClient *acptr;
   char buf[BUFSIZE];
 
-  send_umode(NULL, sptr, old, SEND_UMODES, buf);
+  send_umode(NULL, sptr, old, send_umodes, buf);
 
   for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client)
     {
       if((acptr != cptr) && (acptr != sptr) && (*buf))
         {
           sendto_one(acptr, ":%s MODE %s :%s",
-                   sptr->name, sptr->name, buf);
+		     sptr->name, sptr->name, buf);
         }
     }
 
   if (cptr && MyClient(cptr))
-    send_umode(cptr, sptr, old, ALL_UMODES, buf);
+    send_umode(cptr, sptr, old, all_umodes, buf);
 }
 
 /*
@@ -2491,13 +2352,13 @@
  */
 void send_umode_out_oper(aClient *cptr,
                          aClient *ircop,
-                         int old,
+                         umode_t old,
                          aClient *sptr)
 {
   aClient *acptr;
   char buf[BUFSIZE];
 
-  send_umode(NULL, sptr, old, ALL_UMODES, buf);
+  send_umode(NULL, sptr, old, all_umodes, buf);
 
   if (*buf)
     for(acptr = serv_cptr_list; acptr; acptr = acptr->next_server_client)
@@ -2509,7 +2370,7 @@
           }
       }
 
-  send_umode(NULL, sptr, old, ALL_UMODES, buf);
+  send_umode(NULL, sptr, old, all_umodes, buf);
 
   if (MyClient(sptr) && *buf)
     sendto_one(sptr, ":%s MODE %s :%s",
@@ -2588,4 +2449,56 @@
     sptr->user->silence = lp;
 
     return 0;
+}
+
+void init_umodes()
+{
+  int i, field, bit;
+  /* Fill out the reverse umode map */
+  for (i = 0; user_modes[i].letter; i++)
+    user_modes_from_c_to_bitmask[(unsigned char)user_modes[i].letter] = user_modes[i].mode;
+  /* Fill out the bitfield map */
+  bit = 1;
+  field = 0;
+  for (i = 0; i < BITFIELD_SIZE; i++)
+    {
+      bitfield_lookup[i].bit = bit;
+      bitfield_lookup[i].field = field;
+      if (bit == 0x80000000)
+	{
+	  field++;
+	  bit = 1;
+	}
+      else
+	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
+ */
+  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
+ */
+  SetBit(user_umodes, UMODE_INVISIBLE);
+  SetBit(user_umodes, UMODE_WALLOP);
+  SetBit(user_umodes, UMODE_NINVITE);
+  SetBit(user_umodes, UMODE_BLOCK_NOTID);
+  SetBit(user_umodes, UMODE_NCTCP);
 }
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	Fri Jun  8 18:03:37 2001
+++ ircd-hybrid-6.0/src/send.c	Fri Jun  8 15:46:10 2001
@@ -965,7 +965,7 @@
  */
 
 void
-sendto_ops_flags(int flags, const char *pattern, ...)
+sendto_ops_flag(int flag, const char *pattern, ...)
 
 {
   va_list args;
@@ -974,11 +974,11 @@
 
   va_start(args, pattern);
 
-  if((flags & FLAGS_SKILL) || (flags & FLAGS_SERVNOTICE))
+  if((flag == UMODE_SKILL) || (flag == UMODE_SERVNOTICE))
     {
       for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client)
         {
-          if(cptr->umodes & flags)
+          if(TestBit(cptr->umodes,flag))
             {
               (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
                                me.name, cptr->name);
@@ -989,15 +989,11 @@
             }
         } /* for(cptr = local_cptr_list; cptr; cptr = cptr->next_local_client) */
     }
-
-  flags &= ~FLAGS_SKILL;
-  flags &= ~FLAGS_SERVNOTICE;
-
-  if(flags)
+  else
     {
       for(cptr = oper_cptr_list; cptr; cptr = cptr->next_oper_client)
         {
-          if(cptr->umodes & flags)
+          if(TestBit(cptr->umodes,flag))
             {
               (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
                                me.name, cptr->name);
@@ -1111,15 +1107,7 @@
     {
       if (!SendWallops(cptr))
         continue;
-#if 0      
-      if (!(IsServer(from) || IsMe(from)) &&
-          MyClient(cptr) && !IsOper(cptr))
-        continue;
 
-      if (MyClient(cptr) && !IsAnOper(cptr) &&
-          !(IsServer(from) || IsMe(from)))
-        continue;
-#endif
       /* find connection oper is on */
       index = cptr->from->fd;
 
@@ -1173,7 +1161,7 @@
 
   for (acptr = oper_cptr_list; acptr; acptr = acptr->next_oper_client)
     {
-      if (!SendOperwall(acptr))
+      if (!ReceiveOperwall(acptr))
         continue; /* has to be oper if in this linklist */
 
       sendto_one(acptr, ":%s WALLOPS :%s - %s", sender, type_message, message);
@@ -1362,7 +1350,7 @@
  */
 
 void
-sendto_realops_flags(int flags, const char *pattern, ...)
+sendto_realops_flag(int flag, const char *pattern, ...)
 
 {
   va_list args;
@@ -1373,7 +1361,7 @@
 
   for (cptr = oper_cptr_list; cptr; cptr = cptr->next_oper_client)
     {
-      if(cptr->umodes & flags)
+      if(TestBit(cptr->umodes,flag))
         {
           (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
                            me.name, cptr->name);
@@ -1506,7 +1494,7 @@
  */
 
 void
-sendto_ops_flags_butone(aClient *one, int flags, const char *pattern, ...)
+sendto_ops_flag_butone(aClient *one, int flag, const char *pattern, ...)
 
 {
   va_list args;
@@ -1515,28 +1503,25 @@
 
   va_start(args, pattern);
 
-  if(flags)
+  for(cptr = local_cptr_list; cptr; cptr = cptr->next)
     {
-      for(cptr = local_cptr_list; cptr; cptr = cptr->next)
-        {
-          if (IsPerson(cptr) && (cptr->umodes & flags))
-            {
-              (void)ircsprintf(nbuf, ":%s NOTICE %s :*** Notice -- ",
-                               me.name, cptr->name);
-              (void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
-              vsendto_one(cptr, nbuf, args);
-            }
-        }
-      (void)ircsprintf(nbuf, ":%s WALLOPS %i :",
-                       me.name, flags);
-      (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);
-        }
+      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);
+	}
+    }
+  (void)ircsprintf(nbuf, ":%s WALLOPS %i :",
+		   me.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);
     }
   va_end(args);
-}  /* sendto_ops_flags */
+}
 
diff -ruN -x configure -x *~ -x ircd-hybrid-6.0.orig -x *.rej ircd-hybrid-6.0.orig/src/whowas.c ircd-hybrid-6.0/src/whowas.c
--- ircd-hybrid-6.0.orig/src/whowas.c	Tue Nov 21 06:49:33 2000
+++ ircd-hybrid-6.0/src/whowas.c	Wed Jun  6 11:23:52 2001
@@ -188,7 +188,7 @@
     if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
       return 0;
 
-  if(!IsAnOper(sptr) && !MyConnect(sptr)) /* pace non local requests */
+  if(!NoFloodProtection(sptr) && !MyConnect(sptr)) /* pace non local requests */
     {
       if((last_used + WHOIS_WAIT) > CurrentTime)
         {
@@ -224,7 +224,7 @@
                      parv[0],
                      temp->name,
 #ifdef SERVERHIDE
-                     IsAnOper(sptr) ? temp->servername : NETWORK_NAME,
+                     IsSetOperAuspex(sptr) ? temp->servername : NETWORK_NAME,
 #else
                      temp->servername,
 #endif
