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