Mercurial > pidgin
annotate plugins/icq/icqevent.c @ 1971:7fbd745756c0
[gaim-migrate @ 1981]
i thought i fixed this already
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 07 Jun 2001 07:36:03 +0000 |
parents | 8ed70631ed15 |
children | 7b3f1eb1ef7d |
rev | line source |
---|---|
1309 | 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | |
3 /* | |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
4 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
5 * Bill Soudan <soudan@kde.org> |
1309 | 6 * |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
7 * This program is free software; you can redistribute it and/or modify |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
10 * (at your option) any later version. |
1309 | 11 * |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
12 * This program is distributed in the hope that it will be useful, |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
15 * GNU General Public License for more details. |
1309 | 16 * |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
17 * You should have received a copy of the GNU General Public License |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
18 * along with this program; if not, write to the Free Software |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
1309 | 20 * |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
21 */ |
1309 | 22 |
23 #include <stdlib.h> | |
24 | |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
25 #include "icqlib.h" /* for icqbyteorder.h ?! */ |
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
26 #include "icqbyteorder.h" |
1309 | 27 #include "icqevent.h" |
28 | |
29 #ifdef EVENT_DEBUG | |
30 #include <string.h> | |
31 #include <stdio.h> | |
32 #endif | |
33 | |
34 #define new_event(x, y) y * x = ( y * )malloc(sizeof(y)) | |
35 | |
36 /* generic Event - 'header' for each tcp packet */ | |
37 | |
38 void icq_EventInit(icq_Event *p, int type, int subtype, unsigned long uin, | |
39 int version) | |
40 { | |
41 if (!p) | |
42 return; | |
43 | |
44 p->uin=uin; | |
45 p->version=version; | |
46 p->type=type; | |
47 p->subtype=subtype; | |
48 p->direction=ICQ_EVENT_OUTGOING; | |
49 } | |
50 | |
51 icq_Packet *icq_EventCreatePacket(icq_Event *pbase) | |
52 { | |
53 icq_Packet *p=icq_PacketNew(); | |
54 | |
55 /* create header for tcp packet */ | |
56 icq_PacketAppend32(p, pbase->uin); | |
57 icq_PacketAppend16(p, pbase->version); | |
58 icq_PacketAppend16(p, pbase->subtype); | |
59 icq_PacketAppend16(p, 0x0000); | |
60 icq_PacketAppend32(p, pbase->uin); | |
61 icq_PacketAppend32(p, pbase->type); | |
62 | |
63 return p; | |
64 } | |
65 | |
66 void icq_EventParsePacket(icq_Event *pevent, icq_Packet *p) | |
67 { | |
68 /* parse header of tcp packet */ | |
69 icq_PacketBegin(p); | |
70 (void)icq_PacketRead32(p); /* uin */ | |
71 pevent->version=icq_PacketRead16(p); /* max supported tcp version */ | |
72 pevent->subtype=icq_PacketRead16(p); /* event subtype */ | |
73 (void)icq_PacketRead16(p); /* 0x0000 */ | |
74 pevent->uin=icq_PacketRead32(p); /* uin */ | |
75 pevent->type=icq_PacketRead16(p); /* event type */ | |
76 } | |
77 | |
78 /* Message Event - extends generic Event */ | |
79 | |
80 icq_MessageEvent *icq_CreateMessageEvent(int subtype, unsigned long uin, | |
81 const char *message) | |
82 { | |
83 new_event(p, icq_MessageEvent); | |
84 icq_Event *pbase=(icq_Event *)p; | |
85 icq_MessageEventInit(p, ICQ_TCP_MSG_MSG, subtype, uin, | |
86 ICQ_TCP_MSG_REAL, message); | |
87 | |
88 pbase->createPacket=icq_MessageCreatePacket; | |
89 | |
90 #ifdef EVENT_DEBUG | |
91 pbase->eventName=icq_MessageEventName; | |
92 pbase->eventDump=icq_MessageEventDump; | |
93 #endif | |
94 | |
95 return p; | |
96 } | |
97 | |
98 void icq_MessageEventInit(icq_MessageEvent *p, int type, int subtype, | |
99 unsigned long uin, int msgtype, const char *message) | |
100 { | |
101 icq_EventInit((icq_Event *)p, type, subtype, uin, ICQ_TCP_VER); | |
102 p->type=msgtype; | |
103 p->message=(char *)message; | |
104 p->status=0; /* FIXME */ | |
105 } | |
106 | |
107 icq_Packet *icq_MessageCreatePacket(icq_Event *pbase, icq_TCPLink *plink) | |
108 { | |
109 icq_MessageEvent *pevent=(icq_MessageEvent *)pbase; | |
110 | |
111 /* create header */ | |
112 icq_Packet *p=icq_EventCreatePacket(pbase); | |
113 | |
114 /* append data specific to message event */ | |
115 icq_PacketAppendString(p, (char*)pevent->message); | |
116 icq_PacketAppend32(p, plink->socket_address.sin_addr.s_addr); | |
117 /* FIXME: should be RealIp */ | |
118 icq_PacketAppend32(p, htonl(plink->icqlink->icq_OurIP)); | |
119 icq_PacketAppend32(p, plink->socket_address.sin_port); | |
120 icq_PacketAppend8(p, 0x04); | |
121 icq_PacketAppend16(p, pevent->status); | |
122 icq_PacketAppend16(p, pevent->type); | |
123 | |
124 return p; | |
125 } | |
126 | |
127 void icq_MessageParsePacket(icq_Event *pbase, icq_Packet *p) | |
128 { | |
129 icq_MessageEvent *pevent=(icq_MessageEvent *)pbase; | |
130 | |
131 /* parse message event data from packet */ | |
132 pevent->message=(char *)icq_PacketReadString(p); /* message text */ | |
133 (void)icq_PacketRead32(p); /* remote ip */ | |
134 (void)icq_PacketRead32(p); /* remote real ip */ | |
135 (void)icq_PacketRead32(p); /* remote message port */ | |
136 (void)icq_PacketRead8(p); /* tcp flag */ | |
137 pevent->status=icq_PacketRead16(p); /* remote user status */ | |
138 pevent->type=icq_PacketRead16(p); /* message type */ | |
139 } | |
140 | |
141 #ifdef EVENT_DEBUG | |
142 const char *icq_MessageEventName(icq_Event *p) | |
143 { | |
144 if (p->type==ICQ_EVENT_MESSAGE) | |
145 return "message"; | |
146 else if (p->type==ICQ_EVENT_ACK) | |
147 return "message ack"; | |
148 | |
149 return "message cancel"; | |
150 } | |
151 | |
152 const char *icq_MessageEventDump(icq_Event *p) | |
153 { | |
154 static char buf[255]; | |
155 icq_MessageEvent *pevent=(icq_MessageEvent *)p; | |
156 | |
157 sprintf(buf, ", type=%x, message=\"%10s...\", status=%x", | |
158 pevent->type, pevent->message, pevent->status); | |
159 | |
160 return buf; | |
161 } | |
162 #endif | |
163 | |
164 /* URL Event - extends message Event */ | |
165 | |
166 icq_URLEvent *icq_CreateURLEvent(int subtype, unsigned long uin, | |
167 const char *message, const char *url) | |
168 { | |
169 char *str=(char *)malloc(strlen(message)+strlen(url)+2); | |
170 icq_Event *pbase; | |
171 icq_URLEvent *p; | |
172 | |
173 strcpy((char*)str, message); | |
174 *(str+strlen(message))=0xFE; | |
175 strcpy((char*)(str+strlen(message)+1), url); | |
176 | |
177 /* TODO: make sure create message event copies message */ | |
178 pbase=(icq_Event *)icq_CreateMessageEvent(subtype, uin, str); | |
179 p=(icq_URLEvent *)pbase; | |
180 | |
181 free(str); | |
182 | |
183 *(p->message+strlen(message))=0x00; | |
184 p->url=p->message+strlen(message)+1; | |
185 | |
186 pbase->createPacket=icq_URLCreatePacket; | |
187 | |
188 #ifdef EVENT_DEBUG | |
189 pbase->eventName=icq_URLEventName; | |
190 pbase->eventDump=icq_URLEventDump; | |
191 #endif | |
192 | |
193 return p; | |
194 | |
195 } | |
196 | |
197 icq_Packet *icq_URLCreatePacket(icq_Event *pbase, icq_TCPLink *plink) | |
198 { | |
199 icq_URLEvent *pevent=(icq_URLEvent *)pbase; | |
200 icq_Packet *p; | |
201 | |
202 /* hack message string to include url */ | |
203 *(pevent->message+strlen(pevent->message))=0xFE; | |
204 | |
205 /* create packet */ | |
206 p=icq_MessageCreatePacket(pbase, plink); | |
207 | |
208 /* hack message string to seperate url */ | |
209 *(pevent->message+strlen(pevent->message))=0x00; | |
210 | |
211 return p; | |
212 } | |
213 | |
214 void icq_URLParsePacket(icq_Event *pbase, icq_Packet *p) | |
215 { | |
216 char *pfe; | |
217 icq_URLEvent *pevent=(icq_URLEvent *)pbase; | |
218 | |
219 /* TODO: make sure messageparsepacket allocates message string | |
220 * and add a delete event function */ | |
221 icq_MessageParsePacket(pbase, p); | |
222 | |
223 /* hack message string to seperate url */ | |
224 pfe=strchr(pevent->message, '\xFE'); | |
225 *pfe=0; | |
226 | |
227 /* set url */ | |
228 pevent->url=pfe+1; | |
229 | |
230 } | |
231 | |
232 #ifdef EVENT_DEBUG | |
233 const char *icq_URLEventName(icq_Event *p) | |
234 { | |
235 if (p->type==ICQ_EVENT_MESSAGE) | |
236 return "url"; | |
237 else if (p->type==ICQ_EVENT_ACK) | |
238 return "url ack"; | |
239 | |
240 return "url cancel"; | |
241 } | |
242 | |
243 const char *icq_URLEventDump(icq_Event *p) | |
244 { | |
245 static char buf[255]; | |
246 icq_MessageEvent *pevent=(icq_MessageEvent *)p; | |
247 | |
248 sprintf(buf, ", type=%x, message=\"%10s...\", url=\"%10s...\" status=%x", | |
249 pevent->type, pevent->message, pevent->url, pevent->status); | |
250 | |
251 return buf; | |
252 } | |
253 #endif | |
254 | |
255 | |
256 /* Chat Request Event - extends Message Event */ | |
257 | |
258 icq_ChatRequestEvent *icq_ChatRequestEventNew(int subtype, | |
259 unsigned long uin, const char *message, int port) | |
260 { | |
261 new_event(p, icq_ChatRequestEvent); | |
262 icq_Event *pbase=(icq_Event *)p; | |
263 icq_MessageEventInit((icq_MessageEvent *)p, ICQ_TCP_MSG_CHAT, subtype, | |
264 uin, ICQ_TCP_MSG_REAL, message); | |
265 p->port=port; | |
266 | |
267 pbase->createPacket=icq_ChatRequestCreatePacket; | |
268 | |
269 #ifdef EVENT_DEBUG | |
270 pbase->eventName=icq_ChatRequestEventName; | |
271 pbase->eventDump=icq_ChatRequestEventDump; | |
272 #endif | |
273 | |
274 return p; | |
275 } | |
276 | |
277 icq_Packet *icq_ChatRequestCreatePacket(icq_Event *pbase, | |
278 icq_TCPLink *plink) | |
279 { | |
280 icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)pbase; | |
281 | |
282 /* create header and message data */ | |
283 icq_Packet *p=icq_MessageCreatePacket(pbase, plink); | |
284 | |
285 /* append data specific to chat event */ | |
286 icq_PacketAppendString(p, 0); | |
287 icq_PacketAppend32(p, htonl(pevent->port)); | |
288 icq_PacketAppend32(p, htoicql(pevent->port)); | |
289 | |
290 return p; | |
291 } | |
292 | |
293 void icq_ChatParsePacket(icq_Event *pbase, icq_Packet *p) | |
294 { | |
295 icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)pbase; | |
296 int port; | |
297 | |
298 /* parse header and message event data */ | |
299 icq_MessageParsePacket(pbase, p); | |
300 | |
301 /* parse chat event data */ | |
302 (void)icq_PacketReadString(p); /* null string */ | |
303 port=icq_PacketRead32(p); /* chat listen port, network order */ | |
304 (void)icq_PacketRead32(p); /* chat listen port, intel order */ | |
305 | |
306 pevent->port=ntohl(port); | |
307 } | |
308 | |
309 #ifdef EVENT_DEBUG | |
310 const char *icq_ChatRequestEventName(icq_Event *p) | |
311 { | |
312 if (p->type==ICQ_EVENT_MESSAGE) | |
313 return "chat request"; | |
314 else if (p->type==ICQ_EVENT_ACK) { | |
315 icq_MessageEvent *pevent=(icq_MessageEvent *)p; | |
316 if (pevent->status==ICQ_TCP_STATUS_REFUSE) | |
317 return "chat request refuse"; | |
318 else | |
319 return "chat request ack"; | |
320 } else if (p->type==ICQ_EVENT_CANCEL) | |
321 return "chat request cancel"; | |
322 | |
323 return "unknown chat request"; | |
324 } | |
325 | |
326 const char *icq_ChatRequestEventDump(icq_Event *p) | |
327 { | |
328 static char buf[255]; | |
329 static char buf2[255]; | |
330 icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)p; | |
331 | |
332 strcpy(buf, icq_MessageEventDump(p)); | |
333 sprintf(buf2, ", port=%d", pevent->port); | |
334 strcat(buf, buf2); | |
335 | |
336 return buf; | |
337 } | |
338 #endif | |
339 | |
340 /* File Request Event - builds on Message Event */ | |
341 | |
342 icq_FileRequestEvent *icq_FileRequestEventNew(int subtype, | |
343 unsigned long uin, const char *message, const char *filename, | |
344 unsigned long filesize) | |
345 { | |
346 new_event(p, icq_FileRequestEvent); | |
347 icq_Event *pbase=(icq_Event *)p; | |
348 icq_MessageEventInit((icq_MessageEvent *)p, ICQ_TCP_MSG_FILE, subtype, | |
349 uin, ICQ_TCP_MSG_REAL, message); | |
350 p->filename=filename; | |
351 p->filesize=filesize; | |
352 | |
353 pbase->createPacket=icq_FileRequestCreatePacket; | |
354 | |
355 #ifdef EVENT_DEBUG | |
356 pbase->eventName=icq_FileRequestEventName; | |
357 pbase->eventDump=icq_FileRequestEventDump; | |
358 #endif | |
359 | |
360 return p; | |
361 } | |
362 | |
363 icq_Packet *icq_FileRequestCreatePacket(icq_Event *pbase, | |
364 icq_TCPLink *plink) | |
365 { | |
366 icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase; | |
367 | |
368 /* create header and message data */ | |
369 icq_Packet *p=icq_MessageCreatePacket(pbase, plink); | |
370 | |
371 /* append file event data */ | |
372 icq_PacketAppend32(p, htonl(pevent->port)); | |
373 icq_PacketAppendString(p, pevent->filename); | |
374 icq_PacketAppend32(p, pevent->filesize); | |
375 icq_PacketAppend32(p, htoicql(pevent->port)); | |
376 | |
377 return p; | |
378 } | |
379 | |
380 void icq_FileParsePacket(icq_Event *pbase, icq_Packet *p) | |
381 { | |
382 icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase; | |
383 int port; | |
384 | |
385 /* parse header and message data */ | |
386 icq_MessageParsePacket(pbase, p); | |
387 | |
388 /* parse file event data */ | |
1912
8ed70631ed15
[gaim-migrate @ 1922]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
389 pevent->port=ntohl(icq_PacketRead32(p)); /* file listen port, network */ |
1309 | 390 pevent->filename=icq_PacketReadString(p); /* filename text */ |
391 pevent->filesize=icq_PacketRead32(p); /* total size */ | |
392 (void)icq_PacketRead32(p); /* file listen port, intel */ | |
393 } | |
394 | |
395 #ifdef EVENT_DEBUG | |
396 const char *icq_FileRequestEventName(icq_Event *p) | |
397 { | |
398 if (p->type==ICQ_EVENT_MESSAGE) | |
399 return "file request"; | |
400 else if (p->type==ICQ_EVENT_ACK) { | |
401 icq_MessageEvent *pevent=(icq_MessageEvent *)p; | |
402 if (pevent->status==ICQ_TCP_STATUS_REFUSE) | |
403 return "file request refuse"; | |
404 else | |
405 return "file request ack"; | |
406 } else if (p->type==ICQ_EVENT_CANCEL) | |
407 return "file request cancel"; | |
408 | |
409 return "unknown file request"; | |
410 } | |
411 | |
412 const char *icq_FileRequestEventDump(icq_Event *p) | |
413 { | |
414 static char buf[255]; | |
415 static char buf2[255]; | |
416 icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)p; | |
417 | |
418 strcpy(buf, icq_MessageEventDump(p)); | |
419 sprintf(buf2, ", port=%d, filename=\"%s\", filesize=%ld", pevent->port, | |
420 pevent->filename, pevent->filesize); | |
421 strcat(buf, buf2); | |
422 | |
423 return buf; | |
424 } | |
425 #endif | |
426 | |
427 /* main packet parser */ | |
428 | |
429 icq_Event *icq_ParsePacket(icq_Packet *p) | |
430 { | |
431 /* FIXME */ | |
432 icq_Event *pevent=(icq_Event *)malloc(sizeof(icq_FileRequestEvent)); | |
433 pevent->direction=ICQ_EVENT_INCOMING; | |
434 pevent->time=time(0); | |
435 | |
436 icq_EventParsePacket(pevent, p); | |
437 | |
438 switch(pevent->type) { | |
439 | |
440 case ICQ_TCP_MSG_MSG: | |
441 icq_MessageParsePacket(pevent, p); | |
442 break; | |
443 case ICQ_TCP_MSG_URL: | |
444 icq_URLParsePacket(pevent, p); | |
445 break; | |
446 case ICQ_TCP_MSG_CHAT: | |
447 icq_ChatParsePacket(pevent, p); | |
448 break; | |
449 case ICQ_TCP_MSG_FILE: | |
450 icq_FileParsePacket(pevent, p); | |
451 break; | |
452 default: | |
453 /* FIXME: log */ | |
454 free(pevent); | |
455 pevent=0; | |
456 break; | |
457 } | |
458 | |
459 /* FIXME: ensure no bytes are remaining */ | |
460 | |
461 return pevent; | |
462 } | |
463 | |
464 #ifdef EVENT_DEBUG | |
465 const char *icq_EventDump(icq_Event *pevent) | |
466 { | |
467 static char buf[255]; | |
468 | |
469 sprintf("%s event sent to uin %ld { %s }", (pevent->eventName)(pevent), | |
470 pevent->uin, (pevent->eventDump)(pevent) ); | |
471 | |
472 return buf; | |
473 } | |
474 #endif |