ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/parse.C
Revision: 1.6
Committed: Sun Sep 9 20:05:52 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +2 -1 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * parse.C: Parsing of IRC messages.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.6 static char const rcsid[] = "$Id: parse.C,v 1.5 2007-08-29 21:01:18 pippijn Exp $";
9 pippijn 1.1
10     #include "atheme.h"
11 pippijn 1.6 #include "servers.h"
12 pippijn 1.1 #include "uplink.h"
13     #include "pmodule.h"
14    
15     /* by default, we want the 2.8.21 parser */
16     void (*parse) (char *line) = &irc_parse;
17    
18     /* parses a standard 2.8.21 style IRC stream */
19     void
20     irc_parse (char *line)
21     {
22     sourceinfo_t si;
23     char *pos;
24     char *origin = NULL;
25     char *command = NULL;
26     char *message = NULL;
27     char *parv[MAXPARC + 1];
28     static char coreLine[BUFSIZE];
29     int parc = 0;
30     unsigned int i;
31 pippijn 1.4 pcommand_t const *pcmd;
32 pippijn 1.1
33     /* clear the parv */
34     for (i = 0; i <= MAXPARC; i++)
35     parv[i] = NULL;
36    
37     memset (&si, '\0', sizeof si);
38     si.connection = curr_uplink->conn;
39    
40     if (line != NULL)
41     {
42     /* sometimes we'll get a blank line with just a \n on it...
43     * catch those here... they'll core us later on if we don't
44     */
45     if (*line == '\n')
46     return;
47     if (*line == '\000')
48     return;
49    
50     /* copy the original line so we know what we crashed on */
51     memset ((char *) &coreLine, '\0', BUFSIZE);
52     strlcpy (coreLine, line, BUFSIZE);
53    
54     slog (LG_RAWDATA, "-> %s", line);
55    
56     /* find the first space */
57     if ((pos = strchr (line, ' ')))
58     {
59     *pos = '\0';
60     pos++;
61     /* if it starts with a : we have a prefix/origin
62     * pull the origin off into `origin', and have pos for the
63     * command, message will be the part afterwards
64     */
65     if (*line == ':')
66     {
67     origin = line + 1;
68    
69     si.s = server_find (origin);
70     si.su = user_find (origin);
71    
72     if ((message = strchr (pos, ' ')))
73     {
74     *message = '\0';
75     message++;
76     command = pos;
77     }
78     else
79     {
80     command = pos;
81     message = NULL;
82     }
83     }
84     else
85     {
86     if (me.recvsvr)
87     {
88     origin = me.actual;
89     si.s = server_find (origin);
90     }
91     message = pos;
92     command = line;
93     }
94     }
95     else
96     {
97     if (me.recvsvr)
98     {
99     origin = me.actual;
100     si.s = server_find (origin);
101     }
102     command = line;
103     message = NULL;
104     }
105     if (!si.s && !si.su && me.recvsvr)
106 pippijn 1.5 return slog (LG_INFO, "irc_parse(): got message from nonexistant user or server: %s", origin);
107 pippijn 1.1 si.smu = si.su != NULL ? si.su->myuser : NULL;
108    
109     /* okay, the nasty part is over, now we need to make a
110     * parv out of what's left
111     */
112    
113     if (message)
114     {
115     if (*message == ':')
116     {
117     message++;
118     parv[0] = message;
119     parc = 1;
120     }
121     else
122     parc = tokenize (message, parv);
123     }
124     else
125     parc = 0;
126    
127     /* now we should have origin (or NULL), command, and a parv
128     * with it's accompanying parc... let's make ABSOLUTELY sure
129     */
130     if (!command)
131 pippijn 1.5 return slog (LG_DEBUG, "irc_parse(): command not found: %s", coreLine);
132 pippijn 1.1
133     /* take the command through the hash table */
134     if ((pcmd = pcommand_find (command)))
135     {
136     if (si.su && !(pcmd->sourcetype & MSRC_USER))
137 pippijn 1.5 return slog (LG_INFO, "irc_parse(): user %s sent disallowed command %s", si.su->nick, pcmd->token);
138 pippijn 1.1 else if (si.s && !(pcmd->sourcetype & MSRC_SERVER))
139 pippijn 1.5 return slog (LG_INFO, "irc_parse(): server %s sent disallowed command %s", si.s->name, pcmd->token);
140 pippijn 1.1 else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG))
141 pippijn 1.5 return slog (LG_INFO, "irc_parse(): unregistered server sent disallowed command %s", pcmd->token);
142 pippijn 1.1 if (parc < pcmd->minparc)
143 pippijn 1.5 return slog (LG_INFO, "irc_parse(): insufficient parameters for command %s", pcmd->token);
144 pippijn 1.1 if (pcmd->handler)
145 pippijn 1.5 pcmd->handler (&si, parc, parv);
146 pippijn 1.1 }
147     }
148     }
149    
150     /* parses a P10 IRC stream */
151     void
152     p10_parse (char *line)
153     {
154     sourceinfo_t si;
155     char *pos;
156     char *origin = NULL;
157     char *command = NULL;
158     char *message = NULL;
159     char *parv[MAXPARC + 1];
160     static char coreLine[BUFSIZE];
161     int parc = 0;
162     unsigned int i;
163 pippijn 1.4 pcommand_t const *pcmd;
164 pippijn 1.1
165     /* clear the parv */
166     for (i = 0; i <= MAXPARC; i++)
167     parv[i] = NULL;
168    
169     memset (&si, '\0', sizeof si);
170     si.connection = curr_uplink->conn;
171    
172     if (line != NULL)
173     {
174     /* sometimes we'll get a blank line with just a \n on it...
175     * catch those here... they'll core us later on if we don't
176     */
177     if (*line == '\n')
178     return;
179     if (*line == '\000')
180     return;
181    
182     /* copy the original line so we know what we crashed on */
183     memset ((char *) &coreLine, '\0', BUFSIZE);
184     strlcpy (coreLine, line, BUFSIZE);
185    
186     slog (LG_RAWDATA, "-> %s", line);
187    
188     /* find the first spcae */
189     if ((pos = strchr (line, ' ')))
190     {
191     *pos = '\0';
192     pos++;
193     /* if it starts with a : we have a prefix/origin
194     * pull the origin off into `origin', and have pos for the
195     * command, message will be the part afterwards
196     */
197     if (*line == ':' || me.recvsvr == true)
198     {
199     origin = line;
200     if (*origin == ':')
201     {
202     origin++;
203     si.s = server_find (origin);
204     si.su = user_find_named (origin);
205     }
206     else
207     {
208     si.s = server_find (origin);
209     si.su = user_find (origin);
210     }
211    
212     if ((message = strchr (pos, ' ')))
213     {
214     *message = '\0';
215     message++;
216     command = pos;
217     }
218     else
219     {
220     command = pos;
221     message = NULL;
222     }
223     }
224     else
225     {
226     message = pos;
227     command = line;
228     }
229     }
230    
231     if (!si.s && !si.su && me.recvsvr)
232 pippijn 1.5 return slog (LG_DEBUG, "p10_parse(): got message from nonexistant user or server: %s", origin);
233 pippijn 1.1 si.smu = si.su != NULL ? si.su->myuser : NULL;
234    
235     /* okay, the nasty part is over, now we need to make a
236     * parv out of what's left
237     */
238    
239     if (message)
240     {
241     if (*message == ':')
242     {
243     message++;
244     parv[0] = message;
245     parc = 1;
246     }
247     else
248     parc = tokenize (message, parv);
249     }
250     else
251     parc = 0;
252    
253     /* now we should have origin (or NULL), command, and a parv
254     * with it's accompanying parc... let's make ABSOLUTELY sure
255     */
256     if (!command)
257 pippijn 1.5 return slog (LG_DEBUG, "p10_parse(): command not found: %s", coreLine);
258 pippijn 1.1
259     /* take the command through the hash table */
260     if ((pcmd = pcommand_find (command)))
261     {
262     if (si.su && !(pcmd->sourcetype & MSRC_USER))
263 pippijn 1.5 return slog (LG_INFO, "p10_parse(): user %s sent disallowed command %s", si.su->nick, pcmd->token);
264 pippijn 1.1 else if (si.s && !(pcmd->sourcetype & MSRC_SERVER))
265 pippijn 1.5 return slog (LG_INFO, "p10_parse(): server %s sent disallowed command %s", si.s->name, pcmd->token);
266 pippijn 1.1 else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG))
267 pippijn 1.5 return slog (LG_INFO, "p10_parse(): unregistered server sent disallowed command %s", pcmd->token);
268 pippijn 1.1 if (parc < pcmd->minparc)
269 pippijn 1.5 return slog (LG_INFO, "p10_parse(): insufficient parameters for command %s", pcmd->token);
270 pippijn 1.1 if (pcmd->handler)
271 pippijn 1.5 pcmd->handler (&si, parc, parv);
272 pippijn 1.1 }
273     }
274     }