Author: Kev <klmitch@mit.edu>
authorKevin L. Mitchell <klmitch@mit.edu>
Fri, 8 Dec 2000 20:19:33 +0000 (20:19 +0000)
committerKevin L. Mitchell <klmitch@mit.edu>
Fri, 8 Dec 2000 20:19:33 +0000 (20:19 +0000)
Log message:

Implement a msgq system and switch to it, removing some old dead code in
the process--this includes removing help from Configure.help that no longer
has a corresponding compile-time option, as well as permanently switching
to the new mode implementation.

One of the effects this has is a switch to a priority-queue system, which
should allow wallops to be moved to the head of the sendq.  Lag no longer
becomes an issue for important routing notifications.

Status: stable

Testing needed:

This patch needs to be tested under heavy load.

Testing done:

Compiles and runs with no apparent problems

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@325 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

30 files changed:
ChangeLog
config/config-sh.in
doc/Configure.help
include/client.h
include/msgq.h [new file with mode: 0644]
include/s_user.h
include/send.h
ircd/IPcheck.c
ircd/Makefile.in
ircd/channel.c
ircd/dbuf.c
ircd/ircd_reply.c
ircd/list.c
ircd/listener.c
ircd/m_burst.c
ircd/m_ison.c
ircd/m_mode.c
ircd/m_names.c
ircd/m_settime.c
ircd/m_stats.c
ircd/m_userhost.c
ircd/m_userip.c
ircd/m_version.c
ircd/msgq.c [new file with mode: 0644]
ircd/parse.c
ircd/s_bsd.c
ircd/s_conf.c
ircd/s_debug.c
ircd/s_user.c
ircd/send.c

index e7c50d8626dba7ce601f16660a6168ba655a499b..74ec82a33f8005ff98da5dcb1b1869c9bc3be228 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,124 @@
 2000-12-08  Kevin L. Mitchell  <klmitch@mit.edu>
 
+       * include/send.h: add prio argument to send_buffer to select
+       between normal and priority queues
+
+       * ircd/s_user.c (send_user_info): add prio argument to send_buffer
+       call
+
+       * ircd/m_ison.c (m_ison): add prio argument to send_buffer call
+
+       * ircd/ircd_reply.c (send_reply): add prio argument to send_buffer
+       call
+
+       * ircd/channel.c (send_channel_modes): add prio argument to
+       send_buffer call
+
+       * ircd/send.c (send_buffer): add a prio argument to select the
+       priority queue; update send.c functions to use it
+
+       * ircd/msgq.c (msgq_add): remove msgq_prio; fold msgq_link and
+       msgq_add; add a prio argument to msgq_add to select the priority
+       queue
+
+       * include/msgq.h: remove msgq_prio; add a prio argument to
+       msgq_add
+
+       * ircd/send.c: remove sendbuf; remove GODMODE code; switch to
+       using msgq functions instead of dbuf functions; remove old, dead
+       sendto_* functions; redo send_buffer to take a struct MsgBuf;
+       rework sendcmdto_* functions to make use of the new struct MsgBuf
+
+       * ircd/s_user.c: remove hunt_server; restructure send_user_info to
+       make appropriate use of struct MsgBuf
+
+       * ircd/s_debug.c (count_memory): count memory used by the MsgQ
+       system and report it
+
+       * ircd/s_conf.c (read_configuration_file): use
+       sendto_opmask_butone instead of the now dead sendto_op_mask
+
+       * ircd/s_bsd.c: switch to using appropriate MsgQLength and other
+       calls on sendQ
+
+       * ircd/parse.c (parse_server): get rid of a piece of GODMODE code
+
+       * ircd/msgq.c: add msgq_append and msgq_bufleft; fix a bug in
+       msgq_clean
+
+       * ircd/m_version.c: fix spelling in comments marking dead code
+
+       * ircd/m_userip.c (userip_formatter): restructure to make use of
+       struct MsgBuf
+
+       * ircd/m_userhost.c (userhost_formatter): restructure to make use
+       of struct MsgBuf
+
+       * ircd/m_stats.c: use MsgQLength on a sendQ
+
+       * ircd/m_settime.c: use MsgQLength instead of DBufLength on a
+       sendQ; mark a piece of dead code
+
+       * ircd/m_names.c: use send_reply instead of sendto_one
+
+       * ircd/m_mode.c: use new mode; remove old dead code
+
+       * ircd/m_ison.c (m_ison): restructure to make use of struct MsgBuf
+
+       * ircd/m_burst.c: use BUFSIZE instead of IRC_BUFSIZE; remove old
+       dead code
+
+       * ircd/listener.c (accept_connection): use sendto_opmask_butone
+       instead of sendto_op_mask
+
+       * ircd/list.c (free_client): use MsgQClear to clear sendQ
+
+       * ircd/ircd_reply.c: remove send_error_to_client; restructure
+       send_reply to make use of struct MsgBuf
+
+       * ircd/dbuf.c (dbuf_put): remove argument to flush_sendq_except,
+       since its no longer used (at least currently)
+
+       * ircd/channel.c: restructure send_channel_modes to make use of
+       struct MsgBuf; remove set_mode, add_token_to_sendbuf, cancel_mode,
+       and send_hack_notice; use BUFSIZE instead of IRC_BUFSIZE
+
+       * ircd/Makefile.in: add msgq.c to list of sources; run make depend
+
+       * ircd/IPcheck.c: use sendcmdto_one instead of sendto_one
+
+       * include/send.h: send_buffer now takes a struct MsgBuf * instead
+       of a char *; flush_sendq_except now takes no arguments, as sendq
+       flushing currently only happens in dbuf.h and sendQ is a struct
+       MsgQ; remove prototypes for a lot of old sendto_* functions that
+       aren't used anymore; remove sendbuf and IRC_BUFSIZE--the former is
+       no longer needed, and the latter is identical to BUFSIZE in
+       ircd_defs.h
+
+       * include/s_user.h: make InfoFormatter take a struct MsgBuf*
+       instead of a char *; also make it return void, instead of char *
+
+       * include/msgq.h: add msgq_append and msgq_bufleft functions
+
+       * include/client.h: use a struct MsgQ instead of a struct DBuf for
+       sendq
+
+       * doc/Configure.help: Remove help for compile-time options that
+       have gone away
+
+       * config/config-sh.in: remove CONFIG_NEWMODE
+
        * ircd/m_server.c (mr_server): don't send server IPs in any server
        notices
 
+       * ircd/msgq.c (msgq_vmake): add \r\n to messages
+
+2000-12-07  Kevin L. Mitchell  <klmitch@mit.edu>
+
+       * include/msgq.h: declare the MsgQ API
+
+       * ircd/msgq.c: implementation of new MsgQ system
+
 2000-12-06  Kevin L. Mitchell  <klmitch@mit.edu>
 
        * ircd/ircd_features.c: #include was supposed to be for
index e3ce7c9703f283b897b65b46839f6dff5baf5584..bf2c4307152c4799fbe92e4257577abfabfdaecc 100644 (file)
@@ -334,6 +334,5 @@ endmenu
 
 mainmenu_option next_comment
 comment 'Experimental options (Do you know what you'\''re doing?)'
-  bool 'Use new MODE implementation' CONFIG_NEW_MODE y
   bool 'Use new oper commands (JUPE, CLEARMODE, OPMODE, GLINE)' CONFIG_OPERCMDS y
 endmenu
index d8cf81472ec7cb8b201617a0bb4e4fdc934d05e0..e4b979be2e0edd3c484ee5a6ec43786daf4b8373 100644 (file)
@@ -487,123 +487,6 @@ PPATH
   server's PID so a ps(1) isn't necessary.
   Note that you should not include quotes here.
 
