7cf0feff7f37444939604de7c959ec123e07c8d2
[ircu2.10.12-pk.git] / ircd / s_numeric.c
1 /*
2  * IRC - Internet Relay Chat, ircd/s_numeric.c
3  * Copyright (C) 1990 Jarkko Oikarinen
4  *
5  * Numerous fixes by Markku Savela
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 1, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "sys.h"
23 #include "h.h"
24 #include "struct.h"
25 #include "s_serv.h"
26 #include "s_bsd.h"
27 #include "send.h"
28 #include "support.h"
29 #include "parse.h"
30 #include "numeric.h"
31 #include "channel.h"
32 #include "ircd.h"
33 #include "hash.h"
34 #include "numnicks.h"
35 #include "s_numeric.h"
36
37 RCSTAG_CC("$Id$");
38
39 static char buffer[1024];
40
41 /*
42  * do_numeric()
43  * Rewritten by Nemesi, Jan 1999, to support numeric nicks in parv[1]
44  *
45  * Called when we get a numeric message from a remote _server_ and we are
46  * supposed to forward it somewhere. Note that we always ignore numerics sent
47  * to 'me' and simply drop the message if we can't handle with this properly:
48  * the savy approach is NEVER generate an error in response to an... error :)
49  */
50
51 int do_numeric(int numeric, int nnn, aClient *cptr, aClient *sptr,
52     int parc, char *parv[])
53 {
54   aClient *acptr = NULL;
55   aChannel *achptr = NULL;
56   char *p, *b;
57   int i;
58
59   /* Avoid trash, we need it to come from a server and have a target  */
60   if ((parc < 2) || !IsServer(sptr))
61     return 0;
62
63   /* Who should receive this message ? Will we do something with it ?
64      Note that we use findUser functions, so the target can't be neither
65      a server, nor a channel (?) nor a list of targets (?) .. u2.10
66      should never generate numeric replies to non-users anyway
67      Ahem... it can be a channel actually, csc bots use it :\ --Nem */
68
69   if (IsChannelName(parv[1]))
70     achptr = FindChannel(parv[1]);
71   else
72     acptr = (nnn) ? (findNUser(parv[1])) : (FindUser(parv[1]));
73
74   if (((!acptr) || (acptr->from == cptr)) && !achptr)
75     return 0;
76
77   /* Remap low number numerics, not that I understand WHY.. --Nemesi  */
78   if (numeric < 100)
79     numeric += 100;
80
81   /* Rebuild the buffer with all the parv[] without wasting cycles :) */
82   b = buffer;
83   if (parc > 2)
84   {
85     for (i = 2; i < (parc - 1); i++)
86       for (*b++ = ' ', p = parv[i]; *p; p++)
87         *b++ = *p;
88     for (*b++ = ' ', *b++ = ':', p = parv[parc - 1]; *p; p++)
89       *b++ = *p;
90   }
91   *b = '\000';
92
93   /* Since .06 this will implicitly use numeric nicks when needed     */
94
95   if (acptr)
96     sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
97         sptr->name, numeric, acptr->name, buffer);
98   else
99     sendto_channel_butone(cptr, sptr, achptr, ":%s %d %s%s",
100         sptr->name, numeric, achptr->chname, buffer);
101
102   return 0;
103 }