src/protocols/oscar/locate.c

changeset 7334
4d1a7f313b70
parent 7313
557d9e2b5dea
child 7447
4876aeb16c60
equal deleted inserted replaced
7333:f749f9cd99c4 7334:4d1a7f313b70
321 } 321 }
322 322
323 return NULL; 323 return NULL;
324 } 324 }
325 325
326 /* 326 faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len)
327 * This still takes a length parameter even with a bstream because capabilities
328 * are not naturally bounded.
329 */
330 faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len)
331 { 327 {
332 fu32_t flags = 0; 328 fu32_t flags = 0;
333 int offset; 329 int offset;
334 330
335 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) { 331 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) {
337 int i, identified; 333 int i, identified;
338 334
339 cap = aimbs_getraw(bs, 0x10); 335 cap = aimbs_getraw(bs, 0x10);
340 336
341 for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) { 337 for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
342
343 if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) { 338 if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) {
344 flags |= aim_caps[i].flag; 339 flags |= aim_caps[i].flag;
345 identified++; 340 identified++;
346 break; /* should only match once... */ 341 break; /* should only match once... */
347
348 } 342 }
349 } 343 }
350 344
351 if (!identified) { 345 if (!identified)
352 faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", 346 faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
353 cap[0], cap[1], cap[2], cap[3], 347 cap[0], cap[1], cap[2], cap[3],
354 cap[4], cap[5], 348 cap[4], cap[5],
355 cap[6], cap[7], 349 cap[6], cap[7],
356 cap[8], cap[9], 350 cap[8], cap[9],
357 cap[10], cap[11], cap[12], cap[13], 351 cap[10], cap[11], cap[12], cap[13],
358 cap[14], cap[15]); 352 cap[14], cap[15]);
353
354 free(cap);
355 }
356
357 return flags;
358 }
359
360 faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len)
361 {
362 fu32_t flags = 0;
363 int offset;
364
365 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) {
366 fu8_t *cap;
367 int i, identified;
368
369 cap = aimbs_getraw(bs, 0x02);
370
371 for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
372 if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) {
373 flags |= aim_caps[i].flag;
374 identified++;
375 break; /* should only match once... */
376 }
359 } 377 }
378
379 if (!identified)
380 faimdprintf(sess, 0, "unknown short capability: {%02x%02x}\n", cap[0], cap[1]);
360 381
361 free(cap); 382 free(cap);
362 } 383 }
363 384
364 return flags; 385 return flags;
583 * Type = 0x000d 604 * Type = 0x000d
584 * 605 *
585 * OSCAR Capability information. 606 * OSCAR Capability information.
586 * 607 *
587 */ 608 */
588 outinfo->capabilities = aim_getcap(sess, bs, length); 609 outinfo->capabilities |= aim_locate_getcaps(sess, bs, length);
589 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; 610 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
590 611
591 } else if (type == 0x000e) { 612 } else if (type == 0x000e) {
592 /* 613 /*
593 * Type = 0x000e 614 * Type = 0x000e
616 * Type = 0x0019 637 * Type = 0x0019
617 * 638 *
618 * OSCAR short capability information. A shortened 639 * OSCAR short capability information. A shortened
619 * form of the normal capabilities. 640 * form of the normal capabilities.
620 */ 641 */
642 outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length);
643 outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
621 644
622 } else if (type == 0x001b) { 645 } else if (type == 0x001b) {
623 /* 646 /*
624 * Type = 0x001a 647 * Type = 0x001a
625 * 648 *
894 * obvious equivalent). 917 * obvious equivalent).
895 * 918 *
896 */ 919 */
897 faim_export int aim_locate_setprofile(aim_session_t *sess, 920 faim_export int aim_locate_setprofile(aim_session_t *sess,
898 const char *profile_encoding, const char *profile, const int profile_len, 921 const char *profile_encoding, const char *profile, const int profile_len,
899 const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, 922 const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len)
900 fu32_t caps)
901 { 923 {
902 aim_conn_t *conn; 924 aim_conn_t *conn;
903 aim_frame_t *fr; 925 aim_frame_t *fr;
904 aim_snacid_t snacid; 926 aim_snacid_t snacid;
905 aim_tlvlist_t *tl = NULL; 927 aim_tlvlist_t *tl = NULL;
946 free(encoding); 968 free(encoding);
947 } else 969 } else
948 aim_tlvlist_add_noval(&tl, 0x0004); 970 aim_tlvlist_add_noval(&tl, 0x0004);
949 } 971 }
950 972
951 if (caps != 0x00000000) 973 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
952 aim_tlvlist_add_caps(&tl, 0x0005, caps); 974 return -ENOMEM;
975
976 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
977 aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
978
979 aim_tlvlist_write(&fr->data, &tl);
980 aim_tlvlist_free(&tl);
981
982 aim_tx_enqueue(sess, fr);
983
984 return 0;
985 }
986
987 /*
988 * Subtype 0x0004 - Set your client's capabilities.
989 */
990 faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps)
991 {
992 aim_conn_t *conn;
993 aim_frame_t *fr;
994 aim_snacid_t snacid;
995 aim_tlvlist_t *tl = NULL;
996
997 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
998 return -EINVAL;
999
1000 aim_tlvlist_add_caps(&tl, 0x0005, caps);
953 1001
954 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl)))) 1002 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
955 return -ENOMEM; 1003 return -ENOMEM;
956 1004
957 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); 1005 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
1030 1078
1031 /* Caps will be 5 */ 1079 /* Caps will be 5 */
1032 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) { 1080 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
1033 aim_bstream_t cbs; 1081 aim_bstream_t cbs;
1034 aim_bstream_init(&cbs, tlv->value, tlv->length); 1082 aim_bstream_init(&cbs, tlv->value, tlv->length);
1035 userinfo->capabilities = aim_getcap(sess, &cbs, tlv->length); 1083 userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length);
1036 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; 1084 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
1037 } 1085 }
1038 aim_tlvlist_free(&tlvlist); 1086 aim_tlvlist_free(&tlvlist);
1039 1087
1040 aim_locate_adduserinfo(sess, userinfo); 1088 aim_locate_adduserinfo(sess, userinfo);

mercurial