-Do you want to log the use of /WHO x% (recommended)
-CONFIG_LOG_WHOX
-  Specify 'y' here if you want to log the use of /WHO ... x%... by your
-  Opers (see doc/readme.who).  This is highly recommended since it will
-  reduce the abuse of this `spy' function.  Note: You can disable this
-  spy function completely below, in which case you can give 'n' here.
-  If unsure specify 'y'.
-
-Give the path and(or) filename of this log file
-WPATH
-  WPATH is the filename, relative to DPATH, or the full path, of the
-  log file where the use of /WHO ... x% ... by your Opers will be logged
-  (see doc/readme.who), mostly called "whox.log".
-  Note that you should not include quotes here.
-
-Do you want to log G-lines to a separate file
-CONFIG_LOG_GLINES
-  Specify 'y' here if you want to log G-lines (Global access bans)
-  to a local file.
-
-Give the path and(or) filename of this log file
-GPATH
-  GPATH is the filename, relative to DPATH, or the full path, of the
-  log file where the G-lines will be stored, mostly called "gline.log".
-  Note that you should not include quotes here.
-
-Do you want to log JUPEs to a separate file
-CONFIG_LOG_JUPES
-  Specify 'y' here if you want to log JUPEs (Jupiters) to a local file.
-
-Give the path and(or) filename of this log file
-JPATH
-  JPATH is the filename, relative to DPATH, or the full path, of the
-  log file where the logs of JUPEs will be stored; it is usually called
-  "jupe.log".  Note that you should not include quotes here.
-
-Do you want to log OPMODEs and CLEARMODEs to a separate file
-CONFIG_LOG_OPMODES
-  Specify 'y' here if you want to log OPMODEs and CLEARMODEs to a local
-  file.
-
-Give the path and(or) filename of this log file
-OPATH
-  OPATH is the filename, relative to DPATH, or the full path, of the
-  log file where the logs of OPMODEs and CLEARMODEs will be stored; it
-  is usually called "opmode.log".  Note that you should not include
-  quote here.
-
-Do you want to log connecting users to a separate file
-CONFIG_LOG_USERS
-  Specify 'y' here if you want to log who is connecting to your server.
-  This file can grow VERY fast on a large net work, so you probably
-  want to specify 'n' here.
-
-Give the path and(or) filename of this log file
-FNAME_USERLOG
-  Here you need to specify the name of the log file where the server
-  should write the data about connecting users to. You can also specify
-  a full path.  Note that you should not include quotes here.
-
-Do you want to log Opers to a separate file
-CONFIG_LOG_OPERS
-  Specify 'y' here if you want to log who is successfully becoming an
-  IRC Operator on your server.
-
-Give the path and(or) filename of this log file
-FNAME_OPERLOG
-  Here you need to specify the name of the log file where the server
-  should write the data about Opering users.  You can also specify a
-  full path.  Note that you should not include quotes here.
-
-Do you want to use syslog
-USE_SYSLOG
-  If you are the sys admin of this machine, or if you have permission
-  of the sys admin to do so, you can let the server write data about
-  certain events to the syslog.  You will be prompted for the events
-  that you want to log being one or more of: KILL's, SQUIT's, CONNECT's,
-  OPERing, Connecting Users and finally the log facility.
-  If you are unsure, specify 'n'.  It is probably not a good idea to use
-  this on a large IRC net work.
-
-Log all operator kills to syslog
-SYSLOG_KILL
-  Specify 'y' here if you want all KILLs to be written to syslog.
-  Note that on a large IRC net work this is a LOT of data.
-
-Log all remote squits for all servers to syslog
-SYSLOG_SQUIT
-  Specify 'y' here if you want all SQUITs to be written to syslog.
-  Note that on a large IRC net work this is a LOT of data.
-
-Log remote connect messages for other all servers
-SYSLOG_CONNECT
-  Specify 'y' here if you want all CONNECTs to be written to syslog.
-  Note that on a large IRC net work this is a LOT of data.
-
-Log all users who successfully become an Oper
-SYSLOG_OPER
-  Specify 'y' here if you want all OPERs to be written to syslog.
-  Note that on a large IRC net work this is a LOT of data.
-
-Send userlog stuff to syslog
-SYSLOG_USERS
-  Specify 'y' here if you want all connecting users to be written to syslog.
-  Note that on a large IRC net work this is EXTREMELY MUCH data.
-  You really want to specify 'n' here.
-
-Log facility (daemon, user, local0-7)
-CONFIG_DAEMON
-  Well if you got this far and still need help, then I think you should
-  go back and specify 'n' at the question "Do you want to use syslog".
-
-Which local facility (0-7)
-INT_LOCAL
-  Well if you got this far and still need help, then I think you should
-  go back and specify 'n' at the question "Do you want to use syslog".
-
 Use crypted passwords for operators
 CRYPT_OPER_PASSWORD
   In order to allow certain users to become IRC OPERators, they must
@@ -1055,12 +938,6 @@ DEFAULTMAXSENDQLENGTH
   always override this value in your "ircd.conf" with the Y: lines.
   The given value used to be an often used value for client sendqs.
 
-Use new MODE implementation
-CONFIG_NEW_MODE
-  This enables a new implementation of m_mode.  THIS IS AN EXPERIMENTAL
-  FEATURE; DO NOT ENABLE UNLESS YOU KNOW WHAT YOU ARE DOING!  Note that,
-  due to apparent stability, this new implementation has been enabled.
-
 Use new oper commands (JUPE, CLEARMODE, OPMODE, GLINE)
 CONFIG_OPERCMDS
   Several new oper-only commands were added to the server source
index 4253816144857ed413339adebb528a9870587bba..15ca14d355a78c939fd2b82719ecc80cf8adfd6b 100644 (file)
@@ -31,6 +31,9 @@
 #ifndef INCLUDED_dbuf_h
 #include "dbuf.h"
 #endif
+#ifndef INCLUDED_msgq_h
+#include "msgq.h"
+#endif
 #ifndef INCLUDED_ircd_handler_h
 #include "ircd_handler.h"
 #endif
@@ -110,7 +113,7 @@ struct Client {
   time_t              nextnick;  /* Next time a nick change is allowed */
   time_t              nexttarget; /* Next time a target change is allowed */
   unsigned int        cookie;    /* Random number the user must PONG */
-  struct DBuf         sendQ;     /* Outgoing message queue--if socket full */
+  struct MsgQ         sendQ;     /* Outgoing message queue--if socket full */
   struct DBuf         recvQ;     /* Hold for data incoming yet to be parsed */
   unsigned int        sendM;     /* Statistics: protocol messages send */
   unsigned int        sendK;     /* Statistics: total k-bytes send */
diff --git a/include/msgq.h b/include/msgq.h
new file mode 100644 (file)
index 0000000..8f3747c
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef INCLUDED_msgq_h
+#define INCLUDED_msgq_h
+/*
+ * IRC - Internet Relay Chat, include/msgq.h
+ * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#ifndef INCLUDED_ircd_defs_h
+#include "ircd_defs.h" /* BUFSIZE */
+#endif
+#ifndef INCLUDED_sys_types_h
+#include <sys/types.h>
+#define INCLUDED_sys_types_h
+#endif
+#ifndef INCLUDED_stdarg_h
+#include <stdarg.h>
+#define INCLUDED_stdarg_h
+#endif
+
+struct iovec;
+
+struct Client;
+
+struct MsgCounts {
+  int alloc;
+  int used;
+};
+
+/*
+ * These should be considered read-only
+ */
+extern struct MsgCounts msgBufCounts;  /* resource count for struct MsgBuf */
+extern struct MsgCounts msgCounts;     /* resource count for struct Msg */
+
+struct Msg;
+struct MsgBuf;
+
+struct MsgQList {
+  struct Msg *head;            /* First Msg in queue list */
+  struct Msg *tail;            /* Last Msg in queue list */
+};
+
+struct MsgQ {
+  unsigned int length;         /* Current number of bytes stored */
+  unsigned int count;          /* Current number of messages stored */
+  struct MsgQList queue;       /* Normal Msg queue */
+  struct MsgQList prio;                /* Priority Msg queue */
+};
+
+/*
+ * MsgQLength - Returns the current number of bytes stored in the buffer.
+ */
+#define MsgQLength(mq) ((mq)->length)
+
+/*
+ * MsgQCount - Returns the current number of messages stored in the buffer
+ */
+#define MsgQCount(mq) ((mq)->count)
+
+/*
+ * MsgQClear - Scratch the current content of the buffer.
+ * Release all allocated buffers and make it empty.
+ */
+#define MsgQClear(mq) msgq_delete((mq), MsgQLength(mq))
+
+/*
+ * Prototypes
+ */
+extern void msgq_init(struct MsgQ *mq);
+extern void msgq_delete(struct MsgQ *mq, unsigned int length);
+extern const char *msgq_map(const struct MsgQ *mq, unsigned int *length_p);
+extern int msgq_mapiov(const struct MsgQ *mq, struct iovec *iov, int count);
+extern struct MsgBuf *msgq_make(struct Client *dest, const char *format, ...);
+extern struct MsgBuf *msgq_vmake(struct Client *dest, const char *format,
+                                va_list args);
+extern void msgq_append(struct Client *dest, struct MsgBuf *mb,
+                       const char *format, ...);
+extern void msgq_clean(struct MsgBuf *mb);
+extern void msgq_add(struct MsgQ *mq, struct MsgBuf *mb, int prio);
+extern void msgq_count_memory(size_t *msg_alloc, size_t *msg_used,
+                             size_t *msgbuf_alloc, size_t *msgbuf_used);
+extern unsigned int msgq_bufleft(struct MsgBuf *mb);
+
+#endif /* INCLUDED_msgq_h */
index 274bf4a6511b517a07a922dba8805c56003a3c18..e91de32a7f12adcafc325982b1cf367dba8907e8 100644 (file)
@@ -14,6 +14,7 @@ struct Client;
 struct User;
 struct Gline;
 struct Channel;
+struct MsgBuf;
 
 /*
  * Macros
@@ -49,7 +50,7 @@ struct Channel;
 
 extern struct SLink *opsarray[];
 
-typedef char* (*InfoFormatter)(struct Client* who, char* buf);
+typedef void (*InfoFormatter)(struct Client* who, struct MsgBuf* buf);
 
 /*
  * Prototypes
index 088da8c47817749ff455ce4add83c8f0c276643c..4e5ef56898f51fe880d04b4b5cb21611a29b12b8 100644 (file)
 struct Channel;
 struct Client;
 struct DBuf;
-
+struct MsgBuf;
 
 /*
  * Prototypes
  */
-extern void send_buffer(struct Client* to, char* buf);
-extern void flush_sendq_except(const struct DBuf* one);
-
-extern void sendto_one(struct Client *to, const char* fmt, ...);
-extern void sendbufto_one(struct Client *to);
-extern void sendto_ops(const char* fmt, ...);
-extern void sendto_channel_butserv(struct Channel *chptr, struct Client *from,
-                                   const char* fmt, ...);
-extern void sendto_serv_butone(struct Client *one, const char* fmt, ...);
-extern void sendto_lowprot_butone(struct Client *cptr, int p,
-                                  const char* fmt, ...);
-extern void sendto_highprot_butone(struct Client *cptr, int p,
-                                   const char* fmt, ...);
-extern void sendto_prefix_one(struct Client *to, struct Client *from,
-                              const char* fmt, ...);
+extern void send_buffer(struct Client* to, struct MsgBuf* buf, int prio);
+extern void flush_sendq_except(void);
+
 extern void flush_connections(struct Client* cptr);
 extern void send_queued(struct Client *to);
-extern void vsendto_one(struct Client *to, const char* fmt, va_list vl);
-extern void sendmsgto_channel_butone(struct Client *one, struct Client *from,
-                                  struct Channel *chptr, const char *sender,
-                                  const char *cmd, const char *chname, const char *msg);
-extern void sendto_lchanops_butone(struct Client *one, struct Client *from,
-                                   struct Channel *chptr, const char* fmt, ...);
-extern void sendto_chanopsserv_butone(struct Client *one, struct Client *from,
-                                   struct Channel *chptr, const char* fmt, ...);
-extern void sendto_common_channels(struct Client *user, const char* fmt, ...);
-extern void sendto_match_butone(struct Client *one, struct Client *from,
-                                const char *mask, int what, const char* fmt, ...);
-extern void vsendto_ops(const char *pattern, va_list vl);
-extern void sendto_ops_butone(struct Client *one, struct Client *from,
-                              const char* fmt, ...);
-extern void sendto_g_serv_butone(struct Client *one, const char* fmt, ...);
-extern void sendto_realops(const char* fmt, ...);
-extern void vsendto_op_mask(unsigned int mask,
-                            const char* fmt, va_list vl);
-extern void sendto_op_mask(unsigned int mask, const char* fmt, ...);
-extern void sendbufto_op_mask(unsigned int mask);
-extern void sendbufto_serv_butone(struct Client *one);
-
-extern char sendbuf[2048];
-
-#define IRC_BUFSIZE    512
 
 /* Send a raw message to one client; USE ONLY IF YOU MUST SEND SOMETHING
  * WITHOUT A PREFIX!
index 84ceeb00173d489974ecb50f7e5a87bf1ed09c55..36c2aaab93fbf706092eeb3f171b106b05de35c7 100644 (file)
@@ -25,6 +25,7 @@
 #include "IPcheck.h"
 #include "client.h"
 #include "ircd.h"
+#include "msg.h"
 #include "numnicks.h"       /* NumNick, NumServ (GODMODE) */
 #include "ircd_alloc.h"
 #include "s_debug.h"        /* Debug */
@@ -346,9 +347,9 @@ void ip_registry_connect_succeeded(struct Client *cptr)
     free_targets = entry->target->count;
     tr = " tr";
   }
-  sendto_one(cptr, ":%s NOTICE %s :on %u ca %u(%u) ft %u(%u)%s",
-             me.name, cptr->name, entry->connected, entry->attempts,
-             IPCHECK_CLONE_LIMIT, free_targets, STARTTARGETS, tr);
+  sendcmdto_one(&me, CMD_NOTICE, cptr, ":on %u ca %u(%u) ft %u(%u)%s",
+               entry->connected, entry->attempts, IPCHECK_CLONE_LIMIT,
+               free_targets, STARTTARGETS, tr);
 }
 
 /*
index 050aa6d0cd036378fb62fde9ea77ca63c99c50bb..2ec314b6a4c56102c0405bafc468b03b13a720c2 100644 (file)
@@ -156,6 +156,7 @@ SRC = \
        m_whowas.c \
        match.c \
        motd.c \
+       msgq.c \
        numnicks.c \
        opercmds.c \
        packet.c \
@@ -292,40 +293,41 @@ stamp-m:
 
 IPcheck.o: IPcheck.c ../include/IPcheck.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/numnicks.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/msg.h \
+ ../include/numnicks.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/s_debug.h ../include/s_user.h ../include/send.h
 channel.o: channel.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_chattr.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_snprintf.h \
- ../include/ircd_string.h ../include/list.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/sys.h ../include/whowas.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
+ ../include/match.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h ../include/sprintf_irc.h \
+ ../include/support.h ../include/sys.h ../include/whowas.h
 class.o: class.c ../include/class.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_reply.h ../include/list.h ../include/numeric.h \
- ../include/s_conf.h ../include/s_debug.h ../include/send.h
-client.o: client.c ../include/client.h ../include/ircd_defs.h \
- ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/class.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/list.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_reply.h ../include/list.h \
  ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
  ../include/send.h
+client.o: client.c ../include/client.h ../include/ircd_defs.h \
+ ../config/config.h ../config/setup.h ../include/dbuf.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/class.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/list.h ../include/numeric.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/send.h
 crule.o: crule.c ../include/crule.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_chattr.h ../include/ircd_string.h ../include/match.h \
- ../include/s_bsd.h ../include/s_debug.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_chattr.h ../include/ircd_string.h \
+ ../include/match.h ../include/s_bsd.h ../include/s_debug.h
 dbuf.o: dbuf.c ../include/dbuf.h ../include/ircd_alloc.h \
  ../include/fda.h ../include/ircd_chattr.h ../include/send.h \
  ../include/sys.h ../config/config.h ../config/setup.h
@@ -334,93 +336,95 @@ fileio.o: fileio.c ../include/fileio.h ../include/ircd_alloc.h \
  ../include/fda.h
 gline.o: gline.c ../include/gline.h ../config/config.h \
  ../config/setup.h ../include/client.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
  ../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \
  ../include/s_misc.h ../include/send.h ../include/support.h \
  ../include/msg.h ../include/numnicks.h ../include/sys.h
 hash.o: hash.c ../include/hash.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/channel.h \
- ../include/ircd_chattr.h ../include/ircd_string.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/send.h \
- ../include/support.h ../include/sys.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/ircd_chattr.h \
+ ../include/ircd_string.h ../include/ircd.h ../include/struct.h \
+ ../include/msg.h ../include/send.h ../include/support.h \
+ ../include/sys.h
 ircd.o: ircd.c ../include/ircd.h ../config/config.h ../config/setup.h \
  ../include/struct.h ../include/ircd_defs.h ../include/IPcheck.h \
  ../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/crule.h ../include/hash.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_signal.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
- ../include/list.h ../include/match.h ../include/motd.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/parse.h ../include/res.h ../include/s_auth.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
- ../include/s_misc.h ../include/send.h ../include/sys.h \
- ../include/uping.h ../include/userload.h ../include/version.h \
- ../include/whowas.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/crule.h \
+ ../include/hash.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_signal.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \
+ ../include/match.h ../include/motd.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+ ../include/res.h ../include/s_auth.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/send.h ../include/sys.h ../include/uping.h \
+ ../include/userload.h ../include/version.h ../include/whowas.h
 ircd_alloc.o: ircd_alloc.c ../include/ircd_alloc.h ../include/fda.h \
  ../include/ircd_string.h ../config/config.h ../config/setup.h \
  ../include/ircd_chattr.h ../include/s_debug.h ../include/ircd_defs.h
 ircd_features.o: ircd_features.c ../include/ircd_features.h \
  ../include/client.h ../include/ircd_defs.h ../config/config.h \
- ../config/setup.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
- ../include/s_debug.h ../include/s_misc.h ../include/send.h \
- ../include/support.h ../include/sys.h
+ ../config/setup.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/send.h ../include/support.h ../include/sys.h
 ircd_log.o: ircd_log.c ../include/ircd_log.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_reply.h ../include/ircd_snprintf.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
- ../include/struct.h ../include/numeric.h ../include/s_debug.h \
- ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_snprintf.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+ ../include/numeric.h ../include/s_debug.h ../include/send.h
 ircd_osdep.o: ircd_osdep.c ../include/ircd_osdep.h
 ircd_relay.o: ircd_relay.c ../include/ircd_relay.h \
  ../include/channel.h ../config/config.h ../config/setup.h \
  ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/send.h
 ircd_reply.o: ircd_reply.c ../include/ircd_reply.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_snprintf.h ../include/numeric.h \
- ../include/msg.h ../include/s_conf.h ../include/s_debug.h \
- ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_snprintf.h \
+ ../include/msg.h ../include/numeric.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/send.h
 ircd_signal.o: ircd_signal.c ../include/ircd_signal.h \
  ../include/ircd.h ../config/config.h ../config/setup.h \
  ../include/struct.h ../include/ircd_defs.h
 ircd_snprintf.o: ircd_snprintf.c ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/channel.h \
- ../include/ircd_snprintf.h ../include/struct.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/ircd_snprintf.h ../include/struct.h
 ircd_string.o: ircd_string.c ../include/ircd_string.h \
  ../config/config.h ../config/setup.h ../include/ircd_chattr.h \
  ../include/ircd_defs.h ../include/ircd_log.h chattr.tab.c
 ircd_xopen.o: ircd_xopen.c ../include/ircd_xopen.h
 jupe.o: jupe.c ../include/jupe.h ../config/config.h ../config/setup.h \
  ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_bsd.h ../include/s_misc.h ../include/send.h \
  ../include/support.h ../include/sys.h
 list.o: list.c ../include/list.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/listener.h ../include/match.h \
  ../include/numeric.h ../include/res.h ../include/s_bsd.h \
  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
@@ -428,497 +432,521 @@ list.o: list.c ../include/list.h ../include/client.h \
  ../include/whowas.h
 listener.o: listener.c ../include/listener.h ../include/ircd_defs.h \
  ../include/client.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_osdep.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_osdep.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h \
  ../include/numeric.h ../include/s_bsd.h ../include/s_conf.h \
  ../include/s_misc.h ../include/send.h ../include/sprintf_irc.h \
  ../include/sys.h
 m_admin.o: m_admin.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_user.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/s_user.h
 m_away.o: m_away.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_burst.o: m_burst.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/list.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_misc.h ../include/send.h \
- ../include/support.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+ ../include/match.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_conf.h ../include/s_misc.h \
+ ../include/send.h ../include/support.h
 m_clearmode.o: m_clearmode.c ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/channel.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h \
- ../include/support.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/send.h ../include/support.h
 m_close.o: m_close.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/numeric.h ../include/s_bsd.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
+ ../include/s_bsd.h ../include/send.h
 m_connect.o: m_connect.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/crule.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/jupe.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/crule.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
+ ../include/match.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_user.h ../include/send.h
 m_cprivmsg.o: m_cprivmsg.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_user.h
 m_create.o: m_create.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h
 m_defaults.o: m_defaults.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/numeric.h ../include/numnicks.h \
- ../include/send.h ../include/supported.h ../include/channel.h \
- ../include/version.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h ../include/supported.h \
+ ../include/channel.h ../include/version.h
 m_destruct.o: m_destruct.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_desynch.o: m_desynch.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_bsd.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/send.h
 m_die.o: m_die.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_bsd.h ../include/send.h
 m_endburst.o: m_endburst.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
 m_error.o: m_error.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_debug.h ../include/s_misc.h ../include/send.h
 m_get.o: m_get.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
  ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
  ../include/send.h
 m_gline.o: m_gline.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_misc.h ../include/send.h \
- ../include/support.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_misc.h ../include/send.h ../include/support.h
 m_help.o: m_help.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_info.o: m_info.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_misc.h ../include/s_user.h \
  ../include/send.h ../include/version.h
 m_invite.o: m_invite.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_user.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h
 m_ison.o: m_ison.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/numeric.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/numeric.h ../include/send.h
 m_join.o: m_join.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/gline.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/gline.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
  ../include/send.h ../include/handlers.h
 m_jupe.o: m_jupe.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/jupe.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_misc.h ../include/send.h \
- ../include/support.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/jupe.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_misc.h ../include/send.h ../include/support.h
 m_kick.o: m_kick.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
 m_kill.o: m_kill.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \
- ../include/send.h ../include/whowas.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_misc.h ../include/send.h \
+ ../include/whowas.h
 m_links.o: m_links.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
  ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
  ../include/send.h
 m_list.o: m_list.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_lusers.o: m_lusers.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/querycmds.h ../include/s_user.h \
  ../include/s_serv.h ../include/send.h
 m_map.o: m_map.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_snprintf.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/match.h ../include/numeric.h ../include/s_user.h \
- ../include/s_serv.h ../include/send.h ../include/querycmds.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_snprintf.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/match.h \
+ ../include/numeric.h ../include/s_user.h ../include/s_serv.h \
+ ../include/send.h ../include/querycmds.h
 m_mode.o: m_mode.c ../include/handlers.h ../include/channel.h \
  ../config/config.h ../config/setup.h ../include/ircd_defs.h \
- ../include/client.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/client.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_conf.h ../include/s_debug.h \
  ../include/s_user.h ../include/send.h
 m_motd.o: m_motd.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/match.h ../include/motd.h \
  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_conf.h ../include/class.h ../include/s_user.h \
  ../include/send.h
 m_names.o: m_names.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_nick.o: m_nick.c ../include/IPcheck.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h
 m_notice.o: m_notice.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_chattr.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_chattr.h \
  ../include/ircd_relay.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/match.h ../include/msg.h \
  ../include/numeric.h ../include/send.h ../include/handlers.h
 m_oper.o: m_oper.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/ircd_xopen.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/querycmds.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_user.h ../include/s_misc.h \
- ../include/send.h ../include/support.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd_xopen.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
+ ../include/s_misc.h ../include/send.h ../include/support.h
 m_opmode.o: m_opmode.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/channel.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/channel.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
 m_part.o: m_part.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+ ../include/send.h
 m_pass.o: m_pass.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/send.h
 m_ping.o: m_ping.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_debug.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_debug.h ../include/send.h
 m_pong.o: m_pong.c ../include/client.h ../include/ircd_defs.h \
- ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_user.h ../include/send.h
+ ../config/config.h ../config/setup.h ../include/dbuf.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h
 m_privmsg.o: m_privmsg.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_relay.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_relay.h \
  ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
  ../include/msg.h ../include/numeric.h ../include/send.h
 m_proto.o: m_proto.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
- ../include/send.h ../include/supported.h ../include/channel.h \
- ../include/version.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/send.h \
+ ../include/supported.h ../include/channel.h ../include/version.h
 m_quit.o: m_quit.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/struct.h ../include/s_misc.h \
- ../include/ircd_reply.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/struct.h \
+ ../include/s_misc.h ../include/ircd_reply.h
 m_rehash.o: m_rehash.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/motd.h \
  ../include/numeric.h ../include/s_conf.h ../include/send.h
 m_reset.o: m_reset.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
  ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
  ../include/send.h
 m_restart.o: m_restart.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h \
  ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_rping.o: m_rping.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/opercmds.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+ ../include/s_user.h ../include/send.h
 m_rpong.o: m_rpong.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/opercmds.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+ ../include/send.h
 m_server.o: m_server.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
- ../include/list.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_serv.h ../include/send.h \
- ../include/userload.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \
+ ../include/match.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_serv.h ../include/send.h ../include/userload.h
 m_set.o: m_set.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
  ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
  ../include/send.h
 m_settime.o: m_settime.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
-m_silence.o: m_silence.c ../include/channel.h ../config/config.h \
- ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_user.h ../include/send.h
+m_silence.o: m_silence.c ../include/channel.h ../config/config.h \
+ ../config/setup.h ../include/ircd_defs.h ../include/client.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h
 m_squit.o: m_squit.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
- ../include/match.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
+ ../include/numnicks.h ../include/match.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_user.h ../include/send.h
 m_stats.o: m_stats.c ../include/s_stats.h ../include/channel.h \
  ../config/config.h ../config/setup.h ../include/ircd_defs.h \
  ../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/list.h ../include/listener.h \
- ../include/match.h ../include/motd.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_serv.h ../include/s_user.h \
- ../include/send.h ../include/userload.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/list.h \
+ ../include/listener.h ../include/match.h ../include/motd.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/opercmds.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/userload.h
 m_time.o: m_time.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/s_misc.h ../include/s_user.h \
  ../include/send.h
 m_topic.o: m_topic.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
 m_trace.o: m_trace.c ../include/class.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_user.h ../include/send.h \
+ ../include/version.h
+m_uping.o: m_uping.c ../include/client.h ../include/ircd_defs.h \
+ ../config/config.h ../config/setup.h ../include/dbuf.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \
- ../include/send.h ../include/version.h
-m_uping.o: m_uping.c ../include/client.h ../include/ircd_defs.h \
- ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_user.h ../include/send.h ../include/uping.h
+ ../include/s_conf.h ../include/s_user.h ../include/send.h \
+ ../include/uping.h
 m_user.o: m_user.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
  ../include/send.h
 m_userhost.o: m_userhost.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h \
  ../include/numeric.h ../include/s_user.h ../include/struct.h
 m_userip.o: m_userip.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h \
  ../include/numeric.h ../include/s_user.h ../include/struct.h
 m_version.o: m_version.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h ../include/supported.h ../include/channel.h \
- ../include/version.h
-m_wallchops.o: m_wallchops.c ../include/channel.h ../config/config.h \
- ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
+ ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
+ ../include/s_user.h ../include/send.h ../include/supported.h \
+ ../include/channel.h ../include/version.h
+m_wallchops.o: m_wallchops.c ../include/channel.h ../config/config.h \
+ ../config/setup.h ../include/ircd_defs.h ../include/client.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_wallops.o: m_wallops.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
  ../include/numeric.h ../include/send.h
 m_who.o: m_who.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/match.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h ../include/support.h \
- ../include/whocmds.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h \
+ ../include/support.h ../include/whocmds.h
 m_whois.o: m_whois.c ../include/channel.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_user.h ../include/send.h ../include/whocmds.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h ../include/whocmds.h
 m_whowas.o: m_whowas.c ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_user.h ../include/s_misc.h \
- ../include/send.h ../include/whowas.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/s_misc.h ../include/send.h ../include/whowas.h
 match.o: match.c ../include/match.h ../include/ircd_chattr.h
 motd.o: motd.c ../include/motd.h ../include/class.h \
  ../include/client.h ../include/ircd_defs.h ../config/config.h \
- ../config/setup.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/fileio.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h
+ ../config/setup.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/fileio.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_user.h ../include/send.h
+msgq.o: msgq.c ../include/msgq.h ../include/ircd_defs.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_snprintf.h \
+ ../config/config.h ../config/setup.h
 numnicks.o: numnicks.c ../include/numnicks.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/match.h ../include/s_bsd.h ../include/s_debug.h \
+ ../include/s_misc.h
 opercmds.o: opercmds.c ../include/opercmds.h ../include/class.h \
  ../include/client.h ../include/ircd_defs.h ../config/config.h \
- ../config/setup.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/listener.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/send.h
+ ../config/setup.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/listener.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/send.h
 packet.o: packet.c ../include/packet.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_chattr.h ../include/parse.h \
- ../include/s_bsd.h ../include/s_misc.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+ ../include/parse.h ../include/s_bsd.h ../include/s_misc.h \
+ ../include/send.h
 parse.o: parse.c ../include/parse.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/channel.h \
- ../include/handlers.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/handlers.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_chattr.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/opercmds.h ../include/querycmds.h \
  ../include/res.h ../include/s_bsd.h ../include/s_conf.h \
@@ -930,39 +958,42 @@ random.o: random.c ../include/random.h ../config/config.h \
  ../config/setup.h
 res.o: res.c ../include/res.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \
- ../include/s_misc.h ../include/send.h ../include/sprintf_irc.h \
- ../include/support.h ../include/sys.h
-s_auth.o: s_auth.c ../include/s_auth.h ../config/config.h \
- ../config/setup.h ../include/client.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/IPcheck.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_chattr.h ../include/ircd_log.h \
- ../include/ircd_osdep.h ../include/ircd_string.h ../include/list.h \
- ../include/numeric.h ../include/querycmds.h ../include/res.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_osdep.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
  ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
- ../include/send.h ../include/sprintf_irc.h ../include/sys.h
+ ../include/send.h ../include/sprintf_irc.h ../include/support.h \
+ ../include/sys.h
+s_auth.o: s_auth.c ../include/s_auth.h ../config/config.h \
+ ../config/setup.h ../include/client.h ../include/ircd_defs.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/IPcheck.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_log.h ../include/ircd_osdep.h \
+ ../include/ircd_string.h ../include/list.h ../include/numeric.h \
+ ../include/querycmds.h ../include/res.h ../include/s_bsd.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/send.h \
+ ../include/sprintf_irc.h ../include/sys.h
 s_bsd.o: s_bsd.c ../include/s_bsd.h ../config/config.h \
  ../config/setup.h ../include/client.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/IPcheck.h \
- ../include/channel.h ../include/class.h ../include/hash.h \
- ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
- ../include/struct.h ../include/list.h ../include/listener.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/packet.h ../include/parse.h ../include/querycmds.h \
- ../include/res.h ../include/s_auth.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/sys.h ../include/uping.h ../include/version.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/IPcheck.h ../include/channel.h ../include/class.h \
+ ../include/hash.h ../include/ircd_log.h ../include/ircd_osdep.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+ ../include/list.h ../include/listener.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/packet.h \
+ ../include/parse.h ../include/querycmds.h ../include/res.h \
+ ../include/s_auth.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_user.h ../include/send.h \
+ ../include/sprintf_irc.h ../include/support.h ../include/sys.h \
+ ../include/uping.h ../include/version.h
 s_conf.o: s_conf.c ../include/s_conf.h ../include/IPcheck.h \
  ../include/class.h ../include/client.h ../include/ircd_defs.h \
  ../config/config.h ../config/setup.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/crule.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/crule.h \
  ../include/ircd_features.h ../include/fileio.h ../include/gline.h \
  ../include/hash.h ../include/ircd.h ../include/struct.h \
  ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
@@ -976,21 +1007,22 @@ s_conf.o: s_conf.c ../include/s_conf.h ../include/IPcheck.h \
 s_debug.o: s_debug.c ../include/s_debug.h ../config/config.h \
  ../config/setup.h ../include/ircd_defs.h ../include/channel.h \
  ../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_log.h ../include/ircd_osdep.h \
- ../include/ircd_reply.h ../include/ircd.h ../include/struct.h \
- ../include/list.h ../include/numeric.h ../include/numnicks.h \
- ../include/res.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/send.h ../include/sys.h ../include/whowas.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
+ ../include/ircd_osdep.h ../include/ircd_reply.h ../include/ircd.h \
+ ../include/struct.h ../include/list.h ../include/numeric.h \
+ ../include/numnicks.h ../include/res.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/send.h ../include/sys.h \
+ ../include/whowas.h
 s_err.o: s_err.c ../include/numeric.h ../include/s_debug.h \
  ../config/config.h ../config/setup.h ../include/ircd_defs.h \
  ../include/sprintf_irc.h
 s_misc.o: s_misc.c ../include/s_misc.h ../include/IPcheck.h \
  ../include/channel.h ../config/config.h ../config/setup.h \
  ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
  ../include/match.h ../include/msg.h ../include/numeric.h \
  ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
@@ -1000,54 +1032,58 @@ s_misc.o: s_misc.c ../include/s_misc.h ../include/IPcheck.h \
  ../include/uping.h ../include/userload.h
 s_numeric.o: s_numeric.c ../include/s_numeric.h ../include/channel.h \
  ../config/config.h ../config/setup.h ../include/ircd_defs.h \
- ../include/client.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_snprintf.h ../include/numnicks.h ../include/send.h
+ ../include/client.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_snprintf.h ../include/numnicks.h \
+ ../include/send.h
 s_serv.o: s_serv.c ../include/s_serv.h ../include/IPcheck.h \
  ../include/channel.h ../config/config.h ../config/setup.h \
  ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/ircd_snprintf.h \
- ../include/ircd_xopen.h ../include/jupe.h ../include/list.h \
- ../include/msg.h ../include/match.h ../include/numeric.h \
- ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h \
- ../include/sprintf_irc.h ../include/sys.h ../include/userload.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/ircd_snprintf.h ../include/ircd_xopen.h ../include/jupe.h \
+ ../include/list.h ../include/msg.h ../include/match.h \
+ ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+ ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/send.h ../include/sprintf_irc.h ../include/sys.h \
+ ../include/userload.h
 s_stats.o: s_stats.c ../include/s_stats.h ../include/class.h \
  ../include/client.h ../include/ircd_defs.h ../config/config.h \
- ../config/setup.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/listener.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_user.h ../include/send.h
+ ../config/setup.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/listener.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_user.h ../include/send.h
 s_user.o: s_user.c ../include/s_user.h ../include/IPcheck.h \
  ../include/channel.h ../config/config.h ../config/setup.h \
  ../include/ircd_defs.h ../include/class.h ../include/client.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/gline.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/list.h ../include/match.h \
- ../include/motd.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
- ../include/random.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/supported.h ../include/sys.h ../include/userload.h \
- ../include/version.h ../include/whowas.h ../include/handlers.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/gline.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/list.h \
+ ../include/match.h ../include/motd.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+ ../include/querycmds.h ../include/random.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_serv.h ../include/send.h ../include/sprintf_irc.h \
+ ../include/support.h ../include/supported.h ../include/sys.h \
+ ../include/userload.h ../include/version.h ../include/whowas.h \
+ ../include/handlers.h
 send.o: send.c ../include/send.h ../include/channel.h \
  ../config/config.h ../config/setup.h ../include/ircd_defs.h \
  ../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_snprintf.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/list.h ../include/match.h \
- ../include/msg.h ../include/numnicks.h ../include/s_bsd.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/sprintf_irc.h ../include/sys.h
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_snprintf.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+ ../include/match.h ../include/msg.h ../include/numnicks.h \
+ ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/sprintf_irc.h ../include/sys.h
 sprintf_irc.o: sprintf_irc.c ../include/sprintf_irc.h ../include/sys.h \
  ../config/config.h ../config/setup.h
 support.o: support.c ../include/support.h ../config/config.h \
@@ -1057,9 +1093,9 @@ support.o: support.c ../include/support.h ../config/config.h \
  ../include/send.h ../include/sprintf_irc.h ../include/sys.h
 uping.o: uping.c ../include/uping.h ../include/ircd_defs.h \
  ../include/client.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_log.h ../include/ircd_osdep.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_osdep.h \
  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
  ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
@@ -1067,15 +1103,15 @@ uping.o: uping.c ../include/uping.h ../include/ircd_defs.h \
  ../include/sys.h
 userload.o: userload.c ../include/userload.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/numnicks.h \
- ../include/querycmds.h ../include/s_misc.h ../include/send.h \
- ../include/sys.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/msg.h \
+ ../include/numnicks.h ../include/querycmds.h ../include/s_misc.h \
+ ../include/send.h ../include/sys.h
 whocmds.o: whocmds.c ../include/whocmds.h ../config/config.h \
  ../config/setup.h ../include/channel.h ../include/ircd_defs.h \
- ../include/client.h ../include/dbuf.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/client.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
  ../include/ircd_string.h ../include/list.h ../include/match.h \
  ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
  ../include/random.h ../include/s_bsd.h ../include/s_conf.h \
@@ -1085,9 +1121,9 @@ whocmds.o: whocmds.c ../include/whocmds.h ../config/config.h \
  ../include/msg.h
 whowas.o: whowas.c ../include/whowas.h ../include/client.h \
  ../include/ircd_defs.h ../config/config.h ../config/setup.h \
- ../include/dbuf.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
- ../include/ircd_chattr.h ../include/ircd_string.h ../include/list.h \
- ../include/numeric.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h ../include/support.h ../include/sys.h \
- ../include/msg.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_chattr.h ../include/ircd_string.h \
+ ../include/list.h ../include/numeric.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h ../include/support.h \
+ ../include/sys.h ../include/msg.h
index 6c974c62eaee51ed27e8b3988a19b3b132c97811..cdb3e3689bc751ac3271dc8e051c88987745fc2d 100644 (file)
@@ -25,6 +25,7 @@
 #include "ircd.h"
 #include "ircd_alloc.h"
 #include "ircd_chattr.h"
+#include "ircd_defs.h"
 #include "ircd_log.h"
 #include "ircd_reply.h"
 #include "ircd_snprintf.h"
@@ -32,6 +33,7 @@
 #include "list.h"
 #include "match.h"
 #include "msg.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "numnicks.h"
 #include "querycmds.h"
@@ -858,12 +860,11 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
   int                flag_cnt = 0;
   int                new_mode = 0;
   size_t             len;
-  size_t             sblen;
   struct Membership* member;
   struct SLink*      lp2;
   char modebuf[MODEBUFLEN];
   char parabuf[MODEBUFLEN];
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
 
   assert(0 != cptr);
   assert(0 != chptr); 
@@ -884,22 +885,17 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
 
     /* (Continued) prefix: "<Y> B <channel> <TS>" */
     /* is there any better way we can do this? */
-    sblen = ircd_snprintf(&me, sndbuf, sizeof(sndbuf), "%C " TOK_BURST
-                         " %H %Tu", &me, chptr, chptr->creationtime);
+    mb = msgq_make(&me, "%C " TOK_BURST " %H %Tu", &me, chptr,
+                  chptr->creationtime);
 
     if (first && modebuf[1])    /* Add simple modes (iklmnpst)
                                  if first message */
     {
       /* prefix: "<Y> B <channel> <TS>[ <modes>[ <params>]]" */
-      sndbuf[sblen++] = ' ';
-      strcpy(sndbuf + sblen, modebuf);
-      sblen += strlen(modebuf);
+      msgq_append(&me, mb, " %s", modebuf);
+
       if (*parabuf)
-      {
-        sndbuf[sblen++] = ' ';
-        strcpy(sndbuf + sblen, parabuf);
-        sblen += strlen(parabuf);
-      }
+       msgq_append(&me, mb, " %s", parabuf);
     }
 
     /*
@@ -916,9 +912,8 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
         if ((member->status & CHFL_VOICED_OR_OPPED) !=
             current_flags[flag_cnt])
           continue;             /* Skip members with different flags */
-        if (sblen + NUMNICKLEN + 4 > BUFSIZE - 3)
-          /* The 4 is a possible ",:ov"
-             The -3 is for the "\r\n\0" that is added in send.c */
+       if (msgq_bufleft(mb) < NUMNICKLEN + 4)
+          /* The 4 is a possible ",:ov" */
         {
           full = 1;           /* Make sure we continue after
                                  sending it so far */
@@ -926,11 +921,9 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
                                  mode. --Gte */
           break;              /* Do not add this member to this message */
         }
-        sndbuf[sblen++] = first ? ' ' : ',';
+       msgq_append(&me, mb, "%c%C", first ? ' ' : ',', member->user);
         first = 0;              /* From now on, us comma's to add new nicks */
 
-       sblen += ircd_snprintf(&me, sndbuf + sblen, sizeof(sndbuf) - sblen,
-                              "%C", member->user);
         /*
          * Do we have a nick with a new mode ?
          * Or are we starting a new BURST line?
@@ -939,11 +932,15 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
         {
           new_mode = 0;
           if (IsVoicedOrOpped(member)) {
-            sndbuf[sblen++] = ':';
+           char tbuf[4] = ":";
+           int loc = 1;
+
             if (IsChanOp(member))
-              sndbuf[sblen++] = 'o';
+             tbuf[loc++] = 'o';
             if (HasVoice(member))
-              sndbuf[sblen++] = 'v';
+             tbuf[loc++] = 'v';
+           tbuf[loc] = '\0';
+           msgq_append(&me, mb, tbuf);
           }
         }
       }
@@ -957,31 +954,22 @@ void send_channel_modes(struct Client *cptr, struct Channel *chptr)
       for (first = 2; lp2; lp2 = lp2->next)
       {
         len = strlen(lp2->value.ban.banstr);
-        if (sblen + len + 1 + first > BUFSIZE - 3)
+       if (msgq_bufleft(mb) < len + 1 + first)
           /* The +1 stands for the added ' '.
            * The +first stands for the added ":%".
-           * The -3 is for the "\r\n\0" that is added in send.c
            */
         {
           full = 1;
           break;
         }
-        if (first)
-        {
-          first = 0;
-          sndbuf[sblen++] = ' ';
-          sndbuf[sblen++] = ':';       /* Will be last parameter */
-          sndbuf[sblen++] = '%';       /* To tell bans apart */
-        }
-        else
-          sndbuf[sblen++] = ' ';
-        strcpy(sndbuf + sblen, lp2->value.ban.banstr);
-        sblen += len;
+       msgq_append(&me, mb, " %s%s", first ? ":%" : "",
+                   lp2->value.ban.banstr);
+       first = 0;
       }
     }
 
-    sndbuf[sblen] = '\0';
-    send_buffer(cptr, sndbuf);  /* Send this message */
+    send_buffer(cptr, mb, 0);  /* Send this message */
+    msgq_clean(mb);
   }                             /* Continue when there was something
                                  that didn't fit (full==1) */
 }
@@ -1097,978 +1085,6 @@ static void send_ban_list(struct Client* cptr, struct Channel* chptr)
   send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname);
 }
 
-/*
- * Check and try to apply the channel modes passed in the parv array for
- * the client ccptr to channel chptr.  The resultant changes are printed
- * into mbuf and pbuf (if any) and applied to the channel.
- */
-int set_mode(struct Client* cptr, struct Client* sptr,
-                    struct Channel* chptr, int parc, char* parv[],
-                    char* mbuf, char* pbuf, char* npbuf, int* badop)
-{ 
-  /* 
-   * This size is only needed when a broken
-   * server sends more then MAXMODEPARAMS
-   * parameters
-   */
-  static struct SLink chops[MAXPARA - 2];
-  static int flags[] = {
-    MODE_PRIVATE,    'p',
-    MODE_SECRET,     's',
-    MODE_MODERATED,  'm',
-    MODE_NOPRIVMSGS, 'n',
-    MODE_TOPICLIMIT, 't',
-    MODE_INVITEONLY, 'i',
-    MODE_VOICE,      'v',
-    MODE_KEY,        'k',
-    0x0, 0x0
-  };
-
-  char bmodebuf[MODEBUFLEN];
-  char bparambuf[MODEBUFLEN];
-  char nbparambuf[MODEBUFLEN];     /* "Numeric" Bounce Parameter Buffer */
-  struct SLink*      lp;
-  char*              curr = parv[0];
-  char*              cp = NULL;
-  int*               ip;
-  struct Membership* member_x;
-  struct Membership* member_y;
-  unsigned int       whatt = MODE_ADD;
-  unsigned int       bwhatt = 0;
-  int                limitset = 0;
-  int                bounce;
-  int                add_banid_called = 0;
-  size_t             len;
-  size_t             nlen;
-  size_t             blen;
-  size_t             nblen;
-  int                keychange = 0;
-  unsigned int       nusers = 0;
-  unsigned int       newmode;
-  int                opcnt = 0;
-  int                banlsent = 0;
-  int                doesdeop = 0;
-  int                doesop = 0;
-  int                hacknotice = 0;
-  int                change;
-  int                gotts = 0;
-  struct Client*     who;
-  struct Mode*       mode;
-  struct Mode        oldm;
-  static char        numeric[16];
-  char*              bmbuf = bmodebuf;
-  char*              bpbuf = bparambuf;
-  char*              nbpbuf = nbparambuf;
-  time_t             newtime = 0;
-  struct ConfItem*   aconf;
-
-  *mbuf = *pbuf = *npbuf = *bmbuf = *bpbuf = *nbpbuf = '\0';
-  *badop = 0;
-  if (parc < 1)
-    return 0;
-  /*
-   * Mode is accepted when sptr is a channel operator
-   * but also when the mode is received from a server.
-   * At this point, let any member pass, so they are allowed
-   * to see the bans.
-   */
-  member_y = find_channel_member(sptr, chptr);
-  if (!(IsServer(cptr) || member_y))
-    return 0;
-
-#ifdef OPER_MODE_LCHAN
-  if (IsOperOnLocalChannel(sptr, chptr->chname) && !IsChanOp(member_y))
-    LocalChanOperMode = 1;
-#endif
-
-  mode = &(chptr->mode);
-  memcpy(&oldm, mode, sizeof(struct Mode));
-
-  newmode = mode->mode;
-
-  while (curr && *curr) {
-    switch (*curr) {
-      case '+':
-        whatt = MODE_ADD;
-        break;
-      case '-':
-        whatt = MODE_DEL;
-        break;
-      case 'o':
-      case 'v':
-        if (--parc <= 0)
-          break;
-        parv++;
-        if (MyUser(sptr) && opcnt >= MAXMODEPARAMS)
-          break;
-        /*
-         * Check for nickname changes and try to follow these
-         * to make sure the right client is affected by the
-         * mode change.
-         * Even if we find a nick with find_chasing() there
-         * is still a reason to ignore in a special case.
-         * We need to ignore the mode when:
-         * - It is part of a net.burst (from a server and
-         *   a MODE_ADD). Ofcourse we don't ignore mode
-         *   changes from Uworld.
-         * - The found nick is not on the right side off
-         *   the net.junction.
-         * This fixes the bug that when someone (tries to)
-         * ride a net.break and does so with the nick of
-         * someone on the otherside, that he is nick collided
-         * (killed) but his +o still ops the other person.
-         */
-        if (MyUser(sptr))
-        {
-          if (!(who = find_chasing(sptr, parv[0], NULL)))
-            break;
-        }
-        else
-        {
-          if (!(who = findNUser(parv[0])))
-            break;
-        }
-        if (whatt == MODE_ADD && IsServer(sptr) && who->from != sptr->from &&
-            !find_conf_byhost(cptr->confs, sptr->name, CONF_UWORLD))
-          break;
-
-        if (!(member_x = find_member_link(chptr, who)) ||
-            (MyUser(sptr) && IsZombie(member_x)))
-        {
-         send_reply(cptr, ERR_USERNOTINCHANNEL, who->name, chptr->chname);
-          break;
-        }
-        /*
-         * if the user is +k, prevent a deop from local user
-         */
-        if (whatt == MODE_DEL && IsChannelService(who) && *curr == 'o') {
-          /*
-           * XXX - CHECKME
-           */
-          if (MyUser(cptr)) {
-           send_reply(cptr, ERR_ISCHANSERVICE, parv[0], chptr->chname);
-            break;
-           }
-           else {
-             sprintf_irc(sendbuf,":%s NOTICE * :*** Notice -- Deop of +k user on %s by %s", /* XXX set_mode only called by old m_mode */
-                         me.name,chptr->chname,cptr->name);             
-           }
-        }
-#ifdef NO_OPER_DEOP_LCHAN
-        /*
-         * if the user is an oper on a local channel, prevent him
-         * from being deoped. that oper can deop himself though.
-         */
-        if (whatt == MODE_DEL && IsOperOnLocalChannel(who, chptr->chname) &&
-            (who != sptr) && MyUser(cptr) && *curr == 'o')
-        {
-         send_reply(cptr, ERR_ISOPERLCHAN, parv[0], chptr->chname);
-          break;
-        }
-#endif
-        if (whatt == MODE_ADD)
-        {
-          lp = &chops[opcnt++];
-          lp->value.cptr = who;
-          if (IsServer(sptr) && (!(who->flags & FLAGS_TS8) || ((*curr == 'o') &&
-              !(member_x->status & (CHFL_SERVOPOK | CHFL_CHANOP)))))
-            *badop = ((member_x->status & CHFL_DEOPPED) && (*curr == 'o')) ? 2 : 3;
-          lp->flags = (*curr == 'o') ? MODE_CHANOP : MODE_VOICE;
-          lp->flags |= MODE_ADD;
-        }
-        else if (whatt == MODE_DEL)
-        {
-          lp = &chops[opcnt++];
-          lp->value.cptr = who;
-          doesdeop = 1;         /* Also when -v */
-          lp->flags = (*curr == 'o') ? MODE_CHANOP : MODE_VOICE;
-          lp->flags |= MODE_DEL;
-        }
-        if (*curr == 'o')
-          doesop = 1;
-        break;
-      case 'k':
-        if (--parc <= 0)
-          break;
-        parv++;
-        /* check now so we eat the parameter if present */
-        if (keychange)
-          break;
-        else
-        {
-          char *s = &(*parv)[-1];
-          unsigned short count = KEYLEN + 1;
-
-          while (*++s > ' ' && *s != ':' && --count);
-          *s = '\0';
-          if (!**parv)          /* nothing left in key */
-            break;
-        }
-        if (MyUser(sptr) && opcnt >= MAXMODEPARAMS)
-          break;
-        if (whatt == MODE_ADD)
-        {
-          if (*mode->key && !IsServer(cptr))
-           send_reply(cptr, ERR_KEYSET, chptr->chname);
-          else if (!*mode->key || IsServer(cptr))
-          {
-            lp = &chops[opcnt++];
-            lp->value.cp = *parv;
-            if (strlen(lp->value.cp) > KEYLEN)
-              lp->value.cp[KEYLEN] = '\0';
-            lp->flags = MODE_KEY | MODE_ADD;
-            keychange = 1;
-          }
-        }
-        else if (whatt == MODE_DEL)
-        {
-          /* Debug((DEBUG_INFO, "removing key: mode->key: >%s< *parv: >%s<", mode->key, *parv)); */
-          if (0 == ircd_strcmp(mode->key, *parv) || IsServer(cptr))
-          {
-            /* Debug((DEBUG_INFO, "key matched")); */
-            lp = &chops[opcnt++];
-            lp->value.cp = mode->key;
-            lp->flags = MODE_KEY | MODE_DEL;
-            keychange = 1;
-          }
-        }
-        break;
-      case 'b':
-        if (--parc <= 0) {
-          if (0 == banlsent) {
-            /*
-             * Only send it once
-             */
-            send_ban_list(cptr, chptr);
-            banlsent = 1;
-          }
-          break;
-        }
-        parv++;
-        if (EmptyString(*parv))
-          break;
-        if (MyUser(sptr))
-        {
-          if ((cp = strchr(*parv, ' ')))
-            *cp = 0;
-          if (opcnt >= MAXMODEPARAMS || **parv == ':' || **parv == '\0')
-            break;
-        }
-        if (whatt == MODE_ADD)
-        {
-          lp = &chops[opcnt++];
-          lp->value.cp = *parv;
-          lp->flags = MODE_ADD | MODE_BAN;
-        }
-        else if (whatt == MODE_DEL)
-        {
-          lp = &chops[opcnt++];
-          lp->value.cp = *parv;
-          lp->flags = MODE_DEL | MODE_BAN;
-        }
-        break;
-      case 'l':
-        /*
-         * limit 'l' to only *1* change per mode command but
-         * eat up others.
-         */
-        if (limitset)
-        {
-          if (whatt == MODE_ADD && --parc > 0)
-            parv++;
-          break;
-        }
-        if (whatt == MODE_DEL)
-        {
-          limitset = 1;
-          nusers = 0;
-          break;
-        }
-        if (--parc > 0)
-        {
-          if (EmptyString(*parv))
-            break;
-          if (MyUser(sptr) && opcnt >= MAXMODEPARAMS)
-            break;
-          if (!(nusers = atoi(*++parv)))
-            continue;
-          lp = &chops[opcnt++];
-          lp->flags = MODE_ADD | MODE_LIMIT;
-          limitset = 1;
-          break;
-        }
-        need_more_params(cptr, "MODE +l");
-        break;
-      case 'i':         /* falls through for default case */
-        if (whatt == MODE_DEL)
-          while ((lp = chptr->invites))
-            del_invite(lp->value.cptr, chptr);
-      default:
-        for (ip = flags; *ip; ip += 2)
-          if (*(ip + 1) == *curr)
-            break;
-
-        if (*ip)
-        {
-          if (whatt == MODE_ADD)
-          {
-            if (*ip == MODE_PRIVATE)
-              newmode &= ~MODE_SECRET;
-            else if (*ip == MODE_SECRET)
-              newmode &= ~MODE_PRIVATE;
-            newmode |= *ip;
-          }
-          else
-            newmode &= ~*ip;
-        }
-        else if (!IsServer(cptr))
-         send_reply(cptr, ERR_UNKNOWNMODE, *curr);
-        break;
-    }
-    curr++;
-    /*
-     * Make sure mode strings such as "+m +t +p +i" are parsed
-     * fully.
-     */
-    if (!*curr && parc > 0)
-    {
-      curr = *++parv;
-      parc--;
-      /* If this was from a server, and it is the last
-       * parameter and it starts with a digit, it must
-       * be the creationtime.  --Run
-       */
-      if (IsServer(sptr))
-      {
-        if (parc == 1 && IsDigit(*curr))
-        {
-          newtime = atoi(curr);
-          if (newtime && chptr->creationtime == MAGIC_REMOTE_JOIN_TS)
-          {
-            chptr->creationtime = newtime;
-            *badop = 0;
-          }
-          gotts = 1;
-          if (newtime == 0)
-          {
-            *badop = 2;
-            hacknotice = 1;
-          }
-          else if (newtime > chptr->creationtime)
-          {                     /* It is a net-break ride if we have ops.
-                                   bounce modes if we have ops.  --Run */
-            if (doesdeop)
-              *badop = 2;
-            else if (chptr->creationtime == 0)
-            {
-              if (chptr->creationtime == 0 || doesop)
-                chptr->creationtime = newtime;
-              *badop = 0;
-            }
-            /* Bounce: */
-            else
-              *badop = 1;
-          }
-          /*
-           * A legal *badop can occur when two
-           * people join simultaneously a channel,
-           * Allow for 10 min of lag (and thus hacking
-           * on channels younger then 10 min) --Run
-           */
-          else if (*badop == 0 ||
-              chptr->creationtime > (TStime() - TS_LAG_TIME))
-          {
-            if (newtime < chptr->creationtime)
-              chptr->creationtime = newtime;
-            *badop = 0;
-          }
-          break;
-        }
-      }
-      else
-        *badop = 0;
-    }
-  }                             /* end of while loop for MODE processing */
-
-#ifdef OPER_MODE_LCHAN
-  /*
-   * Now reject non chan ops. Accept modes from opers on local channels
-   * even if they are deopped
-   */
-  if (!IsServer(cptr) &&
-      (!member_y || !(IsChanOp(member_y) ||
-                 IsOperOnLocalChannel(sptr, chptr->chname))))
-#else
-  if (!IsServer(cptr) && (!member_y || !IsChanOp(member_y)))
-#endif
-  {
-    *badop = 0;
-    return (opcnt || newmode != mode->mode || limitset || keychange) ? 0 : -1;
-  }
-
-  if (doesop && newtime == 0 && IsServer(sptr))
-    *badop = 2;
-
-  if (*badop >= 2 &&
-      (aconf = find_conf_byhost(cptr->confs, sptr->name, CONF_UWORLD)))
-    *badop = 4;
-
-#ifdef OPER_MODE_LCHAN
-  bounce = (*badop == 1 || *badop == 2 ||
-            (is_deopped(sptr, chptr) &&
-             !IsOperOnLocalChannel(sptr, chptr->chname))) ? 1 : 0;
-#else
-  bounce = (*badop == 1 || *badop == 2 || is_deopped(sptr, chptr)) ? 1 : 0;
-#endif
-
-  whatt = 0;
-  for (ip = flags; *ip; ip += 2) {
-    if ((*ip & newmode) && !(*ip & oldm.mode))
-    {
-      if (bounce)
-      {
-        if (bwhatt != MODE_DEL)
-        {
-          *bmbuf++ = '-';
-          bwhatt = MODE_DEL;
-        }
-        *bmbuf++ = *(ip + 1);
-      }
-      else
-      {
-        if (whatt != MODE_ADD)
-        {
-          *mbuf++ = '+';
-          whatt = MODE_ADD;
-        }
-        mode->mode |= *ip;
-        *mbuf++ = *(ip + 1);
-      }
-    }
-  }
-  for (ip = flags; *ip; ip += 2) {
-    if ((*ip & oldm.mode) && !(*ip & newmode))
-    {
-      if (bounce)
-      {
-        if (bwhatt != MODE_ADD)
-        {
-          *bmbuf++ = '+';
-          bwhatt = MODE_ADD;
-        }
-        *bmbuf++ = *(ip + 1);
-      }
-      else
-      {
-        if (whatt != MODE_DEL)
-        {
-          *mbuf++ = '-';
-          whatt = MODE_DEL;
-        }
-        mode->mode &= ~*ip;
-        *mbuf++ = *(ip + 1);
-      }
-    }
-  }
-  blen = nblen = 0;
-  if (limitset && !nusers && mode->limit)
-  {
-    if (bounce)
-    {
-      if (bwhatt != MODE_ADD)
-      {
-        *bmbuf++ = '+';
-        bwhatt = MODE_ADD;
-      }
-      *bmbuf++ = 'l';
-      sprintf(numeric, "%-15d", mode->limit);
-      if ((cp = strchr(numeric, ' ')))
-        *cp = '\0';
-      strcat(bpbuf, numeric);
-      blen += strlen(numeric);
-      strcat(bpbuf, " ");
-      strcat(nbpbuf, numeric);
-      nblen += strlen(numeric);
-      strcat(nbpbuf, " ");
-    }
-    else
-    {
-      if (whatt != MODE_DEL)
-      {
-        *mbuf++ = '-';
-        whatt = MODE_DEL;
-      }
-      mode->mode &= ~MODE_LIMIT;
-      mode->limit = 0;
-      *mbuf++ = 'l';
-    }
-  }
-  /*
-   * Reconstruct "+bkov" chain.
-   */
-  if (opcnt)
-  {
-    int i = 0;
-    char c = 0;
-    unsigned int prev_whatt = 0;
-
-    for (; i < opcnt; i++)
-    {
-      lp = &chops[i];
-      /*
-       * make sure we have correct mode change sign
-       */
-      if (whatt != (lp->flags & (MODE_ADD | MODE_DEL)))
-      {
-        if (lp->flags & MODE_ADD)
-        {
-          *mbuf++ = '+';
-          prev_whatt = whatt;
-          whatt = MODE_ADD;
-        }
-        else
-        {
-          *mbuf++ = '-';
-          prev_whatt = whatt;
-          whatt = MODE_DEL;
-        }
-      }
-      len = strlen(pbuf);
-      nlen = strlen(npbuf);
-      /*
-       * get c as the mode char and tmp as a pointer to
-       * the parameter for this mode change.
-       */
-      switch (lp->flags & MODE_WPARAS)
-      {
-        case MODE_CHANOP:
-          c = 'o';
-          cp = lp->value.cptr->name;
-          break;
-        case MODE_VOICE:
-          c = 'v';
-          cp = lp->value.cptr->name;
-          break;
-        case MODE_BAN:
-          /*
-           * I made this a bit more user-friendly (tm):
-           * nick = nick!*@*
-           * nick!user = nick!user@*
-           * user@host = *!user@host
-           * host.name = *!*@host.name    --Run
-           */
-          c = 'b';
-          cp = pretty_mask(lp->value.cp);
-          break;
-        case MODE_KEY:
-          c = 'k';
-          cp = lp->value.cp;
-          break;
-        case MODE_LIMIT:
-          c = 'l';
-          sprintf(numeric, "%-15d", nusers);
-          if ((cp = strchr(numeric, ' ')))
-            *cp = '\0';
-          cp = numeric;
-          break;
-      }
-
-      /* What could be added: cp+' '+' '+<TS>+'\0' */
-      if (len + strlen(cp) + 13 > MODEBUFLEN ||
-          nlen + strlen(cp) + NUMNICKLEN + 12 > MODEBUFLEN)
-        break;
-
-      switch (lp->flags & MODE_WPARAS)
-      {
-        case MODE_KEY:
-          if (strlen(cp) > KEYLEN)
-            *(cp + KEYLEN) = '\0';
-          if ((whatt == MODE_ADD && (*mode->key == '\0' ||
-               0 != ircd_strcmp(mode->key, cp))) ||
-              (whatt == MODE_DEL && (*mode->key != '\0')))
-          {
-            if (bounce)
-            {
-              if (*mode->key == '\0')
-              {
-                if (bwhatt != MODE_DEL)
-                {
-                  *bmbuf++ = '-';
-                  bwhatt = MODE_DEL;
-                }
-                strcat(bpbuf, cp);
-                blen += strlen(cp);
-                strcat(bpbuf, " ");
-                blen++;
-                strcat(nbpbuf, cp);
-                nblen += strlen(cp);
-                strcat(nbpbuf, " ");
-                nblen++;
-              }
-              else
-              {
-                if (bwhatt != MODE_ADD)
-                {
-                  *bmbuf++ = '+';
-                  bwhatt = MODE_ADD;
-                }
-                strcat(bpbuf, mode->key);
-                blen += strlen(mode->key);
-                strcat(bpbuf, " ");
-                blen++;
-                strcat(nbpbuf, mode->key);
-                nblen += strlen(mode->key);
-                strcat(nbpbuf, " ");
-                nblen++;
-              }
-              *bmbuf++ = c;
-              mbuf--;
-              if (*mbuf != '+' && *mbuf != '-')
-                mbuf++;
-              else
-                whatt = prev_whatt;
-            }
-            else
-            {
-              *mbuf++ = c;
-              strcat(pbuf, cp);
-              len += strlen(cp);
-              strcat(pbuf, " ");
-              len++;
-              strcat(npbuf, cp);
-              nlen += strlen(cp);
-              strcat(npbuf, " ");
-              nlen++;
-              if (whatt == MODE_ADD)
-                ircd_strncpy(mode->key, cp, KEYLEN);
-              else
-                *mode->key = '\0';
-            }
-          }
-          break;
-        case MODE_LIMIT:
-          if (nusers && nusers != mode->limit)
-          {
-            if (bounce)
-            {
-              if (mode->limit == 0)
-              {
-                if (bwhatt != MODE_DEL)
-                {
-                  *bmbuf++ = '-';
-                  bwhatt = MODE_DEL;
-                }
-              }
-              else
-              {
-                if (bwhatt != MODE_ADD)
-                {
-                  *bmbuf++ = '+';
-                  bwhatt = MODE_ADD;
-                }
-                sprintf(numeric, "%-15d", mode->limit);
-                if ((cp = strchr(numeric, ' ')))
-                  *cp = '\0';
-                strcat(bpbuf, numeric);
-                blen += strlen(numeric);
-                strcat(bpbuf, " ");
-                blen++;
-                strcat(nbpbuf, numeric);
-                nblen += strlen(numeric);
-                strcat(nbpbuf, " ");
-                nblen++;
-              }
-              *bmbuf++ = c;
-              mbuf--;
-              if (*mbuf != '+' && *mbuf != '-')
-                mbuf++;
-              else
-                whatt = prev_whatt;
-            }
-            else
-            {
-              *mbuf++ = c;
-              strcat(pbuf, cp);
-              len += strlen(cp);
-              strcat(pbuf, " ");
-              len++;
-              strcat(npbuf, cp);
-              nlen += strlen(cp);
-              strcat(npbuf, " ");
-              nlen++;
-              mode->limit = nusers;
-            }
-          }
-          break;
-        case MODE_CHANOP:
-        case MODE_VOICE:
-          member_y = find_member_link(chptr, lp->value.cptr);
-          if (lp->flags & MODE_ADD)
-          {
-            change = (~member_y->status) & CHFL_VOICED_OR_OPPED & lp->flags;
-            if (change && bounce)
-            {
-              if (lp->flags & MODE_CHANOP)
-                SetDeopped(member_y);
-
-              if (bwhatt != MODE_DEL)
-              {
-                *bmbuf++ = '-';
-                bwhatt = MODE_DEL;
-              }
-              *bmbuf++ = c;
-              strcat(bpbuf, lp->value.cptr->name);
-              blen += strlen(lp->value.cptr->name);
-              strcat(bpbuf, " ");
-              blen++;
-              sprintf_irc(nbpbuf + nblen, "%s%s ", NumNick(lp->value.cptr));
-              nblen += strlen(nbpbuf + nblen);
-              change = 0;
-            }
-            else if (change)
-            {
-              member_y->status |= lp->flags & CHFL_VOICED_OR_OPPED;
-              if (IsChanOp(member_y))
-              {
-                ClearDeopped(member_y);
-                if (IsServer(sptr))
-                  ClearServOpOk(member_y);
-              }
-            }
-          }
-          else
-          {
-            change = member_y->status & CHFL_VOICED_OR_OPPED & lp->flags;
-            if (change && bounce)
-            {
-              if (lp->flags & MODE_CHANOP)
-                ClearDeopped(member_y);
-              if (bwhatt != MODE_ADD)
-              {
-                *bmbuf++ = '+';
-                bwhatt = MODE_ADD;
-              }
-              *bmbuf++ = c;
-              strcat(bpbuf, lp->value.cptr->name);
-              blen += strlen(lp->value.cptr->name);
-              strcat(bpbuf, " ");
-              blen++;
-              sprintf_irc(nbpbuf + nblen, "%s%s ", NumNick(lp->value.cptr));
-              blen += strlen(bpbuf + blen);
-              change = 0;
-            }
-            else
-            {
-              member_y->status &= ~change;
-              if ((change & MODE_CHANOP) && IsServer(sptr))
-                SetDeopped(member_y);
-            }
-          }
-          if (change || *badop == 2 || *badop == 4)
-          {
-            *mbuf++ = c;
-            strcat(pbuf, cp);
-            len += strlen(cp);
-            strcat(pbuf, " ");
-            len++;
-            sprintf_irc(npbuf + nlen, "%s%s ", NumNick(lp->value.cptr));
-            nlen += strlen(npbuf + nlen);
-            npbuf[nlen++] = ' ';
-            npbuf[nlen] = 0;
-          }
-          else
-          {
-            mbuf--;
-            if (*mbuf != '+' && *mbuf != '-')
-              mbuf++;
-            else
-              whatt = prev_whatt;
-          }
-          break;
-        case MODE_BAN:
-/*
- * Only bans aren't bounced, it makes no sense to bounce last second
- * bans while propagating bans done before the net.rejoin. The reason
- * why I don't bounce net.rejoin bans is because it is too much
- * work to take care of too long strings adding the necessary TS to
- * net.burst bans -- RunLazy
- * We do have to check for *badop==2 now, we don't want HACKs to take
- * effect.
- *
- * Since BURST - I *did* implement net.rejoin ban bouncing. So now it
- * certainly makes sense to also bounce 'last second' bans (bans done
- * after the net.junction). -- RunHardWorker
- */
-          if ((change = (whatt & MODE_ADD) &&
-              !add_banid(sptr, chptr, cp, !bounce, !add_banid_called)))
-            add_banid_called = 1;
-          else
-            change = (whatt & MODE_DEL) && !del_banid(chptr, cp, !bounce);
-
-          if (bounce && change)
-          {
-            change = 0;
-            if ((whatt & MODE_ADD))
-            {
-              if (bwhatt != MODE_DEL)
-              {
-                *bmbuf++ = '-';
-                bwhatt = MODE_DEL;
-              }
-            }
-            else if ((whatt & MODE_DEL))
-            {
-              if (bwhatt != MODE_ADD)
-              {
-                *bmbuf++ = '+';
-                bwhatt = MODE_ADD;
-              }
-            }
-            *bmbuf++ = c;
-            strcat(bpbuf, cp);
-            blen += strlen(cp);
-            strcat(bpbuf, " ");
-            blen++;
-            strcat(nbpbuf, cp);
-            nblen += strlen(cp);
-            strcat(nbpbuf, " ");
-            nblen++;
-          }
-          if (change)
-          {
-            *mbuf++ = c;
-            strcat(pbuf, cp);
-            len += strlen(cp);
-            strcat(pbuf, " ");
-            len++;
-            strcat(npbuf, cp);
-            nlen += strlen(cp);
-            strcat(npbuf, " ");
-            nlen++;
-          }
-          else
-          {
-            mbuf--;
-            if (*mbuf != '+' && *mbuf != '-')
-              mbuf++;
-            else
-              whatt = prev_whatt;
-          }
-          break;
-      }
-    }                           /* for (; i < opcnt; i++) */
-  }                             /* if (opcnt) */
-
-  *mbuf++ = '\0';
-  *bmbuf++ = '\0';
-
-  /* Bounce here */
-  if (!hacknotice && *bmodebuf && chptr->creationtime)
-  {
-    sendcmdto_one(&me, CMD_MODE, cptr, "%H %s %s %Tu", chptr, bmodebuf,
-                 nbparambuf, *badop == 2 ? (time_t) 0 : chptr->creationtime);
-  }
-  /* If there are possibly bans to re-add, bounce them now */
-  if (add_banid_called && bounce)
-  {
-    struct SLink *ban[6];               /* Max 6 bans at a time */
-    size_t len[6], sblen, total_len;
-    int cnt, delayed = 0;
-    while (delayed || (ban[0] = next_overlapped_ban()))
-    {
-      len[0] = strlen(ban[0]->value.ban.banstr);
-      cnt = 1;                  /* We already got one ban :) */
-      /* XXX sendbuf used to send ban bounces! */
-      sblen = sprintf_irc(sendbuf, ":%s MODE %s +b", /* XXX set_mode only called by old m_mode */
-          me.name, chptr->chname) - sendbuf; /* XXX set_mode only called by old m_mode */
-      total_len = sblen + 1 + len[0];   /* 1 = ' ' */
-      /* Find more bans: */
-      delayed = 0;
-      while (cnt < 6 && (ban[cnt] = next_overlapped_ban()))
-      {
-        len[cnt] = strlen(ban[cnt]->value.ban.banstr);
-        if (total_len + 5 + len[cnt] > BUFSIZE) /* 5 = "b \r\n\0" */
-        {
-          delayed = cnt + 1;    /* != 0 */
-          break;                /* Flush */
-        }
-        sendbuf[sblen++] = 'b'; /* XXX set_mode only called by old m_mode */
-        total_len += 2 + len[cnt++];    /* 2 = "b " */
-      }
-      while (cnt--)
-      {
-        sendbuf[sblen++] = ' '; /* XXX set_mode only called by old m_mode */
-        strcpy(sendbuf + sblen, ban[cnt]->value.ban.banstr); /* XXX set_mode only called by old m_mode */
-        sblen += len[cnt];
-      }
-      sendbufto_one(cptr);      /* Send bounce to uplink */ /* XXX set_mode only called by old m_mode */
-      if (delayed)
-        ban[0] = ban[delayed - 1];
-    }
-  }
-  /* Send -b's of overlapped bans to clients to keep them synchronized */
-  if (add_banid_called && !bounce)
-  {
-    struct SLink *ban;
-    char *banstr[6];            /* Max 6 bans at a time */
-    size_t len[6], sblen, psblen, total_len;
-    int cnt, delayed = 0;
-    struct Membership* member_z;
-    struct Client *acptr;
-    if (IsServer(sptr))
-      /* XXX sendbuf used to send ban bounces! */
-      psblen = sprintf_irc(sendbuf, ":%s MODE %s -b", /* XXX set_mode only called by old m_mode */
-          sptr->name, chptr->chname) - sendbuf; /* XXX set_mode only called by old m_mode */
-    else                        /* We rely on IsRegistered(sptr) being true for MODE */
-      psblen = sprintf_irc(sendbuf, ":%s!%s@%s MODE %s -b", sptr->name, /* XXX set_mode only called by old m_mode */
-          sptr->user->username, sptr->user->host, chptr->chname) - sendbuf; /* XXX set_mode only called by old m_mode */
-    while (delayed || (ban = next_removed_overlapped_ban()))
-    {
-      if (!delayed)
-      {
-        len[0] = strlen((banstr[0] = ban->value.ban.banstr));
-        ban->value.ban.banstr = NULL;
-      }
-      cnt = 1;                  /* We already got one ban :) */
-      sblen = psblen;
-      total_len = sblen + 1 + len[0];   /* 1 = ' ' */
-      /* Find more bans: */
-      delayed = 0;
-      while (cnt < 6 && (ban = next_removed_overlapped_ban()))
-      {
-        len[cnt] = strlen((banstr[cnt] = ban->value.ban.banstr));
-        ban->value.ban.banstr = NULL;
-        if (total_len + 5 + len[cnt] > BUFSIZE) /* 5 = "b \r\n\0" */
-        {
-          delayed = cnt + 1;    /* != 0 */
-          break;                /* Flush */
-        }
-        sendbuf[sblen++] = 'b'; /* XXX set_mode only called by old m_mode */
-        total_len += 2 + len[cnt++];    /* 2 = "b " */
-      }
-      while (cnt--)
-      {
-        sendbuf[sblen++] = ' '; /* XXX set_mode only called by old m_mode */
-        strcpy(sendbuf + sblen, banstr[cnt]); /* XXX set_mode only called by old m_mode */
-        MyFree(banstr[cnt]);
-        sblen += len[cnt];
-      }
-      for (member_z = chptr->members; member_z; member_z = member_z->next_member) {
-        acptr = member_z->user;
-        if (MyConnect(acptr) && !IsZombie(member_z))
-          sendbufto_one(acptr); /* XXX set_mode only called by old m_mode */
-      }
-      if (delayed)
-      {
-        banstr[0] = banstr[delayed - 1];
-        len[0] = len[delayed - 1];
-      }
-    }
-  }
-
-  return gotts ? 1 : -1;
-}
-
 /* We are now treating the <key> part of /join <channel list> <key> as a key
  * ring; that is, we try one key against the actual channel key, and if that
  * doesn't work, we try the next one, and so on. -Kev -Texaco
@@ -2311,121 +1327,6 @@ void list_next_channels(struct Client *cptr, int nr)
   }
 }
 
-/* XXX AIEEEE! sendbuf is an institution here :( */
-void add_token_to_sendbuf(char *token, size_t *sblenp, int *firstp,
-    int *send_itp, char is_a_ban, int mode)
-{
-  int first = *firstp;
-
-  /*
-   * Heh - we do not need to test if it still fits in the buffer, because
-   * this BURST message is reconstructed from another BURST message, and
-   * it only can become smaller. --Run
-   */
-
-  if (*firstp)                  /* First token in this parameter ? */
-  {
-    *firstp = 0;
-    if (*send_itp == 0)
-      *send_itp = 1;            /* Buffer contains data to be sent */
-    sendbuf[(*sblenp)++] = ' '; /* XXX add_token_to_sendbuf only called by old m_burst */
-    if (is_a_ban)
-    {
-      sendbuf[(*sblenp)++] = ':';       /* Bans are always the last "parv" */ /* XXX add_token_to_sendbuf only called by old m_burst */
-      sendbuf[(*sblenp)++] = is_a_ban; /* XXX add_token_to_sendbuf only called by old m_burst */
-    }
-  }
-  else                          /* Of course, 'send_it' is already set here */
-    /* Seperate banmasks with a space because
-       they can contain commas themselfs: */
-    sendbuf[(*sblenp)++] = is_a_ban ? ' ' : ','; /* XXX add_token_to_sendbuf only called by old m_burst */
-  strcpy(sendbuf + *sblenp, token); /* XXX add_token_to_sendbuf only called by old m_burst */
-  *sblenp += strlen(token);
-  if (!is_a_ban)                /* nick list ? Need to take care
-                                   of modes for nicks: */
-  {
-    static int last_mode = 0;
-    mode &= CHFL_CHANOP | CHFL_VOICE;
-    if (first)
-      last_mode = 0;
-    if (last_mode != mode)      /* Append mode like ':ov' if changed */
-    {
-      last_mode = mode;
-      sendbuf[(*sblenp)++] = ':'; /* XXX add_token_to_sendbuf only called by old m_burst */
-      if (mode & CHFL_CHANOP)
-        sendbuf[(*sblenp)++] = 'o'; /* XXX add_token_to_sendbuf only called by old m_burst */
-      if (mode & CHFL_VOICE)
-        sendbuf[(*sblenp)++] = 'v'; /* XXX add_token_to_sendbuf only called by old m_burst */
-    }
-    sendbuf[*sblenp] = '\0'; /* XXX add_token_to_sendbuf only called by old m_burst */
-  }
-}
-
-void cancel_mode(struct Client *sptr, struct Channel *chptr, char m,
-                        const char *param, int *count)
-{
-  static char* pb;
-  static char* sbp;
-  static char* sbpi;
-  int          paramdoesntfit = 0;
-  char parabuf[MODEBUFLEN];
-
-  assert(0 != sptr);
-  assert(0 != chptr);
-  assert(0 != count);
-  
-  if (*count == -1)             /* initialize ? */
-  {
-    /* XXX sendbuf used! */
-    sbp = sbpi =
-        sprintf_irc(sendbuf, ":%s MODE %s -", sptr->name, chptr->chname); /* XXX cancel_mode only called from old ms_burst */
-    pb = parabuf;
-    *count = 0;
-  }
-  /* m == 0 means flush */
-  if (m)
-  {
-    if (param)
-    {
-      size_t nplen = strlen(param);
-      if (pb - parabuf + nplen + 23 > MODEBUFLEN)
-        paramdoesntfit = 1;
-      else
-      {
-        *sbp++ = m;
-        *pb++ = ' ';
-        strcpy(pb, param);
-        pb += nplen;
-        ++*count;
-      }
-    }
-    else
-      *sbp++ = m;
-  }
-  else if (*count == 0)
-    return;
-  if (*count == 6 || !m || paramdoesntfit)
-  {
-    struct Membership* member;
-    strcpy(sbp, parabuf);
-    for (member = chptr->members; member; member = member->next_member)
-      if (MyUser(member->user))
-        sendbufto_one(member->user); /* XXX cancel_mode only called from old ms_burst */
-    sbp = sbpi;
-    pb = parabuf;
-    *count = 0;
-  }
-  if (paramdoesntfit)
-  {
-    *sbp++ = m;
-    *pb++ = ' ';
-    strcpy(pb, param);
-    pb += strlen(param);
-    ++*count;
-  }
-}
-
-
 /*
  * Consider:
  *
@@ -2524,100 +1425,6 @@ int number_of_zombies(struct Channel *chptr)
   return count;
 }
 
-/*
- * send_hack_notice()
- *
- * parc & parv[] are the same as that of the calling function:
- *   mtype == 1 is from m_mode, 2 is from m_create, 3 is from m_kick.
- *
- * This function prepares sendbuf with the server notices and wallops
- *   to be sent for all hacks.  -Ghostwolf 18-May-97
- */
-/* XXX let's get rid of this if we can */
-void send_hack_notice(struct Client *cptr, struct Client *sptr, int parc,
-                      char *parv[], int badop, int mtype)
-{
-  struct Channel *chptr;
-  static char params[MODEBUFLEN];
-  int i = 3;
-  chptr = FindChannel(parv[1]);
-  *params = '\0';
-
-  /* P10 servers require numeric nick conversion before sending. */
-  switch (mtype)
-  {
-    case 1:                     /* Convert nicks for MODE HACKs here  */
-    {
-      char *mode = parv[2];
-      while (i < parc)
-      {
-        while (*mode && *mode != 'o' && *mode != 'v')
-          ++mode;
-        strcat(params, " ");
-        if (*mode == 'o' || *mode == 'v')
-        {
-          /*
-           * blindly stumble through parameter list hoping one of them
-           * might turn out to be a numeric nick
-           * NOTE: this should not cause a problem but _may_ end up finding
-           * something we aren't looking for. findNUser should be able to
-           * handle any garbage that is thrown at it, but may return a client
-           * if we happen to get lucky with a mode string or a timestamp
-           */
-          struct Client *acptr;
-          if ((acptr = findNUser(parv[i])) != NULL)     /* Convert nicks here */
-            strcat(params, acptr->name);
-          else
-          {
-            strcat(params, "<");
-            strcat(params, parv[i]);
-            strcat(params, ">");
-          }
-        }
-        else                    /* If it isn't a numnick, send it 'as is' */
-          strcat(params, parv[i]);
-        i++;
-      }
-      sprintf_irc(sendbuf, /* XXX send_hack_notice only called from old m_mode */
-          ":%s NOTICE * :*** Notice -- %sHACK(%d): %s MODE %s %s%s ["
-          TIME_T_FMT "]", me.name, (badop == 3) ? "BOUNCE or " : "", badop,
-          parv[0], parv[1], parv[2], params, chptr->creationtime);
-      sendbufto_op_mask((badop == 3) ? SNO_HACK3 : (badop == /* XXX DYING */ /* XXX send_hack_notice only called from old m_mode */
-          4) ? SNO_HACK4 : SNO_HACK2);
-
-      if ((IsServer(sptr)) && (badop == 2))
-      {
-        sprintf_irc(sendbuf, ":%s DESYNCH :HACK: %s MODE %s %s%s", /* XXX send_hack_notice only called from old m_mode */
-            me.name, parv[0], parv[1], parv[2], params);
-        sendbufto_serv_butone(cptr); /* XXX DYING */ /* XXX send_hack_notice only called from old m_mode */
-      }
-      break;
-    }
-    case 2:                     /* No conversion is needed for CREATE; the only numnick is sptr */
-    {
-      sendto_serv_butone(cptr, ":%s DESYNCH :HACK: %s CREATE %s %s", /* XXX DYING */
-          me.name, sptr->name, chptr->chname, parv[2]);
-      sendto_op_mask(SNO_HACK2, "HACK(2): %s CREATE %s %s", /* XXX DYING */
-          sptr->name, chptr->chname, parv[2]);
-      break;
-    }
-    case 3:                     /* Convert nick in KICK message */
-    {
-      struct Client *acptr;
-      if ((acptr = findNUser(parv[2])) != NULL) /* attempt to convert nick */
-        sprintf_irc(sendbuf, /* XXX send_hack_notice only called from old m_mode */
-            ":%s NOTICE * :*** Notice -- HACK: %s KICK %s %s :%s",
-            me.name, sptr->name, parv[1], acptr->name, parv[3]);
-      else                      /* if conversion fails, send it 'as is' in <>'s */
-        sprintf_irc(sendbuf, /* XXX send_hack_notice only called from old m_mode */
-            ":%s NOTICE * :*** Notice -- HACK: %s KICK %s <%s> :%s",
-            me.name, sptr->name, parv[1], parv[2], parv[3]);
-      sendbufto_op_mask(SNO_HACK4); /* XXX DYING */ /* XXX send_hack_notice only called from old m_mode */
-      break;
-    }
-  }
-}
-
 /*
  * This helper function builds an argument string in strptr, consisting
  * of the original string, a space, and str1 and str2 concatenated (if,
@@ -3994,7 +2801,7 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
 
   /* figure out if channel name will cause buffer to be overflowed */
   len = chan ? strlen(chan->chname) + 1 : 2;
-  if (jbuf->jb_strlen + len > IRC_BUFSIZE)
+  if (jbuf->jb_strlen + len > BUFSIZE)
     joinbuf_flush(jbuf);
 
   /* add channel to list of channels to send and update counts */
@@ -4012,7 +2819,7 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
 int
 joinbuf_flush(struct JoinBuf *jbuf)
 {
-  char chanlist[IRC_BUFSIZE];
+  char chanlist[BUFSIZE];
   int chanlist_i = 0;
   int i;
 
index be96d72f6ed1809da3d78375ea3d0750fe859e9a..c6bc38f55f612601236d77d88e17ffd9941a750f 100644 (file)
@@ -165,7 +165,7 @@ int dbuf_put(struct DBuf *dyn, const char *buf, unsigned int length)
          * attempt to recover from buffer starvation before
          * bailing this may help servers running out of memory
          */
-        flush_sendq_except(dyn);
+        flush_sendq_except();
         if (0 == (db = dbuf_alloc()))
 #endif
           return dbuf_malloc_error(dyn);
index 0e4a2c601b0deb863cce09d68fa8c310f8ada57b..aa448881afae75fd142e74303a97ccbab6845c34 100644 (file)
@@ -26,8 +26,9 @@
 #include "client.h"
 #include "ircd.h"
 #include "ircd_snprintf.h"
-#include "numeric.h"
 #include "msg.h"
+#include "msgq.h"
+#include "numeric.h"
 #include "s_conf.h"
 #include "s_debug.h"
 #include "send.h"
@@ -64,63 +65,10 @@ int need_more_params(struct Client* cptr, const char* cmd)
   return 0;
 }
 
-/*
- * send_error_to_client - send an error message to a client
- * I don't know if this function is any faster than the other version
- * but it is a bit easier to use. It's reentrant until it hits vsendto_one
- * at least :) --Bleep
- */
-int send_error_to_client(struct Client* cptr, int error, ...)
-{
-  va_list               vl;
-  char                  buf[BUFSIZE];
-  char*                 dest = buf;
-  const char*           src  = me.name;
-  const struct Numeric* num  = get_error_numeric(error);
-
-  assert(0 != cptr);
-  assert(0 != num);
-  /*
-   * prefix
-   */
-  *dest++ = ':';
-  while ((*dest = *src++))
-    ++dest;
-  *dest++ = ' ';
-  /*
-   * numeric
-   */
-  src = num->str;
-  while ((*dest = *src++))
-    ++dest;
-  *dest++ = ' ';
-  /*
-   * client name (nick)
-   */
-  src = cptr->name;
-  while ((*dest = *src++))
-    ++dest;
-  *dest++ = ' ';
-  /*
-   * reply format
-   */
-  strcpy(dest, num->format);
-
-#if 0
-  Debug((DEBUG_INFO, "send_error_to_client: format: ->%s<-", buf));
-#endif
-
-  va_start(vl, error);
-  vsendto_one(cptr, buf, vl);
-  va_end(vl);
-  return 0;
-}
-
-
 int send_reply(struct Client *to, int reply, ...)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   const struct Numeric *num;
 
   assert(0 != to);
@@ -138,13 +86,14 @@ int send_reply(struct Client *to, int reply, ...)
   assert(0 != vd.vd_format);
 
   /* build buffer */
-  ircd_snprintf(to->from, sndbuf, sizeof(sndbuf) - 2, "%:#C %s %C %v", &me,
-               num->str, to, &vd);
+  mb = msgq_make(to->from, "%:#C %s %C %v", &me, num->str, to, &vd);
 
   va_end(vd.vd_args);
 
   /* send it to the user */
-  send_buffer(to, sndbuf);
+  send_buffer(to, mb, 0);
+
+  msgq_clean(mb);
 
   return 0; /* convenience return */
 }
index 8af61ae4752b29b2c0cd5a94164f354fd6b1c978..0d6cc5035fef9f945e7222d601326764a21e3b1f 100644 (file)
@@ -181,7 +181,7 @@ void free_client(struct Client* cptr)
     if (-1 < cptr->fd) {
       close(cptr->fd);
     }
-    DBufClear(&cptr->sendQ);
+    MsgQClear(&cptr->sendQ);
     DBufClear(&cptr->recvQ);
     if (cptr->listener)
       release_listener(cptr->listener);
index f6ce0e3df52abef023ecd28c20da99e9be30f2ff..1123b5e9d77474119d30dd573fec987f792389c0 100644 (file)
@@ -418,7 +418,7 @@ void accept_connection(struct Listener* listener)
      * turns out too many messages are generated for meaningless reasons we
      * can filter them back.
      */
-    sendto_op_mask(SNO_TCPCOMMON,"Unable to accept connection: %s", strerror(errno));
+    sendto_opmask_butone(0, SNO_TCPCOMMON, "Unable to accept connection: %m");
     return;
   }
   /*
index ceb8c9bbe3844771b04030042a2dfaf8cc02ec96..faf51d34463a98d511323bc5e2fb2d2e3a8112aa 100644 (file)
@@ -148,7 +148,7 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   struct SLink *lp, **lp_p;
   unsigned int parse_flags = (MODE_PARSE_FORCE | MODE_PARSE_BURST);
   int param, nickpos = 0, banpos = 0;
-  char modestr[IRC_BUFSIZE], nickstr[IRC_BUFSIZE], banstr[IRC_BUFSIZE];
+  char modestr[BUFSIZE], nickstr[BUFSIZE], banstr[BUFSIZE];
 
   if (parc < 4)
     return protocol_violation(sptr,"Too few parameters for BURST");
@@ -376,1407 +376,3 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 
   return mbuf ? modebuf_flush(mbuf) : 0;
 }
-#if 0
-int ms_burst(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
-{
-  struct Channel* chptr;
-  time_t          timestamp;
-  int             netride = 0;
-  int             wipeout = 0;
-  int             n;
-  int             send_it = 0;
-  int             add_banid_not_called = 1;
-  struct Mode*    current_mode;
-  size_t          sblen;
-  size_t          mblen = 0;
-  int             mblen2;
-  int             pblen2;
-  int             cnt;
-  int             prev_mode;
-  char            prev_key[KEYLEN + 1];
-  struct Membership* member;
-  struct SLink*   lp;
-  char modebuf[MODEBUFLEN];
-  char parabuf[MODEBUFLEN];
-  char bmodebuf[MODEBUFLEN];
-  char bparambuf[MODEBUFLEN];
-
-  /* BURST is only for servers and has at least 4 parameters */
-  if (!IsServer(cptr) || parc < 4)
-    return 0;
-
-  if (!IsBurst(sptr))
-  {
-    int i;
-    char *p;
-    if (find_conf_byhost(cptr->confs, sptr->name, CONF_UWORLD))
-    {
-      p =
-          sprintf_irc(sendbuf, /* XXX DYING */
-          ":%s NOTICE * :*** Notice -- HACK(4): %s BURST %s %s", me.name,
-          sptr->name, parv[1], parv[2]);
-      for (i = 3; i < parc - 1; ++i)
-        p = sprintf_irc(p, " %s", parv[i]);
-      sprintf_irc(p, " :%s", parv[parc - 1]);
-      sendbufto_op_mask(SNO_HACK4); /* XXX DYING */
-    }
-    else
-    {
-#if 1            /* FIXME: This should be removed after all HUBs upgraded to ircu2.10.05 */
-      SetBurst(sptr);
-      if (MyConnect(sptr))
-#endif
-        return exit_client_msg(cptr, cptr, &me,
-            "HACK: BURST message outside net.burst from %s", sptr->name);
-    }
-  }
-
-  /* Find the channel, or create it - note that the creation time
-   * will be 0 if it has to be created */
-  chptr = get_channel(sptr, parv[1], CGT_CREATE);
-  current_mode = &chptr->mode;
-  prev_mode = chptr->mode.mode;
-  if (*chptr->mode.key)
-  {
-    prev_mode |= MODE_KEY;
-    strcpy(prev_key, chptr->mode.key);
-  }
-  if (chptr->mode.limit)
-    prev_mode |= MODE_LIMIT;
-
-  timestamp = atoi(parv[2]);
-
-  /* Copy the new TS when the received creationtime appears to be older */
-  if (!chptr->creationtime || chptr->creationtime > timestamp)
-  {
-    /* Set the new timestamp */
-    chptr->creationtime = timestamp;
-    send_it = 1;                /* Make sure we pass on the different timestamp ! */
-    /* Mark all bans as needed to be wiped out */
-    for (lp = chptr->banlist; lp; lp = lp->next)
-      lp->flags |= CHFL_BURST_BAN_WIPEOUT;
-    /*
-     * Only the first BURST for this channel can have creationtime > timestamp,
-     * so at this moment ALL members are on OUR side, and thus all net.riders:
-     */
-    wipeout = 1;
-  }
-  for (member = chptr->members; member; member = member->next_member)
-    member->status &= ~CHFL_BURST_JOINED;    /* Set later for nicks in the BURST msg */
-  /* If `wipeout' is set then these will be deopped later. */
-
-  /* If the entering creationtime is younger, ignore the modes */
-  if (chptr->creationtime < timestamp)
-    netride = 1;                /* Only pass on the nicks (so they JOIN) */
-
-  /* Prepare buffers to pass the message */
-  *bparambuf = *bmodebuf = *parabuf = '\0';
-  pblen2 = 0;
-  *modebuf = '+';
-  mblen2 = 1;
-  cnt = 0;
-  sblen = sprintf_irc(sendbuf, "%s B %s " TIME_T_FMT, /* XXX DYING */
-      NumServ(sptr), chptr->chname, chptr->creationtime) - sendbuf; /* XXX DYING */
-
-  /* Run over all remaining parameters */
-  for (n = 3; n < parc; n++)
-    switch (*parv[n])           /* What type is it ? mode, nicks or bans ? */
-    {
-      case '+':         /* modes */
-      {
-        char *p = parv[n];
-        while (*(++p))          /* Run over all mode characters */
-        {
-          switch (*p)           /* which mode ? */
-          {
-              /*
-               * The following cases all do the following:
-               * - In case wipeout needed, reset 'prev_mode' to indicate this
-               *   mode should not be cancelled.
-               * - If wipeout or (not netride and the new mode is a change),
-               *   add it to bmodebuf and bparabuf for propagation.
-               * - Else ignore it.
-               * - Add it to modebuf and parabuf for propagation to the
-               *   clients when not netride and the new mode is a change.
-               * Special cases:
-               * - If a +s is received, cancel a +p and sent a -p to the
-               *   clients too (if +p was set).
-               * - If a +p is received and +s is set, ignore the +p.
-               */
-            case 'i':
-            {
-              int tmp;
-              prev_mode &= ~MODE_INVITEONLY;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_INVITEONLY)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'i';
-                current_mode->mode |= MODE_INVITEONLY;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'i';
-              break;
-            }
-            case 'k':
-            {
-              int tmp;
-              char *param = parv[++n];
-              prev_mode &= ~MODE_KEY;
-              if (!(tmp = netride || (*current_mode->key &&
-                  (!strcmp(current_mode->key, param) ||
-                  (!wipeout && strcmp(current_mode->key, param) < 0)))) ||
-                  wipeout)
-              {
-                bmodebuf[mblen++] = 'k';
-                strcat(bparambuf, " ");
-                strcat(bparambuf, param);
-                ircd_strncpy(current_mode->key, param, KEYLEN);
-              }
-              if (!tmp && !wipeout)
-              {
-                modebuf[mblen2++] = 'k';
-                parabuf[pblen2++] = ' ';
-                strcpy(parabuf + pblen2, param);
-                pblen2 += strlen(param);
-                cnt++;
-              }
-              break;
-            }
-            case 'l':
-            {
-              int tmp;
-              unsigned int param = atoi(parv[++n]);
-              prev_mode &= ~MODE_LIMIT;
-              if (!(tmp = netride || (current_mode->limit &&
-                  (current_mode->limit == param ||
-                  (!wipeout && current_mode->limit < param)))) || wipeout)
-              {
-                bmodebuf[mblen++] = 'l';
-                sprintf_irc(bparambuf + strlen(bparambuf), " %d", param);
-                current_mode->limit = param;
-              }
-              if (!tmp)
-              {
-                modebuf[mblen2++] = 'l';
-                pblen2 = sprintf_irc(parabuf + pblen2, " %d", param) - parabuf;
-                cnt++;
-              }
-              break;
-            }
-            case 'm':
-            {
-              int tmp;
-              prev_mode &= ~MODE_MODERATED;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_MODERATED)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'm';
-                current_mode->mode |= MODE_MODERATED;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'm';
-              break;
-            }
-            case 'n':
-            {
-              int tmp;
-              prev_mode &= ~MODE_NOPRIVMSGS;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_NOPRIVMSGS)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'n';
-                current_mode->mode |= MODE_NOPRIVMSGS;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'n';
-              break;
-            }
-            case 'p':
-            {
-              int tmp;
-
-              /* Special case: */
-              if (!netride && !wipeout && (current_mode->mode & MODE_SECRET))
-                break;
-
-              prev_mode &= ~MODE_PRIVATE;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_PRIVATE)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'p';
-                current_mode->mode |= MODE_PRIVATE;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'p';
-              break;
-            }
-            case 's':
-            {
-              int tmp;
-              prev_mode &= ~MODE_SECRET;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_SECRET)) || wipeout)
-              {
-                bmodebuf[mblen++] = 's';
-                current_mode->mode |= MODE_SECRET;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 's';
-
-              /* Special case: */
-              if (!netride && !wipeout && (current_mode->mode & MODE_PRIVATE))
-              {
-                int i;
-                for (i = mblen2 - 1; i >= 0; --i)
-                  modebuf[i + 2] = modebuf[i];
-                modebuf[0] = '-';
-                modebuf[1] = 'p';
-                mblen2 += 2;
-                current_mode->mode &= ~MODE_PRIVATE;
-              }
-
-              break;
-            }
-            case 't':
-            {
-              int tmp;
-              prev_mode &= ~MODE_TOPICLIMIT;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_TOPICLIMIT)) || wipeout)
-              {
-                bmodebuf[mblen++] = 't';
-                current_mode->mode |= MODE_TOPICLIMIT;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 't';
-              break;
-            }
-          }
-        }                       /* <-- while over all modes */
-
-        bmodebuf[mblen] = '\0';
-        sendbuf[sblen] = '\0'; /* XXX DYING */
-        if (mblen)              /* Anything to send at all ? */
-        {
-          send_it = 1;
-          strcpy(sendbuf + sblen, " +"); /* XXX DYING */
-          sblen += 2;
-          strcpy(sendbuf + sblen, bmodebuf); /* XXX DYING */
-          sblen += mblen;
-          strcpy(sendbuf + sblen, bparambuf); /* XXX DYING */
-          sblen += strlen(bparambuf);
-        }
-        break;                  /* Done mode part */
-      }
-      case '%':         /* bans */
-      {
-        char *pv, *p = 0, *ban;
-        int first = 1;
-        if (netride)
-          break;                /* Ignore bans */
-        /* Run over all bans */
-        for (pv = parv[n] + 1; (ban = ircd_strtok(&p, pv, " ")); pv = 0)
-        {
-          int ret;
-          /*
-           * The following part should do the following:
-           * - If the new (un)ban is not a _change_ it is ignored.
-           * - Else, add it to sendbuf for later use.
-           * - If sendbuf is full, send it, and prepare a new
-           *   message in sendbuf.
-           */
-          ret = add_banid(sptr, chptr, ban, 1, add_banid_not_called);
-          if (ret == 0)
-          {
-            add_banid_not_called = 0;
-            /* Mark this new ban so we can send it to the clients later */
-            chptr->banlist->flags |= CHFL_BURST_BAN;
-          }
-          if (ret != -1)
-            /* A new ban was added or an existing one needs to be passed on.
-             * Also add it to sendbuf: */
-            add_token_to_sendbuf(ban, &sblen, &first, &send_it, '%', 0); /* XXX DYING */
-        }
-        break;                  /* Done bans part */
-      }
-      default:                  /* nicks */
-      {
-        char *pv, *p = 0, *nick, *ptr;
-        int first = 1;
-        /* Default mode: */
-        int default_mode = CHFL_DEOPPED;
-        /* Run over all nicks */
-        for (pv = parv[n]; (nick = ircd_strtok(&p, pv, ",")); pv = 0)
-        {
-          struct Client *acptr;
-          if ((ptr = strchr(nick, ':')))        /* New default mode ? */
-          {
-            *ptr = '\0';        /* Fix 'nick' */
-            acptr = findNUser(nick);
-            if (!netride)
-            {
-              /* Calculate new mode change: */
-              default_mode = CHFL_DEOPPED;
-              while (*(++ptr))
-                if (*ptr == 'o')
-                {
-                  default_mode |= CHFL_CHANOP;
-                  default_mode &= ~CHFL_DEOPPED;
-                }
-                else if (*ptr == 'v')
-                  default_mode |= CHFL_VOICE;
-                else
-                  break;
-            }
-          }
-          else
-            acptr = findNUser(nick);
-          /*
-           * Note that at this point we already received a 'NICK' for any
-           * <nick> numeric that is joining (and possibly opped) here.
-           * Therefore we consider the following situations:
-           * - The <nick> numeric exists and is from the direction of cptr: ok
-           * - The <nick> numeric does not exist:
-           *   Apparently this previous <nick> numeric was killed (upstream)
-           *   or it collided with an existing <nick> name.
-           * - The <nick> numeric exists but is from another direction:
-           *   Apparently this previous <nick> numeric was killed,
-           *   and due to a reroute it signed on via another link (probably
-           *   a nick [numeric] collision).
-           * Note that it can't be a QUIT or SQUIT, because a QUIT would
-           * come from the same direction as the BURST (cptr) while an
-           * upstream SQUIT removes the source (server) and we would thus
-           * have this BURST ignored already.
-           * This means that if we find the nick and it is from the correct
-           * direction, it joins. If it doesn't exist or is from another
-           * direction, we have to ignore it. If all nicks are ignored, we
-           * remove the channel again when it is empty and don't propagate
-           * the BURST message.
-           */
-          if (acptr && acptr->from == cptr)
-          {
-            /*
-             * The following should do the following:
-             * - Add it to sendbuf for later use.
-             * - If sendbuf is full, send it, and prepare a new
-             *   message in sendbuf.
-             */
-            add_token_to_sendbuf(nick, &sblen, &first, &send_it, 0, /* XXX DYING */
-                default_mode);
-            /* Let is take effect: (Note that in the case of a netride
-             * 'default_mode' is always CHFL_DEOPPED here). */
-            add_user_to_channel(chptr, acptr, default_mode | CHFL_BURST_JOINED);
-          }
-        }                       /* <-- Next nick */
-        if (!chptr->members)    /* All nicks collided and channel is empty ? */
-        {
-          sub1_from_channel(chptr);
-          return 0;             /* Forget about the (rest of the) message... */
-        }
-        break;                  /* Done nicks part */
-      }
-    }                           /* <-- Next parameter if any */
-  if (!chptr->members)          /* This message only contained bans (then the previous
-                                   message only contained collided nicks, see above) */
-  {
-    sub1_from_channel(chptr);
-    if (!add_banid_not_called)
-      while (next_removed_overlapped_ban());
-    return 0;                   /* Forget about the (rest of the) message... */
-  }
-
-  /* The last (possibly only) message is always send here */
-  if (send_it)                  /* Anything (left) to send ? */
-  {
-    struct DLink *lp;
-    struct Membership* member;
-
-    /* send 'sendbuf' to all downlinks */
-    for (lp = me.serv->down; lp; lp = lp->next)
-    {
-      if (lp->value.cptr == cptr)
-        continue;
-      if (Protocol(lp->value.cptr) > 9)
-        sendbufto_one(lp->value.cptr); /* XXX DYING */
-    }
-
-    /*
-     * Now we finally can screw sendbuf again...
-     * Send all changes to the local clients:
-     *
-     * First send all joins and op them, because 2.9 servers
-     * would protest with a HACK if we first de-opped people.
-     * However, we don't send the +b bans yes, because we
-     * DO first want to -b the old bans (otherwise it's confusing).
-     */
-
-    /* Send all joins: */
-    for (member = chptr->members; member; member = member->next_member)
-      if (IsBurstJoined(member))
-      {
-        sendto_channel_butserv(chptr, member->user, ":%s JOIN :%s", /* XXX DYING */
-                               member->user->name, chptr->chname);
-      }
-
-    if (!netride)
-    {
-      /* Send all +o and +v modes: */
-      for (member = chptr->members; member; member = member->next_member)
-      {
-        if (IsBurstJoined(member))
-        {
-          int mode = CHFL_CHANOP;
-          for (;;)
-          {
-            if ((member->status & mode))
-            {
-              modebuf[mblen2++] = (mode == CHFL_CHANOP) ? 'o' : 'v';
-              parabuf[pblen2++] = ' ';
-              strcpy(parabuf + pblen2, member->user->name);
-              pblen2 += strlen(member->user->name);
-              if (6 == ++cnt)
-              {
-                modebuf[mblen2] = 0;
-                sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DYING */
-                    parv[0], chptr->chname, modebuf, parabuf);
-                *parabuf = 0;
-                pblen2 = 0;
-                mblen2 = 1;
-                cnt = 0;
-              }
-            }
-            if (mode == CHFL_CHANOP)
-              mode = CHFL_VOICE;
-            else
-              break;
-          }
-        }
-      }
-      /* Flush MODEs: */
-      if (cnt > 0 || mblen2 > 1)
-      {
-        modebuf[mblen2] = 0;
-        sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DYING */
-            parv[0], chptr->chname, modebuf, parabuf);
-      }
-    }
-  }
-
-  if (wipeout)
-  {
-    struct Membership* member;
-    struct SLink**     ban;
-    int                mode;
-    char               m;
-    int                count = -1;
-
-    /* Now cancel all previous simple modes */
-    if ((prev_mode & MODE_SECRET))
-      cancel_mode(sptr, chptr, 's', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_PRIVATE))
-      cancel_mode(sptr, chptr, 'p', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_MODERATED))
-      cancel_mode(sptr, chptr, 'm', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_TOPICLIMIT))
-      cancel_mode(sptr, chptr, 't', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_INVITEONLY))
-      cancel_mode(sptr, chptr, 'i', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_NOPRIVMSGS))
-      cancel_mode(sptr, chptr, 'n', 0, &count); /* XXX DYING */
-    if ((prev_mode & MODE_LIMIT))
-    {
-      current_mode->limit = 0;
-      cancel_mode(sptr, chptr, 'l', 0, &count); /* XXX DYING */
-    }
-    if ((prev_mode & MODE_KEY))
-    {
-      *current_mode->key = 0;
-      cancel_mode(sptr, chptr, 'k', prev_key, &count); /* XXX DYING */
-    }
-    current_mode->mode &= ~prev_mode;
-
-    /* And deop and devoice all net.riders on my side */
-    mode = CHFL_CHANOP;
-    m = 'o';
-    for (;;)
-    {
-      struct Membership* member_next = 0;
-
-      for (member = chptr->members; member; member = member_next)
-      {
-        member_next = member->next_member;
-        if (IsBurstJoined(member))
-          continue;             /* This is not a net.rider from
-                                   this side of the net.junction */
-#if defined(NO_INVITE_NETRIDE)
-        /*
-         * Kick net riding users from invite only channels.
-         *  - Isomer 25-11-1999
-         */
-        if (chptr->mode.mode & MODE_INVITEONLY) {
-          /* kick is magical - lotsa zombies and other undead.
-           * I'm hoping this is the right idea, comments anyone?
-           * Set everyone to a zombie, remove ops, and then send kicks
-           * everywhere...
-           */
-           if (IsZombie(member)) { /* don't kick ppl twice */
-                member->status = member->status & ~mode;
-                continue;
-           }
-
-           sendto_highprot_butone(0, 10, "%s " TOK_KICK " %s %s%s :Net Rider", /* XXX DYING */
-            NumServ(&me), chptr->chname, NumNick(member->user));
-           sendto_channel_butserv(chptr, sptr, /* XXX DYING */
-            ":%s KICK %s %s :Net Rider", me.name, chptr->chname,
-            member->user->name);
-
-           if (MyUser(member->user)) {
-             sendto_lowprot_butone(0, 9, ":%s PART %s", /* XXX DYING */
-               member->user->name, chptr->chname, member->user->name);
-             sendto_highprot_butone(0, 10, "%s%s PART %s", /* XXX DYING */
-               NumNick(member->user), chptr->chname);
-             remove_user_from_channel(member->user, chptr);
-           }
-           else {
-             member->status = (member->status & ~mode) | CHFL_ZOMBIE;
-           }
-           continue;
-        }
-#endif /* defined(NO_INVITE_NETRIDE) */
-        if ((member->status & mode))
-        {
-          member->status &= ~mode;
-          if (mode == CHFL_CHANOP)
-            SetDeopped(member);
-          cancel_mode(sptr, chptr, m, member->user->name, &count); /* XXX DYING */
-        }
-      }
-      if (mode == CHFL_VOICE)
-        break;
-      mode = CHFL_VOICE;
-      m = 'v';
-    }
-
-    /* And finally wipeout all bans that are left */
-    for (ban = &chptr->banlist; *ban; ) {
-      struct SLink* tmp = *ban;
-      if ((tmp->flags & CHFL_BURST_BAN_WIPEOUT)) {
-        struct Membership* member_z;
-
-        *ban = tmp->next;
-        cancel_mode(sptr, chptr, 'b', tmp->value.ban.banstr, &count); /* XXX DYING */
-
-        /* Copied from del_banid(): */
-        MyFree(tmp->value.ban.banstr);
-        MyFree(tmp->value.ban.who);
-        free_link(tmp);
-
-        /* Erase ban-valid-bit, for channel members that are banned */
-        for (member_z = chptr->members; member_z; member_z = member_z->next_member)
-          if ((member_z->status & CHFL_BANVALIDMASK) == CHFL_BANVALIDMASK)
-            ClearBanValid(member_z);
-      }
-      else
-        ban = &tmp->next;
-    }
-    /* Also wipeout overlapped bans */
-    if (!add_banid_not_called)
-    {
-      struct SLink *ban;
-      while ((ban = next_removed_overlapped_ban()))
-        cancel_mode(sptr, chptr, 'b', ban->value.ban.banstr, &count); /* XXX DYING */
-    }
-    cancel_mode(sptr, chptr, 0, 0, &count);  /* flush */ /* XXX DYING */
-  }
-
-  if (send_it && !netride)
-  {
-    struct SLink *bl;
-    int deban;
-
-    if (add_banid_not_called || !(bl = next_removed_overlapped_ban()))
-    {
-      deban = 0;
-      bl = chptr->banlist;
-      *modebuf = '+';
-    }
-    else
-    {
-      deban = 1;
-      *modebuf = '-';
-    }
-
-    mblen2 = 1;
-    pblen2 = 0;
-    cnt = 0;
-    for (;;)
-    {
-      size_t nblen = 0;
-      if (bl)
-        nblen = strlen(bl->value.ban.banstr);
-      if (cnt == 6 || (!bl && cnt) || pblen2 + nblen + 12 > MODEBUFLEN) /* The last check is to make sure
-                                                                           that the receiving 2.9 will
-                                                                           still process this */
-      {
-        /* Time to send buffer */
-        modebuf[mblen2] = 0;
-        sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DYING */
-            parv[0], chptr->chname, modebuf, parabuf);
-        *modebuf = deban ? '-' : '+';
-        mblen2 = 1;
-        pblen2 = 0;
-        cnt = 0;
-      }
-      if (!bl)                  /* Done ? */
-        break;
-      if (deban || (bl->flags & CHFL_BURST_BAN))
-      {
-        /* Add ban to buffers and remove it */
-        modebuf[mblen2++] = 'b';
-        parabuf[pblen2++] = ' ';
-        strcpy(parabuf + pblen2, bl->value.ban.banstr);
-        pblen2 += nblen;
-        cnt++;
-        bl->flags &= ~CHFL_BURST_BAN;
-      }
-      if (deban)
-      {
-        if (!(bl = next_removed_overlapped_ban()))
-        {
-          deban = 0;
-          modebuf[mblen2++] = '+';
-          bl = chptr->banlist;
-        }
-      }
-      else
-        bl = bl->next;
-    }
-    /* Flush MODE [-b]+b ...: */
-    if (cnt > 0 || mblen2 > 1)
-    {
-      modebuf[mblen2] = 0;
-      sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DYING */
-          parv[0], chptr->chname, modebuf, parabuf);
-    }
-  }
-  return 0;
-}
-#endif
-
-#if 0
-/*
- * m_burst  --  by Run carlo@runaway.xs4all.nl  december 1995 till march 1997
- *
- * parv[0] = sender prefix
- * parv[1] = channel name
- * parv[2] = channel timestamp
- * The meaning of the following parv[]'s depend on their first character:
- * If parv[n] starts with a '+':
- * Net burst, additive modes
- *   parv[n] = <mode>
- *   parv[n+1] = <param> (optional)
- *   parv[n+2] = <param> (optional)
- * If parv[n] starts with a '%', then n will be parc-1:
- *   parv[n] = %<ban> <ban> <ban> ...
- * If parv[n] starts with another character:
- *   parv[n] = <nick>[:<mode>],<nick>[:<mode>],...
- *   where <mode> is the channel mode (ov) of nick and all following nicks.
- *
- * Example:
- * "S BURST #channel 87654321 +ntkl key 123 AAA,AAB:o,BAA,BAB:ov :%ban1 ban2"
- *
- * Anti net.ride code.
- *
- * When the channel already exist, and its TS is larger then
- * the TS in the BURST message, then we cancel all existing modes.
- * If its is smaller then the received BURST message is ignored.
- * If it's equal, then the received modes are just added.
- */
-int m_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
-  struct Channel* chptr;
-  time_t          timestamp;
-  int             netride = 0;
-  int             wipeout = 0;
-  int             n;
-  int             send_it = 0;
-  int             add_banid_not_called = 1;
-  struct Mode*    current_mode;
-  size_t          sblen;
-  size_t          mblen = 0;
-  int             mblen2;
-  int             pblen2;
-  int             cnt;
-  int             prev_mode;
-  char            prev_key[KEYLEN + 1];
-  struct Membership* member;
-  struct SLink*   lp;
-  char modebuf[MODEBUFLEN];
-  char parabuf[MODEBUFLEN];
-  char bmodebuf[MODEBUFLEN];
-  char bparambuf[MODEBUFLEN];
-
-  /* BURST is only for servers and has at least 4 parameters */
-  if (!IsServer(cptr) || parc < 4)
-    return 0;
-
-  if (!IsBurst(sptr))
-  {
-    int i;
-    char *p;
-    if (find_conf_byhost(cptr->confs, sptr->name, CONF_UWORLD))
-    {
-      p =
-          sprintf_irc(sendbuf, /* XXX DEAD */
-          ":%s NOTICE * :*** Notice -- HACK(4): %s BURST %s %s", me.name,
-          sptr->name, parv[1], parv[2]);
-      for (i = 3; i < parc - 1; ++i)
-        p = sprintf_irc(p, " %s", parv[i]);
-      sprintf_irc(p, " :%s", parv[parc - 1]);
-      sendbufto_op_mask(SNO_HACK4); /* XXX DEAD */
-    }
-    else
-    {
-#if 1                           /* FIXME: This should be removed after all HUBs upgraded to ircu2.10.05 */
-      SetBurst(sptr);
-      if (MyConnect(sptr))
-#endif
-        return exit_client_msg(cptr, cptr, &me,
-            "HACK: BURST message outside net.burst from %s", sptr->name);
-    }
-  }
-
-  /* Find the channel, or create it - note that the creation time
-   * will be 0 if it has to be created */
-  chptr = get_channel(sptr, parv[1], CGT_CREATE);
-  current_mode = &chptr->mode;
-  prev_mode = chptr->mode.mode;
-  if (*chptr->mode.key)
-  {
-    prev_mode |= MODE_KEY;
-    strcpy(prev_key, chptr->mode.key);
-  }
-  if (chptr->mode.limit)
-    prev_mode |= MODE_LIMIT;
-
-  timestamp = atoi(parv[2]);
-
-  /* Copy the new TS when the received creationtime appears to be older */
-  if (!chptr->creationtime || chptr->creationtime > timestamp)
-  {
-    /* Set the new timestamp */
-    chptr->creationtime = timestamp;
-    send_it = 1;                /* Make sure we pass on the different timestamp ! */
-    /* Mark all bans as needed to be wiped out */
-    for (lp = chptr->banlist; lp; lp = lp->next)
-      lp->flags |= CHFL_BURST_BAN_WIPEOUT;
-    /*
-     * Only the first BURST for this channel can have creationtime > timestamp,
-     * so at this moment ALL members are on OUR side, and thus all net.riders:
-     */
-    wipeout = 1;
-  }
-  for (member = chptr->members; member; member = member->next_member)
-    member->status &= ~CHFL_BURST_JOINED;    /* Set later for nicks in the BURST msg */
-  /* If `wipeout' is set then these will be deopped later. */
-
-  /* If the entering creationtime is younger, ignore the modes */
-  if (chptr->creationtime < timestamp)
-    netride = 1;                /* Only pass on the nicks (so they JOIN) */
-
-  /* Prepare buffers to pass the message */
-  *bparambuf = *bmodebuf = *parabuf = '\0';
-  pblen2 = 0;
-  *modebuf = '+';
-  mblen2 = 1;
-  cnt = 0;
-  sblen = sprintf_irc(sendbuf, "%s B %s " TIME_T_FMT, /* XXX DEAD */
-      NumServ(sptr), chptr->chname, chptr->creationtime) - sendbuf; /* XXX DEAD */
-
-  /* Run over all remaining parameters */
-  for (n = 3; n < parc; n++)
-    switch (*parv[n])           /* What type is it ? mode, nicks or bans ? */
-    {
-      case '+':         /* modes */
-      {
-        char *p = parv[n];
-        while (*(++p))          /* Run over all mode characters */
-        {
-          switch (*p)           /* which mode ? */
-          {
-              /*
-               * The following cases all do the following:
-               * - In case wipeout needed, reset 'prev_mode' to indicate this
-               *   mode should not be cancelled.
-               * - If wipeout or (not netride and the new mode is a change),
-               *   add it to bmodebuf and bparabuf for propagation.
-               * - Else ignore it.
-               * - Add it to modebuf and parabuf for propagation to the
-               *   clients when not netride and the new mode is a change.
-               * Special cases:
-               * - If a +s is received, cancel a +p and sent a -p to the
-               *   clients too (if +p was set).
-               * - If a +p is received and +s is set, ignore the +p.
-               */
-            case 'i':
-            {
-              int tmp;
-              prev_mode &= ~MODE_INVITEONLY;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_INVITEONLY)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'i';
-                current_mode->mode |= MODE_INVITEONLY;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'i';
-              break;
-            }
-            case 'k':
-            {
-              int tmp;
-              char *param = parv[++n];
-              prev_mode &= ~MODE_KEY;
-              if (!(tmp = netride || (*current_mode->key &&
-                  (!strcmp(current_mode->key, param) ||
-                  (!wipeout && strcmp(current_mode->key, param) < 0)))) ||
-                  wipeout)
-              {
-                bmodebuf[mblen++] = 'k';
-                strcat(bparambuf, " ");
-                strcat(bparambuf, param);
-                ircd_strncpy(current_mode->key, param, KEYLEN);
-              }
-              if (!tmp && !wipeout)
-              {
-                modebuf[mblen2++] = 'k';
-                parabuf[pblen2++] = ' ';
-                strcpy(parabuf + pblen2, param);
-                pblen2 += strlen(param);
-                cnt++;
-              }
-              break;
-            }
-            case 'l':
-            {
-              int tmp;
-              unsigned int param = atoi(parv[++n]);
-              prev_mode &= ~MODE_LIMIT;
-              if (!(tmp = netride || (current_mode->limit &&
-                  (current_mode->limit == param ||
-                  (!wipeout && current_mode->limit < param)))) || wipeout)
-              {
-                bmodebuf[mblen++] = 'l';
-                sprintf_irc(bparambuf + strlen(bparambuf), " %d", param);
-                current_mode->limit = param;
-              }
-              if (!tmp)
-              {
-                modebuf[mblen2++] = 'l';
-                pblen2 = sprintf_irc(parabuf + pblen2, " %d", param) - parabuf;
-                cnt++;
-              }
-              break;
-            }
-            case 'm':
-            {
-              int tmp;
-              prev_mode &= ~MODE_MODERATED;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_MODERATED)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'm';
-                current_mode->mode |= MODE_MODERATED;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'm';
-              break;
-            }
-            case 'n':
-            {
-              int tmp;
-              prev_mode &= ~MODE_NOPRIVMSGS;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_NOPRIVMSGS)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'n';
-                current_mode->mode |= MODE_NOPRIVMSGS;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'n';
-              break;
-            }
-            case 'p':
-            {
-              int tmp;
-
-              /* Special case: */
-              if (!netride && !wipeout && (current_mode->mode & MODE_SECRET))
-                break;
-
-              prev_mode &= ~MODE_PRIVATE;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_PRIVATE)) || wipeout)
-              {
-                bmodebuf[mblen++] = 'p';
-                current_mode->mode |= MODE_PRIVATE;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 'p';
-              break;
-            }
-            case 's':
-            {
-              int tmp;
-              prev_mode &= ~MODE_SECRET;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_SECRET)) || wipeout)
-              {
-                bmodebuf[mblen++] = 's';
-                current_mode->mode |= MODE_SECRET;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 's';
-
-              /* Special case: */
-              if (!netride && !wipeout && (current_mode->mode & MODE_PRIVATE))
-              {
-                int i;
-                for (i = mblen2 - 1; i >= 0; --i)
-                  modebuf[i + 2] = modebuf[i];
-                modebuf[0] = '-';
-                modebuf[1] = 'p';
-                mblen2 += 2;
-                current_mode->mode &= ~MODE_PRIVATE;
-              }
-
-              break;
-            }
-            case 't':
-            {
-              int tmp;
-              prev_mode &= ~MODE_TOPICLIMIT;
-              if (!(tmp = netride ||
-                  (current_mode->mode & MODE_TOPICLIMIT)) || wipeout)
-              {
-                bmodebuf[mblen++] = 't';
-                current_mode->mode |= MODE_TOPICLIMIT;
-              }
-              if (!tmp)
-                modebuf[mblen2++] = 't';
-              break;
-            }
-          }
-        }                       /* <-- while over all modes */
-
-        bmodebuf[mblen] = '\0';
-        sendbuf[sblen] = '\0'; /* XXX DEAD */
-        if (mblen)              /* Anything to send at all ? */
-        {
-          send_it = 1;
-          strcpy(sendbuf + sblen, " +"); /* XXX DEAD */
-          sblen += 2;
-          strcpy(sendbuf + sblen, bmodebuf); /* XXX DEAD */
-          sblen += mblen;
-          strcpy(sendbuf + sblen, bparambuf); /* XXX DEAD */
-          sblen += strlen(bparambuf);
-        }
-        break;                  /* Done mode part */
-      }
-      case '%':         /* bans */
-      {
-        char *pv, *p = 0, *ban;
-        int first = 1;
-        if (netride)
-          break;                /* Ignore bans */
-        /* Run over all bans */
-        for (pv = parv[n] + 1; (ban = ircd_strtok(&p, pv, " ")); pv = 0)
-        {
-          int ret;
-          /*
-           * The following part should do the following:
-           * - If the new (un)ban is not a _change_ it is ignored.
-           * - Else, add it to sendbuf for later use.
-           * - If sendbuf is full, send it, and prepare a new
-           *   message in sendbuf.
-           */
-          ret = add_banid(sptr, chptr, ban, 1, add_banid_not_called);
-          if (ret == 0)
-          {
-            add_banid_not_called = 0;
-            /* Mark this new ban so we can send it to the clients later */
-            chptr->banlist->flags |= CHFL_BURST_BAN;
-          }
-          if (ret != -1)
-            /* A new ban was added or an existing one needs to be passed on.
-             * Also add it to sendbuf: */
-            add_token_to_sendbuf(ban, &sblen, &first, &send_it, '%', 0); /* XXX DEAD */
-        }
-        break;                  /* Done bans part */
-      }
-      default:                  /* nicks */
-      {
-        char *pv, *p = 0, *nick, *ptr;
-        int first = 1;
-        /* Default mode: */
-        int default_mode = CHFL_DEOPPED;
-        /* Run over all nicks */
-        for (pv = parv[n]; (nick = ircd_strtok(&p, pv, ",")); pv = 0)
-        {
-          struct Client *acptr;
-          if ((ptr = strchr(nick, ':')))        /* New default mode ? */
-          {
-            *ptr = '\0';        /* Fix 'nick' */
-            acptr = findNUser(nick);
-            if (!netride)
-            {
-              /* Calculate new mode change: */
-              default_mode = CHFL_DEOPPED;
-              while (*(++ptr))
-                if (*ptr == 'o')
-                {
-                  default_mode |= CHFL_CHANOP;
-                  default_mode &= ~CHFL_DEOPPED;
-                }
-                else if (*ptr == 'v')
-                  default_mode |= CHFL_VOICE;
-                else
-                  break;
-            }
-          }
-          else
-            acptr = findNUser(nick);
-          /*
-           * Note that at this point we already received a 'NICK' for any
-           * <nick> numeric that is joining (and possibly opped) here.
-           * Therefore we consider the following situations:
-           * - The <nick> numeric exists and is from the direction of cptr: ok
-           * - The <nick> numeric does not exist:
-           *   Apparently this previous <nick> numeric was killed (upstream)
-           *   or it collided with an existing <nick> name.
-           * - The <nick> numeric exists but is from another direction:
-           *   Apparently this previous <nick> numeric was killed,
-           *   and due to a reroute it signed on via another link (probably
-           *   a nick [numeric] collision).
-           * Note that it can't be a QUIT or SQUIT, because a QUIT would
-           * come from the same direction as the BURST (cptr) while an
-           * upstream SQUIT removes the source (server) and we would thus
-           * have this BURST ignored already.
-           * This means that if we find the nick and it is from the correct
-           * direction, it joins. If it doesn't exist or is from another
-           * direction, we have to ignore it. If all nicks are ignored, we
-           * remove the channel again when it is empty and don't propagate
-           * the BURST message.
-           */
-          if (acptr && acptr->from == cptr)
-          {
-            /*
-             * The following should do the following:
-             * - Add it to sendbuf for later use.
-             * - If sendbuf is full, send it, and prepare a new
-             *   message in sendbuf.
-             */
-            add_token_to_sendbuf(nick, &sblen, &first, &send_it, 0, /* XXX DEAD */
-                default_mode);
-            /* Let is take effect: (Note that in the case of a netride
-             * 'default_mode' is always CHFL_DEOPPED here). */
-            add_user_to_channel(chptr, acptr, default_mode | CHFL_BURST_JOINED);
-          }
-        }                       /* <-- Next nick */
-        if (!chptr->members)    /* All nicks collided and channel is empty ? */
-        {
-          sub1_from_channel(chptr);
-          return 0;             /* Forget about the (rest of the) message... */
-        }
-        break;                  /* Done nicks part */
-      }
-    }                           /* <-- Next parameter if any */
-  if (!chptr->members)          /* This message only contained bans (then the previous
-                                   message only contained collided nicks, see above) */
-  {
-    sub1_from_channel(chptr);
-    if (!add_banid_not_called)
-      while (next_removed_overlapped_ban());
-    return 0;                   /* Forget about the (rest of the) message... */
-  }
-
-  /* The last (possibly only) message is always send here */
-  if (send_it)                  /* Anything (left) to send ? */
-  {
-    struct DLink *lp;
-    struct Membership* member;
-
-    /* send 'sendbuf' to all downlinks */
-    for (lp = me.serv->down; lp; lp = lp->next)
-    {
-      if (lp->value.cptr == cptr)
-        continue;
-      if (Protocol(lp->value.cptr) > 9)
-        sendbufto_one(lp->value.cptr); /* XXX DEAD */
-    }
-
-    /*
-     * Now we finally can screw sendbuf again...
-     * Send all changes to the local clients:
-     *
-     * First send all joins and op them, because 2.9 servers
-     * would protest with a HACK if we first de-opped people.
-     * However, we don't send the +b bans yes, because we
-     * DO first want to -b the old bans (otherwise it's confusing).
-     */
-
-    /* Send all joins: */
-    for (member = chptr->members; member; member = member->next_member)
-      if (IsBurstJoined(member))
-      {
-        sendto_channel_butserv(chptr, member->user, ":%s JOIN :%s", /* XXX DEAD */
-                               member->user->name, chptr->chname);
-      }
-
-    if (!netride)
-    {
-      /* Send all +o and +v modes: */
-      for (member = chptr->members; member; member = member->next_member)
-      {
-        if (IsBurstJoined(member))
-        {
-          int mode = CHFL_CHANOP;
-          for (;;)
-          {
-            if ((member->status & mode))
-            {
-              modebuf[mblen2++] = (mode == CHFL_CHANOP) ? 'o' : 'v';
-              parabuf[pblen2++] = ' ';
-              strcpy(parabuf + pblen2, member->user->name);
-              pblen2 += strlen(member->user->name);
-              if (6 == ++cnt)
-              {
-                modebuf[mblen2] = 0;
-                sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DEAD */
-                    parv[0], chptr->chname, modebuf, parabuf);
-                *parabuf = 0;
-                pblen2 = 0;
-                mblen2 = 1;
-                cnt = 0;
-              }
-            }
-            if (mode == CHFL_CHANOP)
-              mode = CHFL_VOICE;
-            else
-              break;
-          }
-        }
-      }
-      /* Flush MODEs: */
-      if (cnt > 0 || mblen2 > 1)
-      {
-        modebuf[mblen2] = 0;
-        sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DEAD */
-            parv[0], chptr->chname, modebuf, parabuf);
-      }
-    }
-  }
-
-  if (wipeout)
-  {
-    struct Membership* member;
-    struct SLink**     ban;
-    int                mode;
-    char               m;
-    int                count = -1;
-
-    /* Now cancel all previous simple modes */
-    if ((prev_mode & MODE_SECRET))
-      cancel_mode(sptr, chptr, 's', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_PRIVATE))
-      cancel_mode(sptr, chptr, 'p', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_MODERATED))
-      cancel_mode(sptr, chptr, 'm', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_TOPICLIMIT))
-      cancel_mode(sptr, chptr, 't', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_INVITEONLY))
-      cancel_mode(sptr, chptr, 'i', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_NOPRIVMSGS))
-      cancel_mode(sptr, chptr, 'n', 0, &count); /* XXX DEAD */
-    if ((prev_mode & MODE_LIMIT))
-    {
-      current_mode->limit = 0;
-      cancel_mode(sptr, chptr, 'l', 0, &count); /* XXX DEAD */
-    }
-    if ((prev_mode & MODE_KEY))
-    {
-      *current_mode->key = 0;
-      cancel_mode(sptr, chptr, 'k', prev_key, &count); /* XXX DEAD */
-    }
-    current_mode->mode &= ~prev_mode;
-
-    /* And deop and devoice all net.riders on my side */
-    mode = CHFL_CHANOP;
-    m = 'o';
-    for (;;)
-    {
-      struct Membership* member_next = 0;
-
-      for (member = chptr->members; member; member = member_next)
-      {
-        member_next = member->next_member;
-        if (IsBurstJoined(member))
-          continue;             /* This is not a net.rider from
-                                   this side of the net.junction */
-#if defined(NO_INVITE_NETRIDE)
-        /*
-         * Kick net riding users from invite only channels.
-         *  - Isomer 25-11-1999
-         */
-        if (chptr->mode.mode & MODE_INVITEONLY) {
-          /* kick is magical - lotsa zombies and other undead.
-           * I'm hoping this is the right idea, comments anyone?
-           * Set everyone to a zombie, remove ops, and then send kicks
-           * everywhere...
-           */
-           if (IsZombie(member)) { /* don't kick ppl twice */
-                member->status = member->status & ~mode;
-                continue;
-           }
-           member->status = (member->status & ~mode) | CHFL_ZOMBIE;
-
-           sendto_highprot_butone(0, 10, "%s " TOK_KICK "%s %s%s :Net Rider", /* XXX DEAD */
-            NumServ(&me), chptr->chname, NumNick(member->user));
-           sendto_channel_butserv(chptr, sptr, /* XXX DEAD */
-            ":%s KICK %s %s :Net Rider", me.name, chptr->chname,
-            member->user->name);
-
-           if (MyUser(member->user)) {
-             sendto_lowprot_butone(0, 9, ":%s PART %s", /* XXX DEAD */
-               member->user->name, chptr->chname, member->user->name);
-             sendto_highprot_butone(0, 10, "%s%s PART %s", /* XXX DEAD */
-               NumNick(member->user), chptr->chname);
-             remove_user_from_channel(member->user, chptr);
-           }
-           else {
-             member->status = (member->status & ~mode) | CHFL_ZOMBIE;
-           }
-           continue;
-        }
-#endif /* defined(NO_INVITE_NETRIDE) */
-        if ((member->status & mode))
-        {
-          member->status &= ~mode;
-          if (mode == CHFL_CHANOP)
-            SetDeopped(member);
-          cancel_mode(sptr, chptr, m, member->user->name, &count); /* XXX DEAD */
-        }
-      }
-      if (mode == CHFL_VOICE)
-        break;
-      mode = CHFL_VOICE;
-      m = 'v';
-    }
-
-    /* And finally wipeout all bans that are left */
-    for (ban = &chptr->banlist; *ban; ) {
-      struct SLink* tmp = *ban;
-      if ((tmp->flags & CHFL_BURST_BAN_WIPEOUT)) {
-        struct Membership* member_z;
-
-        *ban = tmp->next;
-        cancel_mode(sptr, chptr, 'b', tmp->value.ban.banstr, &count); /* XXX DEAD */
-
-        /* Copied from del_banid(): */
-        MyFree(tmp->value.ban.banstr);
-        MyFree(tmp->value.ban.who);
-        free_link(tmp);
-
-        /* Erase ban-valid-bit, for channel members that are banned */
-        for (member_z = chptr->members; member_z; member_z = member_z->next_member)
-          if ((member_z->status & CHFL_BANVALIDMASK) == CHFL_BANVALIDMASK)
-            ClearBanValid(member_z);
-      }
-      else
-        ban = &tmp->next;
-    }
-    /* Also wipeout overlapped bans */
-    if (!add_banid_not_called)
-    {
-      struct SLink *ban;
-      while ((ban = next_removed_overlapped_ban()))
-        cancel_mode(sptr, chptr, 'b', ban->value.ban.banstr, &count); /* XXX DEAD */
-    }
-    cancel_mode(sptr, chptr, 0, 0, &count);  /* flush */ /* XXX DEAD */
-  }
-
-  if (send_it && !netride)
-  {
-    struct SLink *bl;
-    int deban;
-
-    if (add_banid_not_called || !(bl = next_removed_overlapped_ban()))
-    {
-      deban = 0;
-      bl = chptr->banlist;
-      *modebuf = '+';
-    }
-    else
-    {
-      deban = 1;
-      *modebuf = '-';
-    }
-
-    mblen2 = 1;
-    pblen2 = 0;
-    cnt = 0;
-    for (;;)
-    {
-      size_t nblen = 0;
-      if (bl)
-        nblen = strlen(bl->value.ban.banstr);
-      if (cnt == 6 || (!bl && cnt) || pblen2 + nblen + 12 > MODEBUFLEN) /* The last check is to make sure
-                                                                           that the receiving 2.9 will
-                                                                           still process this */
-      {
-        /* Time to send buffer */
-        modebuf[mblen2] = 0;
-        sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DEAD */
-            parv[0], chptr->chname, modebuf, parabuf);
-        *modebuf = deban ? '-' : '+';
-        mblen2 = 1;
-        pblen2 = 0;
-        cnt = 0;
-      }
-      if (!bl)                  /* Done ? */
-        break;
-      if (deban || (bl->flags & CHFL_BURST_BAN))
-      {
-        /* Add ban to buffers and remove it */
-        modebuf[mblen2++] = 'b';
-        parabuf[pblen2++] = ' ';
-        strcpy(parabuf + pblen2, bl->value.ban.banstr);
-        pblen2 += nblen;
-        cnt++;
-        bl->flags &= ~CHFL_BURST_BAN;
-      }
-      if (deban)
-      {
-        if (!(bl = next_removed_overlapped_ban()))
-        {
-          deban = 0;
-          modebuf[mblen2++] = '+';
-          bl = chptr->banlist;
-        }
-      }
-      else
-        bl = bl->next;
-    }
-    /* Flush MODE [-b]+b ...: */
-    if (cnt > 0 || mblen2 > 1)
-    {
-      modebuf[mblen2] = 0;
-      sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s%s", /* XXX DEAD */
-          parv[0], chptr->chname, modebuf, parabuf);
-    }
-  }
-
-  return 0;
-}
-#endif /* 0 */
-
index d97691d1d3066f6ffc428cd8f97f7f6bd13f1abd..2b6852bfd60d8920eae05947250bcdb2a0da05b0 100644 (file)
@@ -92,6 +92,7 @@
 #include "ircd.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "send.h"
 
