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 *