* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/** @file
+ * @brief Send a numeric message to a client.
+ * @version $Id$
+ */
+#include "config.h"
-#include "sys.h"
-#include "h.h"
-#include "struct.h"
-#include "s_serv.h"
-#include "s_bsd.h"
-#include "send.h"
-#include "support.h"
-#include "parse.h"
-#include "numeric.h"
+#include "s_numeric.h"
#include "channel.h"
-#include "ircd.h"
+#include "client.h"
#include "hash.h"
+#include "ircd.h"
+#include "ircd_features.h"
+#include "ircd_snprintf.h"
#include "numnicks.h"
-#include "s_numeric.h"
-
-RCSTAG_CC("$Id$");
+#include "send.h"
+#include "struct.h"
-static char buffer[1024];
/*
* do_numeric()
* Called when we get a numeric message from a remote _server_ and we are
* supposed to forward it somewhere. Note that we always ignore numerics sent
* to 'me' and simply drop the message if we can't handle with this properly:
- * the savy approach is NEVER generate an error in response to an... error :)
+ * the savvy approach is NEVER generate an error in response to an... error :)
*/
-int do_numeric(int numeric, int nnn, aClient *cptr, aClient *sptr,
+/** Forwards a numeric message from a remote server.
+ * @param numeric Value of numeric message.
+ * @param nnn If non-zero, treat parv[1] as a numnick; else as a client name.
+ * @param cptr Client that originated the numeric.
+ * @param sptr Peer that sent us the numeric.
+ * @param parc Count of valid arguments in \a parv.
+ * @param parv Argument list.
+ * @return Zero (always).
+ */
+int do_numeric(int numeric, int nnn, struct Client *cptr, struct Client *sptr,
int parc, char *parv[])
{
- aClient *acptr = NULL;
- aChannel *achptr = NULL;
- char *p, *b;
- int i;
+ struct Client *acptr = 0;
+ struct Channel *achptr = 0;
+ char num[4];
/* Avoid trash, we need it to come from a server and have a target */
if ((parc < 2) || !IsServer(sptr))
else
acptr = (nnn) ? (findNUser(parv[1])) : (FindUser(parv[1]));
- if (((!acptr) || (acptr->from == cptr)) && !achptr)
+ if (((!acptr) || (cli_from(acptr) == cptr)) && !achptr)
return 0;
/* Remap low number numerics, not that I understand WHY.. --Nemesi */
+ /* numerics below 100 talk about the current 'connection', you're not
+ * connected to a remote server so it doesn't make sense to send them
+ * remotely - but the information they contain may be useful, so we
+ * remap them up. Weird, but true. -- Isomer */
if (numeric < 100)
numeric += 100;
- /* Rebuild the buffer with all the parv[] without wasting cycles :) */
- b = buffer;
- if (parc > 2)
- {
- for (i = 2; i < (parc - 1); i++)
- for (*b++ = ' ', p = parv[i]; *p; p++)
- *b++ = *p;
- for (*b++ = ' ', *b++ = ':', p = parv[parc - 1]; *p; p++)
- *b++ = *p;
- }
- *b = '\000';
-
- /* Since .06 this will implicitly use numeric nicks when needed */
+ ircd_snprintf(0, num, sizeof(num), "%03d", numeric);
+ /* Since 2.10.10.pl14 we rewrite numerics from remote servers to appear to
+ * come from the local server
+ */
if (acptr)
- sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
- sptr->name, numeric, acptr->name, buffer);
+ sendcmdto_one((feature_bool(FEAT_HIS_REWRITE) && !IsOper(acptr)) ?
+ &me : sptr,
+ num, num, acptr, "%C %s", acptr, parv[2]);
else
- sendto_channel_butone(cptr, sptr, achptr, ":%s %d %s%s",
- sptr->name, numeric, achptr->chname, buffer);
-
+ sendcmdto_channel_butone(feature_bool(FEAT_HIS_REWRITE) ? &me : sptr,
+ num, num, achptr, cptr, SKIP_DEAF | SKIP_BURST,
+ "%H %s", achptr, parv[2]);
return 0;
}