@@ -118,29 +119,28 @@ int m_ison(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   struct Client* acptr;
   char*          name;
   char*          p = 0;
-  char           buf[BUFSIZE];
-  char*          iter = buf;
-  char*          end = &buf[BUFSIZE - NICKLEN - 4];
+  struct MsgBuf* mb;
 
   if (parc < 2)
     return need_more_params(sptr, "ISON");
 
-  iter = sprintf_irc(buf, rpl_str(RPL_ISON), me.name, sptr->name);
+  mb = msgq_make(sptr, rpl_str(RPL_ISON), me.name, sptr->name);
 
-  for (name = ircd_strtok(&p, parv[1], " "); name; name = ircd_strtok(&p, 0, " ")) {
+  for (name = ircd_strtok(&p, parv[1], " "); name;
+       name = ircd_strtok(&p, 0, " ")) {
     if ((acptr = FindUser(name))) {
-      strcpy(iter, acptr->name);
-      iter += strlen(iter);
-      if (iter >= end)
-        break;
-      *iter++ = ' ';
+      if (msgq_bufleft(mb) < strlen(acptr->name) + 1) {
+       send_buffer(sptr, mb, 0); /* send partial response */
+       msgq_clean(mb); /* then do another round */
+       mb = msgq_make(sptr, rpl_str(RPL_ISON), me.name, sptr->name);
+      }
+      msgq_append(0, mb, "%s ", acptr->name); /* append nickname */
     }
   }
-  *iter = '\0';
-  if (' ' == *--iter)
-    *iter = '\0';
 
-  send_buffer(sptr, buf);
+  send_buffer(sptr, mb, 0); /* send response */
+  msgq_clean(mb);
+
   return 0;
 }
 
index e3c6a21a4d9e35744732c1d131b8186cdd5fa6b0..eaa5f19ebf27c1b0f4dfcd9608d5924c01b0cb14 100644 (file)
@@ -98,7 +98,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef CONFIG_NEW_MODE
 int
 m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 {
@@ -210,314 +209,3 @@ ms_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
 
   return modebuf_flush(&mbuf);
 }
-#else /* CONFIG_NEW_MODE */
-/*
- * m_mode - generic message handler
- */
-int m_mode(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
-{
-  int             badop;
-  int             sendts;
-  struct Channel* chptr = 0;
-  char modebuf[MODEBUFLEN];
-  char parabuf[MODEBUFLEN];
-  char nparabuf[MODEBUFLEN];
-
-
-  if (parc < 2)
-    return need_more_params(sptr, "MODE");
-
-  /*
-   * if local user, cleanup channel name, don't allow local channel operations
-   * for remote clients
-   */
-  if (MyUser(sptr))
-    clean_channelname(parv[1]);
-  else if (IsLocalChannel(parv[1]))
-    return 0;
-
-  /* 
-   * try to find the channel
-   */
-  if ('#' == *parv[1] || '&' == *parv[1] || '+' == *parv[1])
-    chptr = FindChannel(parv[1]);
-  if (!chptr)
-    return set_user_mode(cptr, sptr, parc, parv);
-
-  sptr->flags &= ~FLAGS_TS8;
-  /*
-   * sending an error wasnt good, lets just send an empty mode reply..  poptix
-   */
-  if (IsModelessChannel(chptr->chname)) {
-    if (IsUser(sptr))
-      send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, "+nt", "");
-    return 0;
-  }
-
-  if (parc < 3) {
-    /*
-     * no parameters, send channel modes
-     */
-    *modebuf = *parabuf = '\0';
-    modebuf[1] = '\0';
-    channel_modes(sptr, modebuf, parabuf, chptr);
-    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
-    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
-    return 0;
-  }
-
-  LocalChanOperMode = 0;
-
-  if (!(sendts = set_mode(cptr, sptr, chptr, parc - 2, parv + 2,
-                          modebuf, parabuf, nparabuf, &badop))) {
-    send_reply(sptr, (find_channel_member(sptr, chptr) ?
-                     ERR_CHANOPRIVSNEEDED : ERR_NOTONCHANNEL), chptr->chname);
-    return 0;
-  }
-
-  if (badop >= 2)
-    send_hack_notice(cptr, sptr, parc, parv, badop, 1); /* XXX DYING */
-
-  if (strlen(modebuf) > 1 || sendts > 0) {
-    if (badop != 2 && strlen(modebuf) > 1) {
-#ifdef OPER_MODE_LCHAN
-      if (LocalChanOperMode) {
-       sendcmdto_channel_butserv(&me, CMD_MODE, chptr, "%H %s %s", chptr,
-                                 modebuf, parabuf);
-        sendto_opmask_butone(0, SNO_HACK4, "OPER MODE: %C MODE %H %s %s",
-                            sptr, chptr, modebuf, parabuf);
-      }
-      else
-#endif
-      sendcmdto_channel_butserv(sptr, CMD_MODE, chptr, "%H %s %s", chptr,
-                               modebuf, parabuf);
-    }
-    if (IsLocalChannel(chptr->chname))
-      return 0;
-    /* We send a creationtime of 0, to mark it as a hack --Run */
-    if (IsServer(sptr) && (badop == 2 || sendts > 0)) {
-      if (*modebuf == '\0')
-        strcpy(modebuf, "+");
-      if (badop != 2) {
-       sendcmdto_serv_butone(sptr, CMD_MODE, cptr, "%H %s %s %Tu", chptr,
-                             modebuf, nparabuf, (badop == 4) ? (time_t) 0 :
-                             chptr->creationtime);
-      }
-    }
-    else {
-      sendcmdto_serv_butone(sptr, CMD_MODE, cptr, "%H %s %s", chptr, modebuf,
-                           nparabuf);
-    }
-  }
-  return 0;
-}
-
-/*
- * ms_mode - server message handler
- */
-int ms_mode(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
-{
-  int             badop;
-  int             sendts;
-  struct Channel* chptr = 0;
-  char modebuf[MODEBUFLEN];
-  char parabuf[MODEBUFLEN];
-  char nparabuf[MODEBUFLEN];
-
-  if (parc < 2)
-    return need_more_params(sptr, "MODE");
-
-  /*
-   * if local user, cleanup channel name, don't allow local channel operations
-   * for remote clients
-   */
-  if (MyUser(sptr))
-    clean_channelname(parv[1]);
-  else if (IsLocalChannel(parv[1]))
-    return 0;
-
-  /* 
-   * try to find the channel
-   */
-  if ('#' == *parv[1] || '&' == *parv[1] || '+' == *parv[1])
-    chptr = FindChannel(parv[1]);
-  if (!chptr)
-    return set_user_mode(cptr, sptr, parc, parv);
-
-  sptr->flags &= ~FLAGS_TS8;
-  /*
-   * sending an error wasnt good, lets just send an empty mode reply..  poptix
-   */
-  if (IsModelessChannel(chptr->chname)) {
-    if (IsUser(sptr))
-      send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, "+nt", "");
-    return 0;
-  }
-
-  if (parc < 3) {
-    /*
-     * no parameters, send channel modes
-     */
-    *modebuf = *parabuf = '\0';
-    modebuf[1] = '\0';
-    channel_modes(sptr, modebuf, parabuf, chptr);
-    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
-    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
-    return 0;
-  }
-
-  LocalChanOperMode = 0;
-
-  if (!(sendts = set_mode(cptr, sptr, chptr, parc - 2, parv + 2,
-                          modebuf, parabuf, nparabuf, &badop))) {
-    send_reply(sptr, (find_channel_member(sptr, chptr) ?
-                     ERR_CHANOPRIVSNEEDED : ERR_NOTONCHANNEL), chptr->chname);
-    return 0;
-  }
-
-  if (badop >= 2)
-    send_hack_notice(cptr, sptr, parc, parv, badop, 1); /* XXX DYING */
-
-  if (strlen(modebuf) > 1 || sendts > 0) {
-    if (badop != 2 && strlen(modebuf) > 1) {
-#ifdef OPER_MODE_LCHAN
-      if (LocalChanOperMode) {
-       sendcmdto_channel_butserv(&me, CMD_MODE, chptr, "%H %s %s", chptr,
-                                 modebuf, parabuf);
-        sendto_opmask_butone(0, SNO_HACK4, "OPER MODE: %C MODE %H %s %s",
-                            sptr, chptr, modebuf, parabuf);
-      }
-      else
-#endif
-      sendcmdto_channel_butserv(sptr, CMD_MODE, chptr, "%H %s %s", chptr,
-                               modebuf, parabuf);
-    }
-    if (IsLocalChannel(chptr->chname))
-      return 0;
-    /* We send a creationtime of 0, to mark it as a hack --Run */
-    if (IsServer(sptr) && (badop == 2 || sendts > 0)) {
-      if (*modebuf == '\0')
-        strcpy(modebuf, "+");
-      if (badop != 2) {
-       sendcmdto_serv_butone(sptr, CMD_MODE, cptr, "%H %s %s %Tu", chptr,
-                             modebuf, nparabuf, (badop == 4) ? (time_t) 0 :
-                             chptr->creationtime);
-      }
-    }
-    else {
-      sendcmdto_serv_butone(sptr, CMD_MODE, cptr, "%H %s %s", chptr, modebuf,
-                           nparabuf);
-    }
-  }
-  return 0;
-}
-#endif /* CONFIG_NEW_MODE */
-
-#if 0
-/*
- * m_mode
- * parv[0] - sender
- * parv[1] - channel
- */
-int m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
-  int             badop;
-  int             sendts;
-  struct Channel* chptr = 0;
-
-  if (parc < 2)
-    return need_more_params(sptr, "MODE");
-
-  /*
-   * if local user, cleanup channel name, don't allow local channel operations
-   * for remote clients
-   */
-  if (MyUser(sptr))
-    clean_channelname(parv[1]);
-  else if (IsLocalChannel(parv[1]))
-    return 0;
-
-  /* 
-   * try to find the channel
-   */
-  if ('#' == *parv[1] || '&' == *parv[1] || '+' == *parv[1])
-    chptr = FindChannel(parv[1]);
-  if (!chptr)
-    return set_user_mode(cptr, sptr, parc, parv);
-
-  sptr->flags &= ~FLAGS_TS8;
-  /*
-   * sending an error wasnt good, lets just send an empty mode reply..  poptix
-   */
-  if (IsModelessChannel(chptr->chname)) {
-    if (IsUser(sptr))
-      sendto_one(sptr, rpl_str(RPL_CHANNELMODEIS), me.name, parv[0], /* XXX DEAD */
-                 chptr->chname, "+nt", "");
-    return 0;
-  }
-
-  if (parc < 3) {
-    /*
-     * no parameters, send channel modes
-     */
-    *modebuf = *parabuf = '\0';
-    modebuf[1] = '\0';
-    channel_modes(sptr, modebuf, parabuf, chptr);
-    sendto_one(sptr, rpl_str(RPL_CHANNELMODEIS), me.name, parv[0], /* XXX DEAD */
-               chptr->chname, modebuf, parabuf);
-    sendto_one(sptr, rpl_str(RPL_CREATIONTIME), me.name, parv[0], /* XXX DEAD */
-               chptr->chname, chptr->creationtime);
-    return 0;
-  }
-
-  LocalChanOperMode = 0;
-
-  if (!(sendts = set_mode(cptr, sptr, chptr, parc - 2, parv + 2,
-                          modebuf, parabuf, nparabuf, &badop))) {
-    sendto_one(sptr, err_str(find_channel_member(sptr, chptr) ? ERR_CHANOPRIVSNEEDED : /* XXX DEAD */
-        ERR_NOTONCHANNEL), me.name, parv[0], chptr->chname);
-    return 0;
-  }
-
-  if (badop >= 2)
-    send_hack_notice(cptr, sptr, parc, parv, badop, 1);
-
-  if (strlen(modebuf) > 1 || sendts > 0) {
-    if (badop != 2 && strlen(modebuf) > 1) {
-#ifdef OPER_MODE_LCHAN
-      if (LocalChanOperMode) {
-        sendto_channel_butserv(chptr, &me, ":%s MODE %s %s %s", /* XXX DEAD */
-                               me.name, chptr->chname, modebuf, parabuf);
-        sendto_op_mask(SNO_HACK4,"OPER MODE: %s MODE %s %s %s", /* XXX DEAD */
-                       me.name, chptr->chname, modebuf, parabuf);
-      }
-      else
-#endif
-      sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s", /* XXX DEAD */
-          parv[0], chptr->chname, modebuf, parabuf);
-    }
-    if (IsLocalChannel(chptr->chname))
-      return 0;
-    /* We send a creationtime of 0, to mark it as a hack --Run */
-    if (IsServer(sptr) && (badop == 2 || sendts > 0)) {
-      if (*modebuf == '\0')
-        strcpy(modebuf, "+");
-      if (badop != 2) {
-        sendto_highprot_butone(cptr, 10, "%s " TOK_MODE " %s %s %s " TIME_T_FMT, /* XXX DEAD */
-            NumServ(sptr), chptr->chname, modebuf, nparabuf,
-            (badop == 4) ? (time_t) 0 : chptr->creationtime);
-      }
-    }
-    else {
-      if (IsServer(sptr))
-         sendto_highprot_butone(cptr, 10, "%s " TOK_MODE " %s %s %s", /* XXX DEAD */
-           NumServ(sptr), chptr->chname, modebuf, nparabuf);
-      else
-         sendto_highprot_butone(cptr, 10, "%s%s " TOK_MODE " %s %s %s", /* XXX DEAD */
-           NumNick(sptr), chptr->chname, modebuf, nparabuf);
-    }
-  }
-  return 0;
-}
-
-#endif /* 0 */
index 1c69828aaf06c214021e84822d09f5f0d0c5e72e..c04cf5c11069340e9d1f8ff48d9a1621b23ed459 100644 (file)
@@ -187,7 +187,7 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
     if (mlen + idx + NICKLEN + 5 > BUFSIZE)
       /* space, modifier, nick, \r \n \0 */
     { 
-      sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, sptr->name, buf);
+      send_reply(sptr, RPL_NAMREPLY, buf);
       strcpy(buf, "* ");
       ircd_strncpy(buf + 2, chptr->chname, len + 1);
       buf[len + 2] = 0;
