comparison src/protocols/oscar/login.c @ 2675:e759254b29bb

[gaim-migrate @ 2688] This source code was developed using Microsoft Visual Studio 6.0. committer: Tailor Script <tailor@pidgin.im>
author Adam Fritzler <mid@auk.cx>
date Mon, 05 Nov 2001 12:25:22 +0000
parents c41030cfed76
children
comparison
equal deleted inserted replaced
2674:de99ce38ad1f 2675:e759254b29bb
446 * See comments in conn.c about how the group associations are supposed 446 * See comments in conn.c about how the group associations are supposed
447 * to work, and how they really work. 447 * to work, and how they really work.
448 * 448 *
449 * This info probably doesn't even need to make it to the client. 449 * This info probably doesn't even need to make it to the client.
450 * 450 *
451 * We don't actually call the client here. This starts off the connection
452 * initialization routine required by all AIM connections. The next time
453 * the client is called is the CONNINITDONE callback, which should be
454 * shortly after the rate information is acknowledged.
455 *
451 */ 456 */
452 static int hostonline(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 457 static int hostonline(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
453 { 458 {
454 aim_rxcallback_t userfunc;
455 int ret = 0;
456 fu16_t *families; 459 fu16_t *families;
457 int famcount; 460 int famcount;
461
458 462
459 if (!(families = malloc(aim_bstream_empty(bs)))) 463 if (!(families = malloc(aim_bstream_empty(bs))))
460 return 0; 464 return 0;
461 465
462 for (famcount = 0; aim_bstream_empty(bs); famcount++) { 466 for (famcount = 0; aim_bstream_empty(bs); famcount++) {
463 families[famcount] = aimbs_get16(bs); 467 families[famcount] = aimbs_get16(bs);
464 aim_conn_addgroup(rx->conn, families[famcount]); 468 aim_conn_addgroup(rx->conn, families[famcount]);
465 } 469 }
466 470
467 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
468 ret = userfunc(sess, rx, famcount, families);
469
470 free(families); 471 free(families);
471 472
472 return ret; 473
474 /*
475 * Next step is in the Host Versions handler.
476 *
477 * Note that we must send this before we request rates, since
478 * the format of the rate information depends on the versions we
479 * give it.
480 *
481 */
482 aim_setversions(sess, rx->conn);
483
484 return 1;
473 } 485 }
474 486
475 static int redirect(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 487 static int redirect(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
476 { 488 {
477 int serviceid; 489 int serviceid;
516 aim_freetlvchain(&tlvlist); 528 aim_freetlvchain(&tlvlist);
517 529
518 return ret; 530 return ret;
519 } 531 }
520 532
533 /*
534 * Request Rate Information.
535 *
536 */
537 faim_internal int aim_reqrates(aim_session_t *sess, aim_conn_t *conn)
538 {
539 return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
540 }
541
542 /*
543 * Rate Information Response Acknowledge.
544 *
545 */
546 faim_internal int aim_ratesack(aim_session_t *sess, aim_conn_t *conn)
547 {
548 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
549 aim_frame_t *fr;
550 aim_snacid_t snacid;
551 struct rateclass *rc;
552
553 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
554 return -ENOMEM;
555
556 snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0);
557 aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid);
558
559 for (rc = ins->rates; rc; rc = rc->next)
560 aimbs_put16(&fr->data, rc->classid);
561
562 aim_tx_enqueue(sess, fr);
563
564 return 0;
565 }
566
521 /* 567 /*
522 * The Rate Limiting System, An Abridged Guide to Nonsense. 568 * The Rate Limiting System, An Abridged Guide to Nonsense.
523 * 569 *
524 * OSCAR defines several 'rate classes'. Each class has seperate 570 * OSCAR defines several 'rate classes'. Each class has seperate
525 * rate limiting properties (limit level, alert level, disconnect 571 * rate limiting properties (limit level, alert level, disconnect
566 * system is how the actual numbers relate to the passing of time. This 612 * system is how the actual numbers relate to the passing of time. This
567 * seems to be a big mystery. 613 * seems to be a big mystery.
568 * 614 *
569 */ 615 */
570 616
571 /* XXX parse this */ 617 static void rc_addclass(struct rateclass **head, struct rateclass *inrc)
618 {
619 struct rateclass *rc, *rc2;
620
621 if (!(rc = malloc(sizeof(struct rateclass))))
622 return;
623
624 memcpy(rc, inrc, sizeof(struct rateclass));
625 rc->next = NULL;
626
627 for (rc2 = *head; rc2 && rc2->next; rc2 = rc2->next)
628 ;
629
630 if (!rc2)
631 *head = rc;
632 else
633 rc2->next = rc;
634
635 return;
636 }
637
638 static struct rateclass *rc_findclass(struct rateclass **head, fu16_t id)
639 {
640 struct rateclass *rc;
641
642 for (rc = *head; rc; rc = rc->next) {
643 if (rc->classid == id)
644 return rc;
645 }
646
647 return NULL;
648 }
649
650 static void rc_addpair(struct rateclass *rc, fu16_t group, fu16_t type)
651 {
652 struct snacpair *sp, *sp2;
653
654 if (!(sp = malloc(sizeof(struct snacpair))))
655 return;
656 memset(sp, 0, sizeof(struct snacpair));
657
658 sp->group = group;
659 sp->subtype = type;
660 sp->next = NULL;
661
662 for (sp2 = rc->members; sp2 && sp2->next; sp2 = sp2->next)
663 ;
664
665 if (!sp2)
666 rc->members = sp;
667 else
668 sp2->next = sp;
669
670 return;
671 }
672
572 static int rateresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 673 static int rateresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
573 { 674 {
675 aim_conn_inside_t *ins = (aim_conn_inside_t *)rx->conn->inside;
676 fu16_t numclasses, i;
574 aim_rxcallback_t userfunc; 677 aim_rxcallback_t userfunc;
575 678
576 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 679
577 return userfunc(sess, rx); 680 /*
578 681 * First are the parameters for each rate class.
579 return 0; 682 */
683 numclasses = aimbs_get16(bs);
684 for (i = 0; i < numclasses; i++) {
685 struct rateclass rc;
686
687 memset(&rc, 0, sizeof(struct rateclass));
688
689 rc.classid = aimbs_get16(bs);
690 rc.windowsize = aimbs_get32(bs);
691 rc.clear = aimbs_get32(bs);
692 rc.alert = aimbs_get32(bs);
693 rc.limit = aimbs_get32(bs);
694 rc.disconnect = aimbs_get32(bs);
695 rc.current = aimbs_get32(bs);
696 rc.max = aimbs_get32(bs);
697
698 /*
699 * The server will send an extra five bytes of parameters
700 * depending on the version we advertised in 1/17. If we
701 * didn't send 1/17 (evil!), then this will crash and you
702 * die, as it will default to the old version but we have
703 * the new version hardcoded here.
704 */
705 if (mod->version >= 3)
706 aimbs_getrawbuf(bs, rc.unknown, sizeof(rc.unknown));
707
708 rc_addclass(&ins->rates, &rc);
709 }
710
711 /*
712 * Then the members of each class.
713 */
714 for (i = 0; i < numclasses; i++) {
715 fu16_t classid, count;
716 struct rateclass *rc;
717 int j;
718
719 classid = aimbs_get16(bs);
720 count = aimbs_get16(bs);
721
722 rc = rc_findclass(&ins->rates, classid);
723
724 for (j = 0; j < count; j++) {
725 fu16_t group, subtype;
726
727 group = aimbs_get16(bs);
728 subtype = aimbs_get16(bs);
729
730 if (rc)
731 rc_addpair(rc, group, subtype);
732 }
733 }
734
735 /*
736 * We don't pass the rate information up to the client, as it really
737 * doesn't care. The information is stored in the connection, however
738 * so that we can do more fun stuff later (not really).
739 */
740
741 /*
742 * Last step in the conn init procedure is to acknowledge that we
743 * agree to these draconian limitations.
744 */
745 aim_ratesack(sess, rx->conn);
746
747 /*
748 * Finally, tell the client it's ready to go...
749 */
750 if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE)))
751 userfunc(sess, rx);
752
753
754 return 1;
580 } 755 }
581 756
582 static int ratechange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 757 static int ratechange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
583 { 758 {
584 aim_rxcallback_t userfunc; 759 aim_rxcallback_t userfunc;
778 aim_freetlvchain(&tlvlist); 953 aim_freetlvchain(&tlvlist);
779 954
780 return ret; 955 return ret;
781 } 956 }
782 957
958 faim_internal int aim_setversions(aim_session_t *sess, aim_conn_t *conn)
959 {
960 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
961 struct snacgroup *sg;
962 aim_frame_t *fr;
963 aim_snacid_t snacid;
964
965 if (!ins)
966 return -EINVAL;
967
968 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
969 return -ENOMEM;
970
971 snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0);
972 aim_putsnac(&fr->data, 0x0001, 0x0017, 0x0000, snacid);
973
974 /*
975 * Send only the versions that the server cares about (that it
976 * marked as supporting in the server ready SNAC).
977 */
978 for (sg = ins->groups; sg; sg = sg->next) {
979 aim_module_t *mod;
980
981 if ((mod = aim__findmodulebygroup(sess, sg->group))) {
982 aimbs_put16(&fr->data, mod->family);
983 aimbs_put16(&fr->data, mod->version);
984 } else
985 faimdprintf(sess, 1, "aim_setversions: server supports group 0x%04x but we don't!\n", sg->group);
986 }
987
988 aim_tx_enqueue(sess, fr);
989
990 return 0;
991 }
992
783 static int hostversions(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 993 static int hostversions(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
784 { 994 {
785 aim_rxcallback_t userfunc;
786 int vercount; 995 int vercount;
787 fu8_t *versions; 996 fu8_t *versions;
788 int ret = 0; 997
789 998 /* This is frivolous. (Thank you SmarterChild.) */
790 vercount = aim_bstream_empty(bs)/4; 999 vercount = aim_bstream_empty(bs)/4;
791 versions = aimbs_getraw(bs, aim_bstream_empty(bs)); 1000 versions = aimbs_getraw(bs, aim_bstream_empty(bs));
792
793 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
794 ret = userfunc(sess, rx, vercount, versions);
795
796 free(versions); 1001 free(versions);
797 1002
798 return ret; 1003 /*
1004 * Now request rates.
1005 */
1006 aim_reqrates(sess, rx->conn);
1007
1008 return 1;
799 } 1009 }
800 1010
801 /* 1011 /*
802 * Starting this past week (26 Mar 2001, say), AOL has started sending 1012 * Starting this past week (26 Mar 2001, say), AOL has started sending
803 * this nice little extra SNAC. AFAIK, it has never been used until now. 1013 * this nice little extra SNAC. AFAIK, it has never been used until now.