Mercurial > pidgin.yaz
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. |