Author: Kev <klmitch@mit.edu>
[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  * $Id$
22  */
23 #include "config.h"
24
25 #include "s_numeric.h"
26 #include "channel.h"
27 #include "client.h"
28 #include "hash.h"
29 #include "ircd.h"
30 #include "ircd_policy.h"
31 #include "ircd_snprintf.h"
32 #include "numnicks.h"
33 #include "send.h"
34 #include "struct.h"
35
36
37 /*
38  * do_numeric()
39  * Rewritten by Nemesi, Jan 1999, to support numeric nicks in parv[1]
40  *
41  * Called when we get a numeric message from a remote _server_ and we are
42  * supposed to forward it somewhere. Note that we always ignore numerics sent
43  * to 'me' and simply drop the message if we can't handle with this properly:
44  * the savy approach is NEVER generate an error in response to an... error :)
45  */
46
47 int do_numeric(int numeric, int nnn, struct Client *cptr, struct Client *sptr,
48     int parc, char *parv[])
49 {
50   struct Client *acptr = 0;
51   struct Channel *achptr = 0;
52   char num[4];
53
54   /* Avoid trash, we need it to come from a server and have a target  */
55   if ((parc < 2) || !IsServer(sptr))
56     return 0;
57
58   /* Who should receive this message ? Will we do something with it ?
59      Note that we use findUser functions, so the target can't be neither
60      a server, nor a channel (?) nor a list of targets (?) .. u2.10
61      should never generate numeric replies to non-users anyway
62      Ahem... it can be a channel actually, csc bots use it :\ --Nem */
63
64   if (IsChannelName(parv[1]))
65     achptr = FindChannel(parv[1]);
66   else
67     acptr = (nnn) ? (findNUser(parv[1])) : (FindUser(parv[1]));
68
69   if (((!acptr) || (cli_from(acptr) == cptr)) && !achptr)
70     return 0;
71
72   /* Remap low number numerics, not that I understand WHY.. --Nemesi  */
73   /* numerics below 100 talk about the current 'connection', you're not
74    * connected to a remote server so it doesn't make sense to send them
75    * remotely - but the information they contain may be useful, so we
76    * remap them up.  Weird, but true.  -- Isomer */
77   if (numeric < 100)
78     numeric += 100;
79
80   ircd_snprintf(0, num, sizeof(num), "%03d", numeric);
81
82 #ifdef HEAD_IN_SAND_REWRITE
83   /* Since 2.10.10.pl14 we rewrite numerics from remote servers to appear to
84    * come from the local server
85    */
86   if (IsOper(acptr)) {
87 #endif
88     if (acptr)
89       sendcmdto_one(sptr, num, num, acptr, "%C %s", acptr, parv[2]);
90     else
91       sendcmdto_channel_butone(sptr, num, num, achptr, cptr,
92                                SKIP_DEAF | SKIP_BURST, "%H %s", achptr,
93                                parv[2]);
94 #ifdef HEAD_IN_SAND_REWRITE
95   } else {
96     if (acptr)
97       sendcmdto_one(&me, num, num, acptr, "%C %s", acptr, parv[2]);
98     else
99       sendcmdto_channel_butone(&me, num, num, achptr, cptr,
100                                SKIP_DEAF | SKIP_BURST, "%H %s", achptr,
101                                parv[2]);
102   }
103 #endif
104
105   return 0;
106 }