index a214efbecd045be62812ab2150a5bf91bba155a3..7077690f696337b93af9b9b17e252f2de01fd170 100644 (file)
@@ -142,7 +142,7 @@ int ms_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     parv[1] = tbuf;
 #endif
     for (lp = me.serv->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && DBufLength(&lp->value.cptr->sendQ) < 8000)
+      if (cptr != lp->value.cptr && MsgQLength(&lp->value.cptr->sendQ) < 8000)
        sendcmdto_one(sptr, CMD_NOTICE, lp->value.cptr, "%s", parv[1]);
   }
   else
@@ -218,7 +218,7 @@ int mo_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     parv[1] = tbuf;
 #endif
     for (lp = me.serv->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && DBufLength(&lp->value.cptr->sendQ) < 8000)
+      if (cptr != lp->value.cptr && MsgQLength(&lp->value.cptr->sendQ) < 8000)
        sendcmdto_one(sptr, CMD_SETTIME, lp->value.cptr, "%s", parv[1]);
   }
   else
@@ -296,7 +296,7 @@ int m_settime(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     parv[1] = tbuf;
 #endif
     for (lp = me.serv->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && DBufLength(&lp->value.cptr->sendQ) < 8000)
+      if (cptr != lp->value.cptr && DBufLength(&lp->value.cptr->sendQ) < 8000) /* XXX DEAD */
         sendto_one(lp->value.cptr, ":%s SETTIME %s", parv[0], parv[1]); /* XXX DEAD */
   }
   else
