Changeset e374dee for libfaim/info.c
- Timestamp:
- Oct 10, 2003, 5:12:30 PM (21 years ago)
- Branches:
- master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- fe6f1d3
- Parents:
- f4d0975
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfaim/info.c
r862371b re374dee 9 9 #define FAIM_INTERNAL 10 10 #include <aim.h> 11 #ifdef _WIN32 12 #include "win32dep.h" 13 #endif 11 14 12 15 struct aim_priv_inforeq { … … 30 33 * 31 34 * Gives BOS your profile. 35 * 36 * profile_encoding and awaymsg_encoding MUST be set if profile or 37 * away are set, respectively, and their value may or may not be 38 * restricted to a few choices. I am currently aware of: 32 39 * 33 */ 34 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, fu32_t caps) 35 { 36 static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""}; 40 * us-ascii Just that 41 * unicode-2-0 UCS2-BE 42 * 43 * profile_len and awaymsg_len MUST be set similarly, and they MUST 44 * be the length of their respective strings in bytes. 45 * 46 * To get the previous behavior of awaymsg == "" un-setting the away 47 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the 48 * obvious equivalent). 49 * 50 */ 51 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, 52 const char *profile_encoding, const char *profile, const int profile_len, 53 const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, 54 fu32_t caps) 55 { 56 static const char defencoding[] = {"text/aolrtf; charset=\"%s\""}; 37 57 aim_frame_t *fr; 38 58 aim_tlvlist_t *tl = NULL; 39 59 aim_snacid_t snacid; 60 char *encoding; 61 62 if ((profile && profile_encoding == NULL) || (awaymsg && awaymsg_len && awaymsg_encoding == NULL)) { 63 return -EINVAL; 64 } 40 65 41 66 /* Build to packet first to get real length */ 42 67 if (profile) { 43 aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), defencoding); 44 aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), profile); 68 /* no + 1 here because of %s */ 69 encoding = malloc(strlen(defencoding) + strlen(profile_encoding)); 70 if (encoding == NULL) { 71 return -ENOMEM; 72 } 73 snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding); 74 aim_addtlvtochain_raw(&tl, 0x0001, strlen(encoding), encoding); 75 aim_addtlvtochain_raw(&tl, 0x0002, profile_len, profile); 76 free(encoding); 45 77 } 46 78 … … 54 86 */ 55 87 if (awaymsg) { 56 if (strlen(awaymsg)) { 57 aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), defencoding); 58 aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), awaymsg); 88 if (awaymsg_len) { 89 encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding)); 90 if (encoding == NULL) { 91 return -ENOMEM; 92 } 93 snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding); 94 aim_addtlvtochain_raw(&tl, 0x0003, strlen(encoding), encoding); 95 aim_addtlvtochain_raw(&tl, 0x0004, awaymsg_len, awaymsg); 96 free(encoding); 59 97 } else 60 98 aim_addtlvtochain_noval(&tl, 0x0004); … … 205 243 206 244 /* 207 * Chat is oddball. 208 */ 209 {AIM_CAPS_CHAT, 210 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, 211 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 212 213 /* 214 * These are mostly in order. 215 */ 245 * These are in ascending numerical order. 246 */ 247 {AIM_CAPS_ICHAT, 248 {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 249 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 250 251 {AIM_CAPS_SECUREIM, 252 {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 253 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 254 255 {AIM_CAPS_HIPTOP, 256 {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1, 257 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 258 216 259 {AIM_CAPS_VOICE, 217 260 {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, … … 229 272 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 230 273 231 {AIM_CAPS_ IMIMAGE,274 {AIM_CAPS_DIRECTIM, 232 275 {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, 233 276 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, … … 237 280 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 238 281 282 /* 283 * Windows AIM calls this "Add-ins," which is probably more accurate 284 */ 239 285 {AIM_CAPS_SAVESTOCKS, 240 286 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1, … … 266 312 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 267 313 268 /* from ICQ2002a 269 {AIM_CAPS_ICQUNKNOWN2, 314 /* 315 * Setting this lets AIM users receive messages from ICQ users, and ICQ 316 * users receive messages from AIM users. It also lets ICQ users show 317 * up in buddy lists for AIM users, and AIM users show up in buddy lists 318 * for ICQ users. And ICQ privacy/invisibility acts like AIM privacy, 319 * in that if you add a user to your deny list, you will not be able to 320 * see them as online (previous you could still see them, but they 321 * couldn't see you. 322 */ 323 {AIM_CAPS_INTEROPERATE, 324 {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1, 325 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 326 327 {AIM_CAPS_ICQUTF8, 270 328 {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1, 271 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, */ 329 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 330 331 {AIM_CAPS_ICQUTF8OLD, 332 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 333 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}}, 334 335 /* 336 * Chat is oddball. 337 */ 338 {AIM_CAPS_CHAT, 339 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, 340 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, 341 342 /* 343 {AIM_CAPS_ICQ2GO, 344 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd, 345 0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}}, 346 */ 272 347 273 348 {AIM_CAPS_ICQRTF, 274 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 349 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 275 350 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}}, 276 351 … … 280 355 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}}, */ 281 356 282 {AIM_CAPS_ICQUNKNOWN, 283 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 284 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}}, 357 {AIM_CAPS_APINFO, 358 {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6, 359 0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}}, 360 361 {AIM_CAPS_TRILLIANCRYPT, 362 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb, 363 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}}, 285 364 286 365 {AIM_CAPS_EMPTY, 287 366 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 288 367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 289 290 {AIM_CAPS_TRILLIANCRYPT,291 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,292 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},293 294 {AIM_CAPS_APINFO,295 {0xAA, 0x4A, 0x32, 0xB5, 0xF8, 0x84, 0x48, 0xc6,296 0xA3, 0xD7, 0x8C, 0x50, 0x97, 0x19, 0xFD, 0x5B}},297 368 298 369 {AIM_CAPS_LAST} … … 385 456 } 386 457 458 faim_internal void aim_info_free(aim_userinfo_t *info) 459 { 460 free(info->iconcsum); 461 free(info->availmsg_encoding); 462 free(info->availmsg); 463 } 464 387 465 /* 388 466 * AIM is fairly regular about providing user info. This is a generic 389 467 * routine to extract it in its standard form. 390 468 */ 391 faim_internal int aim_ extractuserinfo(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo)469 faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo) 392 470 { 393 471 int curtlv, tlvcnt; … … 478 556 * Type = 0x0004: Idle time. 479 557 * 480 * Number of seconds since the user actively used the558 * Number of minutes since the user actively used the 481 559 * service. 482 560 * … … 530 608 * apparently a port number, and some Other Stuff. 531 609 * 610 * Format is: 611 * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43 612 * 613 * 532 614 */ 533 615 aimbs_getrawbuf(bs, outinfo->icqinfo.crap, 0x25); … … 570 652 outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN; 571 653 654 } else if (type == 0x0019) { 655 /* faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV type 0x0019: from %s\n", outinfo->sn); */ 656 657 } else if (type == 0x001b) { 658 /* faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV type 0x001b: from %s\n", outinfo->sn); */ 659 572 660 } else if (type == 0x001d) { 573 661 /* 574 * Type 29: Unknown. 575 * 576 * Currently very rare. Always 18 bytes of mostly zero. 577 */ 662 * Type = 0x001d 663 * 664 * Buddy icon information and available messages. 665 * 666 * This almost seems like the AIM protocol guys gave 667 * the iChat guys a Type, and the iChat guys tried to 668 * cram as much cool shit into it as possible. Then 669 * the Windows AIM guys were like, "hey, that's 670 * pretty neat, let's copy those prawns." 671 * 672 * In that spirit, this can contain a custom message, 673 * kind of like an away message, but you're not away 674 * (it's called an "available" message). Or it can 675 * contain information about the buddy icon the user 676 * has stored on the server. 677 */ 678 int type2, number, length2; 679 680 while (aim_bstream_curpos(bs) < endpos) { 681 type2 = aimbs_get16(bs); 682 number = aimbs_get8(bs); 683 length2 = aimbs_get8(bs); 684 685 switch (type2) { 686 case 0x0000: { /* This is an official buddy icon? */ 687 /* This is always 5 bytes of "0x02 01 d2 04 72"? */ 688 aim_bstream_advance(bs, length2); 689 } break; 690 691 case 0x0001: { /* A buddy icon checksum */ 692 if ((length2 > 0) && (number == 0x01)) { 693 free(outinfo->iconcsum); 694 outinfo->iconcsum = aimbs_getraw(bs, length2); 695 outinfo->iconcsumlen = length2; 696 } else 697 aim_bstream_advance(bs, length2); 698 } break; 699 700 case 0x0002: { /* An available message */ 701 if (length2 > 4) { 702 free(outinfo->availmsg); 703 outinfo->availmsg_len = aimbs_get16(bs); 704 outinfo->availmsg = aimbs_getstr(bs, outinfo->availmsg_len); 705 if (aimbs_get16(bs) == 0x0001) { /* We have an encoding */ 706 aimbs_get16(bs); 707 outinfo->availmsg_encoding = aimbs_getstr(bs, aimbs_get16(bs)); 708 } else { 709 /* No explicit encoding, client should use UTF-8 */ 710 outinfo->availmsg_encoding = NULL; 711 } 712 } else 713 aim_bstream_advance(bs, length2); 714 } break; 715 716 default: { 717 aim_bstream_advance(bs, length2); 718 } break; 719 } 720 } 578 721 579 722 } else if (type == 0x001e) { … … 607 750 608 751 /* 609 * Inverse of aim_ extractuserinfo()752 * Inverse of aim_info_extract() 610 753 */ 611 754 faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info) … … 713 856 aim_userinfo_t userinfo; 714 857 char *text_encoding = NULL, *text = NULL; 858 int textlen = 0; 715 859 aim_rxcallback_t userfunc; 716 860 aim_tlvlist_t *tlvlist; 861 aim_tlv_t *text_tlv = NULL; 717 862 aim_snac_t *origsnac = NULL; 718 863 struct aim_priv_inforeq *inforeq; … … 735 880 } 736 881 737 aim_ extractuserinfo(sess, bs, &userinfo);882 aim_info_extract(sess, bs, &userinfo); 738 883 739 884 tlvlist = aim_readtlvchain(bs); … … 748 893 if (inforeq->infotype == AIM_GETINFO_GENERALINFO) { 749 894 text_encoding = aim_gettlv_str(tlvlist, 0x0001, 1); 750 text = aim_gettlv_str(tlvlist, 0x0002, 1);895 text_tlv = aim_gettlv(tlvlist, 0x0002, 1); 751 896 } else if (inforeq->infotype == AIM_GETINFO_AWAYMESSAGE) { 752 897 text_encoding = aim_gettlv_str(tlvlist, 0x0003, 1); 753 text = aim_gettlv_str(tlvlist, 0x0004, 1);898 text_tlv = aim_gettlv(tlvlist, 0x0004, 1); 754 899 } else if (inforeq->infotype == AIM_GETINFO_CAPABILITIES) { 755 900 aim_tlv_t *ct; … … 765 910 } 766 911 912 if (text_tlv) { 913 text = text_tlv->value; 914 textlen = text_tlv->length; 915 } 916 767 917 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 768 ret = userfunc(sess, rx, &userinfo, inforeq->infotype, text_encoding, text); 769 918 ret = userfunc(sess, rx, &userinfo, inforeq->infotype, text_encoding, text, textlen); 919 920 aim_info_free(&userinfo); 770 921 free(text_encoding); 771 free(text);772 773 922 aim_freetlvchain(&tlvlist); 774 775 923 if (origsnac) 776 924 free(origsnac->data); … … 887 1035 mod->family = 0x0002; 888 1036 mod->version = 0x0001; 889 mod->toolid = 0x01 01;890 mod->toolversion = 0x0 47b;1037 mod->toolid = 0x0110; 1038 mod->toolversion = 0x0629; 891 1039 mod->flags = 0; 892 1040 strncpy(mod->name, "locate", sizeof(mod->name));
Note: See TracChangeset
for help on using the changeset viewer.