Mercurial > pidgin.yaz
comparison libfaim/aim_im.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 | bafaf1b68f9a |
children | e4c34ca88d9b |
comparison
equal
deleted
inserted
replaced
337:f5b199e20d12 | 338:9d258a0aa560 |
---|---|
348 | 348 |
349 free(msg); | 349 free(msg); |
350 } | 350 } |
351 else if (channel == 0x0002) | 351 else if (channel == 0x0002) |
352 { | 352 { |
353 int rendtype; | |
354 struct aim_tlv_t *block1; | 353 struct aim_tlv_t *block1; |
355 struct aim_tlvlist_t *list2; | 354 struct aim_tlvlist_t *list2; |
356 struct aim_tlv_t *tmptlv; | 355 struct aim_tlv_t *tmptlv; |
356 struct aim_tlv_t *miscinfo; | |
357 unsigned short reqclass = 0; | |
357 int a; | 358 int a; |
358 | 359 |
359 /* Class. */ | 360 /* Class. */ |
360 if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1))) | 361 if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1))) |
361 userinfo.class = aimutil_get16(tmptlv->value); | 362 userinfo.class = aimutil_get16(tmptlv->value); |
374 | 375 |
375 /* | 376 /* |
376 * There's another block of TLVs embedded in the type 5 here. | 377 * There's another block of TLVs embedded in the type 5 here. |
377 */ | 378 */ |
378 block1 = aim_gettlv(tlvlist, 0x0005, 1); | 379 block1 = aim_gettlv(tlvlist, 0x0005, 1); |
379 if (!block1) | 380 if (!block1) { |
381 printf("faim: no tlv 0x0005 in rendezvous transaction!\n"); | |
382 aim_freetlvchain(&tlvlist); | |
380 return 1; /* major problem */ | 383 return 1; /* major problem */ |
384 } | |
381 | 385 |
382 a = 0x1a; /* skip -- not sure what this information is! */ | 386 a = 0x1a; /* skip -- not sure what this information is! */ |
383 | 387 |
384 /* | 388 /* |
385 * XXX: Ignore if there's no data, only cookie information. | 389 * XXX: Ignore if there's no data, only cookie information. |
386 * | 390 * |
387 * Its probably just an accepted invitation or something. | 391 * Its probably just an accepted invitation or something. |
388 * | 392 * |
389 */ | 393 */ |
390 if (block1->length <= 0x1a) | 394 if (block1->length <= 0x1a) { |
391 { | 395 aim_freetlvchain(&tlvlist); |
396 return 1; | |
397 } | |
398 | |
399 list2 = aim_readtlvchain(block1->value+a, block1->length-a); | |
400 | |
401 if (!(miscinfo = aim_gettlv(list2, 0x2711, 1))) { | |
402 struct aim_msgcookie_t *cook; | |
403 | |
404 if ((cook = aim_uncachecookie(sess, cookie)) == NULL) { | |
405 printf("faim: no 0x2711 info TLV in rendezvous and its not in cache!\n"); | |
406 aim_freetlvchain(&list2); | |
392 aim_freetlvchain(&tlvlist); | 407 aim_freetlvchain(&tlvlist); |
393 return 1; | 408 return 1; |
394 } | 409 } |
395 | 410 |
396 list2 = aim_readtlvchain(block1->value+a, block1->length-a); | 411 if (cook->type == 1) { |
397 | 412 struct aim_filetransfer_t *ft; |
398 if (aim_gettlv(list2, 0x0004, 1) /* start connection */ || | 413 |
399 aim_gettlv(list2, 0x000b, 1) /* close conncetion */) | 414 if (cook->data) { |
400 { | 415 struct aim_tlv_t *errortlv; |
401 rendtype = 1; /* voice request */ | 416 int errorcode = -1; |
402 | 417 |
403 /* | 418 ft = (struct aim_filetransfer_t *)cook->data; |
404 * Call client. | 419 |
405 */ | 420 if ((errortlv = aim_gettlv(list2, 0x000b, 1))) { |
406 userfunc = aim_callhandler(command->conn, 0x0004, 0x0007); | 421 errorcode = aimutil_get16(errortlv->value); |
407 if (userfunc) | 422 } |
408 i = userfunc(sess, | 423 printf("faim: transfer from %s (%s) for %s cancelled (error code %d)\n", ft->sender, ft->ip, ft->filename, errorcode); |
409 command, | 424 free(cook->data); |
410 channel, | 425 } else { |
411 rendtype, | 426 printf("faim: not data attached to file transfer\n"); |
412 &userinfo); | 427 } |
413 else | 428 |
414 i = 0; | 429 } else { |
430 printf("faim: unknown cookie cache type %d\n", cook->type); | |
415 } | 431 } |
416 else | 432 |
417 { | 433 free(cook); |
418 struct aim_chat_roominfo roominfo; | 434 return 1; |
419 char *msg=NULL,*encoding=NULL,*lang=NULL; | 435 } |
420 | 436 |
421 rendtype = 0; /* chat invite */ | 437 |
422 if (aim_gettlv(list2, 0x2711, 1)) | 438 /* |
423 { | 439 * Parse the first two bytes of the 0x2711 TLV. |
424 struct aim_tlv_t *nametlv; | 440 * |
425 | 441 * This can be interpretted in a couple ways. |
426 nametlv = aim_gettlv(list2, 0x2711, 1); | 442 * |
427 aim_chat_readroominfo(nametlv->value, &roominfo); | 443 * It could be said that its a service type or some such and |
428 } | 444 * that voice is 0, file transfer is 1, and chat is 4 (and 5). |
445 * | |
446 * Or it could be said that its an exchange value. Exchanges | |
447 * four and five are for chat, voice is on exchange zero and | |
448 * file transfer is done on exchange 1. | |
449 * | |
450 * It should work out the same no how its thought of. | |
451 * | |
452 */ | |
453 reqclass = aimutil_get16(miscinfo->value+0); | |
454 | |
455 switch (reqclass) { | |
456 case AIM_RENDEZVOUS_VOICE: { | |
457 | |
458 /* XXX: implement all this */ | |
459 | |
460 /* | |
461 * Call client. | |
462 */ | |
463 userfunc = aim_callhandler(command->conn, 0x0004, 0x0007); | |
464 if (userfunc || (i = 0)) { | |
465 i = userfunc(sess, | |
466 command, | |
467 channel, | |
468 reqclass, | |
469 &userinfo); | |
470 } | |
471 break; | |
472 } | |
473 case AIM_RENDEZVOUS_FILETRANSFER: { | |
474 char ip[30]; | |
475 char *desc = NULL; | |
476 struct aim_msgcookie_t cachedcook; | |
477 struct aim_filetransfer_t *ft; | |
478 | |
479 memset(ip, 0, sizeof(ip)); | |
480 | |
481 if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0003, 1)) { | |
482 struct aim_tlv_t *iptlv, *porttlv; | |
429 | 483 |
430 if (aim_gettlv(list2, 0x000c, 1)) | 484 iptlv = aim_gettlv(list2, 0x0003, 1); |
431 msg = aim_gettlv_str(list2, 0x000c, 1); | 485 porttlv = aim_gettlv(list2, 0x0005, 1); |
486 | |
487 snprintf(ip, sizeof(ip)-1, "%d.%d.%d.%d:%d", | |
488 aimutil_get8(iptlv->value+0), | |
489 aimutil_get8(iptlv->value+1), | |
490 aimutil_get8(iptlv->value+2), | |
491 aimutil_get8(iptlv->value+3), | |
492 aimutil_get16(porttlv->value)); | |
493 } | |
494 | |
495 if (aim_gettlv(list2, 0x000c, 1)) { | |
496 desc = aim_gettlv_str(list2, 0x000c, 1); | |
497 } | |
498 | |
499 printf("faim: rend: file transfer request from %s for %s: %s (%s)\n", | |
500 userinfo.sn, | |
501 miscinfo->value+8, | |
502 desc, | |
503 ip); | |
504 | |
505 memcpy(cachedcook.cookie, cookie, 8); | |
506 memcpy(cachedcook.extended, block1->value+10, 16); | |
507 | |
508 ft = malloc(sizeof(struct aim_filetransfer_t)); | |
509 strncpy(ft->sender, userinfo.sn, sizeof(ft->sender)); | |
510 strncpy(ft->ip, ip, sizeof(ft->ip)); | |
511 ft->filename = strdup(miscinfo->value+8); | |
512 cachedcook.type = 1; | |
513 cachedcook.data = ft; | |
514 | |
515 if (aim_cachecookie(sess, &cachedcook) != 0) | |
516 printf("faim: ERROR caching message cookie\n"); | |
517 | |
518 | |
519 aim_denytransfer(sess, command->conn, ft->sender, cookie, 0); | |
520 | |
521 free(desc); | |
522 | |
523 i = 1; | |
524 break; | |
525 } | |
526 case AIM_RENDEZVOUS_FILETRANSFER_GET: { | |
527 printf("faim: file get request (unsupported)\n"); | |
528 i = 1; | |
529 break; | |
530 } | |
531 case AIM_RENDEZVOUS_CHAT_EX3: | |
532 case AIM_RENDEZVOUS_CHAT_EX4: | |
533 case AIM_RENDEZVOUS_CHAT_EX5: { | |
534 struct aim_chat_roominfo roominfo; | |
535 char *msg=NULL,*encoding=NULL,*lang=NULL; | |
536 | |
537 aim_chat_readroominfo(miscinfo->value, &roominfo); | |
538 | |
539 if (aim_gettlv(list2, 0x000c, 1)) | |
540 msg = aim_gettlv_str(list2, 0x000c, 1); | |
432 | 541 |
433 if (aim_gettlv(list2, 0x000d, 1)) | 542 if (aim_gettlv(list2, 0x000d, 1)) |
434 encoding = aim_gettlv_str(list2, 0x000d, 1); | 543 encoding = aim_gettlv_str(list2, 0x000d, 1); |
435 | 544 |
436 if (aim_gettlv(list2, 0x000e, 1)) | 545 if (aim_gettlv(list2, 0x000e, 1)) |
437 lang = aim_gettlv_str(list2, 0x000e, 1); | 546 lang = aim_gettlv_str(list2, 0x000e, 1); |
438 | 547 |
439 /* | 548 /* |
440 * Call client. | 549 * Call client. |
441 */ | 550 */ |
442 userfunc = aim_callhandler(command->conn, 0x0004, 0x0007); | 551 userfunc = aim_callhandler(command->conn, 0x0004, 0x0007); |
443 if (userfunc) | 552 if (userfunc || (i = 0)) |
444 i = userfunc(sess, | 553 i = userfunc(sess, |
445 command, | 554 command, |
446 channel, | 555 channel, |
447 rendtype, | 556 reqclass, /* == roominfo->exchange */ |
448 &userinfo, | 557 &userinfo, |
449 &roominfo, | 558 &roominfo, |
450 msg, | 559 msg, |
451 encoding?encoding+1:NULL, | 560 encoding?encoding+1:NULL, |
452 lang?lang+1:NULL); | 561 lang?lang+1:NULL); |
453 else | |
454 i = 0; | |
455 | |
456 free(roominfo.name); | 562 free(roominfo.name); |
457 free(msg); | 563 free(msg); |
458 free(encoding); | 564 free(encoding); |
459 free(lang); | 565 free(lang); |
460 } | 566 break; |
567 } | |
568 default: { | |
569 printf("faim: rendezvous: unknown rend class 0x%04x\n", reqclass); | |
570 i = 1; | |
571 break; | |
572 } | |
573 } /* switch */ | |
574 | |
461 aim_freetlvchain(&list2); | 575 aim_freetlvchain(&list2); |
462 } | 576 } |
463 | 577 |
464 /* | 578 /* |
465 * Free up the TLV chain. | 579 * Free up the TLV chain. |
466 */ | 580 */ |
467 aim_freetlvchain(&tlvlist); | 581 aim_freetlvchain(&tlvlist); |
468 | 582 |
469 | 583 |
470 return i; | 584 return i; |
585 } | |
586 | |
587 /* | |
588 * Possible codes: | |
589 * AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support" | |
590 * AIM_TRANSFER_DENY_DECLINE -- "client has declined transfer" | |
591 * AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers" | |
592 * | |
593 */ | |
594 u_long aim_denytransfer(struct aim_session_t *sess, | |
595 struct aim_conn_t *conn, | |
596 char *sender, | |
597 char *cookie, | |
598 unsigned short code) | |
599 { | |
600 struct command_tx_struct *newpacket; | |
601 int curbyte, i; | |
602 | |
603 if(!(newpacket = aim_tx_new(0x0002, conn, 10+8+2+1+strlen(sender)+6))) | |
604 return -1; | |
605 | |
606 newpacket->lock = 1; | |
607 | |
608 curbyte = aim_putsnac(newpacket->data, 0x0004, 0x000b, 0x0000, sess->snac_nextid); | |
609 for (i = 0; i < 8; i++) | |
610 curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); | |
611 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); | |
612 curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sender)); | |
613 curbyte += aimutil_putstr(newpacket->data+curbyte, sender, strlen(sender)); | |
614 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0003, code); | |
615 | |
616 newpacket->lock = 0; | |
617 aim_tx_enqueue(sess, newpacket); | |
618 | |
619 return (sess->snac_nextid++); | |
471 } | 620 } |
472 | 621 |
473 /* | 622 /* |
474 * Not real sure what this does, nor does anyone I've talk to. | 623 * Not real sure what this does, nor does anyone I've talk to. |
475 * | 624 * |