index 24f9cf05ac814142cfbe6d68e4f0d39c34fef55b..202933e699b579c750e47518f6d06ff388864b72 100644 (file)
@@ -247,7 +247,7 @@ int m_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           continue;
         send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
                    "%s %u %u %u %u %u :%Tu", (*acptr->name) ? acptr->name : "<unregistered>",
-                   (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+                   (int)MsgQLength(&acptr->sendQ), (int)acptr->sendM,
                    (int)acptr->sendK, (int)acptr->receiveM,
                    (int)acptr->receiveK, CurrentTime - acptr->firsttime);
       }
@@ -482,7 +482,7 @@ int ms_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           continue;
         send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
                    "%s %u %u %u %u %u :%Tu", acptr->name,
-                   (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+                   (int)MsgQLength(&acptr->sendQ), (int)acptr->sendM,
                    (int)acptr->sendK, (int)acptr->receiveM,
                    (int)acptr->receiveK, CurrentTime - acptr->firsttime);
       }
@@ -715,7 +715,7 @@ int mo_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           continue;
         send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
                    "%s %u %u %u %u %u :%Tu", acptr->name,
-                   (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+                   (int)MsgQLength(&acptr->sendQ), (int)acptr->sendM,
                    (int)acptr->sendK, (int)acptr->receiveM,
                    (int)acptr->receiveK, CurrentTime - acptr->firsttime);
       }
