ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/parse.C
Revision: 1.7
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +7 -2 lines
Log Message:
#defines to enum

File Contents

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