| 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 |
| 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); |