| 724 aimbs_put32(&fr->data, totsize); |
724 aimbs_put32(&fr->data, totsize); |
| 725 aimbs_putraw(&fr->data, filename, strlen(filename)); |
725 aimbs_putraw(&fr->data, filename, strlen(filename)); |
| 726 |
726 |
| 727 /* ? */ |
727 /* ? */ |
| 728 aimbs_put32(&fr->data, 0x00000000); |
728 aimbs_put32(&fr->data, 0x00000000); |
| |
729 |
| |
730 aim_tx_enqueue(sess, fr); |
| |
731 |
| |
732 return 0; |
| |
733 } |
| |
734 |
| |
735 /* |
| |
736 * This can be used to send an ICQ authorization reply (deny or grant). It is the "old way." |
| |
737 * The new way is to use SSI. I like the new way a lot better. This seems like such a hack, |
| |
738 * mostly because it's in network byte order. Figuring this stuff out sometimes takes a while, |
| |
739 * but thats ok, because it gives me time to try to figure out what kind of drugs the AOL people |
| |
740 * were taking when they merged the two protocols. |
| |
741 * |
| |
742 * sn is the destination screen name |
| |
743 * type is the type of message. 0x0007 for authorization denied. 0x0008 for authorization granted |
| |
744 * message is the message you want to send, it should be null terminated |
| |
745 */ |
| |
746 faim_export int aim_send_im_ch4(aim_session_t *sess, char *sn, fu16_t type, fu8_t *message) |
| |
747 { |
| |
748 aim_conn_t *conn; |
| |
749 aim_frame_t *fr; |
| |
750 aim_snacid_t snacid; |
| |
751 int i; |
| |
752 |
| |
753 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002))) |
| |
754 return -EINVAL; |
| |
755 |
| |
756 if (!sn || !type || !message) |
| |
757 return -EINVAL; |
| |
758 |
| |
759 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+3+strlen(sn)+12+strlen(message)+1+4))) |
| |
760 return -ENOMEM; |
| |
761 |
| |
762 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0); |
| |
763 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); |
| |
764 |
| |
765 /* |
| |
766 * Cookie |
| |
767 */ |
| |
768 for (i=0; i<8; i++) |
| |
769 aimbs_put8(&fr->data, (fu8_t)rand()); |
| |
770 |
| |
771 /* |
| |
772 * Channel (4) |
| |
773 */ |
| |
774 aimbs_put16(&fr->data, 0x0004); |
| |
775 |
| |
776 /* |
| |
777 * Dest sn |
| |
778 */ |
| |
779 aimbs_put8(&fr->data, strlen(sn)); |
| |
780 aimbs_putraw(&fr->data, sn, strlen(sn)); |
| |
781 |
| |
782 /* |
| |
783 * TLV t(0005) |
| |
784 * |
| |
785 * ICQ data (the UIN and the message). |
| |
786 */ |
| |
787 aimbs_put16(&fr->data, 0x0005); |
| |
788 aimbs_put16(&fr->data, 4 + 2+2+strlen(message)+1); |
| |
789 |
| |
790 /* |
| |
791 * Your UIN |
| |
792 */ |
| |
793 aimbs_putle32(&fr->data, atoi(sess->sn)); |
| |
794 |
| |
795 /* |
| |
796 * TLV t(type) l(strlen(message)+1) v(message+NULL) |
| |
797 */ |
| |
798 aimbs_putle16(&fr->data, type); |
| |
799 aimbs_putle16(&fr->data, strlen(message)+1); |
| |
800 aimbs_putraw(&fr->data, message, strlen(message)+1); |
| |
801 |
| |
802 /* |
| |
803 * TLV t(0006) l(0000) v() |
| |
804 */ |
| |
805 aimbs_put16(&fr->data, 0x0006); |
| |
806 aimbs_put16(&fr->data, 0x0000); |
| 729 |
807 |
| 730 aim_tx_enqueue(sess, fr); |
808 aim_tx_enqueue(sess, fr); |
| 731 |
809 |
| 732 return 0; |
810 return 0; |
| 733 } |
811 } |
| 1517 aim_freetlvchain(&list2); |
1595 aim_freetlvchain(&list2); |
| 1518 |
1596 |
| 1519 return ret; |
1597 return ret; |
| 1520 } |
1598 } |
| 1521 |
1599 |
| |
1600 static int incomingim_ch4(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, fu16_t channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, fu8_t *cookie) |
| |
1601 { |
| |
1602 aim_bstream_t meat; |
| |
1603 aim_rxcallback_t userfunc; |
| |
1604 aim_tlv_t *block; |
| |
1605 struct aim_incomingim_ch4_args args; |
| |
1606 int ret; |
| |
1607 |
| |
1608 /* |
| |
1609 * Make a bstream for the meaty part. Yum. Meat. |
| |
1610 */ |
| |
1611 if (!(block = aim_gettlv(tlvlist, 0x0005, 1))) |
| |
1612 return -1; |
| |
1613 aim_bstream_init(&meat, block->value, block->length); |
| |
1614 |
| |
1615 args.uin = aimbs_getle32(&meat); |
| |
1616 args.type = aimbs_getle16(&meat); |
| |
1617 args.msg = aimbs_getraw(&meat, aimbs_getle16(&meat)); |
| |
1618 |
| |
1619 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
| |
1620 ret = userfunc(sess, rx, channel, userinfo, &args); |
| |
1621 |
| |
1622 free(args.msg); |
| |
1623 |
| |
1624 return ret; |
| |
1625 } |
| |
1626 |
| 1522 /* |
1627 /* |
| 1523 * It can easily be said that parsing ICBMs is THE single |
1628 * It can easily be said that parsing ICBMs is THE single |
| 1524 * most difficult thing to do in the in AIM protocol. In |
1629 * most difficult thing to do in the in AIM protocol. In |
| 1525 * fact, I think I just did say that. |
1630 * fact, I think I just did say that. |
| 1526 * |
1631 * |
| 1554 * features of AIM2/3/3.5. |
1659 * features of AIM2/3/3.5. |
| 1555 * |
1660 * |
| 1556 * Channel 0x0002 is the Rendevous channel, which |
1661 * Channel 0x0002 is the Rendevous channel, which |
| 1557 * is where Chat Invitiations and various client-client |
1662 * is where Chat Invitiations and various client-client |
| 1558 * connection negotiations come from. |
1663 * connection negotiations come from. |
| 1559 * |
1664 * |
| |
1665 * Channel 0x0004 is used for ICQ authorization, or |
| |
1666 * possibly any system notice. |
| |
1667 * |
| 1560 */ |
1668 */ |
| 1561 channel = aimbs_get16(bs); |
1669 channel = aimbs_get16(bs); |
| 1562 |
1670 |
| 1563 /* |
1671 /* |
| 1564 * Extract the standard user info block. |
1672 * Extract the standard user info block. |
| 1598 */ |
1706 */ |
| 1599 tlvlist = aim_readtlvchain(bs); |
1707 tlvlist = aim_readtlvchain(bs); |
| 1600 |
1708 |
| 1601 ret = incomingim_ch2(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie); |
1709 ret = incomingim_ch2(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie); |
| 1602 |
1710 |
| |
1711 aim_freetlvchain(&tlvlist); |
| |
1712 |
| |
1713 } else if (channel == 4) { |
| |
1714 aim_tlvlist_t *tlvlist; |
| |
1715 |
| |
1716 tlvlist = aim_readtlvchain(bs); |
| |
1717 ret = incomingim_ch4(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie); |
| 1603 aim_freetlvchain(&tlvlist); |
1718 aim_freetlvchain(&tlvlist); |
| 1604 |
1719 |
| 1605 } else { |
1720 } else { |
| 1606 |
1721 |
| 1607 faimdprintf(sess, 0, "icbm: ICBM received on an unsupported channel. Ignoring.\n (chan = %04x)", channel); |
1722 faimdprintf(sess, 0, "icbm: ICBM received on an unsupported channel. Ignoring.\n (chan = %04x)", channel); |