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, 9 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

# Content
1 /*
2 * parse.C: Parsing of IRC messages.
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id: parse.C,v 1.5 2007-08-29 21:01:18 pippijn Exp $";
9
10 #include "atheme.h"
11 #include "servers.h"
12 #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 pcommand_t const *pcmd;
32
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 return slog (LG_INFO, "irc_parse(): got message from nonexistant user or server: %s", origin);
107 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 return slog (LG_DEBUG, "irc_parse(): command not found: %s", coreLine);
132
133 /* take the command through the hash table */
134 if ((pcmd = pcommand_find (command)))
135 {
136 if (si.su && !(pcmd->sourcetype & MSRC_USER))
137 return slog (LG_INFO, "irc_parse(): user %s sent disallowed command %s", si.su->nick, pcmd->token);
138 else if (si.s && !(pcmd->sourcetype & MSRC_SERVER))
139 return slog (LG_INFO, "irc_parse(): server %s sent disallowed command %s", si.s->name, pcmd->token);
140 else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG))
141 return slog (LG_INFO, "irc_parse(): unregistered server sent disallowed command %s", pcmd->token);
142 if (parc < pcmd->minparc)
143 return slog (LG_INFO, "irc_parse(): insufficient parameters for command %s", pcmd->token);
144 if (pcmd->handler)
145 pcmd->handler (&si, parc, parv);
146 }
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 pcommand_t const *pcmd;
164
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 return slog (LG_DEBUG, "p10_parse(): got message from nonexistant user or server: %s", origin);
233 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 return slog (LG_DEBUG, "p10_parse(): command not found: %s", coreLine);
258
259 /* take the command through the hash table */
260 if ((pcmd = pcommand_find (command)))
261 {
262 if (si.su && !(pcmd->sourcetype & MSRC_USER))
263 return slog (LG_INFO, "p10_parse(): user %s sent disallowed command %s", si.su->nick, pcmd->token);
264 else if (si.s && !(pcmd->sourcetype & MSRC_SERVER))
265 return slog (LG_INFO, "p10_parse(): server %s sent disallowed command %s", si.s->name, pcmd->token);
266 else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG))
267 return slog (LG_INFO, "p10_parse(): unregistered server sent disallowed command %s", pcmd->token);
268 if (parc < pcmd->minparc)
269 return slog (LG_INFO, "p10_parse(): insufficient parameters for command %s", pcmd->token);
270 if (pcmd->handler)
271 pcmd->handler (&si, parc, parv);
272 }
273 }
274 }