index 43886763f72264cf38700ab28cbe73ac05020ff7..c59e3350a57b7accf22054e983ebadb9017f5246 100644 (file)
 #include "client.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "s_user.h"
 #include "struct.h"
 
 #include <assert.h>
 
-static char* userhost_formatter(struct Client* cptr, char* buf)
+static void userhost_formatter(struct Client* cptr, struct MsgBuf* mb)
 {
   assert(IsUser(cptr));
-  return sprintf_irc(buf, "%s%s=%c%s@%s", cptr->name,
-                     IsAnOper(cptr) ? "*" : "",
-                     (cptr->user->away) ? '-' : '+',
-                     cptr->user->username, cptr->user->host);
+  msgq_append(0, mb, "%s%s=%c%s@%s", cptr->name, IsAnOper(cptr) ? "*" : "",
+             cptr->user->away ? '-' : '+', cptr->user->username,
+             cptr->user->host);
 }
 
 /*
index a4b0ae78a8f7013bdc8bfbd6d40ac9667704ab28..c7b5e01441b79d5e00cd9fbedba91f3716591ccf 100644 (file)
 #include "client.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "s_user.h"
 #include "struct.h"
 
 #include <assert.h>
 
-static char* userip_formatter(struct Client* cptr, char* buf)
+static void userip_formatter(struct Client* cptr, struct MsgBuf* mb)
 {
   assert(IsUser(cptr));
-  return sprintf_irc(buf, "%s%s=%c%s@%s", cptr->name,
-                     IsAnOper(cptr) ? "*" : "",
-                     (cptr->user->away) ? '-' : '+',
-                     cptr->user->username,
-                     ircd_ntoa((const char*) &cptr->ip));
+  msgq_append(0, mb, "%s%s=%c%s@%s", cptr->name, IsAnOper(cptr) ? "*" : "",
+             cptr->user->away ? '-' : '+', cptr->user->username,
+             ircd_ntoa((const char*) &cptr->ip));
 }
 
 /*
index b1b3f24a952ec44df5417ca7769b425e4005eae9..aa303fbbd1a82b16e39781ddaaf506c1ac572cc7 100644 (file)
@@ -181,15 +181,15 @@ int m_version(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   {
     if (!(acptr = find_match_server(parv[1])))
     {
-      sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], parv[1]); /* XXX DEAF */
+      sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], parv[1]); /* XXX DEAD */
       return 0;
     }
     parv[1] = acptr->name;
   }
 
