Mercurial > pidgin.yaz
annotate libfaim/aim_rxhandlers.c @ 338:9d258a0aa560
[gaim-migrate @ 348]
Whoa, all kinds of things happened here. The applet looks better. The
preferences dialog changes based on your compile-time options (oscar,
gnome). Whispering works again. libfaim got updated; it can almost do
RVOUS stuff, and hopefully soon can make requests too. The applet doesn't
need to have its sounds go through GNOME, although it still can. There
is code to facilitate SOCKS5 support (all that needs to be done is to
actually write the code to communicate with the proxy server).
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 06 Jun 2000 09:55:30 +0000 |
parents | f3c8d79688db |
children | e4c34ca88d9b |
rev | line source |
---|---|
237 | 1 /* |
2 * aim_rxhandlers.c | |
3 * | |
4 * This file contains most all of the incoming packet handlers, along | |
5 * with aim_rxdispatch(), the Rx dispatcher. Queue/list management is | |
6 * actually done in aim_rxqueue.c. | |
7 * | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
258
diff
changeset
|
8 * Changes by EWarmenhoven, Wed May 24 09:33:38 UTC 2000: |
258
1eeece1c7b7b
[gaim-migrate @ 268]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
9 * - there were some "bleck" printf's i changed to faimdprintf's. |
1eeece1c7b7b
[gaim-migrate @ 268]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
10 * |
237 | 11 */ |
12 | |
283
0f14e6d8a51b
[gaim-migrate @ 293]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
279
diff
changeset
|
13 #include <faim/aim.h> |
2 | 14 |
15 /* | |
237 | 16 * Bleck functions get called when there's no non-bleck functions |
17 * around to cleanup the mess... | |
2 | 18 */ |
237 | 19 int bleck(struct aim_session_t *sess,struct command_rx_struct *workingPtr, ...) |
20 { | |
21 u_short family; | |
22 u_short subtype; | |
2 | 23 |
237 | 24 u_short maxf; |
25 u_short maxs; | |
2 | 26 |
237 | 27 /* XXX: this is ugly. and big just for debugging. */ |
28 char *literals[14][25] = { | |
29 {"Invalid", | |
30 NULL | |
31 }, | |
32 {"General", | |
33 "Invalid", | |
34 "Error", | |
35 "Client Ready", | |
36 "Server Ready", | |
37 "Service Request", | |
38 "Redirect", | |
39 "Rate Information Request", | |
40 "Rate Information", | |
41 "Rate Information Ack", | |
42 NULL, | |
43 "Rate Information Change", | |
44 "Server Pause", | |
45 NULL, | |
46 "Server Resume", | |
47 "Request Personal User Information", | |
48 "Personal User Information", | |
49 "Evil Notification", | |
50 NULL, | |
51 "Migration notice", | |
52 "Message of the Day", | |
53 "Set Privacy Flags", | |
54 "Well Known URL", | |
55 "NOP" | |
56 }, | |
57 {"Location", | |
58 "Invalid", | |
59 "Error", | |
60 "Request Rights", | |
61 "Rights Information", | |
62 "Set user information", | |
63 "Request User Information", | |
64 "User Information", | |
65 "Watcher Sub Request", | |
66 "Watcher Notification" | |
67 }, | |
68 {"Buddy List Management", | |
69 "Invalid", | |
70 "Error", | |
71 "Request Rights", | |
72 "Rights Information", | |
73 "Add Buddy", | |
74 "Remove Buddy", | |
75 "Watcher List Query", | |
76 "Watcher List Response", | |
77 "Watcher SubRequest", | |
78 "Watcher Notification", | |
79 "Reject Notification", | |
80 "Oncoming Buddy", | |
81 "Offgoing Buddy" | |
82 }, | |
83 {"Messeging", | |
84 "Invalid", | |
85 "Error", | |
86 "Add ICBM Parameter", | |
87 "Remove ICBM Parameter", | |
88 "Request Parameter Information", | |
89 "Parameter Information", | |
90 "Outgoing Message", | |
91 "Incoming Message", | |
92 "Evil Request", | |
93 "Evil Reply", | |
94 "Missed Calls", | |
95 "Message Error", | |
96 "Host Ack" | |
97 }, | |
98 {"Advertisements", | |
99 "Invalid", | |
100 "Error", | |
101 "Request Ad", | |
102 "Ad Data (GIFs)" | |
103 }, | |
104 {"Invitation / Client-to-Client", | |
105 "Invalid", | |
106 "Error", | |
107 "Invite a Friend", | |
108 "Invitation Ack" | |
109 }, | |
110 {"Administrative", | |
111 "Invalid", | |
112 "Error", | |
113 "Information Request", | |
114 "Information Reply", | |
115 "Information Change Request", | |
116 "Information Chat Reply", | |
117 "Account Confirm Request", | |
118 "Account Confirm Reply", | |
119 "Account Delete Request", | |
120 "Account Delete Reply" | |
121 }, | |
122 {"Popups", | |
123 "Invalid", | |
124 "Error", | |
125 "Display Popup" | |
126 }, | |
127 {"BOS", | |
128 "Invalid", | |
129 "Error", | |
130 "Request Rights", | |
131 "Rights Response", | |
132 "Set group permission mask", | |
133 "Add permission list entries", | |
134 "Delete permission list entries", | |
135 "Add deny list entries", | |
136 "Delete deny list entries", | |
137 "Server Error" | |
138 }, | |
139 {"User Lookup", | |
140 "Invalid", | |
141 "Error", | |
142 "Search Request", | |
143 "Search Response" | |
144 }, | |
145 {"Stats", | |
146 "Invalid", | |
147 "Error", | |
148 "Set minimum report interval", | |
149 "Report Events" | |
150 }, | |
151 {"Translate", | |
152 "Invalid", | |
153 "Error", | |
154 "Translate Request", | |
155 "Translate Reply", | |
156 }, | |
157 {"Chat Navigation", | |
158 "Invalid", | |
159 "Error", | |
160 "Request rights", | |
161 "Request Exchange Information", | |
162 "Request Room Information", | |
163 "Request Occupant List", | |
164 "Search for Room", | |
165 "Outgoing Message", | |
166 "Incoming Message", | |
167 "Evil Request", | |
168 "Evil Reply", | |
169 "Chat Error", | |
170 } | |
171 }; | |
2 | 172 |
237 | 173 maxf = sizeof(literals) / sizeof(literals[0]); |
174 maxs = sizeof(literals[0]) / sizeof(literals[0][0]); | |
175 | |
176 family = aimutil_get16(workingPtr->data+0); | |
177 subtype= aimutil_get16(workingPtr->data+2); | |
178 | |
179 if((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL)) | |
258
1eeece1c7b7b
[gaim-migrate @ 268]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
180 faimdprintf(1, "bleck: null handler for %04x/%04x (%s)\n", family, subtype, literals[family][subtype+1]); |
237 | 181 else |
258
1eeece1c7b7b
[gaim-migrate @ 268]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
182 faimdprintf(1, "bleck: null handler for %04x/%04x (no literal)\n",family,subtype); |
237 | 183 |
2 | 184 return 1; |
185 } | |
186 | |
237 | 187 int aim_conn_addhandler(struct aim_session_t *sess, |
188 struct aim_conn_t *conn, | |
189 u_short family, | |
190 u_short type, | |
191 rxcallback_t newhandler, | |
192 u_short flags) | |
193 { | |
194 struct aim_rxcblist_t *new,*cur; | |
195 | |
196 if (!conn) | |
197 return -1; | |
198 | |
199 faimdprintf(1, "aim_conn_addhandler: adding for %04x/%04x\n", family, type); | |
200 | |
201 new = (struct aim_rxcblist_t *)calloc(1, sizeof(struct aim_rxcblist_t)); | |
202 new->family = family; | |
203 new->type = type; | |
204 new->flags = flags; | |
205 if (!newhandler) | |
206 new->handler = &bleck; | |
207 else | |
208 new->handler = newhandler; | |
209 new->next = NULL; | |
210 | |
211 cur = conn->handlerlist; | |
212 if (!cur) | |
213 conn->handlerlist = new; | |
214 else | |
215 { | |
216 while (cur->next) | |
217 cur = cur->next; | |
218 cur->next = new; | |
219 } | |
220 | |
221 return 0; | |
222 } | |
223 | |
224 int aim_clearhandlers(struct aim_conn_t *conn) | |
225 { | |
226 struct aim_rxcblist_t *cur,*tmp; | |
227 if (!conn) | |
228 return -1; | |
2 | 229 |
237 | 230 cur = conn->handlerlist; |
231 while(cur) | |
232 { | |
233 tmp = cur->next; | |
234 free(cur); | |
235 cur = tmp; | |
236 } | |
237 return 0; | |
238 } | |
2 | 239 |
237 | 240 rxcallback_t aim_callhandler(struct aim_conn_t *conn, |
241 u_short family, | |
242 u_short type) | |
2 | 243 { |
237 | 244 struct aim_rxcblist_t *cur; |
245 | |
246 if (!conn) | |
247 return NULL; | |
248 | |
249 faimdprintf(1, "aim_callhandler: calling for %04x/%04x\n", family, type); | |
2 | 250 |
237 | 251 cur = conn->handlerlist; |
252 while(cur) | |
2 | 253 { |
237 | 254 if ( (cur->family == family) && (cur->type == type) ) |
255 return cur->handler; | |
256 cur = cur->next; | |
2 | 257 } |
237 | 258 |
259 if (type==0xffff) | |
260 return NULL; | |
261 return aim_callhandler(conn, family, 0xffff); | |
262 } | |
263 | |
264 int aim_callhandler_noparam(struct aim_session_t *sess, | |
265 struct aim_conn_t *conn, | |
266 u_short family, | |
267 u_short type, | |
268 struct command_rx_struct *ptr) | |
269 { | |
270 rxcallback_t userfunc = NULL; | |
271 userfunc = aim_callhandler(conn, family, type); | |
272 if (userfunc) | |
273 return userfunc(sess, ptr); | |
274 return 1; /* XXX */ | |
2 | 275 } |
276 | |
277 /* | |
278 aim_rxdispatch() | |
279 | |
280 Basically, heres what this should do: | |
281 1) Determine correct packet handler for this packet | |
282 2) Mark the packet handled (so it can be dequeued in purge_queue()) | |
283 3) Send the packet to the packet handler | |
284 4) Go to next packet in the queue and start over | |
285 5) When done, run purge_queue() to purge handled commands | |
286 | |
287 Note that any unhandlable packets should probably be left in the | |
288 queue. This is the best way to prevent data loss. This means | |
289 that a single packet may get looked at by this function multiple | |
290 times. This is more good than bad! This behavior may change. | |
291 | |
292 Aren't queue's fun? | |
293 | |
294 TODO: Get rid of all the ugly if's. | |
295 TODO: Clean up. | |
296 TODO: More support for mid-level handlers. | |
297 TODO: Allow for NULL handlers. | |
298 | |
299 */ | |
237 | 300 int aim_rxdispatch(struct aim_session_t *sess) |
2 | 301 { |
302 int i = 0; | |
303 struct command_rx_struct *workingPtr = NULL; | |
304 | |
237 | 305 if (sess->queue_incoming == NULL) { |
306 faimdprintf(1, "parse_generic: incoming packet queue empty.\n"); | |
307 return 0; | |
308 } else { | |
309 workingPtr = sess->queue_incoming; | |
310 for (i = 0; workingPtr != NULL; workingPtr = workingPtr->next, i++) { | |
311 /* | |
312 * XXX: This is still fairly ugly. | |
313 */ | |
314 if (workingPtr->handled) | |
315 continue; | |
316 | |
317 switch(workingPtr->conn->type) { | |
318 case -1: | |
319 /* | |
320 * This can happen if we have a queued command | |
321 * that was recieved after a connection has | |
322 * been terminated. In which case, the handler | |
323 * list has been cleared, and there's nothing we | |
324 * can do for it. We can only cancel it. | |
325 */ | |
326 workingPtr->handled = 1; | |
327 break; | |
328 case AIM_CONN_TYPE_AUTH: { | |
329 u_long head; | |
330 | |
331 head = aimutil_get32(workingPtr->data); | |
332 if (head == 0x00000001) { | |
333 faimdprintf(1, "got connection ack on auth line\n"); | |
334 workingPtr->handled = 1; | |
335 } else { | |
336 u_short family,subtype; | |
337 | |
338 family = aimutil_get16(workingPtr->data); | |
339 subtype = aimutil_get16(workingPtr->data+2); | |
340 | |
341 switch (family) { | |
342 /* New login protocol */ | |
343 #ifdef SNACLOGIN | |
344 case 0x0017: | |
345 if (subtype == 0x0001) | |
346 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0001, workingPtr); | |
347 else if (subtype == 0x0003) | |
348 workingPtr->handled = aim_authparse(sess, workingPtr); | |
349 else if (subtype == 0x0007) | |
350 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0007, workingPtr); | |
351 else | |
352 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr); | |
353 break; | |
354 #else | |
355 /* XXX: this isnt foolproof */ | |
356 case 0x0001: | |
357 if (subtype == 0x0003) | |
358 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr); | |
359 else | |
360 workingPtr->handled = aim_authparse(sess, workingPtr); | |
361 break; | |
362 case 0x0007: | |
363 if (subtype == 0x0005) | |
364 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr); | |
365 break; | |
366 default: | |
367 /* Old login protocol */ | |
368 /* any user callbacks will be called from here */ | |
369 workingPtr->handled = aim_authparse(sess, workingPtr); | |
2 | 370 #endif |
237 | 371 } |
2 | 372 } |
237 | 373 break; |
374 } | |
375 case AIM_CONN_TYPE_BOS: { | |
376 u_short family; | |
377 u_short subtype; | |
331
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
378 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
379 if (workingPtr->type == 0x04) { |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
380 workingPtr->handled = aim_negchan_middle(sess, workingPtr); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
381 break; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
382 } |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
383 |
237 | 384 family = aimutil_get16(workingPtr->data); |
385 subtype = aimutil_get16(workingPtr->data+2); | |
386 | |
387 switch (family) { | |
388 case 0x0000: /* not really a family, but it works */ | |
389 if (subtype == 0x0001) | |
390 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr); | |
391 else | |
392 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); | |
393 break; | |
394 case 0x0001: /* Family: General */ | |
395 switch (subtype) { | |
396 case 0x0001: | |
397 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); | |
398 break; | |
399 case 0x0003: | |
400 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr); | |
401 break; | |
402 case 0x0005: | |
403 workingPtr->handled = aim_handleredirect_middle(sess, workingPtr); | |
404 break; | |
405 case 0x0007: | |
406 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr); | |
407 break; | |
408 case 0x000a: | |
409 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000a, workingPtr); | |
410 break; | |
411 case 0x000f: | |
412 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr); | |
413 break; | |
414 case 0x0013: | |
415 workingPtr->handled = aim_parsemotd_middle(sess, workingPtr); | |
416 break; | |
417 default: | |
418 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr); | |
419 break; | |
420 } | |
421 case 0x0002: /* Family: Location */ | |
422 switch (subtype) { | |
423 case 0x0001: | |
424 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0001, workingPtr); | |
425 break; | |
426 case 0x0003: | |
427 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0003, workingPtr); | |
428 break; | |
429 case 0x0006: | |
430 workingPtr->handled = aim_parse_userinfo_middle(sess, workingPtr); | |
431 break; | |
432 default: | |
433 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr); | |
434 break; | |
435 } | |
436 case 0x0003: /* Family: Buddy List */ | |
437 switch (subtype) { | |
438 case 0x0001: | |
439 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); | |
440 break; | |
441 case 0x0003: | |
442 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0003, 0x0003, workingPtr); | |
443 break; | |
444 case 0x000b: /* oncoming buddy */ | |
445 workingPtr->handled = aim_parse_oncoming_middle(sess, workingPtr); | |
446 break; | |
447 case 0x000c: /* offgoing buddy */ | |
448 workingPtr->handled = aim_parse_offgoing_middle(sess, workingPtr); | |
449 break; | |
450 default: | |
451 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr); | |
452 } | |
453 break; | |
454 case 0x0004: /* Family: Messeging */ | |
455 switch (subtype) { | |
456 case 0x0001: | |
457 workingPtr->handled = aim_parse_msgerror_middle(sess, workingPtr); | |
458 break; | |
459 case 0x0005: | |
460 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr); | |
461 break; | |
462 case 0x0007: | |
463 workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr); | |
464 break; | |
465 case 0x000a: | |
466 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x000a, workingPtr); | |
467 break; | |
468 default: | |
469 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr); | |
470 } | |
471 break; | |
472 case 0x0009: | |
473 if (subtype == 0x0001) | |
474 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); | |
475 else if (subtype == 0x0003) | |
476 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0009, 0x0003, workingPtr); | |
477 else | |
478 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr); | |
479 break; | |
480 case 0x000a: /* Family: User lookup */ | |
481 switch (subtype) { | |
482 case 0x0001: | |
483 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0001, workingPtr); | |
484 break; | |
485 case 0x0003: | |
486 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0003, workingPtr); | |
487 break; | |
488 default: | |
489 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr); | |
490 } | |
491 break; | |
492 case 0x000b: | |
493 if (subtype == 0x0001) | |
494 workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); | |
495 else if (subtype == 0x0002) | |
496 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000b, 0x0002, workingPtr); | |
497 else | |
498 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr); | |
499 break; | |
500 default: | |
501 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); | |
502 break; | |
503 } | |
504 break; | |
505 } | |
506 case AIM_CONN_TYPE_CHATNAV: { | |
507 u_short family; | |
508 u_short subtype; | |
509 family = aimutil_get16(workingPtr->data); | |
510 subtype= aimutil_get16(workingPtr->data+2); | |
511 | |
512 if ((family == 0x0002) && (subtype == 0x0006)) { | |
513 workingPtr->handled = 1; | |
514 aim_conn_setstatus(workingPtr->conn, AIM_CONN_STATUS_READY); | |
515 } else if ((family == 0x000d) && (subtype == 0x0009)) { | |
516 workingPtr->handled = aim_chatnav_parse_info(sess, workingPtr); | |
517 } else { | |
518 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); | |
519 } | |
520 break; | |
521 } | |
522 case AIM_CONN_TYPE_CHAT: { | |
523 u_short family, subtype; | |
524 | |
525 family = aimutil_get16(workingPtr->data); | |
526 subtype= aimutil_get16(workingPtr->data+2); | |
527 | |
528 if ((family == 0x0000) && (subtype == 0x00001)) | |
529 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr); | |
530 else if (family == 0x0001) { | |
531 if (subtype == 0x0001) | |
532 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0001, workingPtr); | |
533 else if (subtype == 0x0003) | |
534 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr); | |
535 else if (subtype == 0x0007) | |
536 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr); | |
537 else | |
538 printf("Chat: unknown snac %04x/%04x\n", family, subtype); | |
539 } else if (family == 0x000e) { | |
540 if (subtype == 0x0002) | |
541 workingPtr->handled = aim_chat_parse_infoupdate(sess, workingPtr); | |
542 else if (subtype == 0x0003) | |
543 workingPtr->handled = aim_chat_parse_joined(sess, workingPtr); | |
544 else if (subtype == 0x0004) | |
545 workingPtr->handled = aim_chat_parse_leave(sess, workingPtr); | |
546 else if (subtype == 0x0006) | |
547 workingPtr->handled = aim_chat_parse_incoming(sess, workingPtr); | |
548 else | |
549 printf("Chat: unknown snac %04x/%04x\n", family, subtype); | |
550 } else { | |
551 printf("Chat: unknown snac %04x/%04x\n", family, subtype); | |
552 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr); | |
553 } | |
554 break; | |
555 } | |
556 default: | |
557 printf("\ninternal error: unknown connection type (very bad.) (type = %d, fd = %d, channel = %02x, commandlen = %02x)\n\n", workingPtr->conn->type, workingPtr->conn->fd, workingPtr->type, workingPtr->commandlen); | |
558 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); | |
559 break; | |
560 } | |
2 | 561 } |
237 | 562 } |
2 | 563 |
237 | 564 /* |
565 * This doesn't have to be called here. It could easily be done | |
566 * by a seperate thread or something. It's an administrative operation, | |
567 * and can take a while. Though the less you call it the less memory | |
568 * you'll have :) | |
569 */ | |
570 aim_purge_rxqueue(sess); | |
2 | 571 |
572 return 0; | |
573 } | |
574 | |
237 | 575 int aim_parsemotd_middle(struct aim_session_t *sess, |
576 struct command_rx_struct *command, ...) | |
2 | 577 { |
237 | 578 rxcallback_t userfunc = NULL; |
579 char *msg; | |
580 int ret=1; | |
581 struct aim_tlvlist_t *tlvlist; | |
582 u_short id; | |
583 | |
584 /* | |
585 * Dunno. | |
586 */ | |
587 id = aimutil_get16(command->data+10); | |
588 | |
589 /* | |
590 * TLVs follow | |
591 */ | |
592 tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12); | |
593 | |
594 msg = aim_gettlv_str(tlvlist, 0x000b, 1); | |
595 | |
596 userfunc = aim_callhandler(command->conn, 0x0001, 0x0013); | |
597 if (userfunc) | |
598 ret = userfunc(sess, command, id, msg); | |
599 | |
600 aim_freetlvchain(&tlvlist); | |
601 | |
602 return ret; | |
603 | |
604 } | |
2 | 605 |
237 | 606 int aim_handleredirect_middle(struct aim_session_t *sess, |
607 struct command_rx_struct *command, ...) | |
608 { | |
609 struct aim_tlv_t *tmptlv = NULL; | |
610 int serviceid = 0x00; | |
611 char cookie[AIM_COOKIELEN]; | |
612 char *ip = NULL; | |
613 rxcallback_t userfunc = NULL; | |
614 struct aim_tlvlist_t *tlvlist; | |
615 int ret = 1; | |
616 | |
617 if (!(tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10))) | |
2 | 618 { |
237 | 619 printf("libfaim: major bug: unable to read tlvchain from redirect\n"); |
620 return ret; | |
621 } | |
622 | |
623 if (!(tmptlv = aim_gettlv(tlvlist, 0x000d, 1))) | |
624 { | |
625 printf("libfaim: major bug: no service ID in tlvchain from redirect\n"); | |
626 aim_freetlvchain(&tlvlist); | |
627 return ret; | |
2 | 628 } |
237 | 629 serviceid = aimutil_get16(tmptlv->value); |
630 | |
631 if (!(ip = aim_gettlv_str(tlvlist, 0x0005, 1))) | |
632 { | |
633 printf("libfaim: major bug: no IP in tlvchain from redirect (service 0x%02x)\n", serviceid); | |
634 aim_freetlvchain(&tlvlist); | |
635 return ret; | |
636 } | |
637 | |
638 if (!(tmptlv = aim_gettlv(tlvlist, 0x0006, 1))) | |
2 | 639 { |
237 | 640 printf("libfaim: major bug: no cookie in tlvchain from redirect (service 0x%02x)\n", serviceid); |
641 aim_freetlvchain(&tlvlist); | |
642 return ret; | |
643 } | |
644 memcpy(cookie, tmptlv->value, AIM_COOKIELEN); | |
645 | |
646 if (serviceid == AIM_CONN_TYPE_CHAT) | |
647 { | |
648 /* | |
649 * Chat hack. | |
650 * | |
651 */ | |
652 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005); | |
653 if (userfunc) | |
654 ret = userfunc(sess, command, serviceid, ip, cookie, sess->pendingjoin); | |
655 free(sess->pendingjoin); | |
656 sess->pendingjoin = NULL; | |
2 | 657 } |
658 else | |
659 { | |
237 | 660 userfunc = aim_callhandler(command->conn, 0x0001, 0x0005); |
661 if (userfunc) | |
662 ret = userfunc(sess, command, serviceid, ip, cookie); | |
663 } | |
2 | 664 |
237 | 665 /* |
666 * XXX: Is there a leak here? Where does IP get freed? | |
667 */ | |
668 aim_freetlvchain(&tlvlist); | |
2 | 669 |
237 | 670 return ret; |
2 | 671 } |
672 | |
237 | 673 int aim_parse_unknown(struct aim_session_t *sess, |
674 struct command_rx_struct *command, ...) | |
2 | 675 { |
237 | 676 u_int i = 0; |
2 | 677 |
237 | 678 faimdprintf(1, "\nRecieved unknown packet:"); |
2 | 679 |
680 for (i = 0; i < command->commandlen; i++) | |
681 { | |
682 if ((i % 8) == 0) | |
683 printf("\n\t"); | |
684 | |
685 printf("0x%2x ", command->data[i]); | |
686 } | |
687 | |
688 printf("\n\n"); | |
689 | |
690 return 1; | |
691 } | |
692 | |
693 | |
331
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
694 int aim_negchan_middle(struct aim_session_t *sess, |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
695 struct command_rx_struct *command) |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
696 { |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
697 struct aim_tlvlist_t *tlvlist; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
698 char *msg = NULL; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
699 unsigned short code = 0; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
700 struct aim_tlv_t *tmptlv; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
701 rxcallback_t userfunc = NULL; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
702 int ret = 1; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
703 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
704 tlvlist = aim_readtlvchain(command->data, command->commandlen); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
705 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
706 if ((tmptlv = aim_gettlv(tlvlist, 0x0009, 1))) |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
707 code = aimutil_get16(tmptlv->value); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
708 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
709 if ((tmptlv = aim_gettlv(tlvlist, 0x000b, 1))) |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
710 msg = aim_gettlv_str(tlvlist, 0x000b, 1); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
711 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
712 userfunc = aim_callhandler(command->conn, |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
713 AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
714 if (userfunc) |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
715 ret = userfunc(sess, command, code, msg); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
716 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
717 aim_freetlvchain(&tlvlist); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
718 free(msg); |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
719 |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
720 return ret; |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
721 } |
f3c8d79688db
[gaim-migrate @ 341]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
722 |
2 | 723 /* |
724 * aim_parse_generalerrs() | |
725 * | |
726 * Middle handler for 0x0001 snac of each family. | |
727 * | |
728 */ | |
237 | 729 int aim_parse_generalerrs(struct aim_session_t *sess, |
730 struct command_rx_struct *command, ...) | |
2 | 731 { |
732 u_short family; | |
733 u_short subtype; | |
237 | 734 |
735 family = aimutil_get16(command->data+0); | |
736 subtype= aimutil_get16(command->data+2); | |
2 | 737 |
738 switch(family) | |
739 { | |
740 default: | |
741 /* Unknown family */ | |
237 | 742 return aim_callhandler_noparam(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command); |
2 | 743 } |
744 | |
745 return 1; | |
746 } | |
747 | |
748 | |
749 |