-  if (hunt_server(0, cptr, sptr, "%s%s " TOK_VERSION " :%s", 1, parc, parv) == /* XXX DEAF */
+  if (hunt_server(0, cptr, sptr, "%s%s " TOK_VERSION " :%s", 1, parc, parv) == /* XXX DEAD */
       HUNTED_ISME)
-    sendto_one(sptr, rpl_str(RPL_VERSION), /* XXX DEAF */
+    sendto_one(sptr, rpl_str(RPL_VERSION), /* XXX DEAD */
         me.name, parv[0], version, debugmode, me.name, serveropts);
 
   return 0;
diff --git a/ircd/msgq.c b/ircd/msgq.c
new file mode 100644 (file)
index 0000000..3fd22a0
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * IRC - Internet Relay Chat, ircd/msgq.c
+ * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "msgq.h"
+#include "ircd_alloc.h"
+#include "ircd_defs.h"
+#include "ircd_snprintf.h"
+#include "s_debug.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/uio.h>   /* struct iovec */
+
+struct MsgBuf {
+  struct MsgBuf *next;         /* next msg in global queue */
+  struct MsgBuf **prev_p;      /* what points to us in linked list */
+  unsigned int ref;            /* reference count */
+  unsigned int length;         /* length of message */
+  char msg[BUFSIZE + 1];       /* the message */
+};
+
+struct Msg {
+  struct Msg *next;            /* next msg */
+  unsigned int sent;           /* bytes in msg that have already been sent */
+  struct MsgBuf *msg;          /* actual message in queue */
+};
+
+static struct {
+  struct MsgBuf *msgs;
+  struct MsgBuf *free_mbs;
+  struct Msg *free_msgs;
+} MQData = { 0, 0, 0 };
+
+struct MsgCounts msgBufCounts = { 0, 0 };
+struct MsgCounts msgCounts = { 0, 0 };
+
+/*
+ * This routine is used to remove a certain amount of data from a given
+ * queue and release the Msg (and MsgBuf) structure if needed
+ */
+static void
+msgq_delmsg(struct MsgQ *mq, struct MsgQList *qlist, unsigned int *length_p)
+{
+  struct Msg *m;
+  unsigned int msglen;
+
+  assert(0 != mq);
+  assert(0 != qlist);
+  assert(0 != qlist->head);
+  assert(0 != length_p);
+
+  m = qlist->head; /* find the msg we're deleting from */
+
+  msglen = m->msg->length - m->sent; /* calculate how much is left */
+
+  if (*length_p >= msglen) { /* deleted it all? */
+    mq->length -= msglen; /* decrement length */
+    mq->count--; /* decrement the message count */
+    *length_p -= msglen;
+
+    msgq_clean(m->msg); /* free up the struct MsgBuf */
+    m->msg = 0; /* don't let it point anywhere nasty, please */
+
+    if (qlist->head == qlist->tail) /* figure out if we emptied the queue */
+      qlist->head = qlist->tail = 0;
+    else
+      qlist->head = m->next; /* just shift the list down some */
+
+    msgCounts.used--; /* struct Msg is not in use anymore */
+
+    m->next = MQData.free_msgs; /* throw it onto the free list */
+    MQData.free_msgs = m;
+  } else {
+    mq->length -= *length_p; /* decrement queue length */
+    m->sent += *length_p; /* this much of the message has been sent */
+    *length_p = 0; /* we've dealt with it all */
+  }
+}
+
+/*
+ * This just initializes a struct MsgQ.
+ */
+void
+msgq_init(struct MsgQ *mq)
+{
+  assert(0 != mq);
+
+  mq->length = 0;
+  mq->count = 0;
+  mq->queue.head = 0;
+  mq->queue.tail = 0;
+  mq->prio.head = 0;
+  mq->prio.tail = 0;
+}
+
+/*
+ * This routine is used to delete the specified number of bytes off
+ * of the queue.  We only really need to worry about one struct Msg*,
+ * but this allows us to retain the flexibility to deal with more,
+ * which means we could do something fancy involving writev...
+ */
+void
+msgq_delete(struct MsgQ *mq, unsigned int length)
+{
+  assert(0 != mq);
+
+  while (length > 0) {
+    if (mq->queue.head && mq->queue.head->sent > 0) /* partial msg on norm q */
+      msgq_delmsg(mq, &mq->queue, &length);
+    else if (mq->prio.head) /* message (partial or complete) on prio queue */
+      msgq_delmsg(mq, &mq->prio, &length);
+    else if (mq->queue.head) /* message on normal queue */
+      msgq_delmsg(mq, &mq->queue, &length);
+    else
+      break;
+  }
+}
+
+/*
+ * This is similiar to the dbuf_map() function to allow us to plug it
+ * into the existing code more easily; we may want to have something
+ * more fancy in the future that would allow us to make some intelligent
+ * use of writev or similiar functions.
+ */
+const char *
+msgq_map(const struct MsgQ *mq, unsigned int *length_p)
+{
+  assert(0 != mq);
+  assert(0 != length_p);
+
+  if (mq->length <= 0)
+    return 0;
+
+  if (mq->queue.head && mq->queue.head->sent > 0) { /* partial msg on norm q */
+    *length_p = mq->queue.head->msg->length - mq->queue.head->sent;
+    return mq->queue.head->msg->msg + mq->queue.head->sent;
+  } else if (mq->prio.head) { /* message (partial or complete) on prio queue */
+    *length_p = mq->prio.head->msg->length - mq->prio.head->sent;
+    return mq->prio.head->msg->msg + mq->prio.head->sent;
+  } else if (mq->queue.head) { /* message on normal queue */
+    *length_p = mq->queue.head->msg->length; /* partial already dealt with */
+    return mq->queue.head->msg->msg;
+  }
+
+  return 0; /* shouldn't ever happen */
+}
+
+/*
+ * This is the more intelligent routine that can fill in an array of
+ * struct iovec's.
+ */
+int
+msgq_mapiov(const struct MsgQ *mq, struct iovec *iov, int count)
+{
+  struct Msg *queue;
+  struct Msg *prio;
+  int i = 0;
+
+  assert(0 != mq);
+  assert(0 != iov);
+  assert(0 != count);
+
+  if (mq->length <= 0) /* no data to map */
+    return 0;
+
+  if (mq->queue.head && mq->queue.head->sent > 0) { /* partial msg on norm q */
+    iov[i].iov_base = mq->queue.head->msg->msg + mq->queue.head->sent;
+    iov[i].iov_len = mq->queue.head->msg->length - mq->queue.head->sent;
+
+    queue = mq->queue.head->next; /* where we start later... */
+
+    i++; /* filled an iovec... */
+    if (!--count) /* check for space */
+      return i;
+  } else
+    queue = mq->queue.head; /* start at head of queue */
+
+  if (mq->prio.head && mq->prio.head->sent > 0) { /* partial msg on prio q */
+    iov[i].iov_base = mq->prio.head->msg->msg + mq->prio.head->sent;
+    iov[i].iov_len = mq->prio.head->msg->length - mq->prio.head->sent;
+
+    prio = mq->prio.head->next; /* where we start later... */
+
+    i++; /* filled an iovec... */
+    if (!--count) /* check for space */
+      return i;
+  } else
+    prio = mq->prio.head; /* start at head of prio */
+
+  for (; prio; prio = prio->next) { /* go through prio queue */
+    iov[i].iov_base = prio->msg->msg; /* store message */
+    iov[i].iov_len = prio->msg->length;
+
+    i++; /* filled an iovec... */
+    if (!--count) /* check for space */
+      return i;
+  }
+
+  for (; queue; queue = queue->next) { /* go through normal queue */
+    iov[i].iov_base = queue->msg->msg;
+    iov[i].iov_len = queue->msg->length;
+
+    i++; /* filled an iovec... */
+    if (!--count) /* check for space */
+      return i;
+  }
+
+  return i;
+}
+
+/*
+ * This routine builds a struct MsgBuf with the appropriate contents
+ * and returns it; this saves us from having to worry about the contents
+ * of struct MsgBuf in anything other than this module
+ */
+struct MsgBuf *
+msgq_vmake(struct Client *dest, const char *format, va_list vl)
+{
+  struct MsgBuf *mb;
+
+  assert(0 != format);
+
+  if (!(mb = MQData.free_mbs)) { /* do I need to allocate one? */
+    mb = (struct MsgBuf *)MyMalloc(sizeof(struct MsgBuf));
+    msgBufCounts.alloc++; /* we allocated another */
+  } else /* shift the free list */
+    MQData.free_mbs = MQData.free_mbs->next;
+
+  msgBufCounts.used++; /* we're using another */
+
+  mb->next = MQData.msgs; /* initialize the msgbuf */
+  mb->prev_p = &MQData.msgs;
+  mb->ref = 1;
+
+  /* fill the buffer */
+  mb->length = ircd_vsnprintf(dest, mb->msg, sizeof(mb->msg) - 2, format, vl);
+
+  mb->msg[mb->length++] = '\r'; /* add \r\n to buffer */
+  mb->msg[mb->length++] = '\n';
+  mb->msg[mb->length] = '\0'; /* not strictly necessary */
+
+  if (MQData.msgs) /* link it into the list */
+    MQData.msgs->prev_p = &mb->next;
+  MQData.msgs = mb;
+
+  return mb;
+}
+
+struct MsgBuf *
+msgq_make(struct Client *dest, const char *format, ...)
+{
+  va_list vl;
+  struct MsgBuf *mb;
+
+  va_start(vl, format);
+  mb = msgq_vmake(dest, format, vl);
+  va_end(vl);
+
+  return mb;
+}
+
+/*
+ * This routine is used to append a formatted string to a struct MsgBuf.
+ */
+void
+msgq_append(struct Client *dest, struct MsgBuf *mb, const char *format, ...)
+{
+  va_list vl;
+
+  assert(0 != mb);
+  assert(0 != format);
+
+  mb->length -= 2; /* back up to before \r\n */
+
+  va_start(vl, format); /* append to the buffer */
+  mb->length += ircd_vsnprintf(dest, mb->msg + mb->length,
+                              sizeof(mb->msg) - 2 - mb->length, format, vl);
+  va_end(vl);
+
+  mb->msg[mb->length++] = '\r'; /* add \r\n to buffer */
+  mb->msg[mb->length++] = '\n';
+  mb->msg[mb->length] = '\0'; /* not strictly necessary */
+}
+
+/*
+ * This routine is called to decrement the reference count on a
+ * struct MsgBuf and delete it if necessary.
+ */
+void
+msgq_clean(struct MsgBuf *mb)
+{
+  assert(0 != mb);
+  assert(0 < mb->ref);
+  assert(0 != mb->prev_p);
+
+  if (!--mb->ref) { /* deallocate the message */
+    *mb->prev_p = mb->next; /* clip it out of active MsgBuf's list */
+    if (mb->next)
+      mb->next->prev_p = mb->prev_p;
+
+    mb->next = MQData.free_mbs; /* add it to free list */
+    MQData.free_mbs = mb;
+
+    mb->prev_p = 0;
+
+    msgBufCounts.used--; /* decrement the usage count */
+  }
+}
+
+/*
+ * This routine simply adds a struct Msg to the end of a user's MsgQ.
+ */
+void
+msgq_add(struct MsgQ *mq, struct MsgBuf *mb, int prio)
+{
+  struct MsgQList *qlist;
+  struct Msg *msg;
+
+  assert(0 != mq);
+  assert(0 != mb);
+  assert(0 < mb->ref);
+
+  Debug((DEBUG_SEND, "Adding buffer %p [%.*s] to %s queue", mb,
+        mb->length - 2, mb->msg, prio ? "priority" : "normal"));
+
+  qlist = prio ? &mq->prio : &mq->queue;
+
+  if (!(msg = MQData.free_msgs)) { /* do I need to allocate one? */
+    msg = (struct Msg *)MyMalloc(sizeof(struct Msg));
+    msgCounts.alloc++; /* we allocated another */
+  } else /* shift the free list */
+    MQData.free_msgs = MQData.free_msgs->next;
+
+  msgCounts.used++; /* we're using another */
+
+  msg->next = 0; /* initialize the msg */
+  msg->sent = 0;
+  msg->msg = mb;
+
+  mb->ref++; /* increment the ref count on the buffer */
+
+  if (!qlist->head) /* queue list was empty; head and tail point to msg */
+    qlist->head = qlist->tail = msg;
+  else {
+    assert(0 != qlist->tail);
+
+    qlist->tail->next = msg; /* queue had something in it; add to end */
+    qlist->tail = msg;
+  }
+
+  mq->length += mb->length; /* update the queue length */
+  mq->count++; /* and the queue count */
+}
+
+/*
+ * This is for reporting memory usage by the msgq system.
+ */
+void
+msgq_count_memory(size_t *msg_alloc, size_t *msg_used, size_t *msgbuf_alloc,
+                 size_t *msgbuf_used)
+{
+  assert(0 != msg_alloc);
+  assert(0 != msg_used);
+  assert(0 != msgbuf_alloc);
+  assert(0 != msgbuf_used);
+
+  *msg_alloc = msgCounts.alloc * sizeof(struct Msg);
+  *msg_used = msgCounts.used * sizeof(struct Msg);
+  *msgbuf_alloc = msgCounts.alloc * sizeof(struct MsgBuf);
+  *msgbuf_used = msgCounts.used * sizeof(struct MsgBuf);
+}
+
+/*
+ * This routine is used simply to report how much bufferspace is left.
+ */
+unsigned int
+msgq_bufleft(struct MsgBuf *mb)
+{
+  assert(0 != mb);
+
+  return sizeof(mb->msg) - mb->length; /* the -2 for \r\n is in mb->length */
+}
index 2b44a4119486c524a46bf4d3b56e6333baa9f189..658bfc4920efdae0666dec6835e1526dc3f1c1e3 100644 (file)
@@ -949,22 +949,6 @@ int parse_server(struct Client *cptr, char *buffer, char *bufend)
 
   Debug((DEBUG_DEBUG, "Server Parsing: %s", buffer));
 
-#ifdef GODMODE
-  len = strlen(buffer);
-  sdbflag = 1;
-  if (len > 402)
-  {
-    char c = buffer[200];
-    buffer[200] = 0;
-    sendto_ops("RCV:%-8.8s(%.4d): \"%s...%s\"",
-        cptr->name, len, buffer, &buffer[len - 200]);
-    buffer[200] = c;
-  }
-  else
-    sendto_ops("RCV:%-8.8s(%.4d): \"%s\"", cptr->name, len, buffer);
-  sdbflag = 0;
-#endif /* GODMODE */
-
   if (IsDead(cptr))
     return 0;
 
index 5ca23bfa047811a832b1057f3ec78f72adcd53fa..980fe0e614ee90df7ac360e74d0ea4e9703ac33f 100644 (file)
@@ -517,7 +517,7 @@ void close_connection(struct Client *cptr)
   }
   cptr->flags |= FLAGS_DEADSOCKET;
 
-  DBufClear(&cptr->sendQ);
+  MsgQClear(&cptr->sendQ);
   DBufClear(&cptr->recvQ);
   memset(cptr->passwd, 0, sizeof(cptr->passwd));
   set_snomask(cptr, 0, SNO_SET);
@@ -721,7 +721,7 @@ static int on_write_unblocked(struct Client* cptr)
     if (!completed_connection(cptr))
       return 0;
   }
-  else if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
+  else if (cptr->listing && MsgQLength(&cptr->sendQ) < 2048)
     list_next_channels(cptr, 64);
   send_queued(cptr);
   return 1;
@@ -904,8 +904,8 @@ int read_message(time_t delay)
         if (DBufLength(&cptr->recvQ) < 4088 || IsServer(cptr)) {
           PFD_SETR(i);
         }
-        if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
-            (cptr->listing && DBufLength(&cptr->sendQ) < 2048)) {
+        if (MsgQLength(&cptr->sendQ) || IsConnecting(cptr) ||
+            (cptr->listing && MsgQLength(&cptr->sendQ) < 2048)) {
           PFD_SETW(i);
         }
       }
@@ -1142,8 +1142,8 @@ int read_message(time_t delay)
           delay2 = 1;
         if (DBufLength(&cptr->recvQ) < 4088 || IsServer(cptr))
           FD_SET(i, &read_set);
-        if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
-            (cptr->listing && DBufLength(&cptr->sendQ) < 2048))
+        if (MsgQLength(&cptr->sendQ) || IsConnecting(cptr) ||
+            (cptr->listing && MsgQLength(&cptr->sendQ) < 2048))
           FD_SET(i, &write_set);
       }
     }
index 0a017bf1e14486aa61f39c6cc384bc93dd18b1d2..f5ba4ffb8c983aa1cfae1d3af8a78796dee91a29 100644 (file)
@@ -953,7 +953,7 @@ int read_configuration_file(void)
     
     if (':' != line[1]) {
       Debug((DEBUG_ERROR, "Bad config line: %s", line));
-      sendto_op_mask(SNO_OLDSNO,"Bad Config line");
+      sendto_opmask_butone(0, SNO_OLDSNO,"Bad Config line");
       continue;
     }
 
@@ -1128,7 +1128,8 @@ int read_configuration_file(void)
       break;
     default:
       Debug((DEBUG_ERROR, "Error in config file: %s", line));
-      sendto_op_mask(SNO_OLDSNO,"Unknown prefix in config file: %c", *field_vector[0]);
+      sendto_opmask_butone(0, SNO_OLDSNO, "Unknown prefix in config file: %c",
+                          *field_vector[0]);
       aconf->status = CONF_ILLEGAL;
       break;
     }
index 33ce080058e0eed688cf9120148e47fecc88c9ff..8bf56eb07b6a67a24ae7860b7f0927bd5e1d79ba 100644 (file)
@@ -31,6 +31,7 @@
 #include "ircd_reply.h"
 #include "ircd.h"
 #include "list.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "numnicks.h"
 #include "res.h"
@@ -274,6 +275,10 @@ void count_memory(struct Client *cptr, char *nick)
       com = 0,                  /* memory used by conf lines */
       dbufs_allocated = 0,      /* memory used by dbufs */
       dbufs_used = 0,           /* memory used by dbufs */
+      msg_allocated = 0,       /* memory used by struct Msg */
+      msg_used = 0,            /* memory used by struct Msg */
+      msgbuf_allocated = 0,    /* memory used by struct MsgBuf */
+      msgbuf_used = 0,         /* memory used by struct MsgBuf */
       rm = 0,                   /* res memory used */
       totcl = 0, totch = 0, totww = 0, tot = 0;
 
@@ -394,11 +399,20 @@ void count_memory(struct Client *cptr, char *nick)
             ":DBufs allocated %d(%zu) used %d(%zu)", DBufAllocCount,
             dbufs_allocated, DBufUsedCount, dbufs_used);
 
+  msgq_count_memory(&msg_allocated, &msg_used, &msgbuf_allocated,
+                   &msgbuf_used);
+  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
+            ":Msgs allocated %d(%zu) used %d(%zu)", msgCounts.alloc,
+            msg_allocated, msgCounts.used, msg_used);
+  send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
+            ":MsgBufs allocated %d(%zu) used %d(%zu)", msgBufCounts.alloc,
+            msgbuf_allocated, msgBufCounts.used, msgbuf_used);
+
   rm = cres_mem(cptr);
 
   tot =
-      totww + totch + totcl + com + cl * sizeof(struct ConnectionClass) + dbufs_allocated +
-      rm;
+      totww + totch + totcl + com + cl * sizeof(struct ConnectionClass) +
+      dbufs_allocated + msg_allocated + msgbuf_allocated + rm;
   tot += sizeof(void *) * HASHSIZE * 3;
 
 #if !defined(NDEBUG)
@@ -407,7 +421,8 @@ void count_memory(struct Client *cptr, char *nick)
 #endif
 
   send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
-            ":Total: ww %zu ch %zu cl %zu co %zu db %zu", totww, totch,
-            totcl, com, dbufs_allocated);
+            ":Total: ww %zu ch %zu cl %zu co %zu db %zu ms %zu mb %zu",
+            totww, totch, totcl, com, dbufs_allocated, msg_allocated,
+            msgbuf_allocated);
 }
 
index 51c481419b15860af78a8811f629baf2dd787563..ec16da597fcee41c23a9173dde18bd12c33bcf60 100644 (file)
@@ -39,6 +39,7 @@
 #include "match.h"
 #include "motd.h"
 #include "msg.h"
+#include "msgq.h"
 #include "numeric.h"
 #include "numnicks.h"
 #include "parse.h"
@@ -224,58 +225,6 @@ struct Client *next_client(struct Client *next, const char* ch)
  *
  *    returns: (see #defines)
  */
-int hunt_server(int MustBeOper, struct Client *cptr, struct Client *sptr, char *command,
-    int server, int parc, char *parv[])
-{
-  struct Client *acptr;
-  char y[8];
-
-  /* Assume it's me, if no server or an unregistered client */
-  if (parc <= server || EmptyString(parv[server]) || IsUnknown(sptr))
-    return (HUNTED_ISME);
-
-  /* Make sure it's a server */
-  if (MyUser(sptr) || Protocol(cptr) < 10)
-  {
-    /* Make sure it's a server */
-    if (!strchr(parv[server], '*')) {
-      if (0 == (acptr = FindClient(parv[server]))) {
-        sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
-            me.name, parv[0], parv[server]);
-        return HUNTED_NOSUCH;
-      }
-      if (acptr->user)
-        acptr = acptr->user->server;
-    }
-    else if (!(acptr = find_match_server(parv[server])))
-    {
-      send_reply(sptr, ERR_NOSUCHSERVER, parv[server]);
-      return (HUNTED_NOSUCH);
-    }
-  }
-  else if (!(acptr = FindNServer(parv[server])))
-    return (HUNTED_NOSUCH);        /* Server broke off in the meantime */
-
-  if (IsMe(acptr))
-    return (HUNTED_ISME);
-
-  if (MustBeOper && !IsPrivileged(sptr))
-  {
-    send_reply(sptr, ERR_NOPRIVILEGES);
-    return HUNTED_NOSUCH;
-  }
-
-  strcpy(y, acptr->yxx);
-  parv[server] = y;
-
-  assert(!IsServer(sptr));
-  /* XXX sendto_one used with explicit command; must be very careful */
-  sendto_one(acptr, command, NumNick(sptr), parv[1], parv[2], parv[3], parv[4], /* XXX hunt_server */
-      parv[5], parv[6], parv[7], parv[8]);
-
-  return (HUNTED_PASS);
-}
-
 int hunt_server_cmd(struct Client *from, const char *cmd, const char *tok,
                     struct Client *one, int MustBeOper, const char *pattern,
                     int server, int parc, char *parv[])
@@ -1094,30 +1043,30 @@ void send_umode_out(struct Client *cptr, struct Client *sptr, int old)
  */
 void send_user_info(struct Client* sptr, char* names, int rpl, InfoFormatter fmt)
 {
-  char*          sbuf;
   char*          name;
   char*          p = 0;
   int            arg_count = 0;
   int            users_found = 0;
   struct Client* acptr;
-  char           buf[BUFSIZE * 2];
+  struct MsgBuf* mb;
 
   assert(0 != sptr);
   assert(0 != names);
   assert(0 != fmt);
 
-  sbuf = sprintf_irc(buf, rpl_str(rpl), me.name, sptr->name);
+  mb = msgq_make(sptr, rpl_str(rpl), me.name, sptr->name);
 
   for (name = ircd_strtok(&p, names, " "); name; name = ircd_strtok(&p, 0, " ")) {
     if ((acptr = FindUser(name))) {
       if (users_found++)
-        *sbuf++ = ' ';
-      sbuf = (*fmt)(acptr, sbuf);
+       msgq_append(0, mb, " ");
+      (*fmt)(acptr, mb);
     }
     if (5 == ++arg_count)
       break;
   }
-  send_buffer(sptr, buf);
+  send_buffer(sptr, mb, 0);
+  msgq_clean(mb);
 }
 
 
index 5483868eb0159489835e9dcc1a82392d8f5a7579..96bd12b3b1d5246b86068417d916aaec1bc5b13b 100644 (file)
 #include <string.h>
 
 
-char sendbuf[2048];
 static int sentalong[MAXCONNECTIONS];
 static int sentalong_marker;
 struct SLink *opsarray[32];     /* don't use highest bit unless you change
-                                   atoi to strtoul in sendto_op_mask() */
-#ifdef GODMODE
-char sendbuf2[2048];
-int sdbflag;
-#endif /* GODMODE */
-
+                                  atoi to strtoul in sendto_op_mask() */
 /*
  * dead_link
  *
@@ -78,7 +72,7 @@ static void dead_link(struct Client *to, char *notice)
    * notices don't hurt operators below.
    */
   DBufClear(&to->recvQ);
-  DBufClear(&to->sendQ);
+  MsgQClear(&to->sendQ);
 
   /*
    * Keep a copy of the last comment, for later use...
@@ -127,12 +121,12 @@ void flush_connections(struct Client* cptr)
  * by dbuf_put to try to get some more memory before bailing and
  * causing the client to be disconnected.
  */
-void flush_sendq_except(const struct DBuf* one)
+void flush_sendq_except(void)
 {
   int i;
   struct Client* cptr;
   for (i = HighestFd; i >= 0; i--) {
-    if ( (cptr = LocalClientArray[i]) && one != &cptr->sendQ)
+    if ( (cptr = LocalClientArray[i]))
       send_queued(cptr);
   }
 }
@@ -152,13 +146,13 @@ void send_queued(struct Client *to)
   if (IsBlocked(to) || !can_send(to))
     return;                     /* Don't bother */
 
-  while (DBufLength(&to->sendQ) > 0) {
+  while (MsgQLength(&to->sendQ) > 0) {
     unsigned int len;
-    const char* msg = dbuf_map(&to->sendQ, &len);
+    const char* msg = msgq_map(&to->sendQ, &len);
 
     if ((len = deliver_it(to, msg, len))) {
-      dbuf_delete(&to->sendQ, len);
-      to->lastsq = DBufLength(&to->sendQ) / 1024;
+      msgq_delete(&to->sendQ, len);
+      to->lastsq = MsgQLength(&to->sendQ) / 1024;
       if (IsBlocked(to))
         break;
     }
@@ -173,53 +167,8 @@ void send_queued(struct Client *to)
   }
 }
 
-/*
- *  send message to single client
- */
-/* See sendcmdto_one, below */
-void sendto_one(struct Client *to, const char* pattern, ...)
-{
-  va_list vl;
-  va_start(vl, pattern);
-  vsendto_one(to, pattern, vl);
-  va_end(vl);
-}
-
-/* See vsendcmdto_one, below */
-void vsendto_one(struct Client *to, const char* pattern, va_list vl)
+void send_buffer(struct Client* to, struct MsgBuf* buf, int prio)
 {
-  vsprintf_irc(sendbuf, pattern, vl);
-  sendbufto_one(to);
-}
-
-#ifdef GODMODE
-static void send_to_god(struct Client* to, const char* buf)
-{
-  if (!sdbflag && !IsUser(to)) {
-    char sbuf2[BUFSIZE + 1];
-    unsigned int len = strlen(buf) - 2;   /* Remove "\r\n" */
-
-    sdbflag = 1;
-    len = IRCD_MIN(len, BUFSIZE);
-    ircd_strncpy(sbuf2, buf, len);
-    sbuf2[len] = '\0';
-
-    if (len > 402) {
-      char c = sbuf2[200];
-      sbuf2[200] = '\0';
-      sendto_ops("SND:%-8.8s(%.4d): \"%s...%s\"",
-                 to->name, len, sbuf2, &sbuf2[len - 200]);
-    }
-    else
-      sendto_ops("SND:%-8.8s(%.4d): \"%s\"", to->name, len, sbuf2);
-    sdbflag = 0;
-  }
-}
-#endif /* GODMODE */
-
-void send_buffer(struct Client* to, char* buf)
-{
-  unsigned int len;
   assert(0 != to);
   assert(0 != buf);
 
@@ -232,34 +181,19 @@ void send_buffer(struct Client* to, char* buf)
      */
     return;
 
-  if (DBufLength(&to->sendQ) > get_sendq(to)) {
+  if (MsgQLength(&to->sendQ) > get_sendq(to)) {
     if (IsServer(to))
       sendto_opmask_butone(0, SNO_OLDSNO, "Max SendQ limit exceeded for %C: "
-                          "%zu > %zu", to, DBufLength(&to->sendQ),
+                          "%zu > %zu", to, MsgQLength(&to->sendQ),
                           get_sendq(to));
     dead_link(to, "Max sendQ exceeded");
     return;
   }
 
-  Debug((DEBUG_SEND, "Sending [%s] to %s", buf, to->name));
+  Debug((DEBUG_SEND, "Sending [%p] to %s", buf, to->name));
 
-  len = strlen(buf);
-  if (buf[len - 1] != '\n') {
-    if (len > 510)
-      len = 510;
-    buf[len++] = '\r';
-    buf[len++] = '\n';
-    buf[len] = '\0';
-  }
+  msgq_add(&to->sendQ, buf, prio);
 
-  if (0 == dbuf_put(&to->sendQ, buf, len)) {
-    dead_link(to, "Buffer allocation error");
-    return;
-  }
-
-#ifdef GODMODE
-  send_to_god(to, buf);
-#endif /* GODMODE */
   /*
    * Update statistics. The following is slightly incorrect
    * because it counts messages even if queued, but bytes
@@ -275,359 +209,10 @@ void send_buffer(struct Client* to, char* buf)
    * trying to flood that link with data (possible during the net
    * relinking done by servers with a large load).
    */
-  if (DBufLength(&to->sendQ) / 1024 > to->lastsq)
+  if (MsgQLength(&to->sendQ) / 1024 > to->lastsq)
     send_queued(to);
 }
 
-void sendbufto_one(struct Client* to)
-{
-  send_buffer(to, sendbuf);
-}
-
-/* See vsendcmdto_one, below */
-static void vsendto_prefix_one(struct Client *to, struct Client *from,
-    const char* pattern, va_list vl)
-{
-  if (to && from && MyUser(to) && IsUser(from))
-  {
-    static char sender[HOSTLEN + NICKLEN + USERLEN + 5];
-    char *par;
-    int flag = 0;
-    struct User *user = from->user;
-
-    par = va_arg(vl, char *);
-    strcpy(sender, from->name);
-    if (user)
-    {
-      if (*user->username)
-      {
-        strcat(sender, "!");
-        strcat(sender, user->username);
-      }
-      if (*user->host && !MyConnect(from))
-      {
-        strcat(sender, "@");
-        strcat(sender, user->host);
-        flag = 1;
-      }
-    }
-    /*
-     * Flag is used instead of strchr(sender, '@') for speed and
-     * also since username/nick may have had a '@' in them. -avalon
-     */
-    if (!flag && MyConnect(from) && *user->host)
-    {
-      strcat(sender, "@");
-      strcat(sender, from->sockhost);
-    }
-    *sendbuf = ':';
-    strcpy(&sendbuf[1], sender);
-    /* Assuming 'pattern' always starts with ":%s ..." */
-    vsprintf_irc(sendbuf + strlen(sendbuf), &pattern[3], vl);
-  }
-  else
-    vsprintf_irc(sendbuf, pattern, vl);
-  sendbufto_one(to);
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendmsgto_channel_butone(struct Client *one, struct Client *from,
-                              struct Channel *chptr, const char *sender,
-                              const char *cmd, const char *chname, const char *msg)
-{
- /*
-  * Sends a PRIVMSG/NOTICE to all members on a channel but 'one', translating
-  * TOKENS to full messages when sent to local clients. --Gte (12/12/99)
-  */
-  struct Membership* member;
-  struct Client *acptr;
-  char userbuf[2048];
-  char servbuf[2048];
-  int i;
-  int flag=-1;
-
-  assert(0 != cmd);
-  /* 
-   * Precalculate the buffers we sent to the clients instead of doing an
-   * expensive sprintf() per member that we send to.  We still have to
-   * use strcpy() which is evil.
-   */
-  if (IsServer(from)) {
-    sprintf(userbuf,":%s %s %s :%s",
-            from->name, ('P' == *cmd) ? MSG_PRIVATE : MSG_NOTICE, chname, msg);
-    sprintf(servbuf,"%s %s %s :%s", NumServ(from), cmd, chname, msg);
-  }
-  else {
-    sprintf(userbuf,":%s!%s@%s %s %s :%s",
-            from->name, from->user->username, from->user->host,
-            ('P' == *cmd) ? MSG_PRIVATE : MSG_NOTICE, chname, msg);
-    sprintf(servbuf,"%s%s %s %s :%s", NumNick(from), cmd, chname, msg);
-  }
-
-  ++sentalong_marker;
-  for (member = chptr->members; member; member = member->next_member)
-  {
-    acptr = member->user;
-    /* ...was the one I should skip */
-    if (acptr->from == one || IsZombie(member) || IsDeaf(acptr))
-      continue;
-    if (MyConnect(acptr)) {      /* (It is always a client) */
-        if (flag!=0)
-          strcpy(sendbuf,userbuf);
-        flag=0;
-        sendbufto_one(acptr);
-    }
-    else if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker)
-    {
-      sentalong[i] = sentalong_marker;
-      if (!IsBurstOrBurstAck(acptr->from)) {
-        if (flag != 1)
-          strcpy(sendbuf,servbuf);
-        flag = 1;
-        sendbufto_one(acptr);
-  }
-    } /* of if MyConnect() */
-  } /* of for(members) */
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendto_lchanops_butone(struct Client *one, struct Client *from, struct Channel *chptr,
-    const char* pattern, ...)
-{
-  va_list vl;
-  struct Membership* member;
-  struct Client *acptr;
-
-  va_start(vl, pattern);
-
-  for (member = chptr->members; member; member = member->next_member)
-  {
-    acptr = member->user;
-    /* ...was the one I should skip */
-    if (acptr == one || !IsChanOp(member) || IsZombie(member) || IsDeaf(acptr))
-      continue;
-    if (MyConnect(acptr))       /* (It is always a client) */
-      vsendto_prefix_one(acptr, from, pattern, vl);
-  }
-  va_end(vl);
-  return;
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendto_chanopsserv_butone(struct Client *one, struct Client *from, struct Channel *chptr,
-    const char* pattern, ...)
-{
-  va_list vl;
-  struct Membership* member;
-  struct Client *acptr;
-  int i;
-#ifndef NO_PROTOCOL9
-  char  target[128];
-  char* source;
-  char* tp;
-  char* msg;
-#endif
-
-  va_start(vl, pattern);
-
-  ++sentalong_marker;
-  for (member = chptr->members; member; member = member->next_member)
-  {
-    acptr = member->user;
-    if (acptr->from == acptr || /* Skip local clients */
-#ifndef NO_PROTOCOL9
-        Protocol(acptr->from) < 10 ||   /* Skip P09 links */
-#endif
-        acptr->from == one ||   /* ...was the one I should skip */
-        !IsChanOp(member) ||   /* Skip non chanops */
-        IsZombie(member) || IsDeaf(acptr))
-      continue;
-    if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker)
-    {
-      sentalong[i] = sentalong_marker;
-      /* Don't send channel messages to links that are
-         still eating the net.burst: -- Run 2/1/1997 */
-      if (!IsBurstOrBurstAck(acptr->from))
-        vsendto_prefix_one(acptr, from, pattern, vl);
-    }
-  }
-
-#ifndef NO_PROTOCOL9
-  /* Send message to all 2.9 servers */
-  /* This is a hack, because it assumes that we know how `vl' is build up */
-  source = va_arg(vl, char *);
-  tp = va_arg(vl, char *);      /* Channel */
-  msg = va_arg(vl, char *);
-  for (member = chptr->members; member; member = member->next_member)
-  {
-    acptr = member->user;
-    if (acptr->from == acptr || /* Skip local clients */
-        Protocol(acptr->from) > 9 ||    /* Skip P10 servers */
-        acptr->from == one ||   /* ...was the one I should skip */
-        !IsChanOp(member) ||   /* Skip non chanops */
-        IsZombie(member) || IsDeaf(acptr))
-      continue;
-    if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker)
-    {
-      sentalong[i] = sentalong_marker;
-      /* Don't send channel messages to links that are
-         still eating the net.burst: -- Run 2/1/1997 */
-      if (!IsBurstOrBurstAck(acptr->from))
-      {
-        struct Membership* other_member;
-        struct Client* acptr2;
-        tp = target;
-        *tp = 0;
-        /* Find all chanops in this direction: */
-        for (other_member = chptr->members; other_member; other_member = other_member->next_member)
-        {
-          acptr2 = other_member->user;
-          if (acptr2->from == acptr->from && acptr2->from != one &&
-              IsChanOp(other_member) && !IsZombie(other_member) &&
-              !IsDeaf(acptr2))
-          {
-            int len = strlen(acptr2->name);
-            if (tp + len + 2 > target + sizeof(target))
-            {
-              sendto_prefix_one(acptr, from,
-                  ":%s NOTICE %s :%s", source, target, msg);
-              tp = target;
-              *tp = 0;
-            }
-            if (*target)
-              strcpy(tp++, ",");
-            strcpy(tp, acptr2->name);
-            tp += len;
-          }
-        }
-        sendto_prefix_one(acptr, from,
-            ":%s NOTICE %s :%s", source, target, msg);
-      }
-    }
-  }
-#endif
-
-  va_end(vl);
-  return;
-}
-
-/*
- * sendto_serv_butone
- *
- * Send a message to all connected servers except the client 'one'.
- */
-/* See sendcmdto_serv_butone, below */
-void sendto_serv_butone(struct Client *one, const char* pattern, ...)
-{
-  va_list vl;
-  struct DLink *lp;
-
-  va_start(vl, pattern);
-  vsprintf_irc(sendbuf, pattern, vl);
-  va_end(vl);
-
-  for (lp = me.serv->down; lp; lp = lp->next)
-  {
-    if (one && lp->value.cptr == one->from)
-      continue;
-    sendbufto_one(lp->value.cptr);
-  }
-
-}
-
-/*
- * sendbufto_serv_butone()
- *
- * Send prepared sendbuf to all connected servers except the client 'one'
- *  -Ghostwolf 18-May-97
- */
-void sendbufto_serv_butone(struct Client *one)
-{
-  struct DLink *lp;
-
-  for (lp = me.serv->down; lp; lp = lp->next)
-  {
-    if (one && lp->value.cptr == one->from)
-      continue;
-    sendbufto_one(lp->value.cptr);
-  }
-}
-
-
-/*
- * sendto_common_channels()
- *
- * Sends a message to all people (inclusing `acptr') on local server
- * who are in same channel with client `acptr'.
- */
-/* See sendcmdto_common_channels, below */
-void sendto_common_channels(struct Client *acptr, const char* pattern, ...)
-{
-  va_list vl;
-  struct Membership* chan;
-  struct Membership* member;
-
-  assert(0 != acptr);
-  assert(0 != acptr->from);
-  assert(0 != pattern);
-
-  va_start(vl, pattern);
-
-  ++sentalong_marker;
-  if (-1 < acptr->from->fd)
-    sentalong[acptr->from->fd] = sentalong_marker;
-  /*
-   * loop through acptr's channels, and the members on their channels
-   */
-  if (acptr->user) {
-    for (chan = acptr->user->channel; chan; chan = chan->next_channel) {
-      for (member = chan->channel->members; member; member = member->next_member) {
-        struct Client *cptr = member->user;
-        int    i;
-        if (MyConnect(cptr) && 
-            -1 < (i = cptr->fd) && sentalong[i] != sentalong_marker) {
-          sentalong[i] = sentalong_marker;
-          vsendto_prefix_one(cptr, acptr, pattern, vl);
-        }
-      }
-    }
-  }
-  if (MyConnect(acptr))
-    vsendto_prefix_one(acptr, acptr, pattern, vl);
-  va_end(vl);
-  return;
-}
-
-/*
- * sendto_channel_butserv
- *
- * Send a message to all members of a channel that
- * are connected to this server.
- *
- * This contains a subtle bug; after the first call to vsendto_prefix_one()
- * below, vl is in an indeterminate state, according to ANSI; we'd have to
- * move va_start() and va_end() into the loop to correct the problem.  It's
- * easier, however, just to use sendcmdto_channel_butserv(), which builds a
- * buffer and sends that prepared buffer to each channel member.
- */
-/* See sendcmdto_channel_butserv, below */
-void sendto_channel_butserv(struct Channel *chptr, struct Client *from, const char* pattern, ...)
-{
-  va_list vl;
-  struct Membership* member;
-  struct Client *acptr;
-  
-  va_start(vl, pattern);
-
-  for (member = chptr->members; member; member = member->next_member) {
-    acptr = member->user;
-    if (MyConnect(acptr) && !IsZombie(member))
-      vsendto_prefix_one(acptr, from, pattern, vl);
-  }
-  va_end(vl);
-  return;
-}
-
 /*
  * Send a msg to all ppl on servers/hosts that match a specified mask
  * (used for enhanced PRIVMSGs)
@@ -647,300 +232,22 @@ static int match_it(struct Client *one, const char *mask, int what)
   }
 }
 
-/*
- * sendto_match_butone
- *
- * Send to all clients which match the mask in a way defined on 'what';
- * either by user hostname or user servername.
- */
-/* See sendcmdto_match_butone, below */
-void sendto_match_butone(struct Client *one, struct Client *from,
-    const char *mask, int what, const char* pattern, ...)
-{
-  va_list vl;
-  int i;
-  struct Client *cptr, *acptr;
-
-  va_start(vl, pattern);
-  for (i = 0; i <= HighestFd; i++)
-  {
-    if (!(cptr = LocalClientArray[i]))
-      continue;                 /* that clients are not mine */
-    if (cptr == one)            /* must skip the origin !! */
-      continue;
-    if (IsServer(cptr))
-    {
-      for (acptr = GlobalClientList; acptr; acptr = acptr->next)
-        if (IsUser(acptr) && match_it(acptr, mask, what) && acptr->from == cptr)
-          break;
-      /* a person on that server matches the mask, so we
-       *  send *one* msg to that server ...
-       */
-      if (acptr == NULL)
-        continue;
-      /* ... but only if there *IS* a matching person */
-    }
-    /* my client, does he match ? */
-    else if (!(IsUser(cptr) && match_it(cptr, mask, what)))
-      continue;
-    vsendto_prefix_one(cptr, from, pattern, vl);
-  }
-  va_end(vl);
-
-  return;
-}
-
-/*
- * sendto_op_mask
- *
- * Sends message to the list indicated by the bitmask field.
- * Don't try to send to more than one list! That is not supported.
- * Xorath 5/1/97
- */
-#ifdef OLD_VSENDTO_OP_MASK
-void vsendto_op_mask(unsigned int mask, const char *pattern, va_list vl)
-{
-  static char fmt[1024];
-  char *fmt_target;
-  int i = 0;            /* so that 1 points to opsarray[0] */
-  struct SLink *opslist;
-
-  while ((mask >>= 1))
-    i++;
-  if (!(opslist = opsarray[i]))
-    return;
-
-  fmt_target = sprintf_irc(fmt, ":%s NOTICE ", me.name);
-  do
-  {
-    strcpy(fmt_target, opslist->value.cptr->name);
-    strcat(fmt_target, " :*** Notice -- ");
-    strcat(fmt_target, pattern);
-    vsendto_one(opslist->value.cptr, fmt, vl);
-    opslist = opslist->next;
-  }
-  while (opslist);
-}
-#else /* !OLD_VSENDTO_OP_MASK */
-void vsendto_op_mask(unsigned int mask, const char *pattern, va_list vl)
-{
-  vsendto_opmask_butone(0, mask, pattern, vl);
-}
-#endif /* OLD_VSENDTO_OP_MASK */
-
-/*
- * sendbufto_op_mask
- *
- * Send a prepared sendbuf to the list indicated by the bitmask field.
- * Ghostwolf 16-May-97
- */
-void sendbufto_op_mask(unsigned int mask)
-{
-  int i = 0;            /* so that 1 points to opsarray[0] */
-  struct SLink *opslist;
-  while ((mask >>= 1))
-    i++;
-  if (!(opslist = opsarray[i]))
-    return;
-  do
-  {
-    sendbufto_one(opslist->value.cptr);
-    opslist = opslist->next;
-  }
-  while (opslist);
-}
-
-
-/*
- * sendto_ops
- *
- * Send to *local* ops only.
- */
-/* See vsendto_opmask_butone, below */
-void vsendto_ops(const char *pattern, va_list vl)
-{
-  struct Client *cptr;
-  int i;
-  char fmt[1024];
-  char *fmt_target;
-
-  fmt_target = sprintf_irc(fmt, ":%s NOTICE ", me.name);
-
-  for (i = 0; i <= HighestFd; i++)
-    if ((cptr = LocalClientArray[i]) && !IsServer(cptr) &&
-        SendServNotice(cptr))
-    {
-      strcpy(fmt_target, cptr->name);
-      strcat(fmt_target, " :*** Notice -- ");
-      strcat(fmt_target, pattern);
-      vsendto_one(cptr, fmt, vl);
-    }
-}
-
-/* See sendto_opmask_butone, below */
-void sendto_op_mask(unsigned int mask, const char *pattern, ...)
-{
-  va_list vl;
-  va_start(vl, pattern);
-  vsendto_op_mask(mask, pattern, vl);
-  va_end(vl);
-}
-
-/* See sendto_opmask_butone, below */
-void sendto_ops(const char *pattern, ...)
-{
-  va_list vl;
-  va_start(vl, pattern);
-  vsendto_op_mask(SNO_OLDSNO, pattern, vl);
-  va_end(vl);
-}
-
-/*
- * sendto_ops_butone
- *
- * Send message to all operators.
- * one - client not to send message to
- * from- client which message is from *NEVER* NULL!!
- */
-void sendto_ops_butone(struct Client *one, struct Client *from, const char *pattern, ...)
-{
-  va_list vl;
-  int i;
-  struct Client *cptr;
-
-  va_start(vl, pattern);
-  ++sentalong_marker;
-  for (cptr = GlobalClientList; cptr; cptr = cptr->next)
-  {
-    if (!SendWallops(cptr))
-      continue;
-    i = cptr->from->fd;         /* find connection oper is on */
-    if (i < 0 || sentalong[i] == sentalong_marker)       /* sent message along it already ? */
-      continue;
-    if (cptr->from == one)
-      continue;                 /* ...was the one I should skip */
-    sentalong[i] = sentalong_marker;
-    vsendto_prefix_one(cptr->from, from, pattern, vl);
-  }
-  va_end(vl);
-
-  return;
-}
-
-/*
- * sendto_g_serv_butone
- *
- * Send message to all remote +g users (server links).
- *
- * one - server not to send message to.
- */
-void sendto_g_serv_butone(struct Client *one, const char *pattern, ...)
-{
-  va_list vl;
-  struct Client *cptr;
-  int i;
-
-  va_start(vl, pattern);
-  ++sentalong_marker;
-  vsprintf_irc(sendbuf, pattern, vl);
-  for (cptr = GlobalClientList; cptr; cptr = cptr->next)
-  {
-    if (!SendDebug(cptr))
-      continue;
-    i = cptr->from->fd;         /* find connection user is on */
-    if (i < 0 || sentalong[i] == sentalong_marker)       /* sent message along it already ? */
-      continue;
-    if (MyConnect(cptr))
-      continue;
-    sentalong[i] = sentalong_marker;
-    if (cptr->from == one)
-      continue;
-    sendbufto_one(cptr);
-  }
-  va_end(vl);
-
-  return;
-}
-
-/*
- * sendto_prefix_one
- *
- * to - destination client
- * from - client which message is from
- *
- * NOTE: NEITHER OF THESE SHOULD *EVER* BE NULL!!
- * -avalon
- */
-/* See sendcmdto_one, below */
-void sendto_prefix_one(struct Client *to, struct Client *from, const char *pattern, ...)
-{
-  va_list vl;
-  va_start(vl, pattern);
-  vsendto_prefix_one(to, from, pattern, vl);
-  va_end(vl);
-}
-
-/*
- * sendto_realops
- *
- * Send to *local* ops only but NOT +s nonopers.
- */
-/* See sendto_opmask_butone, below */
-void sendto_realops(const char *pattern, ...)
-{
-  va_list vl;
-
-  va_start(vl, pattern);
-  vsendto_op_mask(SNO_OLDREALOP, pattern, vl);
-
-  va_end(vl);
-  return;
-}
-
-/*
- * Send message to all servers of protocol 'p' and lower.
- */
-/* See sendcmdto_serv_butone, below */
-void sendto_lowprot_butone(struct Client *cptr, int p, const char *pattern, ...)
-{
-  va_list vl;
-  struct DLink *lp;
-  va_start(vl, pattern);
-  for (lp = me.serv->down; lp; lp = lp->next)
-    if (lp->value.cptr != cptr && Protocol(lp->value.cptr) <= p)
-      vsendto_one(lp->value.cptr, pattern, vl);
-  va_end(vl);
-}
-
-/*
- * Send message to all servers of protocol 'p' and higher.
- */
-/* See sendcmdto_serv_butone, below */
-void sendto_highprot_butone(struct Client *cptr, int p, const char *pattern, ...)
-{
-  va_list vl;
-  struct DLink *lp;
-  va_start(vl, pattern);
-  for (lp = me.serv->down; lp; lp = lp->next)
-    if (lp->value.cptr != cptr && Protocol(lp->value.cptr) >= p)
-      vsendto_one(lp->value.cptr, pattern, vl);
-  va_end(vl);
-}
-
 /*
  * Send a raw command to a single client; use *ONLY* if you absolutely
  * must send a command without a prefix.
  */
 void sendrawto_one(struct Client *to, const char *pattern, ...)
 {
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   va_list vl;
 
   va_start(vl, pattern);
-  ircd_vsnprintf(to, sndbuf, sizeof(sndbuf) - 2, pattern, vl);
+  mb = msgq_vmake(to, pattern, vl);
   va_end(vl);
 
-  send_buffer(to, sndbuf);
+  send_buffer(to, mb, 0);
+
+  msgq_clean(mb);
 }
 
 /*
@@ -962,17 +269,19 @@ void vsendcmdto_one(struct Client *from, const char *cmd, const char *tok,
                    struct Client *to, const char *pattern, va_list vl)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
 
   to = to->from;
 
   vd.vd_format = pattern; /* set up the struct VarData for %v */
   vd.vd_args = vl;
 
-  ircd_snprintf(to, sndbuf, sizeof(sndbuf) - 2, "%:#C %s %v", from,
-               IsServer(to) || IsMe(to) ? tok : cmd, &vd);
+  mb = msgq_make(to, "%:#C %s %v", from, IsServer(to) || IsMe(to) ? tok : cmd,
+                &vd);
+
+  send_buffer(to, mb, 0);
 
-  send_buffer(to, sndbuf);
+  msgq_clean(mb);
 }
 
 /*
@@ -984,22 +293,24 @@ void sendcmdto_serv_butone(struct Client *from, const char *cmd,
                           const char *pattern, ...)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   struct DLink *lp;
 
   vd.vd_format = pattern; /* set up the struct VarData for %v */
   va_start(vd.vd_args, pattern);
 
   /* use token */
-  ircd_snprintf(&me, sndbuf, sizeof(sndbuf) - 2, "%C %s %v", from, tok, &vd);
+  mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
   va_end(vd.vd_args);
 
   /* send it to our downlinks */
   for (lp = me.serv->down; lp; lp = lp->next) {
     if (one && lp->value.cptr == one->from)
       continue;
-    send_buffer(lp->value.cptr, sndbuf);
+    send_buffer(lp->value.cptr, mb, 0);
   }
+
+  msgq_clean(mb);
 }
 
 /*
@@ -1023,7 +334,7 @@ void sendcmdto_common_channels(struct Client *from, const char *cmd,
                               const char *tok, const char *pattern, ...)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   struct Membership *chan;
   struct Membership *member;
 
@@ -1037,7 +348,7 @@ void sendcmdto_common_channels(struct Client *from, const char *cmd,
   va_start(vd.vd_args, pattern);
 
   /* build the buffer */
-  ircd_snprintf(0, sndbuf, sizeof(sndbuf) - 2, "%:#C %s %v", from, cmd, &vd);
+  mb = msgq_make(0, "%:#C %s %v", from, cmd, &vd);
   va_end(vd.vd_args);
 
   sentalong_marker++;
@@ -1052,11 +363,13 @@ void sendcmdto_common_channels(struct Client *from, const char *cmd,
       if (MyConnect(member->user) && -1 < member->user->from->fd &&
          sentalong[member->user->from->fd] != sentalong_marker) {
        sentalong[member->user->from->fd] = sentalong_marker;
-       send_buffer(member->user, sndbuf);
+       send_buffer(member->user, mb, 0);
       }
 
   if (MyConnect(from))
-    send_buffer(from, sndbuf);
+    send_buffer(from, mb, 0);
+
+  msgq_clean(mb);
 }
 
 /*
@@ -1068,21 +381,23 @@ void sendcmdto_channel_butserv(struct Client *from, const char *cmd,
                               const char *pattern, ...)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   struct Membership *member;
 
   vd.vd_format = pattern; /* set up the struct VarData for %v */
   va_start(vd.vd_args, pattern);
 
   /* build the buffer */
-  ircd_snprintf(0, sndbuf, sizeof(sndbuf) - 2, "%:#C %s %v", from, cmd, &vd);
+  mb = msgq_make(0, "%:#C %s %v", from, cmd, &vd);
   va_end(vd.vd_args);
 
   /* send the buffer to each local channel member */
   for (member = to->members; member; member = member->next_member) {
     if (MyConnect(member->user) && !IsZombie(member))
-      send_buffer(member->user, sndbuf);
+      send_buffer(member->user, mb, 0);
   }
+
+  msgq_clean(mb);
 }
 
 /*
@@ -1109,21 +424,20 @@ void sendcmdto_channel_butone(struct Client *from, const char *cmd,
 {
   struct Membership *member;
   struct VarData vd;
-  char userbuf[IRC_BUFSIZE];
-  char servbuf[IRC_BUFSIZE];
+  struct MsgBuf *user_mb;
+  struct MsgBuf *serv_mb;
 
   vd.vd_format = pattern;
 
   /* Build buffer to send to users */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(0, userbuf, sizeof(userbuf) - 2,
-               skip & SKIP_NONOPS ? "%:#C %s @%v" : "%:#C %s %v", from,
-               skip & SKIP_NONOPS ? MSG_NOTICE : cmd, &vd);
+  user_mb = msgq_make(0, skip & SKIP_NONOPS ? "%:#C %s @%v" : "%:#C %s %v",
+                     from, skip & SKIP_NONOPS ? MSG_NOTICE : cmd, &vd);
   va_end(vd.vd_args);
 
   /* Build buffer to send to servers */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(&me, servbuf, sizeof(servbuf) - 2, "%C %s %v", from, tok, &vd);
+  serv_mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
   va_end(vd.vd_args);
 
   /* send buffer along! */
@@ -1140,10 +454,13 @@ void sendcmdto_channel_butone(struct Client *from, const char *cmd,
     sentalong[member->user->from->fd] = sentalong_marker;
 
     if (MyConnect(member->user)) /* pick right buffer to send */
-      send_buffer(member->user, userbuf);
+      send_buffer(member->user, user_mb, 0);
     else
-      send_buffer(member->user, servbuf);
+      send_buffer(member->user, serv_mb, 0);
   }
+
+  msgq_clean(user_mb);
+  msgq_clean(serv_mb);
 }
 
 /*
@@ -1166,20 +483,19 @@ void sendcmdto_flag_butone(struct Client *from, const char *cmd,
 {
   struct VarData vd;
   struct Client *cptr;
-  char userbuf[IRC_BUFSIZE];
-  char servbuf[IRC_BUFSIZE];
+  struct MsgBuf *user_mb;
+  struct MsgBuf *serv_mb;
 
   vd.vd_format = pattern;
 
   /* Build buffer to send to users */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(0, userbuf, sizeof(userbuf) - 2, "%:#C " MSG_WALLOPS " %v",
-               from, &vd);
+  user_mb = msgq_make(0, "%:#C " MSG_WALLOPS " %v", from, &vd);
   va_end(vd.vd_args);
 
   /* Build buffer to send to servers */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(&me, servbuf, sizeof(servbuf) - 2, "%C %s %v", from, tok, &vd);
+  serv_mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
   va_end(vd.vd_args);
 
   /* send buffer along! */
@@ -1191,10 +507,13 @@ void sendcmdto_flag_butone(struct Client *from, const char *cmd,
     sentalong[cptr->from->fd] = sentalong_marker;
 
     if (MyConnect(cptr)) /* send right buffer */
-      send_buffer(cptr, userbuf);
+      send_buffer(cptr, user_mb, 1);
     else
-      send_buffer(cptr, servbuf);
+      send_buffer(cptr, serv_mb, 1);
   }
+
+  msgq_clean(user_mb);
+  msgq_clean(serv_mb);
 }
 
 /*
@@ -1222,19 +541,19 @@ void sendcmdto_match_butone(struct Client *from, const char *cmd,
 {
   struct VarData vd;
   struct Client *cptr;
-  char userbuf[IRC_BUFSIZE];
-  char servbuf[IRC_BUFSIZE];
+  struct MsgBuf *user_mb;
+  struct MsgBuf *serv_mb;
 
   vd.vd_format = pattern;
 
   /* Build buffer to send to users */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(0, userbuf, sizeof(userbuf) - 2, "%:#C %s %v", from, cmd, &vd);
+  user_mb = msgq_make(0, "%:#C %s %v", from, cmd, &vd);
   va_end(vd.vd_args);
 
   /* Build buffer to send to servers */
   va_start(vd.vd_args, pattern);
-  ircd_snprintf(&me, servbuf, sizeof(servbuf) - 2, "%C %s %v", from, tok, &vd);
+  serv_mb = msgq_make(&me, "%C %s %v", from, tok, &vd);
   va_end(vd.vd_args);
 
   /* send buffer along */
@@ -1247,10 +566,13 @@ void sendcmdto_match_butone(struct Client *from, const char *cmd,
     sentalong[cptr->from->fd] = sentalong_marker;
 
     if (MyConnect(cptr)) /* send right buffer */
-      send_buffer(cptr, userbuf);
+      send_buffer(cptr, user_mb, 0);
     else
-      send_buffer(cptr, servbuf);
+      send_buffer(cptr, serv_mb, 0);
   }
+
+  msgq_clean(user_mb);
+  msgq_clean(serv_mb);
 }
 
 /*
@@ -1274,7 +596,7 @@ void vsendto_opmask_butone(struct Client *one, unsigned int mask,
                           const char *pattern, va_list vl)
 {
   struct VarData vd;
-  char sndbuf[IRC_BUFSIZE];
+  struct MsgBuf *mb;
   int i = 0; /* so that 1 points to opsarray[0] */
   struct SLink *opslist;
 
@@ -1290,9 +612,10 @@ void vsendto_opmask_butone(struct Client *one, unsigned int mask,
    */
   vd.vd_format = pattern;
   vd.vd_args = vl;
-  ircd_snprintf(0, sndbuf, sizeof(sndbuf) - 2, ":%s " MSG_NOTICE
-               " * :*** Notice -- %v", me.name, &vd);
+  mb = msgq_make(0, ":%s " MSG_NOTICE " * :*** Notice -- %v", me.name, &vd);
 
   for (; opslist; opslist = opslist->next)
-    send_buffer(opslist->value.cptr, sndbuf);
+    send_buffer(opslist->value.cptr, mb, 0);
+
+  msgq_clean(mb);
 }