- Timestamp:
- Dec 10, 2003, 3:20:45 PM (20 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:
- b1fe407
- Parents:
- 8c46404
- Location:
- libfaim
- Files:
-
- 3 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
libfaim/Makefile.in
r862371b rcf02dd6 5 5 OBJS=admin.o adverts.o auth.o bos.o buddylist.o bstream.o \ 6 6 chat.o chatnav.o conn.o email.o ft.o icq.o im.o \ 7 in fo.o invite.o md5.o meta.o misc.o msgcookie.o newsearch.o \7 invite.o md5.o misc.o msgcookie.o locate.o \ 8 8 popups.o rxhandlers.o rxqueue.o search.o service.o \ 9 9 snac.o ssi.o stats.o tlv.o translate.o txqueue.o \ 10 util.o 10 util.o odir.o bart.o 11 11 CFLAGS=@CFLAGS@ -I. -DAIM_BUILDDATE=\"x\" -DAIM_BUILDTIME=\"x\" 12 12 -
libfaim/admin.c
re374dee rcf02dd6 111 111 aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); 112 112 113 aim_ addtlvtochain_raw(&tl, 0x0001, strlen(newnick), newnick);114 115 aim_ writetlvchain(&fr->data, &tl);116 aim_ freetlvchain(&tl);113 aim_tlvlist_add_raw(&tl, 0x0001, strlen(newnick), newnick); 114 115 aim_tlvlist_write(&fr->data, &tl); 116 aim_tlvlist_free(&tl); 117 117 118 118 aim_tx_enqueue(sess, fr); … … 139 139 140 140 /* new password TLV t(0002) */ 141 aim_ addtlvtochain_raw(&tl, 0x0002, strlen(newpw), newpw);141 aim_tlvlist_add_raw(&tl, 0x0002, strlen(newpw), newpw); 142 142 143 143 /* current password TLV t(0012) */ 144 aim_ addtlvtochain_raw(&tl, 0x0012, strlen(curpw), curpw);145 146 aim_ writetlvchain(&fr->data, &tl);147 aim_ freetlvchain(&tl);144 aim_tlvlist_add_raw(&tl, 0x0012, strlen(curpw), curpw); 145 146 aim_tlvlist_write(&fr->data, &tl); 147 aim_tlvlist_free(&tl); 148 148 149 149 aim_tx_enqueue(sess, fr); … … 168 168 aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); 169 169 170 aim_ addtlvtochain_raw(&tl, 0x0011, strlen(newemail), newemail);171 172 aim_ writetlvchain(&fr->data, &tl);173 aim_ freetlvchain(&tl);170 aim_tlvlist_add_raw(&tl, 0x0011, strlen(newemail), newemail); 171 172 aim_tlvlist_write(&fr->data, &tl); 173 aim_tlvlist_free(&tl); 174 174 175 175 aim_tx_enqueue(sess, fr); … … 205 205 /* This is 0x0013 if unable to confirm at this time */ 206 206 207 tl = aim_ readtlvchain(bs);207 tl = aim_tlvlist_read(bs); 208 208 209 209 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) -
libfaim/aim.h
re374dee rcf02dd6 78 78 #ifndef TRUE 79 79 #define TRUE (!FALSE) 80 #endif 81 82 #ifndef bool 83 #define bool fu8_t 80 84 #endif 81 85 … … 206 210 } 207 211 212 #define CLIENTINFO_AIM_5_5_3415 { \ 213 "AOL Instant Messenger, version 5.5.3415/WIN32", \ 214 0x0109, \ 215 0x0005, 0x0005, \ 216 0x0000, 0x0057, \ 217 0x000000ef, \ 218 "us", "en", \ 219 } 220 208 221 #define CLIENTINFO_ICHAT_1_0 { \ 209 222 "Apple iChat", \ … … 244 257 } 245 258 246 #define CLIENTINFO_ICQB asic_14_3_1068 { \259 #define CLIENTINFO_ICQBASIC_14_3_1068 { \ 247 260 "ICQBasic", \ 248 261 0x010a, \ … … 253 266 } 254 267 255 #define CLIENTINFO_N etscape_7_0_1 { \268 #define CLIENTINFO_NETSCAPE_7_0_1 { \ 256 269 "Netscape 2000 an approved user of AOL Instant Messenger (SM)", \ 257 270 0x1d0d, \ … … 366 379 } aim_msgcookie_t; 367 380 368 /* Values for sess->flags */369 #define AIM_SESS_FLAGS_SNACLOGIN 0x00000001370 #define AIM_SESS_FLAGS_XORLOGIN 0x00000002371 #define AIM_SESS_FLAGS_NONBLOCKCONNECT 0x00000004372 #define AIM_SESS_FLAGS_DONTTIMEOUTONICBM 0x00000008373 374 381 /* 375 382 * AIM Session: The main client-data interface. … … 427 434 } socksproxy; 428 435 429 fu32_t flags; /* AIM_SESS_FLAGS_ */436 bool nonblocking; 430 437 431 438 int debug; … … 445 452 struct aim_authresp_info *authinfo; 446 453 struct aim_emailinfo *emailinfo; 454 455 struct { 456 struct aim_userinfo_s *userinfo; 457 struct userinfo_node *torequest; 458 struct userinfo_node *requested; 459 int waiting_for_response; 460 } locate; 447 461 448 462 /* Server-stored information (ssi) */ … … 475 489 476 490 491 477 492 /* 478 493 * Get command from connections … … 540 555 faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn); 541 556 faim_export int aim_send_login(aim_session_t *, aim_conn_t *, const char *, const char *, struct client_info_s *, const char *key); 542 faim_export int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest);543 557 faim_export void aim_purge_rxqueue(aim_session_t *); 544 558 faim_export void aim_cleansnacs(aim_session_t *, int maxage); … … 571 585 typedef void (*faim_debugging_callback_t)(aim_session_t *sess, int level, const char *format, va_list va); 572 586 faim_export int aim_setdebuggingcb(aim_session_t *sess, faim_debugging_callback_t); 573 faim_export void aim_session_init(aim_session_t *, fu32_t flags, int debuglevel);587 faim_export void aim_session_init(aim_session_t *, bool nonblocking, int debuglevel); 574 588 faim_export void aim_session_kill(aim_session_t *); 575 589 faim_export void aim_setupproxy(aim_session_t *sess, const char *server, const char *username, const char *password); … … 580 594 581 595 582 /* service.c */596 /* 0x0001 - service.c */ 583 597 faim_export int aim_srv_setavailmsg(aim_session_t *sess, char *msg); 598 faim_export int aim_srv_setidle(aim_session_t *sess, fu32_t idletime); 584 599 585 600 … … 600 615 faim_export int aim_nop(aim_session_t *, aim_conn_t *); 601 616 faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn); 602 faim_export int aim_bos_setidle(aim_session_t *, aim_conn_t *, fu32_t);603 617 faim_export int aim_bos_changevisibility(aim_session_t *, aim_conn_t *, int, const char *); 604 faim_export int aim_bos_setbuddylist(aim_session_t *, aim_conn_t *, const char *);605 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, fu32_t caps);606 618 faim_export int aim_bos_setgroupperm(aim_session_t *, aim_conn_t *, fu32_t mask); 607 619 faim_export int aim_bos_setprivacyflags(aim_session_t *, aim_conn_t *, fu32_t); … … 609 621 faim_export int aim_reqservice(aim_session_t *, aim_conn_t *, fu16_t); 610 622 faim_export int aim_bos_reqrights(aim_session_t *, aim_conn_t *); 611 faim_export int aim_bos_reqbuddyrights(aim_session_t *, aim_conn_t *);612 faim_export int aim_bos_reqlocaterights(aim_session_t *, aim_conn_t *);613 faim_export int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy);614 faim_export int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy);615 623 faim_export int aim_setextstatus(aim_session_t *sess, fu32_t status); 616 624 … … 936 944 937 945 938 /* info.c */946 /* 0x0002 - locate.c */ 939 947 /* 940 948 * AIM User Info, Standard Form. 941 949 */ 942 #define AIM_FLAG_UNCONFIRMED 950 #define AIM_FLAG_UNCONFIRMED 0x0001 /* "damned transients" */ 943 951 #define AIM_FLAG_ADMINISTRATOR 0x0002 944 #define AIM_FLAG_AOL 0x0004945 #define AIM_FLAG_OSCAR_PAY 0x0008946 #define AIM_FLAG_FREE 0x0010947 #define AIM_FLAG_AWAY 0x0020948 #define AIM_FLAG_ICQ 0x0040949 #define AIM_FLAG_WIRELESS 0x0080950 #define AIM_FLAG_UNKNOWN100 0x0100951 #define AIM_FLAG_UNKNOWN200 0x0200952 #define AIM_FLAG_ACTIVEBUDDY 953 #define AIM_FLAG_UNKNOWN800 0x0800954 #define AIM_FLAG_ABINTERNAL 955 #define AIM_FLAG_ALLUSERS 0x001f952 #define AIM_FLAG_AOL 0x0004 953 #define AIM_FLAG_OSCAR_PAY 0x0008 954 #define AIM_FLAG_FREE 0x0010 955 #define AIM_FLAG_AWAY 0x0020 956 #define AIM_FLAG_ICQ 0x0040 957 #define AIM_FLAG_WIRELESS 0x0080 958 #define AIM_FLAG_UNKNOWN100 0x0100 959 #define AIM_FLAG_UNKNOWN200 0x0200 960 #define AIM_FLAG_ACTIVEBUDDY 0x0400 961 #define AIM_FLAG_UNKNOWN800 0x0800 962 #define AIM_FLAG_ABINTERNAL 0x1000 963 #define AIM_FLAG_ALLUSERS 0x001f 956 964 957 965 #define AIM_USERINFO_PRESENT_FLAGS 0x00000001 … … 966 974 #define AIM_USERINFO_PRESENT_CREATETIME 0x00000200 967 975 968 typedef struct { 969 char sn[MAXSNLEN+1]; 976 struct userinfo_node { 977 char *sn; 978 struct userinfo_node *next; 979 }; 980 981 typedef struct aim_userinfo_s { 982 char *sn; 970 983 fu16_t warnlevel; /* evil percent * 10 (999 = 99.9%) */ 971 984 fu16_t idletime; /* in seconds */ … … 982 995 } icqinfo; 983 996 fu32_t present; 997 984 998 fu16_t iconcsumlen; 985 999 fu8_t *iconcsum; 986 char *availmsg_encoding; 987 char *availmsg; 988 int availmsg_len; 1000 1001 char *info; 1002 char *info_encoding; 1003 fu16_t info_len; 1004 1005 char *avail; 1006 char *avail_encoding; 1007 fu16_t avail_len; 1008 1009 char *away; 1010 char *away_encoding; 1011 fu16_t away_len; 1012 1013 struct aim_userinfo_s *next; 989 1014 } aim_userinfo_t; 990 1015 991 faim_export const char *aim_userinfo_sn(aim_userinfo_t *ui); 992 faim_export fu16_t aim_userinfo_flags(aim_userinfo_t *ui); 993 faim_export fu16_t aim_userinfo_idle(aim_userinfo_t *ui); 994 faim_export float aim_userinfo_warnlevel(aim_userinfo_t *ui); 995 faim_export time_t aim_userinfo_createtime(aim_userinfo_t *ui); 996 faim_export time_t aim_userinfo_membersince(aim_userinfo_t *ui); 997 faim_export time_t aim_userinfo_onlinesince(aim_userinfo_t *ui); 998 faim_export fu32_t aim_userinfo_sessionlen(aim_userinfo_t *ui); 999 faim_export int aim_userinfo_hascap(aim_userinfo_t *ui, fu32_t cap); 1000 1001 #define AIM_CAPS_BUDDYICON 0x00000001 1002 #define AIM_CAPS_VOICE 0x00000002 1003 #define AIM_CAPS_DIRECTIM 0x00000004 1004 #define AIM_CAPS_CHAT 0x00000008 1005 #define AIM_CAPS_GETFILE 0x00000010 1006 #define AIM_CAPS_SENDFILE 0x00000020 1007 #define AIM_CAPS_GAMES 0x00000040 1008 #define AIM_CAPS_SAVESTOCKS 0x00000080 1016 #define AIM_CAPS_BUDDYICON 0x00000001 1017 #define AIM_CAPS_VOICE 0x00000002 1018 #define AIM_CAPS_DIRECTIM 0x00000004 1019 #define AIM_CAPS_CHAT 0x00000008 1020 #define AIM_CAPS_GETFILE 0x00000010 1021 #define AIM_CAPS_SENDFILE 0x00000020 1022 #define AIM_CAPS_GAMES 0x00000040 1023 #define AIM_CAPS_SAVESTOCKS 0x00000080 1009 1024 #define AIM_CAPS_SENDBUDDYLIST 0x00000100 1010 #define AIM_CAPS_GAMES2 0x000002001011 #define AIM_CAPS_ICQ 0x000004001012 #define AIM_CAPS_APINFO 0x000008001013 #define AIM_CAPS_ICQRTF 0x000010001014 #define AIM_CAPS_EMPTY 0x000020001025 #define AIM_CAPS_GAMES2 0x00000200 1026 #define AIM_CAPS_ICQ_DIRECT 0x00000400 1027 #define AIM_CAPS_APINFO 0x00000800 1028 #define AIM_CAPS_ICQRTF 0x00001000 1029 #define AIM_CAPS_EMPTY 0x00002000 1015 1030 #define AIM_CAPS_ICQSERVERRELAY 0x00004000 1016 #define AIM_CAPS_ICQUTF8OLD 0x000080001031 #define AIM_CAPS_ICQUTF8OLD 0x00008000 1017 1032 #define AIM_CAPS_TRILLIANCRYPT 0x00010000 1018 #define AIM_CAPS_ICQUTF8 0x000200001033 #define AIM_CAPS_ICQUTF8 0x00020000 1019 1034 #define AIM_CAPS_INTEROPERATE 0x00040000 1020 #define AIM_CAPS_ICHAT 0x00080000 1021 #define AIM_CAPS_HIPTOP 0x00100000 1022 #define AIM_CAPS_SECUREIM 0x00200000 1023 #define AIM_CAPS_LAST 0x00400000 1024 1025 faim_export int aim_0002_000b(aim_session_t *sess, aim_conn_t *conn, const char *sn); 1035 #define AIM_CAPS_ICHAT 0x00080000 1036 #define AIM_CAPS_HIPTOP 0x00100000 1037 #define AIM_CAPS_SECUREIM 0x00200000 1038 #define AIM_CAPS_SMS 0x00400000 1039 #define AIM_CAPS_GENERICUNKNOWN 0x00800000 1040 #define AIM_CAPS_VIDEO 0x01000000 1041 #define AIM_CAPS_LAST 0x02000000 1026 1042 1027 1043 #define AIM_SENDMEMBLOCK_FLAG_ISREQUEST 0 … … 1029 1045 1030 1046 faim_export int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, fu32_t offset, fu32_t len, const fu8_t *buf, fu8_t flag); 1031 1032 #define AIM_GETINFO_GENERALINFO 0x000011033 #define AIM_GETINFO_AWAYMESSAGE 0x000031034 #define AIM_GETINFO_CAPABILITIES 0x00041035 1047 1036 1048 struct aim_invite_priv { … … 1058 1070 #define AIM_COOKIETYPE_OFTICON 0x15 1059 1071 1060 /* 0x0005 */ faim_export int aim_getinfo(aim_session_t *, aim_conn_t *, const char *, fu16_t); 1072 faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn); 1073 1074 /* 0x0002 */ faim_export int aim_locate_reqrights(aim_session_t *sess); 1075 /* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len); 1076 /* 0x0004 */ faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps); 1077 /* 0x0005 */ faim_export int aim_locate_getinfo(aim_session_t *sess, const char *, fu16_t); 1078 /* 0x0009 */ faim_export int aim_locate_setdirinfo(aim_session_t *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy); 1079 /* 0x000b */ faim_export int aim_locate_000b(aim_session_t *sess, const char *sn); 1080 /* 0x000f */ faim_export int aim_locate_setinterests(aim_session_t *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy); 1081 /* 0x0015 */ faim_export int aim_locate_getinfoshort(aim_session_t *sess, const char *sn, fu32_t flags); 1061 1082 1062 1083 1063 1084 1064 1085 /* 0x0003 - buddylist.c */ 1065 /* 0x0004 */ faim_export int aim_add_buddy(aim_session_t *, aim_conn_t *, const char *); 1066 /* 0x0005 */ faim_export int aim_remove_buddy(aim_session_t *, aim_conn_t *, const char *); 1067 /* 0x000b */ faim_export int aim_sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info); 1068 /* 0x000c */ faim_export int aim_sendbuddyoffgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn); 1086 /* 0x0002 */ faim_export int aim_buddylist_reqrights(aim_session_t *, aim_conn_t *); 1087 /* 0x0004 */ faim_export int aim_buddylist_set(aim_session_t *, aim_conn_t *, const char *); 1088 /* 0x0004 */ faim_export int aim_buddylist_addbuddy(aim_session_t *, aim_conn_t *, const char *); 1089 /* 0x0005 */ faim_export int aim_buddylist_removebuddy(aim_session_t *, aim_conn_t *, const char *); 1090 /* 0x000b */ faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info); 1091 /* 0x000c */ faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn); 1069 1092 1070 1093 … … 1194 1217 faim_export fu32_t aim_ssi_getpresence(struct aim_ssi_item *list); 1195 1218 faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn); 1219 faim_export char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn); 1196 1220 faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn); 1197 1221 … … 1205 1229 faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn); 1206 1230 faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias); 1231 faim_export int aim_ssi_editcomment(aim_session_t *sess, const char *gn, const char *sn, const char *alias); 1207 1232 faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn); 1208 1233 faim_export int aim_ssi_cleanlist(aim_session_t *sess); … … 1211 1236 faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence); 1212 1237 faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen); 1238 faim_export int aim_ssi_delicon(aim_session_t *sess); 1213 1239 1214 1240 … … 1326 1352 }; 1327 1353 1328 faim_export int aim_email_sendcookies(aim_session_t *sess, aim_conn_t *conn); 1329 faim_export int aim_email_activate(aim_session_t *sess, aim_conn_t *conn); 1330 1331 1332 1354 faim_export int aim_email_sendcookies(aim_session_t *sess); 1355 faim_export int aim_email_activate(aim_session_t *sess); 1356 1357 1358 1359 #if defined(FAIM_INTERNAL) || defined(FAIM_NEED_TLV) 1333 1360 /* tlv.c - TLV handling */ 1334 #if defined(FAIM_INTERNAL) || defined(FAIM_NEED_TLV) 1335 /* Generic TLV structure.*/1361 1362 /* TLV structure */ 1336 1363 typedef struct aim_tlv_s { 1337 1364 fu16_t type; … … 1340 1367 } aim_tlv_t; 1341 1368 1342 /* List of above.*/1369 /* TLV List structure */ 1343 1370 typedef struct aim_tlvlist_s { 1344 1371 aim_tlv_t *tlv; … … 1346 1373 } aim_tlvlist_t; 1347 1374 1348 /* TLV-handling functions */ 1349 1350 #if 0 1351 /* Very, very raw TLV handling. */ 1352 faim_internal int aim_puttlv_8(fu8_t *buf, const fu16_t t, const fu8_t v); 1353 faim_internal int aim_puttlv_16(fu8_t *buf, const fu16_t t, const fu16_t v); 1354 faim_internal int aim_puttlv_32(fu8_t *buf, const fu16_t t, const fu32_t v); 1355 faim_internal int aim_puttlv_raw(fu8_t *buf, const fu16_t t, const fu16_t l, const fu8_t *v); 1356 #endif 1357 1358 /* TLV list handling. */ 1359 faim_internal aim_tlvlist_t *aim_readtlvchain(aim_bstream_t *bs); 1360 faim_internal aim_tlvlist_t *aim_readtlvchain_num(aim_bstream_t *bs, fu16_t num); 1361 faim_internal aim_tlvlist_t *aim_readtlvchain_len(aim_bstream_t *bs, fu16_t len); 1375 /* TLV handling functions */ 1376 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, fu16_t type, const int nth); 1377 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth); 1378 faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth); 1379 faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth); 1380 faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth); 1381 1382 /* TLV list handling functions */ 1383 faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs); 1384 faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num); 1385 faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len); 1362 1386 faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig); 1387 1388 faim_internal int aim_tlvlist_count(aim_tlvlist_t **list); 1389 faim_internal int aim_tlvlist_size(aim_tlvlist_t **list); 1363 1390 faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two); 1364 faim_internal void aim_freetlvchain(aim_tlvlist_t **list); 1365 faim_internal aim_tlv_t *aim_gettlv(aim_tlvlist_t *, fu16_t t, const int n); 1366 faim_internal char *aim_gettlv_str(aim_tlvlist_t *, const fu16_t t, const int n); 1367 faim_internal fu8_t aim_gettlv8(aim_tlvlist_t *list, const fu16_t type, const int num); 1368 faim_internal fu16_t aim_gettlv16(aim_tlvlist_t *list, const fu16_t t, const int n); 1369 faim_internal fu32_t aim_gettlv32(aim_tlvlist_t *list, const fu16_t t, const int n); 1370 faim_internal int aim_writetlvchain(aim_bstream_t *bs, aim_tlvlist_t **list); 1371 faim_internal int aim_addtlvtochain8(aim_tlvlist_t **list, const fu16_t t, const fu8_t v); 1372 faim_internal int aim_addtlvtochain16(aim_tlvlist_t **list, const fu16_t t, const fu16_t v); 1373 faim_internal int aim_addtlvtochain32(aim_tlvlist_t **list, const fu16_t type, const fu32_t v); 1374 faim_internal int aim_addtlvtochain_raw(aim_tlvlist_t **list, const fu16_t t, const fu16_t l, const fu8_t *v); 1375 faim_internal int aim_addtlvtochain_caps(aim_tlvlist_t **list, const fu16_t t, const fu32_t caps); 1376 faim_internal int aim_addtlvtochain_noval(aim_tlvlist_t **list, const fu16_t type); 1377 faim_internal int aim_addtlvtochain_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *ui); 1378 faim_internal int aim_addtlvtochain_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl); 1379 faim_internal int aim_counttlvchain(aim_tlvlist_t **list); 1380 faim_internal int aim_sizetlvchain(aim_tlvlist_t **list); 1391 faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list); 1392 faim_internal void aim_tlvlist_free(aim_tlvlist_t **list); 1393 1394 faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value); 1395 faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type); 1396 faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value); 1397 faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value); 1398 faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value); 1399 faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps); 1400 faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo); 1401 faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl); 1402 1403 faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t lenth, const fu8_t *value); 1404 faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type); 1405 faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value); 1406 faim_internal int aim_tlvlist_replace_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value); 1407 faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value); 1408 1409 faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type); 1381 1410 #endif /* FAIM_INTERNAL */ 1382 1411 -
libfaim/aim_cbtypes.h
ra0a5179 rcf02dd6 212 212 #define AIM_CB_SSI_REQDATA 0x0004 213 213 #define AIM_CB_SSI_REQIFCHANGED 0x0005 214 #define AIM_CB_SSI_REQLIST 0x0005215 214 #define AIM_CB_SSI_LIST 0x0006 216 215 #define AIM_CB_SSI_ACTIVATE 0x0007 -
libfaim/aim_internal.h
re374dee rcf02dd6 47 47 faim_internal int chat_modfirst(aim_session_t *sess, aim_module_t *mod); 48 48 faim_internal int locate_modfirst(aim_session_t *sess, aim_module_t *mod); 49 faim_internal int general_modfirst(aim_session_t *sess, aim_module_t *mod);49 faim_internal int service_modfirst(aim_session_t *sess, aim_module_t *mod); 50 50 faim_internal int invite_modfirst(aim_session_t *sess, aim_module_t *mod); 51 51 faim_internal int translate_modfirst(aim_session_t *sess, aim_module_t *mod); … … 189 189 faim_internal void aim_conn_addgroup(aim_conn_t *conn, fu16_t group); 190 190 191 faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len);192 faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps);193 194 191 faim_internal int aim_cachecookie(aim_session_t *sess, aim_msgcookie_t *cookie); 195 192 faim_internal aim_msgcookie_t *aim_uncachecookie(aim_session_t *sess, fu8_t *cookie, int type); … … 200 197 faim_internal int aim_cookie_free(aim_session_t *sess, aim_msgcookie_t *cookie); 201 198 199 /* 0x0002 - locate.c */ 200 faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn); 201 faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len); 202 faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len); 203 faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps); 202 204 faim_internal void aim_info_free(aim_userinfo_t *); 203 205 faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *); … … 205 207 206 208 faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo); 207 208 faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...);209 209 210 210 faim_internal void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn); … … 216 216 faim_internal int aim_rates_delparam(aim_session_t *, aim_conn_t *); 217 217 218 faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...); 219 218 220 #ifndef FAIM_INTERNAL_INSANE 219 221 #define printf() printf called inside libfaim -
libfaim/auth.c
re374dee rcf02dd6 12 12 #include "md5.h" 13 13 14 static int aim_encode_password(const char *password, fu8_t *encoded); 15 16 /* 14 #include <ctype.h> 15 16 /** 17 * Encode a password using old XOR method 18 * 19 * This takes a const pointer to a (null terminated) string 20 * containing the unencoded password. It also gets passed 21 * an already allocated buffer to store the encoded password. 22 * This buffer should be the exact length of the password without 23 * the null. The encoded password buffer /is not %NULL terminated/. 24 * 25 * The encoding_table seems to be a fixed set of values. We'll 26 * hope it doesn't change over time! 27 * 28 * This is only used for the XOR method, not the better MD5 method. 29 * 30 * @param password Incoming password. 31 * @param encoded Buffer to put encoded password. 32 */ 33 static int aim_encode_password(const char *password, fu8_t *encoded) 34 { 35 fu8_t encoding_table[] = { 36 #if 0 /* old v1 table */ 37 0xf3, 0xb3, 0x6c, 0x99, 38 0x95, 0x3f, 0xac, 0xb6, 39 0xc5, 0xfa, 0x6b, 0x63, 40 0x69, 0x6c, 0xc3, 0x9f 41 #else /* v2.1 table, also works for ICQ */ 42 0xf3, 0x26, 0x81, 0xc4, 43 0x39, 0x86, 0xdb, 0x92, 44 0x71, 0xa3, 0xb9, 0xe6, 45 0x53, 0x7a, 0x95, 0x7c 46 #endif 47 }; 48 int i; 49 50 for (i = 0; i < strlen(password); i++) 51 encoded[i] = (password[i] ^ encoding_table[i]); 52 53 return 0; 54 } 55 56 #ifdef USE_OLD_MD5 57 static int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest) 58 { 59 md5_state_t state; 60 61 md5_init(&state); 62 md5_append(&state, (const md5_byte_t *)key, strlen(key)); 63 md5_append(&state, (const md5_byte_t *)password, strlen(password)); 64 md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING)); 65 md5_finish(&state, (md5_byte_t *)digest); 66 67 return 0; 68 } 69 #else 70 static int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest) 71 { 72 md5_state_t state; 73 fu8_t passdigest[16]; 74 75 md5_init(&state); 76 md5_append(&state, (const md5_byte_t *)password, strlen(password)); 77 md5_finish(&state, (md5_byte_t *)&passdigest); 78 79 md5_init(&state); 80 md5_append(&state, (const md5_byte_t *)key, strlen(key)); 81 md5_append(&state, (const md5_byte_t *)&passdigest, 16); 82 md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING)); 83 md5_finish(&state, (md5_byte_t *)digest); 84 85 return 0; 86 } 87 #endif 88 89 /* 90 * The FLAP version is sent by itself at the beginning of authorization 91 * connections. The FLAP version is also sent before the cookie when connecting 92 * for other services (BOS, chatnav, chat, etc.). 93 */ 94 faim_export int aim_sendflapver(aim_session_t *sess, aim_conn_t *conn) 95 { 96 aim_frame_t *fr; 97 98 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 4))) 99 return -ENOMEM; 100 101 aimbs_put32(&fr->data, 0x00000001); 102 103 aim_tx_enqueue(sess, fr); 104 105 return 0; 106 } 107 108 /* 17 109 * This just pushes the passed cookie onto the passed connection, without 18 110 * the SNAC header or any of that. … … 31 123 32 124 aimbs_put32(&fr->data, 0x00000001); 33 aim_addtlvtochain_raw(&tl, 0x0006, length, chipsahoy); 34 aim_writetlvchain(&fr->data, &tl); 35 aim_freetlvchain(&tl); 36 37 aim_tx_enqueue(sess, fr); 38 39 return 0; 40 } 41 42 /* 43 * Normally the FLAP version is sent as the first few bytes of the cookie, 44 * meaning you generally never call this. 45 * 46 * But there are times when something might want it seperate. Specifically, 47 * libfaim sends this internally when doing SNAC login. 48 * 49 */ 50 faim_export int aim_sendflapver(aim_session_t *sess, aim_conn_t *conn) 51 { 52 aim_frame_t *fr; 53 54 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 4))) 55 return -ENOMEM; 56 57 aimbs_put32(&fr->data, 0x00000001); 58 59 aim_tx_enqueue(sess, fr); 60 61 return 0; 62 } 63 64 /* 65 * This is a bit confusing. 66 * 67 * Normal SNAC login goes like this: 68 * - connect 69 * - server sends flap version 70 * - client sends flap version 71 * - client sends screen name (17/6) 72 * - server sends hash key (17/7) 73 * - client sends auth request (17/2 -- aim_send_login) 74 * - server yells 75 * 76 * XOR login (for ICQ) goes like this: 77 * - connect 78 * - server sends flap version 79 * - client sends auth request which contains flap version (aim_send_login) 80 * - server yells 81 * 82 * For the client API, we make them implement the most complicated version, 83 * and for the simpler version, we fake it and make it look like the more 84 * complicated process. 85 * 86 * This is done by giving the client a faked key, just so we can convince 87 * them to call aim_send_login right away, which will detect the session 88 * flag that says this is XOR login and ignore the key, sending an ICQ 89 * login request instead of the normal SNAC one. 90 * 91 * As soon as AOL makes ICQ log in the same way as AIM, this is /gone/. 92 * 93 * XXX This may cause problems if the client relies on callbacks only 94 * being called from the context of aim_rxdispatch()... 95 * 96 */ 97 static int goddamnicq(aim_session_t *sess, aim_conn_t *conn, const char *sn) 98 { 99 aim_frame_t fr; 100 aim_rxcallback_t userfunc; 101 102 sess->flags &= ~AIM_SESS_FLAGS_SNACLOGIN; 103 sess->flags |= AIM_SESS_FLAGS_XORLOGIN; 104 105 fr.conn = conn; 106 107 if ((userfunc = aim_callhandler(sess, conn, 0x0017, 0x0007))) 108 userfunc(sess, &fr, ""); 109 110 return 0; 111 } 112 113 /* 114 * In AIM 3.5 protocol, the first stage of login is to request login from the 115 * Authorizer, passing it the screen name for verification. If the name is 116 * invalid, a 0017/0003 is spit back, with the standard error contents. If 117 * valid, a 0017/0007 comes back, which is the signal to send it the main 118 * login command (0017/0002). 119 * 120 */ 121 faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn) 122 { 123 aim_frame_t *fr; 124 aim_snacid_t snacid; 125 aim_tlvlist_t *tl = NULL; 126 127 if (!sess || !conn || !sn) 128 return -EINVAL; 129 130 if ((sn[0] >= '0') && (sn[0] <= '9')) 131 return goddamnicq(sess, conn, sn); 132 133 sess->flags |= AIM_SESS_FLAGS_SNACLOGIN; 134 135 aim_sendflapver(sess, conn); 136 137 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn)))) 138 return -ENOMEM; 139 140 snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0); 141 aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid); 142 143 aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), sn); 144 aim_writetlvchain(&fr->data, &tl); 145 aim_freetlvchain(&tl); 125 aim_tlvlist_add_raw(&tl, 0x0006, length, chipsahoy); 126 aim_tlvlist_write(&fr->data, &tl); 127 aim_tlvlist_free(&tl); 146 128 147 129 aim_tx_enqueue(sess, fr); … … 174 156 175 157 aimbs_put32(&fr->data, 0x00000001); /* FLAP Version */ 176 aim_ addtlvtochain_raw(&tl, 0x0001, strlen(sn), sn);177 aim_ addtlvtochain_raw(&tl, 0x0002, passwdlen, password_encoded);158 aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn); 159 aim_tlvlist_add_raw(&tl, 0x0002, passwdlen, password_encoded); 178 160 179 161 if (ci->clientstring) 180 aim_ addtlvtochain_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring);181 aim_ addtlvtochain16(&tl, 0x0016, (fu16_t)ci->clientid);182 aim_ addtlvtochain16(&tl, 0x0017, (fu16_t)ci->major);183 aim_ addtlvtochain16(&tl, 0x0018, (fu16_t)ci->minor);184 aim_ addtlvtochain16(&tl, 0x0019, (fu16_t)ci->point);185 aim_ addtlvtochain16(&tl, 0x001a, (fu16_t)ci->build);186 aim_ addtlvtochain32(&tl, 0x0014, (fu32_t)ci->distrib); /* distribution chan */187 aim_ addtlvtochain_raw(&tl, 0x000f, strlen(ci->lang), ci->lang);188 aim_ addtlvtochain_raw(&tl, 0x000e, strlen(ci->country), ci->country);189 190 aim_ writetlvchain(&fr->data, &tl);162 aim_tlvlist_add_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring); 163 aim_tlvlist_add_16(&tl, 0x0016, (fu16_t)ci->clientid); 164 aim_tlvlist_add_16(&tl, 0x0017, (fu16_t)ci->major); 165 aim_tlvlist_add_16(&tl, 0x0018, (fu16_t)ci->minor); 166 aim_tlvlist_add_16(&tl, 0x0019, (fu16_t)ci->point); 167 aim_tlvlist_add_16(&tl, 0x001a, (fu16_t)ci->build); 168 aim_tlvlist_add_32(&tl, 0x0014, (fu32_t)ci->distrib); /* distribution chan */ 169 aim_tlvlist_add_raw(&tl, 0x000f, strlen(ci->lang), ci->lang); 170 aim_tlvlist_add_raw(&tl, 0x000e, strlen(ci->country), ci->country); 171 172 aim_tlvlist_write(&fr->data, &tl); 191 173 192 174 free(password_encoded); 193 aim_ freetlvchain(&tl);175 aim_tlvlist_free(&tl); 194 176 195 177 aim_tx_enqueue(sess, fr); … … 199 181 200 182 /* 201 * send_login(int socket, char *sn, char *password)202 * 183 * Subtype 0x0002 184 * 203 185 * This is the initial login request packet. 204 186 * … … 237 219 return -EINVAL; 238 220 239 /* 240 * What the XORLOGIN flag _really_ means is that its an ICQ login, 241 * which is really stupid and painful, so its not done here. 242 * 243 */ 244 if (sess->flags & AIM_SESS_FLAGS_XORLOGIN) 221 /* If we're signing on an ICQ account then use the older, XOR login method */ 222 if (isdigit(sn[0])) 245 223 return goddamnicq2(sess, conn, sn, password, ci); 246 247 224 248 225 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) … … 252 229 aim_putsnac(&fr->data, 0x0017, 0x0002, 0x0000, snacid); 253 230 254 aim_ addtlvtochain_raw(&tl, 0x0001, strlen(sn), sn);231 aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn); 255 232 256 233 aim_encode_password_md5(password, key, digest); 257 aim_ addtlvtochain_raw(&tl, 0x0025, 16, digest);258 259 /* 260 * Newer versions of winaim have an empty type x004c TLV here.261 */ 234 aim_tlvlist_add_raw(&tl, 0x0025, 16, digest); 235 236 #ifndef USE_OLD_MD5 237 aim_tlvlist_add_noval(&tl, 0x004c); 238 #endif 262 239 263 240 if (ci->clientstring) 264 aim_ addtlvtochain_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring);265 aim_ addtlvtochain16(&tl, 0x0016, (fu16_t)ci->clientid);266 aim_ addtlvtochain16(&tl, 0x0017, (fu16_t)ci->major);267 aim_ addtlvtochain16(&tl, 0x0018, (fu16_t)ci->minor);268 aim_ addtlvtochain16(&tl, 0x0019, (fu16_t)ci->point);269 aim_ addtlvtochain16(&tl, 0x001a, (fu16_t)ci->build);270 aim_ addtlvtochain32(&tl, 0x0014, (fu32_t)ci->distrib);271 aim_ addtlvtochain_raw(&tl, 0x000e, strlen(ci->country), ci->country);272 aim_ addtlvtochain_raw(&tl, 0x000f, strlen(ci->lang), ci->lang);241 aim_tlvlist_add_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring); 242 aim_tlvlist_add_16(&tl, 0x0016, (fu16_t)ci->clientid); 243 aim_tlvlist_add_16(&tl, 0x0017, (fu16_t)ci->major); 244 aim_tlvlist_add_16(&tl, 0x0018, (fu16_t)ci->minor); 245 aim_tlvlist_add_16(&tl, 0x0019, (fu16_t)ci->point); 246 aim_tlvlist_add_16(&tl, 0x001a, (fu16_t)ci->build); 247 aim_tlvlist_add_32(&tl, 0x0014, (fu32_t)ci->distrib); 248 aim_tlvlist_add_raw(&tl, 0x000f, strlen(ci->lang), ci->lang); 249 aim_tlvlist_add_raw(&tl, 0x000e, strlen(ci->country), ci->country); 273 250 274 251 #ifndef NOSSI … … 277 254 * to use SSI. 278 255 */ 279 aim_ addtlvtochain8(&tl, 0x004a, 0x01);256 aim_tlvlist_add_8(&tl, 0x004a, 0x01); 280 257 #endif 281 258 282 aim_ writetlvchain(&fr->data, &tl);283 284 aim_ freetlvchain(&tl);259 aim_tlvlist_write(&fr->data, &tl); 260 261 aim_tlvlist_free(&tl); 285 262 286 263 aim_tx_enqueue(sess, fr); 287 288 return 0;289 }290 291 faim_export int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest)292 {293 md5_state_t state;294 295 md5_init(&state);296 md5_append(&state, (const md5_byte_t *)key, strlen(key));297 md5_append(&state, (const md5_byte_t *)password, strlen(password));298 md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));299 md5_finish(&state, (md5_byte_t *)digest);300 301 return 0;302 }303 304 /**305 * aim_encode_password - Encode a password using old XOR method306 * @password: incoming password307 * @encoded: buffer to put encoded password308 *309 * This takes a const pointer to a (null terminated) string310 * containing the unencoded password. It also gets passed311 * an already allocated buffer to store the encoded password.312 * This buffer should be the exact length of the password without313 * the null. The encoded password buffer /is not %NULL terminated/.314 *315 * The encoding_table seems to be a fixed set of values. We'll316 * hope it doesn't change over time!317 *318 * This is only used for the XOR method, not the better MD5 method.319 *320 */321 static int aim_encode_password(const char *password, fu8_t *encoded)322 {323 fu8_t encoding_table[] = {324 #if 0 /* old v1 table */325 0xf3, 0xb3, 0x6c, 0x99,326 0x95, 0x3f, 0xac, 0xb6,327 0xc5, 0xfa, 0x6b, 0x63,328 0x69, 0x6c, 0xc3, 0x9f329 #else /* v2.1 table, also works for ICQ */330 0xf3, 0x26, 0x81, 0xc4,331 0x39, 0x86, 0xdb, 0x92,332 0x71, 0xa3, 0xb9, 0xe6,333 0x53, 0x7a, 0x95, 0x7c334 #endif335 };336 int i;337 338 for (i = 0; i < strlen(password); i++)339 encoded[i] = (password[i] ^ encoding_table[i]);340 264 341 265 return 0; … … 349 273 * The client should check the value passed as errorcode. If 350 274 * its nonzero, there was an error. 351 *352 275 */ 353 276 static int parse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) … … 365 288 * from what is parsed here. 366 289 */ 367 tlvlist = aim_ readtlvchain(bs);290 tlvlist = aim_tlvlist_read(bs); 368 291 369 292 /* … … 371 294 */ 372 295 memset(sess->sn, 0, sizeof(sess->sn)); 373 if (aim_ gettlv(tlvlist, 0x0001, 1)) {374 info->sn = aim_ gettlv_str(tlvlist, 0x0001, 1);296 if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) { 297 info->sn = aim_tlv_getstr(tlvlist, 0x0001, 1); 375 298 strncpy(sess->sn, info->sn, sizeof(sess->sn)); 376 299 } … … 380 303 * have an error url. 381 304 */ 382 if (aim_ gettlv(tlvlist, 0x0008, 1))383 info->errorcode = aim_ gettlv16(tlvlist, 0x0008, 1);384 if (aim_ gettlv(tlvlist, 0x0004, 1))385 info->errorurl = aim_ gettlv_str(tlvlist, 0x0004, 1);305 if (aim_tlv_gettlv(tlvlist, 0x0008, 1)) 306 info->errorcode = aim_tlv_get16(tlvlist, 0x0008, 1); 307 if (aim_tlv_gettlv(tlvlist, 0x0004, 1)) 308 info->errorurl = aim_tlv_getstr(tlvlist, 0x0004, 1); 386 309 387 310 /* 388 311 * BOS server address. 389 312 */ 390 if (aim_ gettlv(tlvlist, 0x0005, 1))391 info->bosip = aim_ gettlv_str(tlvlist, 0x0005, 1);313 if (aim_tlv_gettlv(tlvlist, 0x0005, 1)) 314 info->bosip = aim_tlv_getstr(tlvlist, 0x0005, 1); 392 315 393 316 /* 394 317 * Authorization cookie. 395 318 */ 396 if (aim_ gettlv(tlvlist, 0x0006, 1)) {319 if (aim_tlv_gettlv(tlvlist, 0x0006, 1)) { 397 320 aim_tlv_t *tmptlv; 398 321 399 tmptlv = aim_ gettlv(tlvlist, 0x0006, 1);322 tmptlv = aim_tlv_gettlv(tlvlist, 0x0006, 1); 400 323 401 324 info->cookielen = tmptlv->length; … … 410 333 * XXX - Not really true! 411 334 */ 412 if (aim_ gettlv(tlvlist, 0x0011, 1))413 info->email = aim_ gettlv_str(tlvlist, 0x0011, 1);335 if (aim_tlv_gettlv(tlvlist, 0x0011, 1)) 336 info->email = aim_tlv_getstr(tlvlist, 0x0011, 1); 414 337 415 338 /* … … 427 350 * 428 351 */ 429 if (aim_ gettlv(tlvlist, 0x0013, 1))430 info->regstatus = aim_ gettlv16(tlvlist, 0x0013, 1);431 432 if (aim_ gettlv(tlvlist, 0x0040, 1))433 info->latestbeta.build = aim_ gettlv32(tlvlist, 0x0040, 1);434 if (aim_ gettlv(tlvlist, 0x0041, 1))435 info->latestbeta.url = aim_ gettlv_str(tlvlist, 0x0041, 1);436 if (aim_ gettlv(tlvlist, 0x0042, 1))437 info->latestbeta.info = aim_ gettlv_str(tlvlist, 0x0042, 1);438 if (aim_ gettlv(tlvlist, 0x0043, 1))439 info->latestbeta.name = aim_ gettlv_str(tlvlist, 0x0043, 1);440 if (aim_ gettlv(tlvlist, 0x0048, 1))441 ; /* no idea what this is*/442 443 if (aim_ gettlv(tlvlist, 0x0044, 1))444 info->latestrelease.build = aim_ gettlv32(tlvlist, 0x0044, 1);445 if (aim_ gettlv(tlvlist, 0x0045, 1))446 info->latestrelease.url = aim_ gettlv_str(tlvlist, 0x0045, 1);447 if (aim_ gettlv(tlvlist, 0x0046, 1))448 info->latestrelease.info = aim_ gettlv_str(tlvlist, 0x0046, 1);449 if (aim_ gettlv(tlvlist, 0x0047, 1))450 info->latestrelease.name = aim_ gettlv_str(tlvlist, 0x0047, 1);451 if (aim_ gettlv(tlvlist, 0x0049, 1))452 ; /* no idea what this is*/352 if (aim_tlv_gettlv(tlvlist, 0x0013, 1)) 353 info->regstatus = aim_tlv_get16(tlvlist, 0x0013, 1); 354 355 if (aim_tlv_gettlv(tlvlist, 0x0040, 1)) 356 info->latestbeta.build = aim_tlv_get32(tlvlist, 0x0040, 1); 357 if (aim_tlv_gettlv(tlvlist, 0x0041, 1)) 358 info->latestbeta.url = aim_tlv_getstr(tlvlist, 0x0041, 1); 359 if (aim_tlv_gettlv(tlvlist, 0x0042, 1)) 360 info->latestbeta.info = aim_tlv_getstr(tlvlist, 0x0042, 1); 361 if (aim_tlv_gettlv(tlvlist, 0x0043, 1)) 362 info->latestbeta.name = aim_tlv_getstr(tlvlist, 0x0043, 1); 363 if (aim_tlv_gettlv(tlvlist, 0x0048, 1)) 364 ; /* beta serial */ 365 366 if (aim_tlv_gettlv(tlvlist, 0x0044, 1)) 367 info->latestrelease.build = aim_tlv_get32(tlvlist, 0x0044, 1); 368 if (aim_tlv_gettlv(tlvlist, 0x0045, 1)) 369 info->latestrelease.url = aim_tlv_getstr(tlvlist, 0x0045, 1); 370 if (aim_tlv_gettlv(tlvlist, 0x0046, 1)) 371 info->latestrelease.info = aim_tlv_getstr(tlvlist, 0x0046, 1); 372 if (aim_tlv_gettlv(tlvlist, 0x0047, 1)) 373 info->latestrelease.name = aim_tlv_getstr(tlvlist, 0x0047, 1); 374 if (aim_tlv_gettlv(tlvlist, 0x0049, 1)) 375 ; /* lastest release serial */ 453 376 454 377 /* 455 378 * URL to change password. 456 379 */ 457 if (aim_ gettlv(tlvlist, 0x0054, 1))458 info->chpassurl = aim_ gettlv_str(tlvlist, 0x0054, 1);380 if (aim_tlv_gettlv(tlvlist, 0x0054, 1)) 381 info->chpassurl = aim_tlv_getstr(tlvlist, 0x0054, 1); 459 382 460 383 /* 461 384 * Unknown. Seen on an @mac.com screen name with value of 0x003f 462 385 */ 463 if (aim_ gettlv(tlvlist, 0x0055, 1))386 if (aim_tlv_gettlv(tlvlist, 0x0055, 1)) 464 387 ; 465 388 … … 469 392 ret = userfunc(sess, rx, info); 470 393 471 aim_ freetlvchain(&tlvlist);394 aim_tlvlist_free(&tlvlist); 472 395 473 396 return ret; … … 475 398 476 399 /* 400 * Subtype 0x0007 (kind of) - Send a fake type 0x0007 SNAC to the client 401 * 402 * This is a bit confusing. 403 * 404 * Normal SNAC login goes like this: 405 * - connect 406 * - server sends flap version 407 * - client sends flap version 408 * - client sends screen name (17/6) 409 * - server sends hash key (17/7) 410 * - client sends auth request (17/2 -- aim_send_login) 411 * - server yells 412 * 413 * XOR login (for ICQ) goes like this: 414 * - connect 415 * - server sends flap version 416 * - client sends auth request which contains flap version (aim_send_login) 417 * - server yells 418 * 419 * For the client API, we make them implement the most complicated version, 420 * and for the simpler version, we fake it and make it look like the more 421 * complicated process. 422 * 423 * This is done by giving the client a faked key, just so we can convince 424 * them to call aim_send_login right away, which will detect the session 425 * flag that says this is XOR login and ignore the key, sending an ICQ 426 * login request instead of the normal SNAC one. 427 * 428 * As soon as AOL makes ICQ log in the same way as AIM, this is /gone/. 429 * 430 * XXX This may cause problems if the client relies on callbacks only 431 * being called from the context of aim_rxdispatch()... 432 * 433 */ 434 static int goddamnicq(aim_session_t *sess, aim_conn_t *conn, const char *sn) 435 { 436 aim_frame_t fr; 437 aim_rxcallback_t userfunc; 438 439 fr.conn = conn; 440 441 if ((userfunc = aim_callhandler(sess, conn, 0x0017, 0x0007))) 442 userfunc(sess, &fr, ""); 443 444 return 0; 445 } 446 447 /* 448 * Subtype 0x0006 449 * 450 * In AIM 3.5 protocol, the first stage of login is to request login from the 451 * Authorizer, passing it the screen name for verification. If the name is 452 * invalid, a 0017/0003 is spit back, with the standard error contents. If 453 * valid, a 0017/0007 comes back, which is the signal to send it the main 454 * login command (0017/0002). 455 * 456 */ 457 faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn) 458 { 459 aim_frame_t *fr; 460 aim_snacid_t snacid; 461 aim_tlvlist_t *tl = NULL; 462 463 if (!sess || !conn || !sn) 464 return -EINVAL; 465 466 if (isdigit(sn[0])) 467 return goddamnicq(sess, conn, sn); 468 469 aim_sendflapver(sess, conn); 470 471 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn) /*+8*/ ))) 472 return -ENOMEM; 473 474 snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0); 475 aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid); 476 477 aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn); 478 /* aim_tlvlist_add_noval(&tl, 0x004b); 479 aim_tlvlist_add_noval(&tl, 0x005a); */ 480 aim_tlvlist_write(&fr->data, &tl); 481 aim_tlvlist_free(&tl); 482 483 aim_tx_enqueue(sess, fr); 484 485 return 0; 486 } 487 488 /* 489 * Subtype 0x0007 490 * 477 491 * Middle handler for 0017/0007 SNACs. Contains the auth key prefixed 478 492 * by only its length in a two byte word. -
libfaim/bos.c
re374dee rcf02dd6 13 13 faim_export int aim_bos_reqrights(aim_session_t *sess, aim_conn_t *conn) 14 14 { 15 return aim_genericreq_n (sess, conn, 0x0009, 0x0002);15 return aim_genericreq_n_snacid(sess, conn, 0x0009, 0x0002); 16 16 } 17 17 … … 27 27 * TLVs follow 28 28 */ 29 tlvlist = aim_ readtlvchain(bs);29 tlvlist = aim_tlvlist_read(bs); 30 30 31 31 /* 32 32 * TLV type 0x0001: Maximum number of buddies on permit list. 33 33 */ 34 if (aim_ gettlv(tlvlist, 0x0001, 1))35 maxpermits = aim_ gettlv16(tlvlist, 0x0001, 1);34 if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) 35 maxpermits = aim_tlv_get16(tlvlist, 0x0001, 1); 36 36 37 37 /* 38 38 * TLV type 0x0002: Maximum number of buddies on deny list. 39 39 */ 40 if (aim_ gettlv(tlvlist, 0x0002, 1))41 maxdenies = aim_ gettlv16(tlvlist, 0x0002, 1);40 if (aim_tlv_gettlv(tlvlist, 0x0002, 1)) 41 maxdenies = aim_tlv_get16(tlvlist, 0x0002, 1); 42 42 43 43 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 44 44 ret = userfunc(sess, rx, maxpermits, maxdenies); 45 45 46 aim_ freetlvchain(&tlvlist);46 aim_tlvlist_free(&tlvlist); 47 47 48 48 return ret; -
libfaim/buddylist.c
re374dee rcf02dd6 15 15 * 16 16 */ 17 faim_export int aim_b os_reqbuddyrights(aim_session_t *sess, aim_conn_t *conn)18 { 19 return aim_genericreq_n (sess, conn, 0x0003, 0x0002);17 faim_export int aim_buddylist_reqrights(aim_session_t *sess, aim_conn_t *conn) 18 { 19 return aim_genericreq_n_snacid(sess, conn, 0x0003, 0x0002); 20 20 } 21 21 … … 34 34 * TLVs follow 35 35 */ 36 tlvlist = aim_ readtlvchain(bs);36 tlvlist = aim_tlvlist_read(bs); 37 37 38 38 /* 39 39 * TLV type 0x0001: Maximum number of buddies. 40 40 */ 41 if (aim_ gettlv(tlvlist, 0x0001, 1))42 maxbuddies = aim_ gettlv16(tlvlist, 0x0001, 1);41 if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) 42 maxbuddies = aim_tlv_get16(tlvlist, 0x0001, 1); 43 43 44 44 /* … … 50 50 * 51 51 */ 52 if (aim_ gettlv(tlvlist, 0x0002, 1))53 maxwatchers = aim_ gettlv16(tlvlist, 0x0002, 1);52 if (aim_tlv_gettlv(tlvlist, 0x0002, 1)) 53 maxwatchers = aim_tlv_get16(tlvlist, 0x0002, 1); 54 54 55 55 /* … … 62 62 ret = userfunc(sess, rx, maxbuddies, maxwatchers); 63 63 64 aim_ freetlvchain(&tlvlist);64 aim_tlvlist_free(&tlvlist); 65 65 66 66 return ret; … … 74 74 * 75 75 */ 76 faim_export int aim_ add_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)76 faim_export int aim_buddylist_addbuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn) 77 77 { 78 78 aim_frame_t *fr; … … 106 106 * 107 107 */ 108 faim_export int aim_b os_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)108 faim_export int aim_buddylist_set(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list) 109 109 { 110 110 aim_frame_t *fr; … … 154 154 * 155 155 */ 156 faim_export int aim_ remove_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)156 faim_export int aim_buddylist_removebuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn) 157 157 { 158 158 aim_frame_t *fr; … … 182 182 * 183 183 */ 184 faim_export int aim_ sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info)184 faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info) 185 185 { 186 186 aim_frame_t *fr; … … 209 209 * 210 210 */ 211 faim_export int aim_ sendbuddyoffgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn)211 faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn) 212 212 { 213 213 aim_frame_t *fr; … … 253 253 ret = userfunc(sess, rx, &userinfo); 254 254 255 if (snac->subtype == 0x000b) 256 aim_locate_requestuserinfo(sess, userinfo.sn); 255 257 aim_info_free(&userinfo); 256 258 -
libfaim/chat.c
re374dee rcf02dd6 104 104 aimbs_put16(&bs, instance); 105 105 106 aim_ addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);106 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); 107 107 108 108 free(buf); … … 144 144 145 145 aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance); 146 aim_ writetlvchain(&fr->data, &tl);147 aim_ freetlvchain(&tl);146 aim_tlvlist_write(&fr->data, &tl); 147 aim_tlvlist_free(&tl); 148 148 149 149 aim_tx_enqueue(sess, fr); … … 250 250 aim_putcap(&hdrbs, AIM_CAPS_CHAT); 251 251 252 aim_ addtlvtochain16(&itl, 0x000a, 0x0001);253 aim_ addtlvtochain_noval(&itl, 0x000f);254 aim_ addtlvtochain_raw(&itl, 0x000c, strlen(msg), msg);252 aim_tlvlist_add_16(&itl, 0x000a, 0x0001); 253 aim_tlvlist_add_noval(&itl, 0x000f); 254 aim_tlvlist_add_raw(&itl, 0x000c, strlen(msg), msg); 255 255 aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance); 256 aim_ writetlvchain(&hdrbs, &itl);257 258 aim_ addtlvtochain_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);259 260 aim_ writetlvchain(&fr->data, &otl);256 aim_tlvlist_write(&hdrbs, &itl); 257 258 aim_tlvlist_add_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); 259 260 aim_tlvlist_write(&fr->data, &otl); 261 261 262 262 free(hdr); 263 aim_ freetlvchain(&itl);264 aim_ freetlvchain(&otl);263 aim_tlvlist_free(&itl); 264 aim_tlvlist_free(&otl); 265 265 266 266 aim_tx_enqueue(sess, fr); … … 308 308 * Everything else are TLVs. 309 309 */ 310 tlvlist = aim_ readtlvchain(bs);310 tlvlist = aim_tlvlist_read(bs); 311 311 312 312 /* 313 313 * TLV type 0x006a is the room name in Human Readable Form. 314 314 */ 315 if (aim_ gettlv(tlvlist, 0x006a, 1))316 roomname = aim_ gettlv_str(tlvlist, 0x006a, 1);315 if (aim_tlv_gettlv(tlvlist, 0x006a, 1)) 316 roomname = aim_tlv_getstr(tlvlist, 0x006a, 1); 317 317 318 318 /* 319 319 * Type 0x006f: Number of occupants. 320 320 */ 321 if (aim_ gettlv(tlvlist, 0x006f, 1))322 usercount = aim_ gettlv16(tlvlist, 0x006f, 1);321 if (aim_tlv_gettlv(tlvlist, 0x006f, 1)) 322 usercount = aim_tlv_get16(tlvlist, 0x006f, 1); 323 323 324 324 /* 325 325 * Type 0x0073: Occupant list. 326 326 */ 327 if (aim_ gettlv(tlvlist, 0x0073, 1)) {327 if (aim_tlv_gettlv(tlvlist, 0x0073, 1)) { 328 328 int curoccupant = 0; 329 329 aim_tlv_t *tmptlv; 330 330 aim_bstream_t occbs; 331 331 332 tmptlv = aim_ gettlv(tlvlist, 0x0073, 1);332 tmptlv = aim_tlv_gettlv(tlvlist, 0x0073, 1); 333 333 334 334 /* Allocate enough userinfo structs for all occupants */ … … 344 344 * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG) 345 345 */ 346 if (aim_ gettlv(tlvlist, 0x00c9, 1))347 flags = aim_ gettlv16(tlvlist, 0x00c9, 1);346 if (aim_tlv_gettlv(tlvlist, 0x00c9, 1)) 347 flags = aim_tlv_get16(tlvlist, 0x00c9, 1); 348 348 349 349 /* 350 350 * Type 0x00ca: Creation time (4 bytes) 351 351 */ 352 if (aim_ gettlv(tlvlist, 0x00ca, 1))353 creationtime = aim_ gettlv32(tlvlist, 0x00ca, 1);352 if (aim_tlv_gettlv(tlvlist, 0x00ca, 1)) 353 creationtime = aim_tlv_get32(tlvlist, 0x00ca, 1); 354 354 355 355 /* 356 356 * Type 0x00d1: Maximum Message Length 357 357 */ 358 if (aim_ gettlv(tlvlist, 0x00d1, 1))359 maxmsglen = aim_ gettlv16(tlvlist, 0x00d1, 1);358 if (aim_tlv_gettlv(tlvlist, 0x00d1, 1)) 359 maxmsglen = aim_tlv_get16(tlvlist, 0x00d1, 1); 360 360 361 361 /* 362 362 * Type 0x00d2: Unknown. (2 bytes) 363 363 */ 364 if (aim_ gettlv(tlvlist, 0x00d2, 1))365 unknown_d2 = aim_ gettlv16(tlvlist, 0x00d2, 1);364 if (aim_tlv_gettlv(tlvlist, 0x00d2, 1)) 365 unknown_d2 = aim_tlv_get16(tlvlist, 0x00d2, 1); 366 366 367 367 /* 368 368 * Type 0x00d3: Room Description 369 369 */ 370 if (aim_ gettlv(tlvlist, 0x00d3, 1))371 roomdesc = aim_ gettlv_str(tlvlist, 0x00d3, 1);370 if (aim_tlv_gettlv(tlvlist, 0x00d3, 1)) 371 roomdesc = aim_tlv_getstr(tlvlist, 0x00d3, 1); 372 372 373 373 /* 374 374 * Type 0x000d4: Unknown (flag only) 375 375 */ 376 if (aim_ gettlv(tlvlist, 0x000d4, 1))376 if (aim_tlv_gettlv(tlvlist, 0x000d4, 1)) 377 377 ; 378 378 … … 380 380 * Type 0x00d5: Unknown. (1 byte) 381 381 */ 382 if (aim_ gettlv(tlvlist, 0x00d5, 1))383 unknown_d5 = aim_ gettlv8(tlvlist, 0x00d5, 1);382 if (aim_tlv_gettlv(tlvlist, 0x00d5, 1)) 383 unknown_d5 = aim_tlv_get8(tlvlist, 0x00d5, 1); 384 384 385 385 … … 387 387 * Type 0x00d6: Encoding 1 ("us-ascii") 388 388 */ 389 if (aim_ gettlv(tlvlist, 0x000d6, 1))389 if (aim_tlv_gettlv(tlvlist, 0x000d6, 1)) 390 390 ; 391 391 … … 393 393 * Type 0x00d7: Language 1 ("en") 394 394 */ 395 if (aim_ gettlv(tlvlist, 0x000d7, 1))395 if (aim_tlv_gettlv(tlvlist, 0x000d7, 1)) 396 396 ; 397 397 … … 399 399 * Type 0x00d8: Encoding 2 ("us-ascii") 400 400 */ 401 if (aim_ gettlv(tlvlist, 0x000d8, 1))401 if (aim_tlv_gettlv(tlvlist, 0x000d8, 1)) 402 402 ; 403 403 … … 405 405 * Type 0x00d9: Language 2 ("en") 406 406 */ 407 if (aim_ gettlv(tlvlist, 0x000d9, 1))407 if (aim_tlv_gettlv(tlvlist, 0x000d9, 1)) 408 408 ; 409 409 … … 411 411 * Type 0x00da: Maximum visible message length 412 412 */ 413 if (aim_ gettlv(tlvlist, 0x000da, 1))414 maxvisiblemsglen = aim_ gettlv16(tlvlist, 0x00da, 1);413 if (aim_tlv_gettlv(tlvlist, 0x000da, 1)) 414 maxvisiblemsglen = aim_tlv_get16(tlvlist, 0x00da, 1); 415 415 416 416 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { … … 438 438 free(roomname); 439 439 free(roomdesc); 440 aim_ freetlvchain(&tlvlist);440 aim_tlvlist_free(&tlvlist); 441 441 442 442 return ret; … … 516 516 * Type 1: Flag meaning this message is destined to the room. 517 517 */ 518 aim_ addtlvtochain_noval(&otl, 0x0001);518 aim_tlvlist_add_noval(&otl, 0x0001); 519 519 520 520 /* … … 522 522 */ 523 523 if (!(flags & AIM_CHATFLAGS_NOREFLECT)) 524 aim_ addtlvtochain_noval(&otl, 0x0006);524 aim_tlvlist_add_noval(&otl, 0x0006); 525 525 526 526 /* … … 528 528 */ 529 529 if (flags & AIM_CHATFLAGS_AWAY) 530 aim_ addtlvtochain_noval(&otl, 0x0007);530 aim_tlvlist_add_noval(&otl, 0x0007); 531 531 532 532 /* 533 533 * SubTLV: Type 1: Message 534 534 */ 535 aim_ addtlvtochain_raw(&itl, 0x0001, msglen, msg);535 aim_tlvlist_add_raw(&itl, 0x0001, msglen, msg); 536 536 537 537 /* … … 542 542 * 543 543 */ 544 aim_ addtlvtochain_frozentlvlist(&otl, 0x0005, &itl);545 546 aim_ writetlvchain(&fr->data, &otl);547 548 aim_ freetlvchain(&itl);549 aim_ freetlvchain(&otl);544 aim_tlvlist_add_frozentlvlist(&otl, 0x0005, &itl); 545 546 aim_tlvlist_write(&fr->data, &otl); 547 548 aim_tlvlist_free(&itl); 549 aim_tlvlist_free(&otl); 550 550 551 551 aim_tx_enqueue(sess, fr); … … 621 621 * Start parsing TLVs right away. 622 622 */ 623 otl = aim_ readtlvchain(bs);623 otl = aim_tlvlist_read(bs); 624 624 625 625 /* 626 626 * Type 0x0003: Source User Information 627 627 */ 628 if (aim_ gettlv(otl, 0x0003, 1)) {628 if (aim_tlv_gettlv(otl, 0x0003, 1)) { 629 629 aim_tlv_t *userinfotlv; 630 630 aim_bstream_t tbs; 631 631 632 userinfotlv = aim_ gettlv(otl, 0x0003, 1);632 userinfotlv = aim_tlv_gettlv(otl, 0x0003, 1); 633 633 634 634 aim_bstream_init(&tbs, userinfotlv->value, userinfotlv->length); … … 640 640 * room (as opposed to a whisper). 641 641 */ 642 if (aim_ gettlv(otl, 0x0001, 1))642 if (aim_tlv_gettlv(otl, 0x0001, 1)) 643 643 ; 644 644 … … 646 646 * Type 0x0005: Message Block. Conains more TLVs. 647 647 */ 648 if (aim_ gettlv(otl, 0x0005, 1)) {648 if (aim_tlv_gettlv(otl, 0x0005, 1)) { 649 649 aim_tlvlist_t *itl; 650 650 aim_tlv_t *msgblock; 651 651 aim_bstream_t tbs; 652 652 653 msgblock = aim_ gettlv(otl, 0x0005, 1);653 msgblock = aim_tlv_gettlv(otl, 0x0005, 1); 654 654 aim_bstream_init(&tbs, msgblock->value, msgblock->length); 655 itl = aim_ readtlvchain(&tbs);655 itl = aim_tlvlist_read(&tbs); 656 656 657 657 /* 658 658 * Type 0x0001: Message. 659 659 */ 660 if (aim_ gettlv(itl, 0x0001, 1))661 msg = aim_ gettlv_str(itl, 0x0001, 1);662 663 aim_ freetlvchain(&itl);660 if (aim_tlv_gettlv(itl, 0x0001, 1)) 661 msg = aim_tlv_getstr(itl, 0x0001, 1); 662 663 aim_tlvlist_free(&itl); 664 664 } 665 665 … … 670 670 free(cookie); 671 671 free(msg); 672 aim_ freetlvchain(&otl);672 aim_tlvlist_free(&otl); 673 673 674 674 return ret; -
libfaim/chatnav.c
re374dee rcf02dd6 68 68 aimbs_put8(&fr->data, 0x01); 69 69 70 aim_ addtlvtochain_raw(&tl, 0x00d3, strlen(name), name);71 aim_ addtlvtochain_raw(&tl, 0x00d6, strlen(charset), charset);72 aim_ addtlvtochain_raw(&tl, 0x00d7, strlen(lang), lang);70 aim_tlvlist_add_raw(&tl, 0x00d3, strlen(name), name); 71 aim_tlvlist_add_raw(&tl, 0x00d6, strlen(charset), charset); 72 aim_tlvlist_add_raw(&tl, 0x00d7, strlen(lang), lang); 73 73 74 74 /* tlvcount */ 75 aimbs_put16(&fr->data, aim_ counttlvchain(&tl));76 aim_ writetlvchain(&fr->data, &tl);77 78 aim_ freetlvchain(&tl);75 aimbs_put16(&fr->data, aim_tlvlist_count(&tl)); 76 aim_tlvlist_write(&fr->data, &tl); 77 78 aim_tlvlist_free(&tl); 79 79 80 80 aim_tx_enqueue(sess, fr); … … 93 93 aim_tlvlist_t *tlvlist, *innerlist; 94 94 95 tlvlist = aim_ readtlvchain(bs);95 tlvlist = aim_tlvlist_read(bs); 96 96 97 97 /* 98 98 * Type 0x0002: Maximum concurrent rooms. 99 99 */ 100 if (aim_ gettlv(tlvlist, 0x0002, 1))101 maxrooms = aim_ gettlv8(tlvlist, 0x0002, 1);100 if (aim_tlv_gettlv(tlvlist, 0x0002, 1)) 101 maxrooms = aim_tlv_get8(tlvlist, 0x0002, 1); 102 102 103 103 /* … … 108 108 * 109 109 */ 110 for (curexchange = 0; ((exchangetlv = aim_ gettlv(tlvlist, 0x0003, curexchange+1))); ) {110 for (curexchange = 0; ((exchangetlv = aim_tlv_gettlv(tlvlist, 0x0003, curexchange+1))); ) { 111 111 aim_bstream_t tbs; 112 112 … … 119 119 /* exchange number */ 120 120 exchanges[curexchange-1].number = aimbs_get16(&tbs); 121 innerlist = aim_ readtlvchain(&tbs);121 innerlist = aim_tlvlist_read(&tbs); 122 122 123 123 /* … … 127 127 * 128 128 */ 129 if (aim_ gettlv(innerlist, 0x000a, 1))129 if (aim_tlv_gettlv(innerlist, 0x000a, 1)) 130 130 ; 131 131 … … 133 133 * Type 0x000d: Unknown. 134 134 */ 135 if (aim_ gettlv(innerlist, 0x000d, 1))135 if (aim_tlv_gettlv(innerlist, 0x000d, 1)) 136 136 ; 137 137 … … 139 139 * Type 0x0004: Unknown 140 140 */ 141 if (aim_ gettlv(innerlist, 0x0004, 1))141 if (aim_tlv_gettlv(innerlist, 0x0004, 1)) 142 142 ; 143 143 … … 145 145 * Type 0x0002: Unknown 146 146 */ 147 if (aim_ gettlv(innerlist, 0x0002, 1)) {147 if (aim_tlv_gettlv(innerlist, 0x0002, 1)) { 148 148 fu16_t classperms; 149 149 150 classperms = aim_ gettlv16(innerlist, 0x0002, 1);150 classperms = aim_tlv_get16(innerlist, 0x0002, 1); 151 151 152 152 faimdprintf(sess, 1, "faim: class permissions %x\n", classperms); … … 162 162 * 163 163 */ 164 if (aim_ gettlv(innerlist, 0x00c9, 1))165 exchanges[curexchange-1].flags = aim_ gettlv16(innerlist, 0x00c9, 1);164 if (aim_tlv_gettlv(innerlist, 0x00c9, 1)) 165 exchanges[curexchange-1].flags = aim_tlv_get16(innerlist, 0x00c9, 1); 166 166 167 167 /* 168 168 * Type 0x00ca: Creation Date 169 169 */ 170 if (aim_ gettlv(innerlist, 0x00ca, 1))170 if (aim_tlv_gettlv(innerlist, 0x00ca, 1)) 171 171 ; 172 172 … … 174 174 * Type 0x00d0: Mandatory Channels? 175 175 */ 176 if (aim_ gettlv(innerlist, 0x00d0, 1))176 if (aim_tlv_gettlv(innerlist, 0x00d0, 1)) 177 177 ; 178 178 … … 180 180 * Type 0x00d1: Maximum Message length 181 181 */ 182 if (aim_ gettlv(innerlist, 0x00d1, 1))182 if (aim_tlv_gettlv(innerlist, 0x00d1, 1)) 183 183 ; 184 184 … … 186 186 * Type 0x00d2: Maximum Occupancy? 187 187 */ 188 if (aim_ gettlv(innerlist, 0x00d2, 1))188 if (aim_tlv_gettlv(innerlist, 0x00d2, 1)) 189 189 ; 190 190 … … 192 192 * Type 0x00d3: Exchange Description 193 193 */ 194 if (aim_ gettlv(innerlist, 0x00d3, 1))195 exchanges[curexchange-1].name = aim_ gettlv_str(innerlist, 0x00d3, 1);194 if (aim_tlv_gettlv(innerlist, 0x00d3, 1)) 195 exchanges[curexchange-1].name = aim_tlv_getstr(innerlist, 0x00d3, 1); 196 196 else 197 197 exchanges[curexchange-1].name = NULL; … … 200 200 * Type 0x00d4: Exchange Description URL 201 201 */ 202 if (aim_ gettlv(innerlist, 0x00d4, 1))202 if (aim_tlv_gettlv(innerlist, 0x00d4, 1)) 203 203 ; 204 204 … … 211 211 * 212 212 */ 213 if (aim_ gettlv(innerlist, 0x00d5, 1)) {213 if (aim_tlv_gettlv(innerlist, 0x00d5, 1)) { 214 214 fu8_t createperms; 215 215 216 createperms = aim_ gettlv8(innerlist, 0x00d5, 1);216 createperms = aim_tlv_get8(innerlist, 0x00d5, 1); 217 217 } 218 218 … … 220 220 * Type 0x00d6: Character Set (First Time) 221 221 */ 222 if (aim_ gettlv(innerlist, 0x00d6, 1))223 exchanges[curexchange-1].charset1 = aim_ gettlv_str(innerlist, 0x00d6, 1);222 if (aim_tlv_gettlv(innerlist, 0x00d6, 1)) 223 exchanges[curexchange-1].charset1 = aim_tlv_getstr(innerlist, 0x00d6, 1); 224 224 else 225 225 exchanges[curexchange-1].charset1 = NULL; … … 228 228 * Type 0x00d7: Language (First Time) 229 229 */ 230 if (aim_ gettlv(innerlist, 0x00d7, 1))231 exchanges[curexchange-1].lang1 = aim_ gettlv_str(innerlist, 0x00d7, 1);230 if (aim_tlv_gettlv(innerlist, 0x00d7, 1)) 231 exchanges[curexchange-1].lang1 = aim_tlv_getstr(innerlist, 0x00d7, 1); 232 232 else 233 233 exchanges[curexchange-1].lang1 = NULL; … … 236 236 * Type 0x00d8: Character Set (Second Time) 237 237 */ 238 if (aim_ gettlv(innerlist, 0x00d8, 1))239 exchanges[curexchange-1].charset2 = aim_ gettlv_str(innerlist, 0x00d8, 1);238 if (aim_tlv_gettlv(innerlist, 0x00d8, 1)) 239 exchanges[curexchange-1].charset2 = aim_tlv_getstr(innerlist, 0x00d8, 1); 240 240 else 241 241 exchanges[curexchange-1].charset2 = NULL; … … 244 244 * Type 0x00d9: Language (Second Time) 245 245 */ 246 if (aim_ gettlv(innerlist, 0x00d9, 1))247 exchanges[curexchange-1].lang2 = aim_ gettlv_str(innerlist, 0x00d9, 1);246 if (aim_tlv_gettlv(innerlist, 0x00d9, 1)) 247 exchanges[curexchange-1].lang2 = aim_tlv_getstr(innerlist, 0x00d9, 1); 248 248 else 249 249 exchanges[curexchange-1].lang2 = NULL; … … 252 252 * Type 0x00da: Unknown 253 253 */ 254 if (aim_ gettlv(innerlist, 0x00da, 1))255 ; 256 257 aim_ freetlvchain(&innerlist);254 if (aim_tlv_gettlv(innerlist, 0x00da, 1)) 255 ; 256 257 aim_tlvlist_free(&innerlist); 258 258 } 259 259 … … 272 272 } 273 273 free(exchanges); 274 aim_ freetlvchain(&tlvlist);274 aim_tlvlist_free(&tlvlist); 275 275 276 276 return ret; … … 290 290 aim_bstream_t bbbs; 291 291 292 tlvlist = aim_ readtlvchain(bs);293 294 if (!(bigblock = aim_ gettlv(tlvlist, 0x0004, 1))) {292 tlvlist = aim_tlvlist_read(bs); 293 294 if (!(bigblock = aim_tlv_gettlv(tlvlist, 0x0004, 1))) { 295 295 faimdprintf(sess, 0, "no bigblock in top tlv in create room response\n"); 296 aim_ freetlvchain(&tlvlist);296 aim_tlvlist_free(&tlvlist); 297 297 return 0; 298 298 } … … 308 308 if (detaillevel != 0x02) { 309 309 faimdprintf(sess, 0, "unknown detaillevel in create room response (0x%02x)\n", detaillevel); 310 aim_ freetlvchain(&tlvlist);310 aim_tlvlist_free(&tlvlist); 311 311 free(ck); 312 312 return 0; … … 315 315 unknown = aimbs_get16(&bbbs); 316 316 317 innerlist = aim_ readtlvchain(&bbbs);318 319 if (aim_ gettlv(innerlist, 0x006a, 1))320 fqcn = aim_ gettlv_str(innerlist, 0x006a, 1);321 322 if (aim_ gettlv(innerlist, 0x00c9, 1))323 flags = aim_ gettlv16(innerlist, 0x00c9, 1);324 325 if (aim_ gettlv(innerlist, 0x00ca, 1))326 createtime = aim_ gettlv32(innerlist, 0x00ca, 1);327 328 if (aim_ gettlv(innerlist, 0x00d1, 1))329 maxmsglen = aim_ gettlv16(innerlist, 0x00d1, 1);330 331 if (aim_ gettlv(innerlist, 0x00d2, 1))332 maxoccupancy = aim_ gettlv16(innerlist, 0x00d2, 1);333 334 if (aim_ gettlv(innerlist, 0x00d3, 1))335 name = aim_ gettlv_str(innerlist, 0x00d3, 1);336 337 if (aim_ gettlv(innerlist, 0x00d5, 1))338 createperms = aim_ gettlv8(innerlist, 0x00d5, 1);317 innerlist = aim_tlvlist_read(&bbbs); 318 319 if (aim_tlv_gettlv(innerlist, 0x006a, 1)) 320 fqcn = aim_tlv_getstr(innerlist, 0x006a, 1); 321 322 if (aim_tlv_gettlv(innerlist, 0x00c9, 1)) 323 flags = aim_tlv_get16(innerlist, 0x00c9, 1); 324 325 if (aim_tlv_gettlv(innerlist, 0x00ca, 1)) 326 createtime = aim_tlv_get32(innerlist, 0x00ca, 1); 327 328 if (aim_tlv_gettlv(innerlist, 0x00d1, 1)) 329 maxmsglen = aim_tlv_get16(innerlist, 0x00d1, 1); 330 331 if (aim_tlv_gettlv(innerlist, 0x00d2, 1)) 332 maxoccupancy = aim_tlv_get16(innerlist, 0x00d2, 1); 333 334 if (aim_tlv_gettlv(innerlist, 0x00d3, 1)) 335 name = aim_tlv_getstr(innerlist, 0x00d3, 1); 336 337 if (aim_tlv_gettlv(innerlist, 0x00d5, 1)) 338 createperms = aim_tlv_get8(innerlist, 0x00d5, 1); 339 339 340 340 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { … … 345 345 free(name); 346 346 free(fqcn); 347 aim_ freetlvchain(&innerlist);348 aim_ freetlvchain(&tlvlist);347 aim_tlvlist_free(&innerlist); 348 aim_tlvlist_free(&tlvlist); 349 349 350 350 return ret; -
libfaim/conn.c
re374dee rcf02dd6 192 192 193 193 /** 194 * aim_connrst - Clears out connection list, killing remaining connections. 195 * @sess: Session to be cleared 196 * 197 * Clears out the connection list and kills any connections left. 198 * 194 * Clears out connection list, killing remaining connections. 195 * 196 * @param sess Session to be cleared 199 197 */ 200 198 static void aim_connrst(aim_session_t *sess) … … 218 216 219 217 /** 220 * aim_conn_init - Reset a connection to default values. 221 * @deadconn: Connection to be reset 222 * 218 * Reset a connection to default values. 223 219 * Initializes and/or resets a connection structure. 224 220 * 221 * @param deadconn Connection to be reset 225 222 */ 226 223 static void aim_conn_init(aim_conn_t *deadconn) … … 533 530 fd = socket(hp->h_addrtype, SOCK_STREAM, 0); 534 531 535 if (sess-> flags & AIM_SESS_FLAGS_NONBLOCKCONNECT)532 if (sess->nonblocking) 536 533 fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */ 537 534 538 535 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { 539 if (sess-> flags & AIM_SESS_FLAGS_NONBLOCKCONNECT) {536 if (sess->nonblocking) { 540 537 if ((errno == EINPROGRESS) || (errno == EINTR)) { 541 538 if (statusret) … … 853 850 854 851 /** 855 * aim_session_init - Initializes a session structure 856 * @sess: Session to initialize 857 * @flags: Flags to use. Any of %AIM_SESS_FLAGS %OR'd together. 858 * @debuglevel: Level of debugging output (zero is least) 859 * 860 * Sets up the initial values for a session. 861 * 862 */ 863 faim_export void aim_session_init(aim_session_t *sess, fu32_t flags, int debuglevel) 852 * Initializes a session structure by setting the initial values 853 * stuff in the aim_session_t struct. 854 * 855 * @param sess Session to initialize. 856 * @param nonblocking Set to true if you want connections to be non-blocking. 857 * @param debuglevel Level of debugging output (zero is least). 858 */ 859 faim_export void aim_session_init(aim_session_t *sess, bool nonblocking, int debuglevel) 864 860 { 865 861 … … 873 869 aim_initsnachash(sess); 874 870 sess->msgcookies = NULL; 875 sess->icq_info = NULL; 876 sess->oft_info = NULL; 877 sess->snacid_next = 0x00000001; 878 879 sess->flags = 0; 871 sess->nonblocking = nonblocking; 880 872 sess->debug = debuglevel; 881 873 sess->debugcb = defaultdebugcb; 882 883 874 sess->modlistv = NULL; 884 875 sess->snacid_next = 0x00000001; 876 877 sess->locate.userinfo = NULL; 878 sess->locate.torequest = NULL; 879 sess->locate.requested = NULL; 880 sess->locate.waiting_for_response = FALSE; 885 881 sess->ssi.received_data = 0; 886 882 sess->ssi.numitems = 0; … … 890 886 sess->ssi.timestamp = (time_t)0; 891 887 sess->ssi.waiting_for_ack = 0; 892 888 sess->icq_info = NULL; 893 889 sess->authinfo = NULL; 894 890 sess->emailinfo = NULL; 895 896 /* 897 * Default to SNAC login unless XORLOGIN is explicitly set. 898 */ 899 if (!(flags & AIM_SESS_FLAGS_XORLOGIN)) 900 sess->flags |= AIM_SESS_FLAGS_SNACLOGIN; 901 sess->flags |= flags; 891 sess->oft_info = NULL; 902 892 903 893 /* … … 907 897 aim_tx_setenqueue(sess, AIM_TX_QUEUED, NULL); 908 898 909 910 899 /* 911 900 * Register all the modules for this session... 912 901 */ 913 902 aim__registermodule(sess, misc_modfirst); /* load the catch-all first */ 914 aim__registermodule(sess, general_modfirst);903 aim__registermodule(sess, service_modfirst); 915 904 aim__registermodule(sess, locate_modfirst); 916 905 aim__registermodule(sess, buddylist_modfirst); … … 926 915 aim__registermodule(sess, chatnav_modfirst); 927 916 aim__registermodule(sess, chat_modfirst); 928 /* aim__registermodule(sess, odir_modfirst); */ /* kretch */929 /* aim__registermodule(sess, bart_modfirst); */ /* kretch */917 aim__registermodule(sess, odir_modfirst); 918 aim__registermodule(sess, bart_modfirst); 930 919 /* missing 0x11 - 0x12 */ 931 920 aim__registermodule(sess, ssi_modfirst); … … 1058 1047 aim_tx_enqueue(sess, fr); 1059 1048 1049 /* clean out SNACs over 60sec old */ 1050 aim_cleansnacs(sess, 60); 1051 1060 1052 return 0; 1061 1053 } -
libfaim/email.c
re374dee rcf02dd6 19 19 * @return Return 0 if no errors, otherwise return the error number. 20 20 */ 21 faim_export int aim_email_sendcookies(aim_session_t *sess, aim_conn_t *conn) 22 { 21 faim_export int aim_email_sendcookies(aim_session_t *sess) 22 { 23 aim_conn_t *conn; 23 24 aim_frame_t *fr; 24 25 aim_snacid_t snacid; 25 26 26 if (!sess || ! conn)27 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_EML))) 27 28 return -EINVAL; 28 29 … … 81 82 fu8_t *cookie8, *cookie16; 82 83 int tmp, havenewmail = 0; /* Used to tell the client we have _new_ mail */ 84 85 char *alertitle = NULL, *alerturl = NULL; 83 86 84 87 cookie8 = aimbs_getraw(bs, 8); /* Possibly the code used to log you in to mail? */ … … 105 108 new->cookie16 = cookie16; 106 109 107 tlvlist = aim_ readtlvchain_num(bs, aimbs_get16(bs));108 109 tmp = aim_ gettlv16(tlvlist, 0x0080, 1);110 tlvlist = aim_tlvlist_readnum(bs, aimbs_get16(bs)); 111 112 tmp = aim_tlv_get16(tlvlist, 0x0080, 1); 110 113 if (tmp) { 111 114 if (new->nummsgs < tmp) … … 118 121 new->nummsgs++; /* We know we have at least 1 new email */ 119 122 } 120 new->url = aim_ gettlv_str(tlvlist, 0x0007, 1);121 if (!(new->unread = aim_ gettlv8(tlvlist, 0x0081, 1))) {123 new->url = aim_tlv_getstr(tlvlist, 0x0007, 1); 124 if (!(new->unread = aim_tlv_get8(tlvlist, 0x0081, 1))) { 122 125 havenewmail = 0; 123 126 new->nummsgs = 0; 124 127 } 125 new->domain = aim_gettlv_str(tlvlist, 0x0082, 1); 126 new->flag = aim_gettlv16(tlvlist, 0x0084, 1); 127 128 new->domain = aim_tlv_getstr(tlvlist, 0x0082, 1); 129 new->flag = aim_tlv_get16(tlvlist, 0x0084, 1); 130 131 alertitle = aim_tlv_getstr(tlvlist, 0x0005, 1); 132 alerturl = aim_tlv_getstr(tlvlist, 0x000d, 1); 133 128 134 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 129 ret = userfunc(sess, rx, new, havenewmail); 130 131 aim_freetlvchain(&tlvlist); 135 ret = userfunc(sess, rx, new, havenewmail, alertitle, (alerturl ? alerturl + 2 : NULL)); 136 137 aim_tlvlist_free(&tlvlist); 138 139 free(alertitle); 140 free(alerturl); 132 141 133 142 return ret; … … 141 150 * @return Return 0 if no errors, otherwise return the error number. 142 151 */ 143 faim_export int aim_email_activate(aim_session_t *sess, aim_conn_t *conn) 144 { 152 faim_export int aim_email_activate(aim_session_t *sess) 153 { 154 aim_conn_t *conn; 145 155 aim_frame_t *fr; 146 156 aim_snacid_t snacid; 147 157 148 if (!sess || ! conn)158 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_EML))) 149 159 return -EINVAL; 150 160 -
libfaim/ft.c
re374dee rcf02dd6 259 259 return 0; /* not an error */ 260 260 261 if ( addr.sa_family != AF_INET) { /* just in case IPv6 really is happening */261 if ((addr.sa_family != AF_INET) && (addr.sa_family != AF_INET6)) { /* just in case IPv6 really is happening */ 262 262 close(acceptfd); 263 263 aim_conn_close(cur); -
libfaim/icq.c
re374dee rcf02dd6 317 317 318 318 aim_tx_enqueue(sess, fr); 319 320 return 0; 321 } 322 323 /* 324 * Send an SMS message. This is the non-US way. The US-way is to IM 325 * their cell phone number (+19195551234). 326 * 327 * We basically construct and send an XML message. The format is: 328 * <icq_sms_message> 329 * <destination>full_phone_without_leading_+</destination> 330 * <text>message</text> 331 * <codepage>1252</codepage> 332 * <senders_UIN>self_uin</senders_UIN> 333 * <senders_name>self_name</senders_name> 334 * <delivery_receipt>Yes|No</delivery_receipt> 335 * <time>Wkd, DD Mmm YYYY HH:MM:SS TMZ</time> 336 * </icq_sms_message> 337 * 338 * Yeah hi Peter, whaaaat's happening. If there's any way to use 339 * a codepage other than 1252 that would be great. Thaaaanks. 340 */ 341 faim_export int aim_icq_sendsms(aim_session_t *sess, const char *name, const char *msg, const char *alias) 342 { 343 aim_conn_t *conn; 344 aim_frame_t *fr; 345 aim_snacid_t snacid; 346 int bslen, xmllen; 347 char *xml, timestr[30]; 348 time_t t; 349 struct tm *tm; 350 351 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015))) 352 return -EINVAL; 353 354 if (!name || !msg || !alias) 355 return -EINVAL; 356 357 time(&t); 358 tm = gmtime(&t); 359 strftime(timestr, 30, "%a, %d %b %Y %T %Z", tm); 360 361 /* The length of xml included the null terminating character */ 362 xmllen = 225 + strlen(name) + strlen(msg) + strlen(sess->sn) + strlen(alias) + strlen(timestr) + 1; 363 364 if (!(xml = (char *)malloc(xmllen*sizeof(char)))) 365 return -ENOMEM; 366 snprintf(xml, xmllen, "<icq_sms_message>\n" 367 "\t<destination>%s</destination>\n" 368 "\t<text>%s</text>\n" 369 "\t<codepage>1252</codepage>\n" 370 "\t<senders_UIN>%s</senders_UIN>\n" 371 "\t<senders_name>%s</senders_name>\n" 372 "\t<delivery_receipt>Yes</delivery_receipt>\n" 373 "\t<time>%s</time>\n" 374 "</icq_sms_message>\n", 375 name, msg, sess->sn, alias, timestr); 376 377 bslen = 37 + xmllen; 378 379 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen))) { 380 free(xml); 381 return -ENOMEM; 382 } 383 384 snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0); 385 aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid); 386 387 /* For simplicity, don't bother using a tlvlist */ 388 aimbs_put16(&fr->data, 0x0001); 389 aimbs_put16(&fr->data, bslen); 390 391 aimbs_putle16(&fr->data, bslen - 2); 392 aimbs_putle32(&fr->data, atoi(sess->sn)); 393 aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */ 394 aimbs_putle16(&fr->data, snacid); /* eh. */ 395 396 /* From libicq200-0.3.2/src/SNAC-SRV.cpp */ 397 aimbs_putle16(&fr->data, 0x8214); 398 aimbs_put16(&fr->data, 0x0001); 399 aimbs_put16(&fr->data, 0x0016); 400 aimbs_put32(&fr->data, 0x00000000); 401 aimbs_put32(&fr->data, 0x00000000); 402 aimbs_put32(&fr->data, 0x00000000); 403 aimbs_put32(&fr->data, 0x00000000); 404 405 aimbs_put16(&fr->data, 0x0000); 406 aimbs_put16(&fr->data, xmllen); 407 aimbs_putraw(&fr->data, xml, xmllen); 408 409 aim_tx_enqueue(sess, fr); 410 411 free(xml); 319 412 320 413 return 0; … … 368 461 fu16_t cmdlen, cmd, reqid; 369 462 370 if (!(tl = aim_ readtlvchain(bs)) || !(datatlv = aim_gettlv(tl, 0x0001, 1))) {371 aim_ freetlvchain(&tl);463 if (!(tl = aim_tlvlist_read(bs)) || !(datatlv = aim_tlv_gettlv(tl, 0x0001, 1))) { 464 aim_tlvlist_free(&tl); 372 465 faimdprintf(sess, 0, "corrupt ICQ response\n"); 373 466 return 0; … … 549 642 } 550 643 551 aim_ freetlvchain(&tl);644 aim_tlvlist_free(&tl); 552 645 553 646 return ret; -
libfaim/im.c
re374dee rcf02dd6 167 167 return -EINVAL; 168 168 169 return aim_genericreq_n (sess, conn, 0x0004, 0x0004);169 return aim_genericreq_n_snacid(sess, conn, 0x0004, 0x0004); 170 170 } 171 171 … … 390 390 aim_tx_enqueue(sess, fr); 391 391 392 /* Move this to receive aim_flap_nop and send aim_flap_nop */ 393 if (!(sess->flags & AIM_SESS_FLAGS_DONTTIMEOUTONICBM)) 394 aim_cleansnacs(sess, 60); /* clean out SNACs over 60sec old */ 392 /* clean out SNACs over 60sec old */ 393 aim_cleansnacs(sess, 60); 395 394 396 395 return 0; … … 633 632 aim_im_puticbm(&fr->data, ck, 0x0002, sn); 634 633 635 aim_ addtlvtochain_noval(&tl, 0x0003);634 aim_tlvlist_add_noval(&tl, 0x0003); 636 635 637 636 hdrlen = 2+8+16+6+8+6+4; … … 643 642 aim_putcap(&hdrbs, AIM_CAPS_DIRECTIM); 644 643 645 aim_ addtlvtochain16(&itl, 0x000a, 0x0001);646 aim_ addtlvtochain_raw(&itl, 0x0003, 4, ip);647 aim_ addtlvtochain16(&itl, 0x0005, port);648 aim_ addtlvtochain_noval(&itl, 0x000f);644 aim_tlvlist_add_16(&itl, 0x000a, 0x0001); 645 aim_tlvlist_add_raw(&itl, 0x0003, 4, ip); 646 aim_tlvlist_add_16(&itl, 0x0005, port); 647 aim_tlvlist_add_noval(&itl, 0x000f); 649 648 650 aim_ writetlvchain(&hdrbs, &itl);651 652 aim_ addtlvtochain_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);653 654 aim_ writetlvchain(&fr->data, &tl);649 aim_tlvlist_write(&hdrbs, &itl); 650 651 aim_tlvlist_add_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); 652 653 aim_tlvlist_write(&fr->data, &tl); 655 654 656 655 free(hdr); 657 aim_ freetlvchain(&itl);658 aim_ freetlvchain(&tl);656 aim_tlvlist_free(&itl); 657 aim_tlvlist_free(&tl); 659 658 660 659 aim_tx_enqueue(sess, fr); … … 688 687 aim_bstream_t bs; 689 688 690 aim_ addtlvtochain16(&subtl, 0x000a, 0x0001);691 aim_ addtlvtochain_noval(&subtl, 0x000f);692 /* aim_ addtlvtochain_raw(&subtl, 0x000e, 2, "en");693 aim_ addtlvtochain_raw(&subtl, 0x000d, 8, "us-ascii");694 aim_ addtlvtochain_raw(&subtl, 0x000c, 24, "Please accept this file."); */689 aim_tlvlist_add_16(&subtl, 0x000a, 0x0001); 690 aim_tlvlist_add_noval(&subtl, 0x000f); 691 /* aim_tlvlist_add_raw(&subtl, 0x000e, 2, "en"); 692 aim_tlvlist_add_raw(&subtl, 0x000d, 8, "us-ascii"); 693 aim_tlvlist_add_raw(&subtl, 0x000c, 24, "Please accept this file."); */ 695 694 if (oft_info->clientip) { 696 695 fu8_t ip[4]; … … 703 702 i++; 704 703 } 705 aim_ addtlvtochain_raw(&subtl, 0x0003, 4, ip);704 aim_tlvlist_add_raw(&subtl, 0x0003, 4, ip); 706 705 } 707 aim_ addtlvtochain16(&subtl, 0x0005, oft_info->port);706 aim_tlvlist_add_16(&subtl, 0x0005, oft_info->port); 708 707 709 708 /* TLV t(2711) */ … … 719 718 aimbs_put8(&bs, 0x00); 720 719 721 aim_ addtlvtochain_raw(&subtl, 0x2711, bs.len, bs.data);720 aim_tlvlist_add_raw(&subtl, 0x2711, bs.len, bs.data); 722 721 free(buf); 723 722 } … … 729 728 730 729 /* TLV t(0005) - Encompasses everything from above. Gee. */ 731 buflen = 2+8+16+aim_ sizetlvchain(&subtl);730 buflen = 2+8+16+aim_tlvlist_size(&subtl); 732 731 buf = malloc(buflen); 733 732 aim_bstream_init(&bs, buf, buflen); … … 735 734 aimbs_putraw(&bs, oft_info->cookie, 8); 736 735 aim_putcap(&bs, AIM_CAPS_SENDFILE); 737 aim_ writetlvchain(&bs, &subtl);738 aim_ freetlvchain(&subtl);739 aim_ addtlvtochain_raw(&tl, 0x0005, bs.len, bs.data);736 aim_tlvlist_write(&bs, &subtl); 737 aim_tlvlist_free(&subtl); 738 aim_tlvlist_add_raw(&tl, 0x0005, bs.len, bs.data); 740 739 free(buf); 741 740 742 741 /* TLV t(0003) - Request an ack */ 743 aim_ addtlvtochain_noval(&tl, 0x0003);744 } 745 746 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + aim_ sizetlvchain(&tl))))742 aim_tlvlist_add_noval(&tl, 0x0003); 743 } 744 745 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + aim_tlvlist_size(&tl)))) 747 746 return -ENOMEM; 748 747 … … 754 753 755 754 /* All that crap from above (the 0x0005 TLV and the 0x0003 TLV) */ 756 aim_ writetlvchain(&fr->data, &tl);757 aim_ freetlvchain(&tl);755 aim_tlvlist_write(&fr->data, &tl); 756 aim_tlvlist_free(&tl); 758 757 759 758 aim_tx_enqueue(sess, fr); … … 1033 1032 sn = aimbs_getstr(bs, snlen); 1034 1033 1035 tlvlist = aim_ readtlvchain(bs);1036 1037 if (aim_ gettlv(tlvlist, 0x0003, 1))1034 tlvlist = aim_tlvlist_read(bs); 1035 1036 if (aim_tlv_gettlv(tlvlist, 0x0003, 1)) 1038 1037 icbmflags |= AIM_IMFLAGS_ACK; 1039 if (aim_ gettlv(tlvlist, 0x0004, 1))1038 if (aim_tlv_gettlv(tlvlist, 0x0004, 1)) 1040 1039 icbmflags |= AIM_IMFLAGS_AWAY; 1041 1040 1042 if ((msgblock = aim_ gettlv(tlvlist, 0x0002, 1))) {1041 if ((msgblock = aim_tlv_gettlv(tlvlist, 0x0002, 1))) { 1043 1042 aim_bstream_t mbs; 1044 1043 int featurelen, msglen; … … 1065 1064 1066 1065 free(sn); 1067 aim_ freetlvchain(&tlvlist);1066 aim_tlvlist_free(&tlvlist); 1068 1067 1069 1068 return ret; … … 1655 1654 * There's another block of TLVs embedded in the type 5 here. 1656 1655 */ 1657 block1 = aim_ gettlv(tlvlist, 0x0005, 1);1656 block1 = aim_tlv_gettlv(tlvlist, 0x0005, 1); 1658 1657 aim_bstream_init(&bbs, block1->value, block1->length); 1659 1658 … … 1678 1677 * identify what type of rendezvous this is. 1679 1678 */ 1680 args.reqclass = aim_ getcap(sess, &bbs, 0x10);1679 args.reqclass = aim_locate_getcaps(sess, &bbs, 0x10); 1681 1680 1682 1681 /* … … 1686 1685 * Ack packets for instance have nothing more to them. 1687 1686 */ 1688 list2 = aim_ readtlvchain(&bbs);1687 list2 = aim_tlvlist_read(&bbs); 1689 1688 1690 1689 /* … … 1693 1692 * XXX - I don't like this. Maybe just read in an int? Or inet_ntoa... 1694 1693 */ 1695 if (aim_ gettlv(list2, 0x0002, 1)) {1694 if (aim_tlv_gettlv(list2, 0x0002, 1)) { 1696 1695 aim_tlv_t *iptlv; 1697 1696 1698 iptlv = aim_ gettlv(list2, 0x0002, 1);1697 iptlv = aim_tlv_gettlv(list2, 0x0002, 1); 1699 1698 if (iptlv->length == 4) 1700 snprintf(proxyip, sizeof(proxyip), "%hh d.%hhd.%hhd.%hhd",1699 snprintf(proxyip, sizeof(proxyip), "%hhu.%hhu.%hhu.%hhu", 1701 1700 iptlv->value[0], iptlv->value[1], 1702 1701 iptlv->value[2], iptlv->value[3]); … … 1706 1705 * IP address from the perspective of the client. 1707 1706 */ 1708 if (aim_ gettlv(list2, 0x0003, 1)) {1707 if (aim_tlv_gettlv(list2, 0x0003, 1)) { 1709 1708 aim_tlv_t *iptlv; 1710 1709 1711 iptlv = aim_ gettlv(list2, 0x0003, 1);1710 iptlv = aim_tlv_gettlv(list2, 0x0003, 1); 1712 1711 if (iptlv->length == 4) 1713 snprintf(clientip, sizeof(clientip), "%hh d.%hhd.%hhd.%hhd",1712 snprintf(clientip, sizeof(clientip), "%hhu.%hhu.%hhu.%hhu", 1714 1713 iptlv->value[0], iptlv->value[1], 1715 1714 iptlv->value[2], iptlv->value[3]); … … 1721 1720 * This is added by the server. 1722 1721 */ 1723 if (aim_ gettlv(list2, 0x0004, 1)) {1722 if (aim_tlv_gettlv(list2, 0x0004, 1)) { 1724 1723 aim_tlv_t *iptlv; 1725 1724 1726 iptlv = aim_ gettlv(list2, 0x0004, 1);1725 iptlv = aim_tlv_gettlv(list2, 0x0004, 1); 1727 1726 if (iptlv->length == 4) 1728 snprintf(verifiedip, sizeof(verifiedip), "%hh d.%hhd.%hhd.%hhd",1727 snprintf(verifiedip, sizeof(verifiedip), "%hhu.%hhu.%hhu.%hhu", 1729 1728 iptlv->value[0], iptlv->value[1], 1730 1729 iptlv->value[2], iptlv->value[3]); … … 1734 1733 * Port number for something. 1735 1734 */ 1736 if (aim_ gettlv(list2, 0x0005, 1))1737 args.port = aim_ gettlv16(list2, 0x0005, 1);1735 if (aim_tlv_gettlv(list2, 0x0005, 1)) 1736 args.port = aim_tlv_get16(list2, 0x0005, 1); 1738 1737 1739 1738 /* … … 1742 1741 * 0x0002 - "I will accept this file from you" 1743 1742 */ 1744 if (aim_ gettlv(list2, 0x000a, 1))1743 if (aim_tlv_gettlv(list2, 0x000a, 1)) 1745 1744 ; 1746 1745 … … 1748 1747 * Error code. 1749 1748 */ 1750 if (aim_ gettlv(list2, 0x000b, 1))1751 args.errorcode = aim_ gettlv16(list2, 0x000b, 1);1749 if (aim_tlv_gettlv(list2, 0x000b, 1)) 1750 args.errorcode = aim_tlv_get16(list2, 0x000b, 1); 1752 1751 1753 1752 /* 1754 1753 * Invitation message / chat description. 1755 1754 */ 1756 if (aim_ gettlv(list2, 0x000c, 1))1757 args.msg = aim_ gettlv_str(list2, 0x000c, 1);1755 if (aim_tlv_gettlv(list2, 0x000c, 1)) 1756 args.msg = aim_tlv_getstr(list2, 0x000c, 1); 1758 1757 1759 1758 /* 1760 1759 * Character set. 1761 1760 */ 1762 if (aim_ gettlv(list2, 0x000d, 1))1763 args.encoding = aim_ gettlv_str(list2, 0x000d, 1);1761 if (aim_tlv_gettlv(list2, 0x000d, 1)) 1762 args.encoding = aim_tlv_getstr(list2, 0x000d, 1); 1764 1763 1765 1764 /* 1766 1765 * Language. 1767 1766 */ 1768 if (aim_ gettlv(list2, 0x000e, 1))1769 args.language = aim_ gettlv_str(list2, 0x000e, 1);1767 if (aim_tlv_gettlv(list2, 0x000e, 1)) 1768 args.language = aim_tlv_getstr(list2, 0x000e, 1); 1770 1769 1771 1770 /* … … 1774 1773 * Maybe means we should connect directly to transfer the file? 1775 1774 */ 1776 if (aim_ gettlv(list2, 0x000f, 1))1775 if (aim_tlv_gettlv(list2, 0x000f, 1)) 1777 1776 ; 1778 1777 … … 1782 1781 * Maybe means we should proxy the file transfer through an AIM server? 1783 1782 */ 1784 if (aim_ gettlv(list2, 0x0010, 1))1783 if (aim_tlv_gettlv(list2, 0x0010, 1)) 1785 1784 ; 1786 1785 … … 1798 1797 * Service Data blocks are module-specific in format. 1799 1798 */ 1800 if ((servdatatlv = aim_ gettlv(list2, 0x2711 /* 10001 */, 1))) {1799 if ((servdatatlv = aim_tlv_gettlv(list2, 0x2711 /* 10001 */, 1))) { 1801 1800 1802 1801 aim_bstream_init(&sdbs, servdatatlv->value, servdatatlv->length); … … 1832 1831 free((char *)args.language); 1833 1832 1834 aim_ freetlvchain(&list2);1833 aim_tlvlist_free(&list2); 1835 1834 1836 1835 return ret; … … 1848 1847 * Make a bstream for the meaty part. Yum. Meat. 1849 1848 */ 1850 if (!(block = aim_ gettlv(tlvlist, 0x0005, 1)))1849 if (!(block = aim_tlv_gettlv(tlvlist, 0x0005, 1))) 1851 1850 return -1; 1852 1851 aim_bstream_init(&meat, block->value, block->length); … … 1947 1946 * further data is derived from what is parsed here. 1948 1947 */ 1949 tlvlist = aim_ readtlvchain(bs);1948 tlvlist = aim_tlvlist_read(bs); 1950 1949 1951 1950 ret = incomingim_ch2(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie); 1952 1951 1953 aim_ freetlvchain(&tlvlist);1952 aim_tlvlist_free(&tlvlist); 1954 1953 1955 1954 } else if (channel == 4) { 1956 1955 aim_tlvlist_t *tlvlist; 1957 1956 1958 tlvlist = aim_ readtlvchain(bs);1957 tlvlist = aim_tlvlist_read(bs); 1959 1958 ret = incomingim_ch4(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie); 1960 aim_ freetlvchain(&tlvlist);1959 aim_tlvlist_free(&tlvlist); 1961 1960 1962 1961 } else { … … 2056 2055 aimbs_putraw(&fr->data, sender, strlen(sender)); 2057 2056 2058 aim_ addtlvtochain16(&tl, 0x0003, code);2059 aim_ writetlvchain(&fr->data, &tl);2060 aim_ freetlvchain(&tl);2057 aim_tlvlist_add_16(&tl, 0x0003, code); 2058 aim_tlvlist_write(&fr->data, &tl); 2059 aim_tlvlist_free(&tl); 2061 2060 2062 2061 aim_tx_enqueue(sess, fr); -
libfaim/misc.c
r862371b rcf02dd6 12 12 /* 13 13 * Generic routine for sending commands. 14 *15 14 * 16 15 * I know I can do this in a smarter way...but I'm not thinking straight -
libfaim/odir.c
r07ab1cb rcf02dd6 31 31 32 32 /* Create a TLV chain, write it to the outgoing frame, then free the chain */ 33 aim_ addtlvtochain_raw(&tl, 0x001c, strlen(region), region);34 aim_ addtlvtochain16(&tl, 0x000a, 0x0001); /* Type of search */35 aim_ addtlvtochain_raw(&tl, 0x0005, strlen(email), email);36 37 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_ sizetlvchain(&tl))))33 aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region); 34 aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */ 35 aim_tlvlist_add_raw(&tl, 0x0005, strlen(email), email); 36 37 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl)))) 38 38 return -ENOMEM; 39 39 snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0); 40 40 aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid); 41 41 42 aim_ writetlvchain(&fr->data, &tl);43 aim_ freetlvchain(&tl);42 aim_tlvlist_write(&fr->data, &tl); 43 aim_tlvlist_free(&tl); 44 44 45 45 aim_tx_enqueue(sess, fr); … … 80 80 81 81 /* Create a TLV chain, write it to the outgoing frame, then free the chain */ 82 aim_ addtlvtochain_raw(&tl, 0x001c, strlen(region), region);83 aim_ addtlvtochain16(&tl, 0x000a, 0x0000); /* Type of search */82 aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region); 83 aim_tlvlist_add_16(&tl, 0x000a, 0x0000); /* Type of search */ 84 84 if (first) 85 aim_ addtlvtochain_raw(&tl, 0x0001, strlen(first), first);85 aim_tlvlist_add_raw(&tl, 0x0001, strlen(first), first); 86 86 if (last) 87 aim_ addtlvtochain_raw(&tl, 0x0002, strlen(last), last);87 aim_tlvlist_add_raw(&tl, 0x0002, strlen(last), last); 88 88 if (middle) 89 aim_ addtlvtochain_raw(&tl, 0x0003, strlen(middle), middle);89 aim_tlvlist_add_raw(&tl, 0x0003, strlen(middle), middle); 90 90 if (maiden) 91 aim_ addtlvtochain_raw(&tl, 0x0004, strlen(maiden), maiden);91 aim_tlvlist_add_raw(&tl, 0x0004, strlen(maiden), maiden); 92 92 if (country) 93 aim_ addtlvtochain_raw(&tl, 0x0006, strlen(country), country);93 aim_tlvlist_add_raw(&tl, 0x0006, strlen(country), country); 94 94 if (state) 95 aim_ addtlvtochain_raw(&tl, 0x0007, strlen(state), state);95 aim_tlvlist_add_raw(&tl, 0x0007, strlen(state), state); 96 96 if (city) 97 aim_ addtlvtochain_raw(&tl, 0x0008, strlen(city), city);97 aim_tlvlist_add_raw(&tl, 0x0008, strlen(city), city); 98 98 if (nick) 99 aim_ addtlvtochain_raw(&tl, 0x000c, strlen(nick), nick);99 aim_tlvlist_add_raw(&tl, 0x000c, strlen(nick), nick); 100 100 if (zip) 101 aim_ addtlvtochain_raw(&tl, 0x000d, strlen(zip), zip);101 aim_tlvlist_add_raw(&tl, 0x000d, strlen(zip), zip); 102 102 if (address) 103 aim_ addtlvtochain_raw(&tl, 0x0021, strlen(address), address);104 105 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_ sizetlvchain(&tl))))103 aim_tlvlist_add_raw(&tl, 0x0021, strlen(address), address); 104 105 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl)))) 106 106 return -ENOMEM; 107 107 snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0); 108 108 aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid); 109 109 110 aim_ writetlvchain(&fr->data, &tl);111 aim_ freetlvchain(&tl);110 aim_tlvlist_write(&fr->data, &tl); 111 aim_tlvlist_free(&tl); 112 112 113 113 aim_tx_enqueue(sess, fr); … … 135 135 136 136 /* Create a TLV chain, write it to the outgoing frame, then free the chain */ 137 aim_ addtlvtochain_raw(&tl, 0x001c, strlen(region), region);138 aim_ addtlvtochain16(&tl, 0x000a, 0x0001); /* Type of search */137 aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region); 138 aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */ 139 139 if (interest) 140 aim_ addtlvtochain_raw(&tl, 0x0001, strlen(interest), interest);141 142 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_ sizetlvchain(&tl))))140 aim_tlvlist_add_raw(&tl, 0x0001, strlen(interest), interest); 141 142 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl)))) 143 143 return -ENOMEM; 144 144 snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0); 145 145 aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid); 146 146 147 aim_ writetlvchain(&fr->data, &tl);148 aim_ freetlvchain(&tl);147 aim_tlvlist_write(&fr->data, &tl); 148 aim_tlvlist_free(&tl); 149 149 150 150 aim_tx_enqueue(sess, fr); … … 174 174 while (numresults) { 175 175 struct aim_odir *new; 176 aim_tlvlist_t *tl = aim_ readtlvchain_num(bs, aimbs_get16(bs));176 aim_tlvlist_t *tl = aim_tlvlist_readnum(bs, aimbs_get16(bs)); 177 177 new = (struct aim_odir *)malloc(sizeof(struct aim_odir)); 178 new->first = aim_ gettlv_str(tl, 0x0001, 1);179 new->last = aim_ gettlv_str(tl, 0x0002, 1);180 new->middle = aim_ gettlv_str(tl, 0x0003, 1);181 new->maiden = aim_ gettlv_str(tl, 0x0004, 1);182 new->email = aim_ gettlv_str(tl, 0x0005, 1);183 new->country = aim_ gettlv_str(tl, 0x0006, 1);184 new->state = aim_ gettlv_str(tl, 0x0007, 1);185 new->city = aim_ gettlv_str(tl, 0x0008, 1);186 new->sn = aim_ gettlv_str(tl, 0x0009, 1);187 new->interest = aim_ gettlv_str(tl, 0x000b, 1);188 new->nick = aim_ gettlv_str(tl, 0x000c, 1);189 new->zip = aim_ gettlv_str(tl, 0x000d, 1);190 new->region = aim_ gettlv_str(tl, 0x001c, 1);191 new->address = aim_ gettlv_str(tl, 0x0021, 1);178 new->first = aim_tlv_getstr(tl, 0x0001, 1); 179 new->last = aim_tlv_getstr(tl, 0x0002, 1); 180 new->middle = aim_tlv_getstr(tl, 0x0003, 1); 181 new->maiden = aim_tlv_getstr(tl, 0x0004, 1); 182 new->email = aim_tlv_getstr(tl, 0x0005, 1); 183 new->country = aim_tlv_getstr(tl, 0x0006, 1); 184 new->state = aim_tlv_getstr(tl, 0x0007, 1); 185 new->city = aim_tlv_getstr(tl, 0x0008, 1); 186 new->sn = aim_tlv_getstr(tl, 0x0009, 1); 187 new->interest = aim_tlv_getstr(tl, 0x000b, 1); 188 new->nick = aim_tlv_getstr(tl, 0x000c, 1); 189 new->zip = aim_tlv_getstr(tl, 0x000d, 1); 190 new->region = aim_tlv_getstr(tl, 0x001c, 1); 191 new->address = aim_tlv_getstr(tl, 0x0021, 1); 192 192 new->next = results; 193 193 results = new; -
libfaim/oscar.c
r07ab1cb rcf02dd6 31 31 #include "buddyicon.h" 32 32 #include "conversation.h" 33 #include "core.h" 33 34 #include "debug.h" 34 35 #include "ft.h" … … 41 42 #include "request.h" 42 43 #include "util.h" 43 #include "html.h"44 44 45 45 #include "aim.h" 46 46 #include "md5.h" 47 48 /* XXX CORE/UI */49 #include "gtkinternal.h"50 #include "gaim.h"51 52 47 53 48 #define UC_AOL 0x02 … … 61 56 #define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3" 62 57 58 #define OSCAR_CONNECT_STEPS 6 59 63 60 static GaimPlugin *my_protocol = NULL; 64 61 65 static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE ;66 static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE ;62 static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT; 63 static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT; 67 64 68 65 static fu8_t features_aim[] = {0x01, 0x01, 0x01, 0x02}; 69 66 static fu8_t features_icq[] = {0x01, 0x06}; 70 67 71 struct oscar_data { 68 typedef struct _OscarData OscarData; 69 struct _OscarData { 72 70 aim_session_t *sess; 73 71 aim_conn_t *conn; … … 101 99 gboolean killme; 102 100 gboolean icq; 103 GSList *evilhack;104 101 guint icontimer; 105 102 guint getblisttimer; … … 151 148 }; 152 149 153 /* Various PRPL-specific buddy info that we want to keep track of */ 150 /* 151 * Various PRPL-specific buddy info that we want to keep track of 152 * Some other info is maintained by locate.c, and I'd like to move 153 * the rest of this to libfaim, mostly im.c 154 */ 154 155 struct buddyinfo { 155 time_t signon;156 int caps;157 156 gboolean typingnot; 158 157 gchar *availmsg; … … 168 167 time_t ico_time; 169 168 gboolean ico_need; 170 171 fu16_t iconcsumlen; 172 fu8_t *iconcsum; 169 gboolean ico_sent; 173 170 }; 174 171 … … 219 216 static int gaim_parse_misses (aim_session_t *, aim_frame_t *, ...); 220 217 static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...); 221 static int gaim_parse_user _info(aim_session_t *, aim_frame_t *, ...);218 static int gaim_parse_userinfo (aim_session_t *, aim_frame_t *, ...); 222 219 static int gaim_parse_motd (aim_session_t *, aim_frame_t *, ...); 223 220 static int gaim_chatnav_info (aim_session_t *, aim_frame_t *, ...); 224 static int gaim_c hat_join (aim_session_t *, aim_frame_t *, ...);225 static int gaim_c hat_leave (aim_session_t *, aim_frame_t *, ...);226 static int gaim_c hat_info_update (aim_session_t *, aim_frame_t *, ...);227 static int gaim_c hat_incoming_msg(aim_session_t *, aim_frame_t *, ...);221 static int gaim_conv_chat_join (aim_session_t *, aim_frame_t *, ...); 222 static int gaim_conv_chat_leave (aim_session_t *, aim_frame_t *, ...); 223 static int gaim_conv_chat_info_update (aim_session_t *, aim_frame_t *, ...); 224 static int gaim_conv_chat_incoming_msg(aim_session_t *, aim_frame_t *, ...); 228 225 static int gaim_email_parseupdate(aim_session_t *, aim_frame_t *, ...); 229 226 static int gaim_icon_error (aim_session_t *, aim_frame_t *, ...); … … 284 281 285 282 /* prpl actions - remove this at some point */ 283 /* Because I don't like forward declarations? I think that was why... */ 286 284 static void oscar_set_info(GaimConnection *gc, const char *text); 287 285 … … 295 293 struct buddyinfo *bi = data; 296 294 g_free(bi->availmsg); 297 g_free(bi->iconcsum);298 295 g_free(bi); 299 296 } … … 384 381 } 385 382 386 static struct direct_im *find_direct_im( struct oscar_data *od, const char *who) {383 static struct direct_im *find_direct_im(OscarData *od, const char *who) { 387 384 GSList *d = od->direct_ims; 388 385 struct direct_im *m = NULL; … … 428 425 429 426 static struct chat_connection *find_oscar_chat(GaimConnection *gc, int id) { 430 GSList *g = (( struct oscar_data *)gc->proto_data)->oscar_chats;427 GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; 431 428 struct chat_connection *c = NULL; 432 429 … … 444 441 static struct chat_connection *find_oscar_chat_by_conn(GaimConnection *gc, 445 442 aim_conn_t *conn) { 446 GSList *g = (( struct oscar_data *)gc->proto_data)->oscar_chats;443 GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; 447 444 struct chat_connection *c = NULL; 448 445 … … 460 457 static void gaim_odc_disconnect(aim_session_t *sess, aim_conn_t *conn) { 461 458 GaimConnection *gc = sess->aux_data; 462 struct oscar_data *od = (struct oscar_data *)gc->proto_data;459 OscarData *od = (OscarData *)gc->proto_data; 463 460 GaimConversation *cnv; 464 461 struct direct_im *dim; … … 496 493 aim_session_t *sess = aim_conn_getsess(conn); 497 494 GaimConnection *gc = sess ? sess->aux_data : NULL; 498 struct oscar_data *od;495 OscarData *od; 499 496 500 497 if (!gc) { 501 /* gc is null. we return, else we seg SIGSEG on next line. */502 498 gaim_debug(GAIM_DEBUG_INFO, "oscar", 503 499 "oscar callback for closed connection (1).\n"); … … 505 501 } 506 502 507 od = ( struct oscar_data *)gc->proto_data;503 od = (OscarData *)gc->proto_data; 508 504 509 505 if (!g_list_find(gaim_connections_get_all(), gc)) { … … 606 602 607 603 static void oscar_debug(aim_session_t *sess, int level, const char *format, va_list va) { 608 char *s = g_strdup_vprintf(format, va);609 char buf[256];610 char *t;611 604 GaimConnection *gc = sess->aux_data; 612 613 g_snprintf(buf, sizeof(buf), "%s %d: ", gaim_account_get_username(gaim_connection_get_account(gc)), level); 614 t = g_strconcat(buf, s, NULL); 615 gaim_debug(GAIM_DEBUG_INFO, "oscar", t); 616 if (t[strlen(t)-1] != '\n') 605 gchar *s = g_strdup_vprintf(format, va); 606 gchar *buf; 607 608 buf = g_strdup_printf("%s %d: %s", gaim_account_get_username(gaim_connection_get_account(gc)), level, s); 609 gaim_debug(GAIM_DEBUG_INFO, "oscar", buf); 610 if (buf[strlen(buf)-1] != '\n') 617 611 gaim_debug(GAIM_DEBUG_INFO, NULL, "\n"); 618 g_free( t);612 g_free(buf); 619 613 g_free(s); 620 614 } … … 623 617 { 624 618 GaimConnection *gc = data; 625 struct oscar_data *od;619 OscarData *od; 626 620 aim_session_t *sess; 627 621 aim_conn_t *conn; … … 635 629 sess = od->sess; 636 630 conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); 637 638 631 conn->fd = source; 639 632 … … 645 638 aim_conn_completeconnect(sess, conn); 646 639 gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, oscar_callback, conn); 640 aim_request_login(sess, conn, gaim_account_get_username(gaim_connection_get_account(gc))); 641 647 642 gaim_debug(GAIM_DEBUG_INFO, "oscar", 648 "Password sent, waiting for response\n"); 643 "Screen name sent, waiting for response\n"); 644 gaim_connection_update_progress(gc, _("Screen name sent"), 1, OSCAR_CONNECT_STEPS); 649 645 } 650 646 … … 652 648 aim_session_t *sess; 653 649 aim_conn_t *conn; 654 char buf[256];655 650 GaimConnection *gc = gaim_account_get_connection(account); 656 struct oscar_data *od = gc->proto_data = g_new0(struct oscar_data, 1);651 OscarData *od = gc->proto_data = g_new0(OscarData, 1); 657 652 658 653 gaim_debug(GAIM_DEBUG_MISC, "oscar", "oscar_login: gc = %p\n", gc); … … 667 662 668 663 sess = g_new0(aim_session_t, 1); 669 670 aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 0); 664 aim_session_init(sess, TRUE, 0); 671 665 aim_setdebuggingcb(sess, oscar_debug); 672 673 /* we need an immediate queue because we don't use a while-loop to 674 * see if things need to be sent. */ 666 /* 667 * We need an immediate queue because we don't use a while-loop 668 * to see if things need to be sent. 669 */ 675 670 aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL); 676 671 od->sess = sess; … … 685 680 } 686 681 687 g_snprintf(buf, sizeof(buf), _("Signon: %s"), gaim_account_get_username(account));688 gaim_connection_update_progress(gc, buf, 2, 5);689 690 682 aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0); 691 683 aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); … … 699 691 return; 700 692 } 701 aim_request_login(sess, conn, gaim_account_get_username(account)); 693 694 gaim_connection_update_progress(gc, _("Connecting"), 0, OSCAR_CONNECT_STEPS); 702 695 } 703 696 704 697 static void oscar_close(GaimConnection *gc) { 705 struct oscar_data *od = (struct oscar_data *)gc->proto_data;698 OscarData *od = (OscarData *)gc->proto_data; 706 699 707 700 while (od->oscar_chats) { … … 733 726 } 734 727 g_hash_table_destroy(od->buddyinfo); 735 while (od->evilhack) {736 g_free(od->evilhack->data);737 od->evilhack = g_slist_remove(od->evilhack, od->evilhack->data);738 }739 728 while (od->create_rooms) { 740 729 struct create_room *cr = od->create_rooms->data; … … 773 762 static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) { 774 763 GaimConnection *gc = data; 775 struct oscar_data *od;764 OscarData *od; 776 765 aim_session_t *sess; 777 766 aim_conn_t *bosconn; … … 794 783 aim_conn_completeconnect(sess, bosconn); 795 784 gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, oscar_callback, bosconn); 785 796 786 gaim_connection_update_progress(gc, 797 _("Connection established, cookie sent"), 4, 5);787 _("Connection established, cookie sent"), 4, OSCAR_CONNECT_STEPS); 798 788 } 799 789 … … 834 824 struct aim_oft_info *oft_info = xfer->data; 835 825 GaimConnection *gc = oft_info->sess->aux_data; 836 struct oscar_data *od = gc->proto_data;826 OscarData *od = gc->proto_data; 837 827 838 828 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) { … … 900 890 struct aim_oft_info *oft_info = xfer->data; 901 891 GaimConnection *gc = oft_info->sess->aux_data; 902 struct oscar_data *od = gc->proto_data;892 OscarData *od = gc->proto_data; 903 893 904 894 gaim_debug(GAIM_DEBUG_INFO, "oscar", "AAA - in oscar_xfer_end\n"); … … 919 909 struct aim_oft_info *oft_info = xfer->data; 920 910 GaimConnection *gc = oft_info->sess->aux_data; 921 struct oscar_data *od = gc->proto_data;911 OscarData *od = gc->proto_data; 922 912 923 913 gaim_debug(GAIM_DEBUG_INFO, "oscar", … … 936 926 struct aim_oft_info *oft_info = xfer->data; 937 927 GaimConnection *gc = oft_info->sess->aux_data; 938 struct oscar_data *od = gc->proto_data;928 OscarData *od = gc->proto_data; 939 929 940 930 gaim_debug(GAIM_DEBUG_INFO, "oscar", … … 1007 997 1008 998 static void oscar_ask_sendfile(GaimConnection *gc, const char *destsn) { 1009 struct oscar_data *od = (struct oscar_data *)gc->proto_data;999 OscarData *od = (OscarData *)gc->proto_data; 1010 1000 GaimXfer *xfer; 1011 1001 struct aim_oft_info *oft_info; … … 1038 1028 static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { 1039 1029 GaimConnection *gc = sess->aux_data; 1040 struct oscar_data *od = gc->proto_data;1030 OscarData *od = gc->proto_data; 1041 1031 GaimAccount *account = gc->account; 1042 1032 aim_conn_t *bosconn; … … 1136 1126 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0); 1137 1127 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parse_mtn, 0); 1138 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_user _info, 0);1128 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_userinfo, 0); 1139 1129 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0); 1140 1130 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); … … 1163 1153 #endif 1164 1154 1165 ((struct oscar_data *)gc->proto_data)->conn = bosconn;1155 od->conn = bosconn; 1166 1156 for (i = 0; i < (int)strlen(info->bosip); i++) { 1167 1157 if (info->bosip[i] == ':') { … … 1182 1172 gaim_input_remove(gc->inpa); 1183 1173 1174 gaim_connection_update_progress(gc, _("Received authorization"), 3, OSCAR_CONNECT_STEPS); 1175 1184 1176 return 1; 1185 1177 } 1186 1178 1179 /* XXX - Should use gaim_url_fetch for the below stuff */ 1187 1180 struct pieceofcrap { 1188 1181 GaimConnection *gc; … … 1198 1191 { 1199 1192 struct pieceofcrap *pos = data; 1200 struct oscar_data *od = pos->gc->proto_data;1193 OscarData *od = pos->gc->proto_data; 1201 1194 char in = '\0'; 1202 1195 int x = 0; … … 1217 1210 "this is fixed. Check %s for updates."), GAIM_WEBSITE); 1218 1211 gaim_notify_warning(pos->gc, NULL, 1219 _("Gaim was Unable to get a valid AIM login hash."),1212 _("Gaim was unable to get a valid AIM login hash."), 1220 1213 buf); 1221 1214 gaim_input_remove(pos->inpa); … … 1247 1240 "this is fixed. Check %s for updates."), GAIM_WEBSITE); 1248 1241 gaim_notify_warning(pos->gc, NULL, 1249 _("Gaim was Unable to get a valid AIM login hash."),1242 _("Gaim was unable to get a valid AIM login hash."), 1250 1243 buf); 1251 1244 g_free(buf); … … 1335 1328 "this is fixed. Check %s for updates."), GAIM_WEBSITE); 1336 1329 gaim_notify_warning(pos->gc, NULL, 1337 _("Gaim was Unable to get a valid login hash."),1330 _("Gaim was unable to get a valid login hash."), 1338 1331 buf); 1339 1332 } … … 1343 1336 1344 1337 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { 1345 char *key;1346 va_list ap;1347 1338 GaimConnection *gc = sess->aux_data; 1339 OscarData *od = gc->proto_data; 1348 1340 GaimAccount *account = gaim_connection_get_account(gc); 1349 1341 GaimAccount *ac = gaim_connection_get_account(gc); 1350 struct oscar_data *od = gc->proto_data; 1342 #if 0 1343 struct client_info_s info = {"gaim", 7, 3, 2003, "us", "en", 0x0004, 0x0000, 0x04b}; 1344 #endif 1345 va_list ap; 1346 char *key; 1351 1347 1352 1348 va_start(ap, fr); … … 1359 1355 gaim_account_get_password(account), &info, key); 1360 1356 } else { 1361 #if 01362 struct client_info_s info = {"gaim", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x04b};1363 #endif1364 1357 struct client_info_s info = CLIENTINFO_AIM_KNOWNGOOD; 1365 1358 aim_send_login(sess, fr->conn, gaim_account_get_username(ac), 1366 1359 gaim_account_get_password(account), &info, key); 1367 1360 } 1361 1362 gaim_connection_update_progress(gc, _("Password sent"), 2, OSCAR_CONNECT_STEPS); 1368 1363 1369 1364 return 1; … … 1376 1371 1377 1372 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, 0x0001, gaim_parse_genericerr, 0); 1378 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, gaim_c hat_join, 0);1379 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, gaim_c hat_leave, 0);1380 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, gaim_c hat_info_update, 0);1381 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, gaim_c hat_incoming_msg, 0);1373 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, gaim_conv_chat_join, 0); 1374 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, gaim_conv_chat_leave, 0); 1375 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, gaim_conv_chat_info_update, 0); 1376 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, gaim_conv_chat_incoming_msg, 0); 1382 1377 1383 1378 aim_clientready(sess, fr->conn); … … 1407 1402 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_EML, AIM_CB_EML_MAILSTATUS, gaim_email_parseupdate, 0); 1408 1403 1409 aim_email_sendcookies(sess , fr->conn);1410 aim_email_activate(sess , fr->conn);1404 aim_email_sendcookies(sess); 1405 aim_email_activate(sess); 1411 1406 aim_clientready(sess, fr->conn); 1412 1407 … … 1416 1411 static int conninitdone_icon(aim_session_t *sess, aim_frame_t *fr, ...) { 1417 1412 GaimConnection *gc = sess->aux_data; 1418 struct oscar_data *od = gc->proto_data;1413 OscarData *od = gc->proto_data; 1419 1414 1420 1415 aim_conn_addhandler(sess, fr->conn, 0x0018, 0x0001, gaim_parse_genericerr, 0); … … 1435 1430 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) { 1436 1431 GaimConnection *gc = data; 1437 struct oscar_data *od;1432 OscarData *od; 1438 1433 aim_session_t *sess; 1439 1434 aim_conn_t *tstconn; … … 1464 1459 { 1465 1460 GaimConnection *gc = data; 1466 struct oscar_data *od;1461 OscarData *od; 1467 1462 aim_session_t *sess; 1468 1463 aim_conn_t *tstconn; … … 1494 1489 struct chat_connection *ccon = data; 1495 1490 GaimConnection *gc = ccon->gc; 1496 struct oscar_data *od;1491 OscarData *od; 1497 1492 aim_session_t *sess; 1498 1493 aim_conn_t *tstconn; … … 1526 1521 static void oscar_email_connect(gpointer data, gint source, GaimInputCondition cond) { 1527 1522 GaimConnection *gc = data; 1528 struct oscar_data *od;1523 OscarData *od; 1529 1524 aim_session_t *sess; 1530 1525 aim_conn_t *tstconn; … … 1555 1550 static void oscar_icon_connect(gpointer data, gint source, GaimInputCondition cond) { 1556 1551 GaimConnection *gc = data; 1557 struct oscar_data *od;1552 OscarData *od; 1558 1553 aim_session_t *sess; 1559 1554 aim_conn_t *tstconn; … … 1748 1743 static int gaim_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...) { 1749 1744 GaimConnection *gc = sess->aux_data; 1750 struct oscar_data *od = gc->proto_data;1745 OscarData *od = gc->proto_data; 1751 1746 struct buddyinfo *bi; 1752 1747 time_t time_idle = 0, signon = 0; … … 1789 1784 } 1790 1785 1791 if (caps & AIM_CAPS_ICQ )1792 caps ^= AIM_CAPS_ICQ ;1786 if (caps & AIM_CAPS_ICQ_DIRECT) 1787 caps ^= AIM_CAPS_ICQ_DIRECT; 1793 1788 1794 1789 if (info->present & AIM_USERINFO_PRESENT_IDLE) { … … 1805 1800 gaim_connection_set_display_name(gc, info->sn); 1806 1801 1807 bi = g_hash_table_lookup(od->buddyinfo, normalize(info->sn));1802 bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, info->sn)); 1808 1803 if (!bi) { 1809 1804 bi = g_new0(struct buddyinfo, 1); 1810 g_hash_table_insert(od->buddyinfo, g_strdup(normalize(info->sn)), bi); 1811 } 1812 bi->signon = info->onlinesince ? info->onlinesince : (info->sessionlen + time(NULL)); 1813 if (caps) 1814 bi->caps = caps; 1805 g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, info->sn)), bi); 1806 } 1815 1807 bi->typingnot = FALSE; 1816 1808 bi->ico_informed = FALSE; … … 1819 1811 /* Available message stuff */ 1820 1812 free(bi->availmsg); 1821 if (info->avail msg)1822 if (info->avail msg_encoding) {1823 gchar *enc = g_strdup_printf("charset=\"%s\"", info->avail msg_encoding);1824 bi->availmsg = oscar_encoding_to_utf8(enc, info->avail msg, info->availmsg_len);1813 if (info->avail != NULL) 1814 if (info->avail_encoding) { 1815 gchar *enc = g_strdup_printf("charset=\"%s\"", info->avail_encoding); 1816 bi->availmsg = oscar_encoding_to_utf8(enc, info->avail, info->avail_len); 1825 1817 g_free(enc); 1826 1818 } else { 1827 1819 /* No explicit encoding means utf8. Yay. */ 1828 bi->availmsg = g_strdup(info->avail msg);1820 bi->availmsg = g_strdup(info->avail); 1829 1821 } 1830 1822 else … … 1833 1825 /* Server stored icon stuff */ 1834 1826 if (info->iconcsumlen) { 1835 char *b16, *saved_b16; 1836 GaimBuddy *b; 1837 1838 free(bi->iconcsum); 1839 bi->iconcsum = malloc(info->iconcsumlen); 1840 memcpy(bi->iconcsum, info->iconcsum, info->iconcsumlen); 1841 bi->iconcsumlen = info->iconcsumlen; 1842 b16 = tobase16(bi->iconcsum, bi->iconcsumlen); 1827 const char *filename = NULL, *saved_b16 = NULL; 1828 char *b16 = NULL; 1829 GaimBuddy *b = NULL; 1830 1831 b16 = gaim_base16_encode(info->iconcsum, info->iconcsumlen); 1843 1832 b = gaim_find_buddy(gc->account, info->sn); 1844 saved_b16 = gaim_buddy_get_setting(b, "icon_checksum"); 1833 /* 1834 * If for some reason the checksum is valid, but cached file is not.. 1835 * we want to know. 1836 */ 1837 filename = gaim_buddy_get_setting(b, "buddy_icon"); 1838 if (filename != NULL) { 1839 if (g_file_test(filename, G_FILE_TEST_EXISTS)) 1840 saved_b16 = gaim_buddy_get_setting(b, "icon_checksum"); 1841 } else 1842 saved_b16 = NULL; 1843 1845 1844 if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) { 1846 1845 GSList *cur = od->requesticon; … … 1848 1847 cur = cur->next; 1849 1848 if (!cur) { 1850 od->requesticon = g_slist_append(od->requesticon, strdup(normalize(info->sn)));1849 od->requesticon = g_slist_append(od->requesticon, g_strdup(gaim_normalize(gc->account, info->sn))); 1851 1850 if (od->icontimer) 1852 1851 g_source_remove(od->icontimer); … … 1854 1853 } 1855 1854 } 1856 g_free(saved_b16);1857 1855 g_free(b16); 1858 1856 } … … 1865 1863 static int gaim_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...) { 1866 1864 GaimConnection *gc = sess->aux_data; 1867 struct oscar_data *od = gc->proto_data;1865 OscarData *od = gc->proto_data; 1868 1866 va_list ap; 1869 1867 aim_userinfo_t *info; … … 1875 1873 serv_got_update(gc, info->sn, 0, 0, 0, 0, 0); 1876 1874 1877 g_hash_table_remove(od->buddyinfo, normalize(info->sn));1875 g_hash_table_remove(od->buddyinfo, gaim_normalize(gc->account, info->sn)); 1878 1876 1879 1877 return 1; … … 1890 1888 struct direct_im *dim = data; 1891 1889 GaimConnection *gc = dim->gc; 1892 struct oscar_data *od = gc->proto_data;1890 OscarData *od = gc->proto_data; 1893 1891 GaimConversation *cnv; 1894 1892 char buf[256]; … … 1929 1927 static int oscar_sendfile_estblsh(aim_session_t *sess, aim_frame_t *fr, ...) { 1930 1928 GaimConnection *gc = sess->aux_data; 1931 struct oscar_data *od = (struct oscar_data *)gc->proto_data;1929 OscarData *od = (OscarData *)gc->proto_data; 1932 1930 GaimXfer *xfer; 1933 1931 struct aim_oft_info *oft_info; … … 2002 2000 static int oscar_sendfile_prompt(aim_session_t *sess, aim_frame_t *fr, ...) { 2003 2001 GaimConnection *gc = sess->aux_data; 2004 struct oscar_data *od = gc->proto_data;2002 OscarData *od = gc->proto_data; 2005 2003 GaimXfer *xfer; 2006 2004 struct aim_oft_info *oft_info; … … 2047 2045 static int oscar_sendfile_ack(aim_session_t *sess, aim_frame_t *fr, ...) { 2048 2046 GaimConnection *gc = sess->aux_data; 2049 struct oscar_data *od = gc->proto_data;2047 OscarData *od = gc->proto_data; 2050 2048 GaimXfer *xfer; 2051 2049 va_list ap; … … 2079 2077 static int oscar_sendfile_done(aim_session_t *sess, aim_frame_t *fr, ...) { 2080 2078 GaimConnection *gc = sess->aux_data; 2081 struct oscar_data *od = gc->proto_data;2079 OscarData *od = gc->proto_data; 2082 2080 GaimXfer *xfer; 2083 2081 va_list ap; … … 2104 2102 static void accept_direct_im(struct ask_direct *d) { 2105 2103 GaimConnection *gc = d->gc; 2106 struct oscar_data *od;2104 OscarData *od; 2107 2105 struct direct_im *dim; 2108 2106 char *host; int port = 4443; … … 2114 2112 } 2115 2113 2116 od = ( struct oscar_data *)gc->proto_data;2114 od = (OscarData *)gc->proto_data; 2117 2115 gaim_debug(GAIM_DEBUG_INFO, "oscar", "Accepted DirectIM.\n"); 2118 2116 … … 2163 2161 static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args) { 2164 2162 GaimConnection *gc = sess->aux_data; 2165 struct oscar_data *od = gc->proto_data;2166 char *tmp;2167 Gaim ImFlags flags = 0;2163 OscarData *od = gc->proto_data; 2164 gchar *tmp; 2165 GaimConvImFlags flags = 0; 2168 2166 gsize convlen; 2169 2167 GError *err = NULL; … … 2171 2169 const char *iconfile; 2172 2170 2173 bi = g_hash_table_lookup(od->buddyinfo, normalize(userinfo->sn));2171 bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, userinfo->sn)); 2174 2172 if (!bi) { 2175 2173 bi = g_new0(struct buddyinfo, 1); 2176 g_hash_table_insert(od->buddyinfo, g_strdup( normalize(userinfo->sn)), bi);2174 g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, userinfo->sn)), bi); 2177 2175 } 2178 2176 2179 2177 if (args->icbmflags & AIM_IMFLAGS_AWAY) 2180 flags |= GAIM_ IM_AUTO_RESP;2178 flags |= GAIM_CONV_IM_AUTO_RESP; 2181 2179 2182 2180 if (args->icbmflags & AIM_IMFLAGS_TYPINGNOT) … … 2197 2195 2198 2196 if ((iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc))) && 2199 (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) ) {2197 (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) && !bi->ico_sent && bi->ico_informed) { 2200 2198 FILE *file; 2201 2199 struct stat st; … … 2241 2239 gaim_debug(GAIM_DEBUG_INFO, "oscar", 2242 2240 "Unicode IM conversion: %s\n", err->message); 2243 tmp = strdup(_("(There was an error receiving this message)"));2241 tmp = g_strdup(_("(There was an error receiving this message)")); 2244 2242 g_error_free(err); 2245 2243 } … … 2263 2261 gaim_debug(GAIM_DEBUG_INFO, "oscar", 2264 2262 "ISO-8859-1 IM conversion: %s\n", err->message); 2265 tmp = strdup(_("(There was an error receiving this message)"));2263 tmp = g_strdup(_("(There was an error receiving this message)")); 2266 2264 g_error_free(err); 2267 2265 } 2268 2266 } 2269 2267 2270 /* strip_linefeed(tmp); */2268 /* gaim_str_strip_cr(tmp); */ 2271 2269 serv_got_im(gc, userinfo->sn, tmp, flags, time(NULL)); 2272 2270 g_free(tmp); … … 2277 2275 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) { 2278 2276 GaimConnection *gc = sess->aux_data; 2279 struct oscar_data *od = gc->proto_data;2277 OscarData *od = gc->proto_data; 2280 2278 const char *username = gaim_account_get_username(gaim_connection_get_account(gc)); 2281 2279 … … 2438 2436 2439 2437 if (g_list_find(gaim_connections_get_all(), gc)) { 2440 struct oscar_data *od = gc->proto_data;2438 OscarData *od = gc->proto_data; 2441 2439 GaimBuddy *buddy = gaim_find_buddy(gc->account, data->name); 2442 2440 GaimGroup *group = gaim_find_buddys_group(buddy); … … 2464 2462 2465 2463 if (g_list_find(gaim_connections_get_all(), gc)) { 2466 /* struct oscar_data *od = gc->proto_data; */2464 /* OscarData *od = gc->proto_data; */ 2467 2465 /* XXX - Take the buddy out of our buddy list */ 2468 2466 } … … 2502 2500 2503 2501 if (g_list_find(gaim_connections_get_all(), gc)) { 2504 struct oscar_data *od = gc->proto_data;2502 OscarData *od = gc->proto_data; 2505 2503 #ifdef NOSSI 2506 2504 GaimBuddy *buddy; … … 2509 2507 buddy = gaim_find_buddy(gc->account, data->name); 2510 2508 aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message); 2511 show_got_added(gc, NULL, data->name, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);2509 gaim_account_notify_added(gc->account, NULL, data->name, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL); 2512 2510 #else 2513 2511 aim_ssi_sendauthreply(od->sess, data->name, 0x01, NULL); … … 2523 2521 2524 2522 if (g_list_find(gaim_connections_get_all(), gc)) { 2525 struct oscar_data *od = gc->proto_data;2523 OscarData *od = gc->proto_data; 2526 2524 #ifdef NOSSI 2527 2525 aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, msg ? msg : _("No reason given.")); … … 2540 2538 } 2541 2539 2542 /* When someone sends you contacts*/2543 static void gaim_icq_ contactadd(struct name_data *data) {2540 /* When someone sends you buddies */ 2541 static void gaim_icq_buddyadd(struct name_data *data) { 2544 2542 GaimConnection *gc = data->gc; 2545 2543 2546 2544 if (g_list_find(gaim_connections_get_all(), gc)) { 2547 show_add_buddy(gc, data->name, NULL, data->nick);2545 gaim_blist_request_add_buddy(gaim_connection_get_account(gc), data->name, NULL, data->nick); 2548 2546 } 2549 2547 … … 2568 2566 msg2 = (gchar **)g_malloc((numtoks+1)*sizeof(gchar *)); 2569 2567 for (i=0; msg1[i]; i++) { 2570 strip_linefeed(msg1[i]);2568 gaim_str_strip_cr(msg1[i]); 2571 2569 msg2[i] = g_convert(msg1[i], strlen(msg1[i]), "UTF-8", "ISO-8859-1", NULL, NULL, &err); 2572 2570 if (err) { … … 2595 2593 case 0x04: { /* Someone sent you a URL */ 2596 2594 if (i >= 2) { 2597 gchar *uin = g_strdup_printf("%u", args->uin); 2598 gchar *message = g_strdup_printf("<A HREF=\"%s\">%s</A>", msg2[1], msg2[0]); 2599 serv_got_im(gc, uin, message, 0, time(NULL)); 2600 g_free(uin); 2601 g_free(message); 2595 if (msg2[1] != NULL) { 2596 gchar *uin = g_strdup_printf("%u", args->uin); 2597 gchar *message = g_strdup_printf("<A HREF=\"%s\">%s</A>", 2598 msg2[1], 2599 (msg2[0] && msg2[0][0]) ? msg2[0] : msg2[1]); 2600 serv_got_im(gc, uin, message, 0, time(NULL)); 2601 g_free(uin); 2602 g_free(message); 2603 } 2602 2604 } 2603 2605 } break; … … 2626 2628 case 0x07: { /* Someone has denied you authorization */ 2627 2629 if (i >= 1) { 2628 gchar *dialog_msg = g_strdup_printf(_("The user %u has denied your request to add them to your contactlist for the following reason:\n%s"), args->uin, msg2[0] ? msg2[0] : _("No reason given."));2630 gchar *dialog_msg = g_strdup_printf(_("The user %u has denied your request to add them to your buddy list for the following reason:\n%s"), args->uin, msg2[0] ? msg2[0] : _("No reason given.")); 2629 2631 gaim_notify_info(gc, NULL, _("ICQ authorization denied."), 2630 2632 dialog_msg); … … 2634 2636 2635 2637 case 0x08: { /* Someone has granted you authorization */ 2636 gchar *dialog_msg = g_strdup_printf(_("The user %u has granted your request to add them to your contactlist."), args->uin);2638 gchar *dialog_msg = g_strdup_printf(_("The user %u has granted your request to add them to your buddy list."), args->uin); 2637 2639 gaim_notify_info(gc, NULL, "ICQ authorization accepted.", 2638 2640 dialog_msg); … … 2666 2668 case 0x12: { 2667 2669 /* Ack for authorizing/denying someone. Or possibly an ack for sending any system notice */ 2668 /* Someone added you to their contactlist? */2670 /* Someone added you to their buddy list? */ 2669 2671 } break; 2670 2672 2671 case 0x13: { /* Someone has sent you some ICQ contacts */2673 case 0x13: { /* Someone has sent you some ICQ buddies */ 2672 2674 int i, num; 2673 2675 gchar **text; … … 2679 2681 for (i=0; i<num; i++) { 2680 2682 struct name_data *data = g_new(struct name_data, 1); 2681 gchar *message = g_strdup_printf(_("ICQ user %u has sent you a contact: %s (%s)"), args->uin, text[i*2+2], text[i*2+1]);2683 gchar *message = g_strdup_printf(_("ICQ user %u has sent you a buddy: %s (%s)"), args->uin, text[i*2+2], text[i*2+1]); 2682 2684 data->gc = gc; 2683 2685 data->name = g_strdup(text[i*2+1]); … … 2685 2687 2686 2688 gaim_request_action(gc, NULL, message, 2687 _("Do you want to add this contact"2688 "to your Buddy List?"),2689 _("Do you want to add this buddy " 2690 "to your buddy list?"), 2689 2691 0, data, 2, 2690 _("Add"), G_CALLBACK(gaim_icq_ contactadd),2692 _("Add"), G_CALLBACK(gaim_icq_buddyadd), 2691 2693 _("Decline"), G_CALLBACK(oscar_free_name_data)); 2692 2694 g_free(message); … … 2696 2698 } break; 2697 2699 2698 case 0x1a: { /* Someone has sent you a greeting card or requested contacts? */2700 case 0x1a: { /* Someone has sent you a greeting card or requested buddies? */ 2699 2701 /* This is boring and silly. */ 2700 2702 } break; … … 2851 2853 static int gaim_parse_clientauto_ch2(aim_session_t *sess, const char *who, fu16_t reason, const char *cookie) { 2852 2854 GaimConnection *gc = sess->aux_data; 2853 struct oscar_data *od = gc->proto_data;2855 OscarData *od = gc->proto_data; 2854 2856 2855 2857 /* BBB */ … … 2881 2883 char *status_msg = gaim_icq_status(state); 2882 2884 char *dialog_msg, **splitmsg; 2883 struct oscar_data *od = gc->proto_data;2884 GSList *l = od->evilhack;2885 gboolean evilhack = FALSE;2886 2885 2887 2886 /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ 2888 2887 splitmsg = g_strsplit(msg, "\r\n", 0); 2889 2888 2890 /* If who is in od->evilhack, then we're just getting the away message, otherwise this 2891 * will just get appended to the info box (which is already showing). */ 2892 while (l) { 2893 char *x = l->data; 2894 if (!strcmp(x, normalize(who))) { 2895 evilhack = TRUE; 2896 g_free(x); 2897 od->evilhack = g_slist_remove(od->evilhack, x); 2898 break; 2899 } 2900 l = l->next; 2901 } 2902 2903 if (evilhack) 2904 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, status_msg, g_strjoinv("<BR>", splitmsg)); 2905 else 2906 dialog_msg = g_strdup_printf(_("<B>Status:</B> %s<HR>%s"), status_msg, g_strjoinv("<BR>", splitmsg)); 2907 g_show_info_text(gc, who, 2, dialog_msg, NULL); 2889 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, status_msg, g_strjoinv("<BR>", splitmsg)); 2890 gaim_notify_formatted(gc, NULL, _("Buddy Information"), NULL, dialog_msg, NULL, NULL); 2908 2891 2909 2892 g_free(status_msg); … … 2974 2957 #if 0 2975 2958 GaimConnection *gc = sess->aux_data; 2976 struct oscar_data *od = gc->proto_data;2959 OscarData *od = gc->proto_data; 2977 2960 GaimXfer *xfer; 2978 2961 #endif … … 3040 3023 } 3041 3024 3025 /* 3026 * We get this error when there was an error in the locate family. This 3027 * happens when you request info of someone who is offline. 3028 */ 3042 3029 static int gaim_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...) { 3043 char *buf;3030 gchar *buf; 3044 3031 va_list ap; 3045 3032 fu16_t reason; … … 3051 3038 va_end(ap); 3052 3039 3053 buf = g_strdup_printf(_("User information for %s unavailable:"), destn); 3054 gaim_notify_error(sess->aux_data, NULL, buf, 3055 (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("No reason given.")); 3056 g_free(buf); 3040 if (destn != NULL) { 3041 buf = g_strdup_printf(_("User information for %s unavailable:"), destn); 3042 gaim_notify_error(sess->aux_data, NULL, buf, 3043 (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("No reason given.")); 3044 g_free(buf); 3045 } 3057 3046 3058 3047 return 1; … … 3092 3081 break; 3093 3082 case AIM_CAPS_DIRECTIM: 3094 tmp = _(" Direct IM");3083 tmp = _("AIM Direct IM"); 3095 3084 break; 3096 3085 case AIM_CAPS_CHAT: … … 3113 3102 tmp = _("Send Buddy List"); 3114 3103 break; 3115 case AIM_CAPS_ICQ :3116 tmp = _(" EveryBuddy Bug");3104 case AIM_CAPS_ICQ_DIRECT: 3105 tmp = _("ICQ Direct Connect"); 3117 3106 break; 3118 3107 case AIM_CAPS_APINFO: … … 3141 3130 break; 3142 3131 case AIM_CAPS_SECUREIM: 3143 tmp = _("Secure IM"); 3132 tmp = _("Security Enabled"); 3133 break; 3134 case AIM_CAPS_VIDEO: 3135 tmp = _("Video Chat"); 3144 3136 break; 3145 3137 default: … … 3157 3149 } 3158 3150 3159 static int gaim_parse_user _info(aim_session_t *sess, aim_frame_t *fr, ...) {3151 static int gaim_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...) { 3160 3152 GaimConnection *gc = sess->aux_data; 3161 struct oscar_data *od = gc->proto_data; 3162 gchar *header; 3163 GSList *l = od->evilhack; 3164 gboolean evilhack = FALSE; 3165 gchar *membersince = NULL, *onlinesince = NULL, *idle = NULL; 3153 GString *text; 3154 gchar *info_utf8 = NULL, *away_utf8 = NULL; 3155 const char *final = NULL; 3166 3156 va_list ap; 3167 aim_userinfo_t *info; 3168 fu16_t infotype; 3169 char *text_enc = NULL, *text = NULL, *utf8 = NULL; 3170 int text_len; 3171 const char *username = gaim_account_get_username(gaim_connection_get_account(gc)); 3157 aim_userinfo_t *userinfo; 3172 3158 3173 3159 va_start(ap, fr); 3174 info = va_arg(ap, aim_userinfo_t *); 3175 infotype = (fu16_t) va_arg(ap, unsigned int); 3176 text_enc = va_arg(ap, char *); 3177 text = va_arg(ap, char *); 3178 text_len = va_arg(ap, int); 3160 userinfo = va_arg(ap, aim_userinfo_t *); 3179 3161 va_end(ap); 3180 3162 3181 if (text_len > 0) { 3182 if (!(utf8 = oscar_encoding_to_utf8(text_enc, text, text_len))) { 3183 utf8 = g_strdup(_("<i>Unable to display information because it was sent in an unknown encoding.</i>")); 3184 gaim_debug(GAIM_DEBUG_ERROR, "oscar", 3185 "Encountered an unknown encoding while parsing userinfo\n"); 3186 } 3187 } 3188 3189 if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE) { 3190 onlinesince = g_strdup_printf(_("Online Since : <b>%s</b><br>\n"), 3191 asctime(localtime((time_t *)&info->onlinesince))); 3192 } 3193 3194 if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { 3195 membersince = g_strdup_printf(_("Member Since : <b>%s</b><br>\n"), 3196 asctime(localtime((time_t *)&info->membersince))); 3197 } 3198 3199 if (info->present & AIM_USERINFO_PRESENT_IDLE) { 3200 gchar *itime = sec_to_text(info->idletime*60); 3201 idle = g_strdup_printf(_("Idle : <b>%s</b>"), itime); 3163 text = g_string_new(""); 3164 g_string_append_printf(text, _("Username: <b>%s</b><br>\n"), userinfo->sn); 3165 g_string_append_printf(text, _("Warning Level: <b>%d%%</b><br>\n"), (int)((userinfo->warnlevel/10.0) + 0.5)); 3166 3167 if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) 3168 g_string_append_printf(text, _("Online Since: <b>%s</b><br>\n"), 3169 asctime(localtime((time_t *)&userinfo->onlinesince))); 3170 3171 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) 3172 g_string_append_printf(text, _("Member Since: <b>%s</b><br>\n"), 3173 asctime(localtime((time_t *)&userinfo->membersince))); 3174 3175 if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) { 3176 gchar *itime = gaim_str_seconds_to_string(userinfo->idletime*60); 3177 g_string_append_printf(text, _("Idle: <b>%s</b>"), itime); 3202 3178 g_free(itime); 3203 3179 } else 3204 idle = g_strdup(_("Idle: <b>Active</b>")); 3205 3206 header = g_strdup_printf(_("Username : <b>%s</b> %s <br>\n" 3207 "Warning Level : <b>%d %%</b><br>\n" 3208 "%s" 3209 "%s" 3210 "%s\n" 3211 "<hr>\n"), 3212 info->sn, 3213 /* images(info->flags), */ 3214 "", 3215 (int)((info->warnlevel/10.0) + 0.5), 3216 onlinesince ? onlinesince : "", 3217 membersince ? membersince : "", 3218 idle ? idle : ""); 3219 3220 g_free(onlinesince); 3221 g_free(membersince); 3222 g_free(idle); 3223 3224 while (l) { 3225 char *x = l->data; 3226 if (!strcmp(x, normalize(info->sn))) { 3227 evilhack = TRUE; 3228 g_free(x); 3229 od->evilhack = g_slist_remove(od->evilhack, x); 3230 break; 3231 } 3232 l = l->next; 3233 } 3234 3235 if (infotype == AIM_GETINFO_AWAYMESSAGE) { 3236 if (evilhack) { 3237 g_show_info_text(gc, info->sn, 2, 3238 header, 3239 (utf8 && *utf8) ? away_subs(utf8, username) : 3240 _("<i>User has no away message</i>"), NULL); 3241 } else { 3242 g_show_info_text(gc, info->sn, 0, 3243 header, 3244 (utf8 && *utf8) ? away_subs(utf8, username) : NULL, 3245 (utf8 && *utf8) ? "<hr>" : NULL, 3246 NULL); 3247 } 3248 } else if (infotype == AIM_GETINFO_CAPABILITIES) { 3249 g_show_info_text(gc, info->sn, 2, 3250 header, 3251 "<i>", _("Client Capabilities: "), 3252 caps_string(info->capabilities), 3253 "</i>", 3254 NULL); 3255 } else { 3256 g_show_info_text(gc, info->sn, 1, 3257 (utf8 && *utf8) ? away_subs(utf8, username) : _("<i>No Information Provided</i>"), 3258 NULL); 3259 } 3260 3261 g_free(header); 3262 g_free(utf8); 3180 g_string_append_printf(text, _("Idle: <b>Active</b>")); 3181 3182 if ((userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) { 3183 away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len); 3184 if (away_utf8 != NULL) { 3185 g_string_append_printf(text, "<hr>%s", away_utf8); 3186 g_free(away_utf8); 3187 } 3188 } 3189 3190 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) { 3191 info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len); 3192 if (info_utf8 != NULL) { 3193 g_string_append_printf(text, "<hr>%s", info_utf8); 3194 g_free(info_utf8); 3195 } 3196 } 3197 3198 final = gaim_str_sub_away_formatters(text->str, gaim_account_get_username(gaim_connection_get_account(gc))); 3199 g_string_free(text, TRUE); 3200 gaim_notify_formatted(gc, NULL, _("Buddy Information"), NULL, final, NULL, NULL); 3263 3201 3264 3202 return 1; … … 3288 3226 fu16_t type; 3289 3227 GaimConnection *gc = sess->aux_data; 3290 struct oscar_data *od = (struct oscar_data *)gc->proto_data;3228 OscarData *od = (OscarData *)gc->proto_data; 3291 3229 3292 3230 va_start(ap, fr); … … 3363 3301 } 3364 3302 3365 static int gaim_c hat_join(aim_session_t *sess, aim_frame_t *fr, ...) {3303 static int gaim_conv_chat_join(aim_session_t *sess, aim_frame_t *fr, ...) { 3366 3304 va_list ap; 3367 3305 int count, i; … … 3381 3319 3382 3320 for (i = 0; i < count; i++) 3383 gaim_c hat_add_user(GAIM_CHAT(c->cnv), info[i].sn, NULL);3321 gaim_conv_chat_add_user(GAIM_CONV_CHAT(c->cnv), info[i].sn, NULL); 3384 3322 3385 3323 return 1; 3386 3324 } 3387 3325 3388 static int gaim_c hat_leave(aim_session_t *sess, aim_frame_t *fr, ...) {3326 static int gaim_conv_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...) { 3389 3327 va_list ap; 3390 3328 int count, i; … … 3404 3342 3405 3343 for (i = 0; i < count; i++) 3406 gaim_c hat_remove_user(GAIM_CHAT(c->cnv), info[i].sn, NULL);3344 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c->cnv), info[i].sn, NULL); 3407 3345 3408 3346 return 1; 3409 3347 } 3410 3348 3411 static int gaim_c hat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) {3349 static int gaim_conv_chat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) { 3412 3350 va_list ap; 3413 3351 aim_userinfo_t *userinfo; … … 3445 3383 } 3446 3384 3447 static int gaim_c hat_incoming_msg(aim_session_t *sess, aim_frame_t *fr, ...) {3385 static int gaim_conv_chat_incoming_msg(aim_session_t *sess, aim_frame_t *fr, ...) { 3448 3386 GaimConnection *gc = sess->aux_data; 3449 3387 va_list ap; … … 3467 3405 struct aim_emailinfo *emailinfo; 3468 3406 int havenewmail; 3407 char *alertitle, *alerturl; 3469 3408 3470 3409 va_start(ap, fr); 3471 3410 emailinfo = va_arg(ap, struct aim_emailinfo *); 3472 3411 havenewmail = va_arg(ap, int); 3412 alertitle = va_arg(ap, char *); 3413 alerturl = va_arg(ap, char *); 3473 3414 va_end(ap); 3474 3415 … … 3479 3420 g_free(to); 3480 3421 } 3422 3423 if (alertitle) 3424 gaim_debug(GAIM_DEBUG_MISC, "oscar", "Got an alert '%s' %s\n", alertitle, alerturl ? alerturl : ""); 3481 3425 3482 3426 return 1; … … 3485 3429 static int gaim_icon_error(aim_session_t *sess, aim_frame_t *fr, ...) { 3486 3430 GaimConnection *gc = sess->aux_data; 3487 struct oscar_data *od = gc->proto_data;3431 OscarData *od = gc->proto_data; 3488 3432 char *sn; 3489 3433 … … 3503 3447 static int gaim_icon_parseicon(aim_session_t *sess, aim_frame_t *fr, ...) { 3504 3448 GaimConnection *gc = sess->aux_data; 3505 struct oscar_data *od = gc->proto_data;3449 OscarData *od = gc->proto_data; 3506 3450 GSList *cur; 3507 3451 va_list ap; … … 3523 3467 gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc), 3524 3468 sn, icon, iconlen); 3525 b16 = tobase16(iconcsum, iconcsumlen);3469 b16 = gaim_base16_encode(iconcsum, iconcsumlen); 3526 3470 if (b16) { 3527 3471 gaim_buddy_set_setting(b, "icon_checksum", b16); 3528 3472 gaim_blist_save(); 3529 free(b16);3473 g_free(b16); 3530 3474 } 3531 3475 } … … 3551 3495 static gboolean gaim_icon_timerfunc(gpointer data) { 3552 3496 GaimConnection *gc = data; 3553 struct oscar_data *od = gc->proto_data;3554 struct buddyinfo *bi;3497 OscarData *od = gc->proto_data; 3498 aim_userinfo_t *userinfo; 3555 3499 aim_conn_t *conn; 3556 3500 … … 3595 3539 } 3596 3540 3597 bi = g_hash_table_lookup(od->buddyinfo, (char *)od->requesticon->data);3598 if ( bi && (bi->iconcsumlen > 0)) {3599 aim_bart_request(od->sess, od->requesticon->data, bi->iconcsum, bi->iconcsumlen);3541 userinfo = aim_locate_finduserinfo(od->sess, (char *)od->requesticon->data); 3542 if ((userinfo != NULL) && (userinfo->iconcsumlen > 0)) { 3543 aim_bart_request(od->sess, od->requesticon->data, userinfo->iconcsum, userinfo->iconcsumlen); 3600 3544 return FALSE; 3601 3545 } else { … … 3690 3634 va_end(ap); 3691 3635 3692 serv_got_eviled(gc, (userinfo && userinfo->sn [0]) ? userinfo->sn : NULL, (newevil/10.0) + 0.5);3636 serv_got_eviled(gc, (userinfo && userinfo->sn) ? userinfo->sn : NULL, (newevil/10.0) + 0.5); 3693 3637 3694 3638 return 1; … … 3714 3658 static int gaim_connerr(aim_session_t *sess, aim_frame_t *fr, ...) { 3715 3659 GaimConnection *gc = sess->aux_data; 3716 struct oscar_data *od = gc->proto_data;3660 OscarData *od = gc->proto_data; 3717 3661 va_list ap; 3718 3662 fu16_t code; … … 3740 3684 3741 3685 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) { 3686 GaimConnection *gc = sess->aux_data; 3742 3687 3743 3688 aim_reqpersonalinfo(sess, fr->conn); 3744 3689 3745 3690 #ifndef NOSSI 3746 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting ssilist\n");3691 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting rights and list\n"); 3747 3692 aim_ssi_reqrights(sess); 3748 3693 aim_ssi_reqdata(sess); 3749 3694 #endif 3750 3695 3751 aim_ bos_reqlocaterights(sess, fr->conn);3752 aim_b os_reqbuddyrights(sess, fr->conn);3696 aim_locate_reqrights(sess); 3697 aim_buddylist_reqrights(sess, fr->conn); 3753 3698 aim_im_reqparams(sess); 3754 aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi ?*/3699 aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */ 3755 3700 3756 3701 #ifdef NOSSI 3702 gaim_debug(GAIM_DEBUG_INFO, "oscar", "bos: requesting rights\n"); 3703 aim_bos_reqrights(sess, fr->conn); 3757 3704 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS); 3758 3705 aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE); 3759 3706 #endif 3760 3707 3708 gaim_connection_update_progress(gc, _("Finalizing connection"), 5, OSCAR_CONNECT_STEPS); 3709 3761 3710 return 1; 3762 3711 } … … 3764 3713 static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...) { 3765 3714 GaimConnection *gc = sess->aux_data; 3766 struct oscar_data *od = gc->proto_data;3715 OscarData *od = gc->proto_data; 3767 3716 3768 3717 aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ADM, 0x0003, gaim_info_change, 0); … … 3839 3788 { 3840 3789 GaimConnection *gc = sess->aux_data; 3841 struct oscar_data *od = (struct oscar_data *)gc->proto_data;3790 OscarData *od = (OscarData *)gc->proto_data; 3842 3791 va_list ap; 3843 3792 fu16_t maxsiglen; … … 3853 3802 3854 3803 if (od->icq) 3855 aim_ bos_setprofile(sess, fr->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq);3804 aim_locate_setcaps(od->sess, caps_icq); 3856 3805 else 3857 oscar_set_info(gc, gc->account->user_info); 3806 aim_locate_setcaps(od->sess, caps_aim); 3807 oscar_set_info(gc, gc->account->user_info); 3858 3808 3859 3809 return 1; … … 3864 3814 fu16_t maxbuddies, maxwatchers; 3865 3815 GaimConnection *gc = sess->aux_data; 3866 struct oscar_data *od = (struct oscar_data *)gc->proto_data;3816 OscarData *od = (OscarData *)gc->proto_data; 3867 3817 3868 3818 va_start(ap, fr); … … 3881 3831 3882 3832 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) { 3833 GaimConnection *gc = sess->aux_data; 3834 OscarData *od = (OscarData *)gc->proto_data; 3835 va_list ap; 3883 3836 fu16_t maxpermits, maxdenies; 3884 va_list ap;3885 GaimConnection *gc = sess->aux_data;3886 struct oscar_data *od = (struct oscar_data *)gc->proto_data;3887 3837 3888 3838 va_start(ap, fr); … … 3904 3854 aim_clientready(sess, fr->conn); 3905 3855 aim_srv_setavailmsg(sess, NULL); 3906 aim_ bos_setidle(sess, fr->conn, 0);3856 aim_srv_setidle(sess, 0); 3907 3857 3908 3858 if (od->icq) { … … 3935 3885 args.msglen = msg->msglen; 3936 3886 args.msg = msg->msg; 3937 t = g et_time(msg->year, msg->month, msg->day, msg->hour, msg->minute, 0);3887 t = gaim_time_build(msg->year, msg->month, msg->day, msg->hour, msg->minute, 0); 3938 3888 incomingim_chan4(sess, fr->conn, NULL, &args, t); 3939 3889 … … 3946 3896 return 1; 3947 3897 } 3898 3899 #if 0 3900 /* 3901 * Update, 2003-11-09: 3902 * Joseph S. Myers, a gcc dude, fixed this for gcc 3.4! Rock on! 3903 * 3904 * It may not be my place to do this, but... 3905 * I feel pretty strongly that the "last 2 digits" warning is ridiculously 3906 * stupid, and should not exist for % switches (%x in our case) that request 3907 * a year in the preferred representation for the current locale. For that 3908 * reason I've chosen to not use this workaround (n., see kluge). 3909 * 3910 * I have a date. I want to show it to the user in the "preferred" way. 3911 * Whether that displays a 2 digit year is perfectly fine--after all, it's 3912 * what the locale wanted. 3913 * 3914 * If I have a necessity for a full representation of the year in the current 3915 * locale, then I'll use a switch that returns a full representation of the 3916 * year. 3917 * 3918 * If you think the preferred locale should show 4 digits instead of 2 digits 3919 * (because you're anal, or whatever), then change the f***ing locale. 3920 * 3921 * I guess the bottom line is--I'm trying to show a date to the user how they 3922 * prefer to see it, why the hell does gcc want me to change that? 3923 * 3924 * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3190 3925 * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8714 3926 */ 3927 3928 /* 3929 * This function was recommended by the STRFTIME(3) man page to remove the 3930 * "last 2 digits" warning. 3931 */ 3932 static size_t my_strftime(char *s, size_t max, const char *fmt, 3933 const struct tm *tm) 3934 { 3935 return strftime(s, max, fmt, tm); 3936 } 3937 #endif 3948 3938 3949 3939 static int gaim_icqinfo(aim_session_t *sess, aim_frame_t *fr, ...) … … 3966 3956 g_snprintf(who, sizeof(who), "%u", info->uin); 3967 3957 buf = g_strdup_printf("<b>%s:</b> %s", _("UIN"), who); 3968 if (info->nick && info->nick[0] && (utf8 = gaim_ try_conv_to_utf8(info->nick))) {3958 if (info->nick && info->nick[0] && (utf8 = gaim_utf8_try_convert(info->nick))) { 3969 3959 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Nick"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 3970 3960 } 3971 if (info->first && info->first[0] && (utf8 = gaim_ try_conv_to_utf8(info->first))) {3961 if (info->first && info->first[0] && (utf8 = gaim_utf8_try_convert(info->first))) { 3972 3962 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("First Name"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 3973 3963 } 3974 if (info->last && info->last[0] && (utf8 = gaim_ try_conv_to_utf8(info->last))) {3964 if (info->last && info->last[0] && (utf8 = gaim_utf8_try_convert(info->last))) { 3975 3965 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Last Name"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 3976 3966 } 3977 if (info->email && info->email[0] && (utf8 = gaim_ try_conv_to_utf8(info->email))) {3967 if (info->email && info->email[0] && (utf8 = gaim_utf8_try_convert(info->email))) { 3978 3968 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Email Address"), ":</b> <a href=\"mailto:", utf8, "\">", utf8, "</a>", NULL); g_free(tmp); g_free(utf8); 3979 3969 } … … 3981 3971 int i; 3982 3972 for (i = 0; i < info->numaddresses; i++) { 3983 if (info->email2[i] && info->email2[i][0] && (utf8 = gaim_ try_conv_to_utf8(info->email2[i]))) {3973 if (info->email2[i] && info->email2[i][0] && (utf8 = gaim_utf8_try_convert(info->email2[i]))) { 3984 3974 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Email Address"), ":</b> <a href=\"mailto:", utf8, "\">", utf8, "</a>", NULL); g_free(tmp); g_free(utf8); 3985 3975 } 3986 3976 } 3987 3977 } 3988 if (info->mobile && info->mobile[0] && (utf8 = gaim_ try_conv_to_utf8(info->mobile))) {3978 if (info->mobile && info->mobile[0] && (utf8 = gaim_utf8_try_convert(info->mobile))) { 3989 3979 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Mobile Phone"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 3990 3980 } … … 4006 3996 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Age"), ":</b> ", age, NULL); g_free(tmp); 4007 3997 } 4008 if (info->personalwebpage && info->personalwebpage[0] && (utf8 = gaim_ try_conv_to_utf8(info->personalwebpage))) {3998 if (info->personalwebpage && info->personalwebpage[0] && (utf8 = gaim_utf8_try_convert(info->personalwebpage))) { 4009 3999 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Personal Web Page"), ":</b> <a href=\"", utf8, "\">", utf8, "</a>", NULL); g_free(tmp); g_free(utf8); 4010 4000 } 4011 if (info->info && info->info[0] && (utf8 = gaim_ try_conv_to_utf8(info->info))) {4001 if (info->info && info->info[0] && (utf8 = gaim_utf8_try_convert(info->info))) { 4012 4002 tmp = buf; buf = g_strconcat(tmp, "<hr><b>", _("Additional Information"), ":</b><br>", utf8, NULL); g_free(tmp); g_free(utf8); 4013 4003 } … … 4015 4005 if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) { 4016 4006 tmp = buf; buf = g_strconcat(tmp, "<b>", _("Home Address"), ":</b>", NULL); g_free(tmp); 4017 if (info->homeaddr && info->homeaddr[0] && (utf8 = gaim_ try_conv_to_utf8(info->homeaddr))) {4007 if (info->homeaddr && info->homeaddr[0] && (utf8 = gaim_utf8_try_convert(info->homeaddr))) { 4018 4008 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Address"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4019 4009 } 4020 if (info->homecity && info->homecity[0] && (utf8 = gaim_ try_conv_to_utf8(info->homecity))) {4010 if (info->homecity && info->homecity[0] && (utf8 = gaim_utf8_try_convert(info->homecity))) { 4021 4011 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("City"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4022 4012 } 4023 if (info->homestate && info->homestate[0] && (utf8 = gaim_ try_conv_to_utf8(info->homestate))) {4013 if (info->homestate && info->homestate[0] && (utf8 = gaim_utf8_try_convert(info->homestate))) { 4024 4014 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("State"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4025 4015 } 4026 if (info->homezip && info->homezip[0] && (utf8 = gaim_ try_conv_to_utf8(info->homezip))) {4016 if (info->homezip && info->homezip[0] && (utf8 = gaim_utf8_try_convert(info->homezip))) { 4027 4017 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Zip Code"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4028 4018 } … … 4031 4021 if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) { 4032 4022 tmp = buf; buf = g_strconcat(tmp, "<b>", _("Work Address"), ":</b>", NULL); g_free(tmp); 4033 if (info->workaddr && info->workaddr[0] && (utf8 = gaim_ try_conv_to_utf8(info->workaddr))) {4023 if (info->workaddr && info->workaddr[0] && (utf8 = gaim_utf8_try_convert(info->workaddr))) { 4034 4024 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Address"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4035 4025 } 4036 if (info->workcity && info->workcity[0] && (utf8 = gaim_ try_conv_to_utf8(info->workcity))) {4026 if (info->workcity && info->workcity[0] && (utf8 = gaim_utf8_try_convert(info->workcity))) { 4037 4027 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("City"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4038 4028 } 4039 if (info->workstate && info->workstate[0] && (utf8 = gaim_ try_conv_to_utf8(info->workstate))) {4029 if (info->workstate && info->workstate[0] && (utf8 = gaim_utf8_try_convert(info->workstate))) { 4040 4030 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("State"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4041 4031 } 4042 if (info->workzip && info->workzip[0] && (utf8 = gaim_ try_conv_to_utf8(info->workzip))) {4032 if (info->workzip && info->workzip[0] && (utf8 = gaim_utf8_try_convert(info->workzip))) { 4043 4033 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Zip Code"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4044 4034 } … … 4047 4037 if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) { 4048 4038 tmp = buf; buf = g_strconcat(tmp, "<b>", _("Work Information"), ":</b>", NULL); g_free(tmp); 4049 if (info->workcompany && info->workcompany[0] && (utf8 = gaim_ try_conv_to_utf8(info->workcompany))) {4039 if (info->workcompany && info->workcompany[0] && (utf8 = gaim_utf8_try_convert(info->workcompany))) { 4050 4040 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Company"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4051 4041 } 4052 if (info->workdivision && info->workdivision[0] && (utf8 = gaim_ try_conv_to_utf8(info->workdivision))) {4042 if (info->workdivision && info->workdivision[0] && (utf8 = gaim_utf8_try_convert(info->workdivision))) { 4053 4043 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Division"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4054 4044 } 4055 if (info->workposition && info->workposition[0] && (utf8 = gaim_ try_conv_to_utf8(info->workposition))) {4045 if (info->workposition && info->workposition[0] && (utf8 = gaim_utf8_try_convert(info->workposition))) { 4056 4046 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Position"), ":</b> ", utf8, NULL); g_free(tmp); g_free(utf8); 4057 4047 } 4058 if (info->workwebpage && info->workwebpage[0] && (utf8 = gaim_ try_conv_to_utf8(info->workwebpage))) {4048 if (info->workwebpage && info->workwebpage[0] && (utf8 = gaim_utf8_try_convert(info->workwebpage))) { 4059 4049 tmp = buf; buf = g_strconcat(tmp, "\n<br><b>", _("Web Page"), ":</b> <a href=\"", utf8, "\">", utf8, "</a>", NULL); g_free(tmp); g_free(utf8); 4060 4050 } … … 4083 4073 va_end(ap); 4084 4074 4085 if (info->uin && info->nick && info->nick[0] && (utf8 = gaim_ try_conv_to_utf8(info->nick))) {4075 if (info->uin && info->nick && info->nick[0] && (utf8 = gaim_utf8_try_convert(info->nick))) { 4086 4076 g_snprintf(who, sizeof(who), "%u", info->uin); 4087 4077 serv_got_alias(gc, who, utf8); … … 4098 4088 static int gaim_popup(aim_session_t *sess, aim_frame_t *fr, ...) 4099 4089 { 4090 GaimConnection *gc = sess->aux_data; 4091 gchar *text; 4092 va_list ap; 4100 4093 char *msg, *url; 4101 4094 fu16_t wid, hei, delay; 4102 va_list ap;4103 4095 4104 4096 va_start(ap, fr); … … 4110 4102 va_end(ap); 4111 4103 4112 serv_got_popup(msg, url, wid, hei); 4104 text = g_strdup_printf("%s<br><a href=\"%s\">%s</a>", msg, url, url); 4105 gaim_notify_formatted(gc, NULL, _("Pop-Up Message"), NULL, text, NULL, NULL); 4106 g_free(text); 4113 4107 4114 4108 return 1; 4115 4109 } 4116 4110 4117 static int gaim_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...) { 4111 static int gaim_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...) 4112 { 4118 4113 GaimConnection *gc = sess->aux_data; 4119 4114 gchar *secondary; … … 4248 4243 4249 4244 static void oscar_keepalive(GaimConnection *gc) { 4250 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4245 OscarData *od = (OscarData *)gc->proto_data; 4251 4246 aim_flap_nop(od->sess, od->conn); 4252 4247 } 4253 4248 4254 4249 static int oscar_send_typing(GaimConnection *gc, const char *name, int typing) { 4255 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4250 OscarData *od = (OscarData *)gc->proto_data; 4256 4251 struct direct_im *dim = find_direct_im(od, name); 4257 4252 if (dim) … … 4267 4262 for (list=gc->account->deny; (list && aim_sncmp(name, list->data)); list=list->next); 4268 4263 if (!list) { 4269 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(name));4264 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name)); 4270 4265 if (bi && bi->typingnot) { 4271 4266 if (typing == GAIM_TYPING) … … 4281 4276 } 4282 4277 static void oscar_ask_direct_im(GaimConnection *gc, const char *name); 4283 static int gaim_odc_send_im(aim_session_t *, aim_conn_t *, const char *, Gaim ImFlags);4284 4285 static int oscar_send_im(GaimConnection *gc, const char *name, const char *message, Gaim ImFlags imflags) {4286 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4278 static int gaim_odc_send_im(aim_session_t *, aim_conn_t *, const char *, GaimConvImFlags); 4279 4280 static int oscar_send_im(GaimConnection *gc, const char *name, const char *message, GaimConvImFlags imflags) { 4281 OscarData *od = (OscarData *)gc->proto_data; 4287 4282 struct direct_im *dim = find_direct_im(od, name); 4288 4283 int ret = 0; … … 4294 4289 /* If we're directly connected, send a direct IM */ 4295 4290 ret = gaim_odc_send_im(od->sess, dim->conn, message, imflags); 4296 } else if (imflags & GAIM_ IM_IMAGES) {4291 } else if (imflags & GAIM_CONV_IM_IMAGES) { 4297 4292 /* Trying to send an IM image outside of a direct connection. */ 4298 4293 oscar_ask_direct_im(gc, name); … … 4304 4299 gsize len; 4305 4300 4306 bi = g_hash_table_lookup(od->buddyinfo, normalize(name));4301 bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name)); 4307 4302 if (!bi) { 4308 4303 bi = g_new0(struct buddyinfo, 1); 4309 g_hash_table_insert(od->buddyinfo, g_strdup( normalize(name)), bi);4304 g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, name)), bi); 4310 4305 } 4311 4306 … … 4319 4314 args.featureslen = sizeof(features_aim); 4320 4315 4321 if (imflags & GAIM_ IM_AUTO_RESP)4316 if (imflags & GAIM_CONV_IM_AUTO_RESP) 4322 4317 args.flags |= AIM_IMFLAGS_AWAY; 4323 4318 } … … 4341 4336 args.iconstamp = st.st_mtime; 4342 4337 4343 if ((args.iconlen != bi->ico_me_len) || (args.iconsum != bi->ico_me_csum) || (args.iconstamp != bi->ico_me_time)) 4338 if ((args.iconlen != bi->ico_me_len) || (args.iconsum != bi->ico_me_csum) || (args.iconstamp != bi->ico_me_time)) { 4344 4339 bi->ico_informed = FALSE; 4340 bi->ico_sent = FALSE; 4341 } 4345 4342 4346 4343 if (!bi->ico_informed) { … … 4362 4359 /* For ICQ send newlines as CR/LF, for AIM send newlines as <BR> */ 4363 4360 if (isdigit(name[0])) 4364 tmpmsg = add_cr(message);4361 tmpmsg = gaim_str_add_cr(message); 4365 4362 else 4366 tmpmsg = strdup_withhtml(message);4363 tmpmsg = gaim_strdup_withhtml(message); 4367 4364 len = strlen(tmpmsg); 4368 4365 … … 4421 4418 } 4422 4419 4423 static void oscar_get_info(GaimConnection *g, const char *name) { 4424 struct oscar_data *od = (struct oscar_data *)g->proto_data; 4425 if (od->icq) 4420 static void oscar_get_info(GaimConnection *gc, const char *name) { 4421 OscarData *od = (OscarData *)gc->proto_data; 4422 4423 if (od->icq && isdigit(name[0])) 4426 4424 aim_icq_getallinfo(od->sess, name); 4427 4425 else 4428 /* people want the away message on the top, so we get the away message 4429 * first and then get the regular info, since it's too difficult to 4430 * insert in the middle. i hate people. */ 4431 aim_getinfo(od->sess, od->conn, name, AIM_GETINFO_AWAYMESSAGE); 4432 } 4433 4434 static void oscar_get_away(GaimConnection *g, const char *who) { 4435 struct oscar_data *od = (struct oscar_data *)g->proto_data; 4426 aim_locate_getinfoshort(od->sess, name, 0x00000003); 4427 } 4428 4429 static void oscar_get_away(GaimConnection *gc, const char *who) { 4430 OscarData *od = (OscarData *)gc->proto_data; 4436 4431 if (od->icq) { 4437 GaimBuddy *budlight = gaim_find_buddy(g ->account, who);4432 GaimBuddy *budlight = gaim_find_buddy(gc->account, who); 4438 4433 if (budlight) 4439 4434 if ((budlight->uc & 0xffff0000) >> 16) … … 4444 4439 else 4445 4440 gaim_debug(GAIM_DEBUG_ERROR, "oscar", 4446 "Error: Could not find %s in local contactlist, therefore unable to request status message.\n", who);4441 "Error: Could not find %s in local buddy list, therefore unable to request status message.\n", who); 4447 4442 } else 4448 aim_ getinfo(od->sess, od->conn, who, AIM_GETINFO_GENERALINFO);4449 } 4450 4451 static void oscar_set_dir(GaimConnection *g , const char *first, const char *middle, const char *last,4443 aim_locate_getinfoshort(od->sess, who, 0x00000002); 4444 } 4445 4446 static void oscar_set_dir(GaimConnection *gc, const char *first, const char *middle, const char *last, 4452 4447 const char *maiden, const char *city, const char *state, const char *country, int web) { 4453 4448 /* XXX - some of these things are wrong, but i'm lazy */ 4454 struct oscar_data *od = (struct oscar_data *)g->proto_data;4455 aim_ setdirectoryinfo(od->sess, od->conn, first, middle, last,4449 OscarData *od = (OscarData *)gc->proto_data; 4450 aim_locate_setdirinfo(od->sess, first, middle, last, 4456 4451 maiden, NULL, NULL, city, state, NULL, 0, web); 4457 4452 } 4458 4453 4459 4454 static void oscar_set_idle(GaimConnection *gc, int time) { 4460 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4461 aim_ bos_setidle(od->sess, od->conn, time);4455 OscarData *od = (OscarData *)gc->proto_data; 4456 aim_srv_setidle(od->sess, time); 4462 4457 } 4463 4458 4464 4459 static void oscar_set_info(GaimConnection *gc, const char *text) { 4465 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4460 OscarData *od = (OscarData *)gc->proto_data; 4466 4461 fu32_t flags = 0; 4467 4462 char *text_html = NULL; … … 4476 4471 "again when you are fully connected.")); 4477 4472 4478 if (od->icq) 4479 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq); 4480 else { 4481 if (!text) { 4482 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, NULL, 0, caps_aim); 4483 return; 4484 } 4473 if (!text) { 4474 aim_locate_setprofile(od->sess, NULL, "", 0, NULL, NULL, 0); 4475 return; 4476 } 4485 4477 4486 text_html = strdup_withhtml(text); 4487 flags = oscar_encoding_check(text_html); 4488 if (flags & AIM_IMFLAGS_UNICODE) { 4489 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); 4490 aim_bos_setprofile(od->sess, od->conn, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); 4491 g_free(msg); 4492 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { 4493 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); 4494 aim_bos_setprofile(od->sess, od->conn, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); 4495 g_free(msg); 4496 } else { 4497 msglen = strlen(text_html); 4498 aim_bos_setprofile(od->sess, od->conn, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); 4499 } 4500 4501 if (msglen > od->rights.maxsiglen) { 4502 gchar *errstr; 4503 errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " 4504 "has been exceeded. Gaim has truncated it for you.", 4505 "The maximum profile length of %d bytes " 4506 "has been exceeded. Gaim has truncated it for you.", 4507 od->rights.maxsiglen), od->rights.maxsiglen); 4508 gaim_notify_warning(gc, NULL, _("Profile too long."), errstr); 4509 g_free(errstr); 4510 } 4511 4512 g_free(text_html); 4513 4514 } 4478 text_html = gaim_strdup_withhtml(text); 4479 flags = oscar_encoding_check(text_html); 4480 if (flags & AIM_IMFLAGS_UNICODE) { 4481 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); 4482 aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); 4483 g_free(msg); 4484 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { 4485 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); 4486 aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); 4487 g_free(msg); 4488 } else { 4489 msglen = strlen(text_html); 4490 aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); 4491 } 4492 4493 if (msglen > od->rights.maxsiglen) { 4494 gchar *errstr; 4495 errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " 4496 "has been exceeded. Gaim has truncated it for you.", 4497 "The maximum profile length of %d bytes " 4498 "has been exceeded. Gaim has truncated it for you.", 4499 od->rights.maxsiglen), od->rights.maxsiglen); 4500 gaim_notify_warning(gc, NULL, _("Profile too long."), errstr); 4501 g_free(errstr); 4502 } 4503 4504 g_free(text_html); 4515 4505 4516 4506 return; 4517 4507 } 4518 4508 4519 static void oscar_set_away_aim(GaimConnection *gc, struct oscar_data *od, const char *text)4509 static void oscar_set_away_aim(GaimConnection *gc, OscarData *od, const char *text) 4520 4510 { 4521 4511 fu32_t flags = 0; … … 4538 4528 4539 4529 if (!text) { 4540 aim_ bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, "", 0, caps_aim);4530 aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0); 4541 4531 return; 4542 4532 } 4543 4533 4544 text_html = strdup_withhtml(text);4534 text_html = gaim_strdup_withhtml(text); 4545 4535 flags = oscar_encoding_check(text_html); 4546 4536 if (flags & AIM_IMFLAGS_UNICODE) { 4547 4537 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); 4548 aim_ bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "unicode-2-0", msg,4549 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen) , caps_aim);4538 aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, 4539 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); 4550 4540 g_free(msg); 4551 4541 gc->away = g_strndup(text, od->rights.maxawaymsglen/2); 4552 4542 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { 4553 4543 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); 4554 aim_ bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "iso-8859-1", msg,4555 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen) , caps_aim);4544 aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, 4545 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); 4556 4546 g_free(msg); 4557 4547 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); 4558 4548 } else { 4559 4549 msglen = strlen(text_html); 4560 aim_ bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "us-ascii", text_html,4561 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen) , caps_aim);4550 aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, 4551 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); 4562 4552 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); 4563 4553 } … … 4579 4569 } 4580 4570 4581 static void oscar_set_away_icq(GaimConnection *gc, struct oscar_data *od, const char *state, const char *message)4571 static void oscar_set_away_icq(GaimConnection *gc, OscarData *od, const char *state, const char *message) 4582 4572 { 4583 4573 GaimAccount *account = gaim_connection_get_account(gc); … … 4631 4621 static void oscar_set_away(GaimConnection *gc, const char *state, const char *message) 4632 4622 { 4633 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4623 OscarData *od = (OscarData *)gc->proto_data; 4634 4624 4635 4625 if (od->icq) … … 4642 4632 4643 4633 static void oscar_warn(GaimConnection *gc, const char *name, int anon) { 4644 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4634 OscarData *od = (OscarData *)gc->proto_data; 4645 4635 aim_im_warn(od->sess, od->conn, name, anon ? AIM_WARN_ANON : 0); 4646 4636 } … … 4648 4638 static void oscar_dir_search(GaimConnection *gc, const char *first, const char *middle, const char *last, 4649 4639 const char *maiden, const char *city, const char *state, const char *country, const char *email) { 4650 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4640 OscarData *od = (OscarData *)gc->proto_data; 4651 4641 if (strlen(email)) 4652 4642 aim_search_address(od->sess, od->conn, email); … … 4654 4644 4655 4645 static void oscar_add_buddy(GaimConnection *gc, const char *name, GaimGroup *g) { 4656 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4646 OscarData *od = (OscarData *)gc->proto_data; 4657 4647 #ifdef NOSSI 4658 4648 aim_add_buddy(od->sess, od->conn, name); … … 4673 4663 4674 4664 static void oscar_add_buddies(GaimConnection *gc, GList *buddies) { 4675 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4665 OscarData *od = (OscarData *)gc->proto_data; 4676 4666 #ifdef NOSSI 4677 4667 char buf[MSG_LEN]; … … 4679 4669 while (buddies) { 4680 4670 if (n > MSG_LEN - 18) { 4681 aim_b os_setbuddylist(od->sess, od->conn, buf);4671 aim_buddylist_set(od->sess, od->conn, buf); 4682 4672 n = 0; 4683 4673 } … … 4685 4675 buddies = buddies->next; 4686 4676 } 4687 aim_b os_setbuddylist(od->sess, od->conn, buf);4677 aim_buddylist_set(od->sess, od->conn, buf); 4688 4678 #else 4689 4679 if (od->sess->ssi.received_data) { 4690 4680 while (buddies) { 4691 GaimBuddy *buddy = gaim_find_buddy(gc->account, (const char *)buddies->data); 4692 GaimGroup *group = gaim_find_buddys_group(buddy); 4693 if (buddy && group) { 4694 gaim_debug(GAIM_DEBUG_INFO, "oscar", 4695 "ssi: adding buddy %s to group %s\n", (const char *)buddies->data, group->name); 4696 aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0); 4697 } 4681 oscar_add_buddy(gc, (const char *)buddies->data, NULL); 4698 4682 buddies = buddies->next; 4699 4683 } … … 4703 4687 4704 4688 static void oscar_remove_buddy(GaimConnection *gc, const char *name, const char *group) { 4705 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4689 OscarData *od = (OscarData *)gc->proto_data; 4706 4690 #ifdef NOSSI 4707 4691 aim_remove_buddy(od->sess, od->conn, name); … … 4716 4700 4717 4701 static void oscar_remove_buddies(GaimConnection *gc, GList *buddies, const char *group) { 4718 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4702 OscarData *od = (OscarData *)gc->proto_data; 4719 4703 #ifdef NOSSI 4720 4704 GList *cur; … … 4735 4719 #ifndef NOSSI 4736 4720 static void oscar_move_buddy(GaimConnection *gc, const char *name, const char *old_group, const char *new_group) { 4737 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4721 OscarData *od = (OscarData *)gc->proto_data; 4738 4722 if (od->sess->ssi.received_data && strcmp(old_group, new_group)) { 4739 4723 gaim_debug(GAIM_DEBUG_INFO, "oscar", … … 4744 4728 4745 4729 static void oscar_alias_buddy(GaimConnection *gc, const char *name, const char *alias) { 4746 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4730 OscarData *od = (OscarData *)gc->proto_data; 4747 4731 if (od->sess->ssi.received_data) { 4748 4732 char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, name); … … 4756 4740 4757 4741 static void oscar_rename_group(GaimConnection *g, const char *old_group, const char *new_group, GList *members) { 4758 struct oscar_data *od = (struct oscar_data *)g->proto_data;4742 OscarData *od = (OscarData *)g->proto_data; 4759 4743 4760 4744 if (od->sess->ssi.received_data) { … … 4780 4764 static int gaim_ssi_parseerr(aim_session_t *sess, aim_frame_t *fr, ...) { 4781 4765 GaimConnection *gc = sess->aux_data; 4782 struct oscar_data *od = gc->proto_data;4766 OscarData *od = gc->proto_data; 4783 4767 va_list ap; 4784 4768 fu16_t reason; … … 4807 4791 static int gaim_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...) { 4808 4792 GaimConnection *gc = sess->aux_data; 4809 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4793 OscarData *od = (OscarData *)gc->proto_data; 4810 4794 int numtypes, i; 4811 4795 fu16_t *maxitems; … … 4840 4824 GaimConnection *gc = sess->aux_data; 4841 4825 GaimAccount *account = gaim_connection_get_account(gc); 4842 struct oscar_data *od = (struct oscar_data *)gc->proto_data;4826 OscarData *od = (OscarData *)gc->proto_data; 4843 4827 struct aim_ssi_item *curitem; 4844 4828 int tmp; … … 4862 4846 /* Add from server list to local list */ 4863 4847 for (curitem=sess->ssi.local; curitem; curitem=curitem->next) { 4848 if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL))) 4864 4849 switch (curitem->type) { 4865 4850 case 0x0000: { /* Buddy */ 4866 4851 if (curitem->name) { 4867 4852 char *gname = aim_ssi_itemlist_findparentname(sess->ssi.local, curitem->name); 4868 char *gname_utf8 = g aim_try_conv_to_utf8(gname);4853 char *gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL; 4869 4854 char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name); 4870 char *alias_utf8 = gaim_try_conv_to_utf8(alias);4855 char *alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL; 4871 4856 GaimBuddy *buddy = gaim_find_buddy(gc->account, curitem->name); 4872 4857 /* Should gname be freed here? -- elb */ … … 4893 4878 export = TRUE; 4894 4879 } 4895 free(gname_utf8);4896 free(alias_utf8);4880 g_free(gname_utf8); 4881 g_free(alias_utf8); 4897 4882 } 4898 4883 } break; … … 4958 4943 GaimGroup *group; 4959 4944 GaimBuddy *buddy; 4960 struct gaim_buddy_list *blist;4945 GaimBuddyList *blist; 4961 4946 GSList *cur; 4962 4947 … … 4975 4960 buddy = (GaimBuddy *)bnode; 4976 4961 if (buddy->account == gc->account) { 4977 gchar *servernick = gaim_buddy_get_setting(buddy, "servernick");4978 if (servernick) {4962 const char *servernick = gaim_buddy_get_setting(buddy, "servernick"); 4963 if (servernick) 4979 4964 serv_got_alias(gc, buddy->name, servernick); 4980 g_free(servernick); 4981 } 4965 4982 4966 if (aim_ssi_itemlist_exists(sess->ssi.local, buddy->name)) { 4983 4967 /* Store local alias on server */ … … 5061 5045 } 5062 5046 5063 case 0x000e: { /* contactrequires authorization */5047 case 0x000e: { /* buddy requires authorization */ 5064 5048 if ((retval->action == AIM_CB_SSI_ADD) && (retval->name)) 5065 5049 gaim_auth_sendrequest(gc, retval->name); … … 5112 5096 gaim_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg, 5113 5097 0, data, 5114 G_CALLBACK(gaim_icq_ contactadd),5098 G_CALLBACK(gaim_icq_buddyadd), 5115 5099 G_CALLBACK(oscar_free_name_data)); 5116 5100 … … 5185 5169 if (reply) { 5186 5170 /* Granted */ 5187 dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your contactlist."), nombre);5171 dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your buddy list."), nombre); 5188 5172 gaim_notify_info(gc, NULL, _("Authorization Granted"), dialog_msg); 5189 5173 } else { 5190 5174 /* Denied */ 5191 dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your contactlist for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));5175 dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given.")); 5192 5176 gaim_notify_info(gc, NULL, _("Authorization Denied"), dialog_msg); 5193 5177 } … … 5211 5195 gaim_debug(GAIM_DEBUG_INFO, "oscar", 5212 5196 "ssi: %s added you to their buddy list\n", sn); 5213 show_got_added(gc, NULL, sn, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);5197 gaim_account_notify_added(gc->account, NULL, sn, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL); 5214 5198 5215 5199 return 1; … … 5238 5222 5239 5223 static void oscar_join_chat(GaimConnection *g, GHashTable *data) { 5240 struct oscar_data *od = (struct oscar_data *)g->proto_data;5224 OscarData *od = (OscarData *)g->proto_data; 5241 5225 aim_conn_t *cur; 5242 5226 char *name, *exchange; … … 5264 5248 5265 5249 static void oscar_chat_invite(GaimConnection *g, int id, const char *message, const char *name) { 5266 struct oscar_data *od = (struct oscar_data *)g->proto_data;5250 OscarData *od = (OscarData *)g->proto_data; 5267 5251 struct chat_connection *ccon = find_oscar_chat(g, id); 5268 5252 … … 5275 5259 5276 5260 static void oscar_chat_leave(GaimConnection *g, int id) { 5277 struct oscar_data *od = g ? (struct oscar_data *)g->proto_data : NULL;5261 OscarData *od = g ? (OscarData *)g->proto_data : NULL; 5278 5262 GSList *bcs = g->buddy_chats; 5279 5263 GaimConversation *b = NULL; … … 5284 5268 count++; 5285 5269 b = (GaimConversation *)bcs->data; 5286 if (id == gaim_c hat_get_id(GAIM_CHAT(b)))5270 if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))) 5287 5271 break; 5288 5272 bcs = bcs->next; … … 5296 5280 "Attempting to leave room %s (currently in %d rooms)\n", b->name, count); 5297 5281 5298 c = find_oscar_chat(g, gaim_c hat_get_id(GAIM_CHAT(b)));5282 c = find_oscar_chat(g, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))); 5299 5283 if (c != NULL) { 5300 5284 if (od) … … 5309 5293 } 5310 5294 /* we do this because with Oscar it doesn't tell us we left */ 5311 serv_got_chat_left(g, gaim_c hat_get_id(GAIM_CHAT(b)));5295 serv_got_chat_left(g, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))); 5312 5296 } 5313 5297 5314 5298 static int oscar_chat_send(GaimConnection *g, int id, const char *message) { 5315 struct oscar_data *od = (struct oscar_data *)g->proto_data;5299 OscarData *od = (OscarData *)g->proto_data; 5316 5300 GSList *bcs = g->buddy_chats; 5317 5301 GaimConversation *b = NULL; … … 5322 5306 while (bcs) { 5323 5307 b = (GaimConversation *)bcs->data; 5324 if (id == gaim_c hat_get_id(GAIM_CHAT(b)))5308 if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))) 5325 5309 break; 5326 5310 bcs = bcs->next; … … 5357 5341 return -E2BIG; 5358 5342 5359 buf2 = strip_html(buf);5343 buf2 = gaim_markup_strip_html(buf); 5360 5344 if (strlen(buf2) > c->maxvis) { 5361 5345 g_free(buf2); … … 5384 5368 static void oscar_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) 5385 5369 { 5370 GaimAccount *account = NULL; 5371 GaimConnection *gc = NULL; 5372 OscarData *od = NULL; 5386 5373 char *emblems[4] = {NULL,NULL,NULL,NULL}; 5387 5374 int i = 0; 5375 aim_userinfo_t *userinfo = NULL; 5376 5377 if (b != NULL) 5378 account = b->account; 5379 if (account != NULL) 5380 gc = account->gc; 5381 if (gc != NULL) 5382 od = gc->proto_data; 5388 5383 5389 5384 if (!GAIM_BUDDY_IS_ONLINE(b)) { 5390 GaimAccount *account;5391 GaimConnection *gc;5392 struct oscar_data *od;5393 5385 char *gname; 5394 if ((b->name) && (account = b->account) && (gc = account->gc) && 5395 (od = gc->proto_data) && (od->sess->ssi.received_data) && 5386 if ((b->name) && (od) && (od->sess->ssi.received_data) && 5396 5387 (gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name)) && 5397 5388 (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name))) { … … 5432 5423 /* if (b->uc & UC_UNCONFIRMED && i < 4) 5433 5424 emblems[i++] = "unconfirmed"; */ 5425 5426 if ((i < 4) && (od != NULL)) { 5427 userinfo = aim_locate_finduserinfo(od->sess, b->name); 5428 if ((userinfo != NULL) && (userinfo->capabilities & AIM_CAPS_SECUREIM)) 5429 emblems[i++] = "secure"; 5430 } 5431 5434 5432 *se = emblems[0]; 5435 5433 *sw = emblems[1]; … … 5440 5438 static char *oscar_tooltip_text(GaimBuddy *b) { 5441 5439 GaimConnection *gc = b->account->gc; 5442 struct oscar_data *od = gc->proto_data; 5443 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name)); 5444 gchar *tmp, *yay = g_strdup(""); 5440 OscarData *od = gc->proto_data; 5441 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(b->account, b->name)); 5442 aim_userinfo_t *userinfo = aim_locate_finduserinfo(od->sess, b->name); 5443 gchar *tmp = NULL, *ret = g_strdup(""); 5445 5444 5446 5445 if (GAIM_BUDDY_IS_ONLINE(b)) { 5447 5446 if (isdigit(b->name[0])) { 5448 char * tmp, *status;5447 char *status; 5449 5448 status = gaim_icq_status((b->uc & 0xffff0000) >> 16); 5450 tmp = yay;5451 yay= g_strconcat(tmp, _("<b>Status:</b> "), status, "\n", NULL);5449 tmp = ret; 5450 ret = g_strconcat(tmp, _("<b>Status:</b> "), status, "\n", NULL); 5452 5451 g_free(tmp); 5453 5452 g_free(status); 5454 5453 } 5455 5454 5456 if ( bi) {5457 char *tstr = sec_to_text(time(NULL) - bi->signon +5455 if (userinfo != NULL) { 5456 char *tstr = gaim_str_seconds_to_string(time(NULL) - userinfo->onlinesince + 5458 5457 (gc->login_time_official ? gc->login_time_official - gc->login_time : 0)); 5459 tmp = yay; 5460 yay = g_strconcat(tmp, _("<b>Logged In:</b> "), tstr, "\n", NULL); 5461 free(tmp); 5462 free(tstr); 5463 5464 if (bi->ipaddr) { 5465 char *tstr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", 5466 (bi->ipaddr & 0xff000000) >> 24, 5467 (bi->ipaddr & 0x00ff0000) >> 16, 5468 (bi->ipaddr & 0x0000ff00) >> 8, 5469 (bi->ipaddr & 0x000000ff)); 5470 tmp = yay; 5471 yay = g_strconcat(tmp, _("<b>IP Address:</b> "), tstr, "\n", NULL); 5472 free(tmp); 5473 free(tstr); 5474 } 5475 5476 if (bi->caps) { 5477 char *caps = caps_string(bi->caps); 5478 tmp = yay; 5479 yay = g_strconcat(tmp, _("<b>Capabilities:</b> "), caps, "\n", NULL); 5480 free(tmp); 5481 } 5482 5483 if (bi->availmsg && !(b->uc & UC_UNAVAILABLE)) { 5484 gchar *escaped = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); 5485 tmp = yay; 5486 yay = g_strconcat(tmp, _("<b>Available:</b> "), escaped, "\n", NULL); 5487 free(tmp); 5488 g_free(escaped); 5458 tmp = ret; 5459 ret = g_strconcat(tmp, _("<b>Logged In:</b> "), tstr, "\n", NULL); 5460 g_free(tmp); 5461 g_free(tstr); 5462 } 5463 5464 if ((bi != NULL) && (bi->ipaddr)) { 5465 char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", 5466 (bi->ipaddr & 0xff000000) >> 24, 5467 (bi->ipaddr & 0x00ff0000) >> 16, 5468 (bi->ipaddr & 0x0000ff00) >> 8, 5469 (bi->ipaddr & 0x000000ff)); 5470 tmp = ret; 5471 ret = g_strconcat(tmp, _("<b>IP Address:</b> "), tstr, "\n", NULL); 5472 g_free(tmp); 5473 g_free(tstr); 5474 } 5475 5476 if ((userinfo != NULL) && (userinfo->capabilities)) { 5477 char *caps = caps_string(userinfo->capabilities); 5478 tmp = ret; 5479 ret = g_strconcat(tmp, _("<b>Capabilities:</b> "), caps, "\n", NULL); 5480 g_free(tmp); 5481 } 5482 5483 if ((bi != NULL) && (bi->availmsg != NULL) && !(b->uc & UC_UNAVAILABLE)) { 5484 gchar *escaped = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); 5485 tmp = ret; 5486 ret = g_strconcat(tmp, _("<b>Available:</b> "), escaped, "\n", NULL); 5487 g_free(tmp); 5488 g_free(escaped); 5489 } 5490 5491 if ((userinfo != NULL) && (userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) { 5492 gchar *away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len); 5493 if (away_utf8 != NULL) { 5494 gchar *tmp1, *tmp2; 5495 const char *tmp3; 5496 tmp1 = gaim_strreplace(away_utf8, "<BR>", "\n"); 5497 tmp2 = gaim_markup_strip_html(tmp1); 5498 g_free(tmp1); 5499 tmp1 = g_markup_escape_text(tmp2, strlen(tmp2)); 5500 g_free(tmp2); 5501 tmp3 = gaim_str_sub_away_formatters(tmp1, gaim_account_get_username(gaim_connection_get_account(gc))); 5502 g_free(tmp1); 5503 tmp = ret; 5504 ret = g_strconcat(tmp, _("<b>Away Message:</b> "), tmp3, "\n", NULL); 5505 g_free(tmp); 5506 g_free(away_utf8); 5489 5507 } 5490 5508 } … … 5492 5510 char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name); 5493 5511 if (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name)) { 5494 tmp = yay;5495 yay= g_strconcat(tmp, _("<b>Status:</b> Not Authorized"), "\n", NULL);5512 tmp = ret; 5513 ret = g_strconcat(tmp, _("<b>Status:</b> Not Authorized"), "\n", NULL); 5496 5514 g_free(tmp); 5497 5515 } else { 5498 tmp = yay;5499 yay= g_strconcat(tmp, _("<b>Status:</b> Offline"), "\n", NULL);5516 tmp = ret; 5517 ret = g_strconcat(tmp, _("<b>Status:</b> Offline"), "\n", NULL); 5500 5518 g_free(tmp); 5501 5519 } … … 5503 5521 5504 5522 /* remove the trailing newline character */ 5505 if ( yay)5506 yay[strlen(yay)-1] = '\0';5507 return yay;5523 if (ret) 5524 ret[strlen(ret)-1] = '\0'; 5525 return ret; 5508 5526 } 5509 5527 5510 5528 static char *oscar_status_text(GaimBuddy *b) { 5511 5529 GaimConnection *gc = b->account->gc; 5512 struct oscar_data *od = gc->proto_data;5530 OscarData *od = gc->proto_data; 5513 5531 gchar *ret = NULL; 5514 5532 … … 5519 5537 ret = g_strdup(_("Away")); 5520 5538 } else if (GAIM_BUDDY_IS_ONLINE(b)) { 5521 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name));5539 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(b->account, b->name)); 5522 5540 if (bi->availmsg) 5523 5541 ret = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); … … 5536 5554 static int oscar_icon_req(aim_session_t *sess, aim_frame_t *fr, ...) { 5537 5555 GaimConnection *gc = sess->aux_data; 5538 struct oscar_data *od = gc->proto_data;5556 OscarData *od = gc->proto_data; 5539 5557 va_list ap; 5540 5558 fu16_t type; 5541 5559 fu8_t flags = 0, length = 0; 5542 5560 char *md5 = NULL; 5561 5543 5562 5544 5563 va_start(ap, fr); … … 5598 5617 static int gaim_odc_initiate(aim_session_t *sess, aim_frame_t *fr, ...) { 5599 5618 GaimConnection *gc = sess->aux_data; 5600 struct oscar_data *od = (struct oscar_data *)gc->proto_data;5619 OscarData *od = (OscarData *)gc->proto_data; 5601 5620 GaimConversation *cnv; 5602 5621 struct direct_im *dim; … … 5646 5665 double percent; 5647 5666 GaimConnection *gc = sess->aux_data; 5648 struct oscar_data *od = (struct oscar_data *)gc->proto_data;5667 OscarData *od = (OscarData *)gc->proto_data; 5649 5668 GaimConversation *c; 5650 5669 struct direct_im *dim; … … 5662 5681 } 5663 5682 /* XXX is this really necessary? */ 5664 while (gtk_events_pending()) 5665 gtk_main_iteration(); 5683 gaim_core_mainloop_finish_events(); 5666 5684 5667 5685 c = gaim_find_conversation_with_account(sn, gaim_connection_get_account(gc)); … … 5705 5723 static int gaim_odc_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { 5706 5724 GaimConnection *gc = sess->aux_data; 5707 Gaim ImFlags imflags = 0;5725 GaimConvImFlags imflags = 0; 5708 5726 GString *newmsg = g_string_new(""); 5709 5727 GSList *images = NULL; … … 5726 5744 5727 5745 if (isawaymsg) 5728 imflags |= GAIM_ IM_AUTO_RESP;5746 imflags |= GAIM_CONV_IM_AUTO_RESP; 5729 5747 5730 5748 /* message has a binary trailer */ … … 5790 5808 /* set the flag if we caught any images */ 5791 5809 if (images) 5792 imflags |= GAIM_ IM_IMAGES;5810 imflags |= GAIM_CONV_IM_IMAGES; 5793 5811 } else { 5794 5812 g_string_append_len(newmsg, msg, len); … … 5840 5858 } 5841 5859 5842 static int gaim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *message, Gaim ImFlags imflags) {5860 static int gaim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *message, GaimConvImFlags imflags) { 5843 5861 char *buf; 5844 5862 size_t len; 5845 5863 int ret; 5846 5864 5847 if (imflags & GAIM_ IM_IMAGES) {5865 if (imflags & GAIM_CONV_IM_IMAGES) { 5848 5866 GString *msg = g_string_new(""); 5849 5867 GString *data = g_string_new("<BINARY>"); … … 5872 5890 g_string_append_printf(msg, 5873 5891 "<IMG SRC=\"file://%s\" ID=\"%d\" DATASIZE=\"%d\">", 5874 image->filename, oscar_id, image->size);5892 image->filename, oscar_id, (int)image->size); 5875 5893 else 5876 5894 g_string_append_printf(msg, 5877 5895 "<IMG ID=\"%d\" DATASIZE=\"%d\">", 5878 oscar_id, image->size);5896 oscar_id, (int)image->size); 5879 5897 5880 5898 /* ... and append the data to the binary section ... */ 5881 5899 g_string_append_printf(data, "<DATA ID=\"%d\" SIZE=\"%d\">", 5882 oscar_id, image->size);5900 oscar_id, (int)image->size); 5883 5901 data = g_string_append_len(data, image->data, image->size); 5884 5902 data = g_string_append(data, "</DATA>"); … … 5915 5933 5916 5934 /* XXX - The last parameter below is the encoding. Let Paco-Paco do something with it. */ 5917 if (imflags & GAIM_ IM_AUTO_RESP)5935 if (imflags & GAIM_CONV_IM_AUTO_RESP) 5918 5936 ret = aim_odc_send_im(sess, conn, buf, len, 0, 1); 5919 5937 else … … 5937 5955 static void oscar_direct_im(struct ask_do_dir_im *data) { 5938 5956 GaimConnection *gc = data->gc; 5939 struct oscar_data *od;5957 OscarData *od; 5940 5958 struct direct_im *dim; 5941 5959 … … 5946 5964 } 5947 5965 5948 od = ( struct oscar_data *)gc->proto_data;5966 od = (OscarData *)gc->proto_data; 5949 5967 5950 5968 dim = find_direct_im(od, data->who); … … 6002 6020 static void oscar_set_permit_deny(GaimConnection *gc) { 6003 6021 GaimAccount *account = gaim_connection_get_account(gc); 6004 struct oscar_data *od = (struct oscar_data *)gc->proto_data;6022 OscarData *od = (OscarData *)gc->proto_data; 6005 6023 #ifdef NOSSI 6006 6024 GSList *list, *g = gaim_blist_groups(), *g1; … … 6066 6084 oscar_set_permit_deny(gc); 6067 6085 #else 6068 struct oscar_data *od = (struct oscar_data *)gc->proto_data;6086 OscarData *od = (OscarData *)gc->proto_data; 6069 6087 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to add a permit\n"); 6070 6088 if (od->sess->ssi.received_data) … … 6078 6096 oscar_set_permit_deny(gc); 6079 6097 #else 6080 struct oscar_data *od = (struct oscar_data *)gc->proto_data;6098 OscarData *od = (OscarData *)gc->proto_data; 6081 6099 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to add a deny\n"); 6082 6100 if (od->sess->ssi.received_data) … … 6090 6108 oscar_set_permit_deny(gc); 6091 6109 #else 6092 struct oscar_data *od = (struct oscar_data *)gc->proto_data;6110 OscarData *od = (OscarData *)gc->proto_data; 6093 6111 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to delete a permit\n"); 6094 6112 if (od->sess->ssi.received_data) … … 6102 6120 oscar_set_permit_deny(gc); 6103 6121 #else 6104 struct oscar_data *od = (struct oscar_data *)gc->proto_data;6122 OscarData *od = (OscarData *)gc->proto_data; 6105 6123 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to delete a deny\n"); 6106 6124 if (od->sess->ssi.received_data) … … 6111 6129 static GList *oscar_away_states(GaimConnection *gc) 6112 6130 { 6113 struct oscar_data *od = gc->proto_data;6131 OscarData *od = gc->proto_data; 6114 6132 GList *m = NULL; 6115 6133 … … 6128 6146 } 6129 6147 6148 static void oscar_ssi_editcomment(struct name_data *data, const char *text) { 6149 OscarData *od = data->gc->proto_data; 6150 GaimBuddy *b; 6151 GaimGroup *g; 6152 6153 if (!(b = gaim_find_buddy(gaim_connection_get_account(data->gc), data->name))) { 6154 oscar_free_name_data(data); 6155 return; 6156 } 6157 6158 if (!(g = gaim_find_buddys_group(b))) { 6159 oscar_free_name_data(data); 6160 return; 6161 } 6162 6163 aim_ssi_editcomment(od->sess, g->name, data->name, text); 6164 oscar_free_name_data(data); 6165 } 6166 6167 static void oscar_buddycb_edit_comment(GaimConnection *gc, const char *name) { 6168 OscarData *od = gc->proto_data; 6169 struct name_data *data = g_new(struct name_data, 1); 6170 GaimBuddy *b; 6171 GaimGroup *g; 6172 char *comment; 6173 gchar *comment_utf8; 6174 6175 if (!(b = gaim_find_buddy(gaim_connection_get_account(gc), name))) 6176 return; 6177 if (!(g = gaim_find_buddys_group(b))) 6178 return; 6179 comment = aim_ssi_getcomment(od->sess->ssi.local, g->name, name); 6180 comment_utf8 = comment ? gaim_utf8_try_convert(comment) : NULL; 6181 6182 data->gc = gc; 6183 data->name = g_strdup(name); 6184 data->nick = NULL; 6185 6186 gaim_request_input(gc, NULL, _("Buddy Comment:"), NULL, 6187 comment_utf8, TRUE, FALSE, 6188 _("OK"), G_CALLBACK(oscar_ssi_editcomment), 6189 _("Cancel"), G_CALLBACK(oscar_free_name_data), 6190 data); 6191 6192 free(comment); 6193 g_free(comment_utf8); 6194 } 6195 6130 6196 static GList *oscar_buddy_menu(GaimConnection *gc, const char *who) { 6131 struct oscar_data *od = gc->proto_data;6197 OscarData *od = gc->proto_data; 6132 6198 GList *m = NULL; 6133 6199 struct proto_buddy_menu *pbm; 6200 6201 pbm = g_new0(struct proto_buddy_menu, 1); 6202 pbm->label = _("Edit Buddy Comment"); 6203 pbm->callback = oscar_buddycb_edit_comment; 6204 pbm->gc = gc; 6205 m = g_list_append(m, pbm); 6134 6206 6135 6207 if (od->icq) { … … 6143 6215 } else { 6144 6216 GaimBuddy *b = gaim_find_buddy(gc->account, who); 6145 struct buddyinfo *bi;6217 aim_userinfo_t *userinfo; 6146 6218 6147 6219 if (b) 6148 bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name));6149 6150 if (b && bi&& aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) {6151 if ( bi->caps & AIM_CAPS_DIRECTIM) {6220 userinfo = aim_locate_finduserinfo(od->sess, b->name); 6221 6222 if (b && userinfo && aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) { 6223 if (userinfo->capabilities & AIM_CAPS_DIRECTIM) { 6152 6224 pbm = g_new0(struct proto_buddy_menu, 1); 6153 6225 pbm->label = _("Direct IM"); … … 6157 6229 } 6158 6230 6159 if ( bi->caps & AIM_CAPS_SENDFILE) {6231 if (userinfo->capabilities & AIM_CAPS_SENDFILE) { 6160 6232 pbm = g_new0(struct proto_buddy_menu, 1); 6161 6233 pbm->label = _("Send File"); … … 6165 6237 } 6166 6238 #if 0 6167 if ( bi->caps & AIM_CAPS_GETFILE) {6239 if (userinfo->capabilities & AIM_CAPS_GETFILE) { 6168 6240 pbm = g_new0(struct proto_buddy_menu, 1); 6169 6241 pbm->label = _("Get File"); … … 6191 6263 6192 6264 static void oscar_format_screenname(GaimConnection *gc, const char *nick) { 6193 struct oscar_data *od = gc->proto_data;6265 OscarData *od = gc->proto_data; 6194 6266 if (!aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), nick)) { 6195 6267 if (!aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH)) { … … 6217 6289 static void oscar_confirm_account(GaimConnection *gc) 6218 6290 { 6219 struct oscar_data *od = gc->proto_data;6291 OscarData *od = gc->proto_data; 6220 6292 aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH); 6221 6293 … … 6230 6302 static void oscar_show_email(GaimConnection *gc) 6231 6303 { 6232 struct oscar_data *od = gc->proto_data;6304 OscarData *od = gc->proto_data; 6233 6305 aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH); 6234 6306 … … 6243 6315 static void oscar_change_email(GaimConnection *gc, const char *email) 6244 6316 { 6245 struct oscar_data *od = gc->proto_data;6317 OscarData *od = gc->proto_data; 6246 6318 aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH); 6247 6319 … … 6266 6338 static void oscar_show_awaitingauth(GaimConnection *gc) 6267 6339 { 6268 struct oscar_data *od = gc->proto_data;6340 OscarData *od = gc->proto_data; 6269 6341 gchar *nombre, *text, *tmp; 6270 6342 GaimBlistNode *gnode, *cnode, *bnode; … … 6312 6384 } 6313 6385 6386 static void search_by_email_cb(GaimConnection *gc, const char *email) 6387 { 6388 serv_dir_search(gc, "", "", "", "", "", "", "", email); 6389 } 6390 6391 static void oscar_show_find_email(GaimConnection *gc) 6392 { 6393 gaim_request_input(gc, _("Find Buddy by E-mail"), 6394 _("Search for a buddy by e-mail address"), 6395 _("Type the e-mail address of the buddy you are " 6396 "searching for."), 6397 NULL, FALSE, FALSE, 6398 _("Search"), G_CALLBACK(search_by_email_cb), 6399 _("Cancel"), NULL, gc); 6400 } 6401 6314 6402 #if 0 6315 6403 static void oscar_setavailmsg(GaimConnection *gc, char *text) { 6316 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 6317 6404 OscarData *od = (OscarData *)gc->proto_data; 6405 6406 aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0); 6318 6407 aim_srv_setavailmsg(od->sess, text); 6319 6408 } … … 6321 6410 static void oscar_show_setavailmsg(GaimConnection *gc) 6322 6411 { 6323 gaim_request_input(gc, NULL, _("Available Message:"), 6324 NULL, _("Please talk to me, I'm lonely! (and single)"), TRUE, FALSE, 6412 gaim_request_input(gc, NULL, _("Available Message:"), NULL, 6413 _("I'm doing work and hoping for a distraction--IM me!"), 6414 TRUE, FALSE, 6325 6415 _("OK"), G_CALLBACK(oscar_setavailmsg), 6326 6416 _("Cancel"), NULL, … … 6329 6419 #endif 6330 6420 6421 static void oscar_show_set_info(GaimConnection *gc) 6422 { 6423 gaim_account_request_change_user_info(gaim_connection_get_account(gc)); 6424 } 6425 6426 static void oscar_change_pass(GaimConnection *gc) 6427 { 6428 gaim_account_request_change_password(gaim_connection_get_account(gc)); 6429 } 6430 6331 6431 static void oscar_show_chpassurl(GaimConnection *gc) 6332 6432 { 6333 struct oscar_data *od = gc->proto_data;6433 OscarData *od = gc->proto_data; 6334 6434 gchar *substituted = gaim_strreplace(od->sess->authinfo->chpassurl, "%s", gaim_account_get_username(gaim_connection_get_account(gc))); 6335 6435 gaim_notify_uri(gc, substituted); … … 6337 6437 } 6338 6438 6439 static void oscar_show_imforwardingurl(GaimConnection *gc) 6440 { 6441 gaim_notify_uri(gc, "http://mymobile.aol.com/dbreg/register?action=imf&clientID=1"); 6442 } 6443 6339 6444 static void oscar_set_icon(GaimConnection *gc, const char *iconfile) 6340 6445 { 6341 struct oscar_data *od = gc->proto_data;6446 OscarData *od = gc->proto_data; 6342 6447 aim_session_t *sess = od->sess; 6343 6448 FILE *file; … … 6372 6477 static GList *oscar_actions(GaimConnection *gc) 6373 6478 { 6374 struct oscar_data *od = gc->proto_data;6479 OscarData *od = gc->proto_data; 6375 6480 struct proto_actions_menu *pam; 6376 6481 GList *m = NULL; … … 6378 6483 pam = g_new0(struct proto_actions_menu, 1); 6379 6484 pam->label = _("Set User Info"); 6380 pam->callback = show_set_info;6485 pam->callback = oscar_show_set_info; 6381 6486 pam->gc = gc; 6382 6487 m = g_list_append(m, pam); … … 6392 6497 pam = g_new0(struct proto_actions_menu, 1); 6393 6498 pam->label = _("Change Password"); 6394 pam->callback = show_change_passwd;6499 pam->callback = oscar_change_pass; 6395 6500 pam->gc = gc; 6396 6501 m = g_list_append(m, pam); … … 6404 6509 } 6405 6510 6511 if (od->sess->authinfo->chpassurl) { 6512 pam = g_new0(struct proto_actions_menu, 1); 6513 pam->label = _("Configure IM Forwarding (URL)"); 6514 pam->callback = oscar_show_imforwardingurl; 6515 pam->gc = gc; 6516 m = g_list_append(m, pam); 6517 } 6518 6406 6519 if (!od->icq) { 6407 6520 /* AIM actions */ … … 6445 6558 pam = g_new0(struct proto_actions_menu, 1); 6446 6559 pam->label = _("Search for Buddy by Email"); 6447 pam->callback = show_find_email;6560 pam->callback = oscar_show_find_email; 6448 6561 pam->gc = gc; 6449 6562 m = g_list_append(m, pam); … … 6460 6573 static void oscar_change_passwd(GaimConnection *gc, const char *old, const char *new) 6461 6574 { 6462 struct oscar_data *od = gc->proto_data;6575 OscarData *od = gc->proto_data; 6463 6576 6464 6577 if (od->icq) { … … 6479 6592 static void oscar_convo_closed(GaimConnection *gc, const char *who) 6480 6593 { 6481 struct oscar_data *od = gc->proto_data;6594 OscarData *od = gc->proto_data; 6482 6595 struct direct_im *dim = find_direct_im(od, who); 6483 6596 -
libfaim/popups.c
r862371b rcf02dd6 23 23 fu16_t width, height, delay; 24 24 25 tl = aim_ readtlvchain(bs);25 tl = aim_tlvlist_read(bs); 26 26 27 msg = aim_ gettlv_str(tl, 0x0001, 1);28 url = aim_ gettlv_str(tl, 0x0002, 1);29 width = aim_ gettlv16(tl, 0x0003, 1);30 height = aim_ gettlv16(tl, 0x0004, 1);31 delay = aim_ gettlv16(tl, 0x0005, 1);27 msg = aim_tlv_getstr(tl, 0x0001, 1); 28 url = aim_tlv_getstr(tl, 0x0002, 1); 29 width = aim_tlv_get16(tl, 0x0003, 1); 30 height = aim_tlv_get16(tl, 0x0004, 1); 31 delay = aim_tlv_get16(tl, 0x0005, 1); 32 32 33 33 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 34 34 ret = userfunc(sess, rx, msg, url, width, height, delay); 35 35 36 aim_ freetlvchain(&tl);36 aim_tlvlist_free(&tl); 37 37 free(msg); 38 38 free(url); -
libfaim/rxhandlers.c
re374dee rcf02dd6 185 185 return consumenonsnac(sess, fr, 0x0017, 0x0003); 186 186 187 tlvlist = aim_ readtlvchain(&fr->data);188 189 if (aim_ gettlv(tlvlist, 0x0009, 1))190 code = aim_ gettlv16(tlvlist, 0x0009, 1);191 192 if (aim_ gettlv(tlvlist, 0x000b, 1))193 msg = aim_ gettlv_str(tlvlist, 0x000b, 1);187 tlvlist = aim_tlvlist_read(&fr->data); 188 189 if (aim_tlv_gettlv(tlvlist, 0x0009, 1)) 190 code = aim_tlv_get16(tlvlist, 0x0009, 1); 191 192 if (aim_tlv_gettlv(tlvlist, 0x000b, 1)) 193 msg = aim_tlv_getstr(tlvlist, 0x000b, 1); 194 194 195 195 if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) 196 196 ret = userfunc(sess, fr, code, msg); 197 197 198 aim_ freetlvchain(&tlvlist);198 aim_tlvlist_free(&tlvlist); 199 199 200 200 free(msg); -
libfaim/search.c
re374dee rcf02dd6 78 78 searchaddr = (char *)snac2->data; 79 79 80 tlvlist = aim_ readtlvchain(bs);81 m = aim_ counttlvchain(&tlvlist);80 tlvlist = aim_tlvlist_read(bs); 81 m = aim_tlvlist_count(&tlvlist); 82 82 83 /* XXX uhm. */ 84 while ((cur = aim_gettlv_str(tlvlist, 0x0001, j+1)) && j < m) { 83 /* XXX uhm. 84 * This is the only place that uses something other than 1 for the 3rd 85 * parameter to aim_tlv_gettlv_whatever(). 86 */ 87 while ((cur = aim_tlv_getstr(tlvlist, 0x0001, j+1)) && j < m) { 85 88 buf = realloc(buf, (j+1) * (MAXSNLEN+1)); 86 89 … … 91 94 } 92 95 93 aim_ freetlvchain(&tlvlist);96 aim_tlvlist_free(&tlvlist); 94 97 95 98 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) -
libfaim/service.c
re374dee rcf02dd6 109 109 memset(&redir, 0, sizeof(redir)); 110 110 111 tlvlist = aim_ readtlvchain(bs);112 113 if (!aim_ gettlv(tlvlist, 0x000d, 1) ||114 !aim_ gettlv(tlvlist, 0x0005, 1) ||115 !aim_ gettlv(tlvlist, 0x0006, 1)) {116 aim_ freetlvchain(&tlvlist);111 tlvlist = aim_tlvlist_read(bs); 112 113 if (!aim_tlv_gettlv(tlvlist, 0x000d, 1) || 114 !aim_tlv_gettlv(tlvlist, 0x0005, 1) || 115 !aim_tlv_gettlv(tlvlist, 0x0006, 1)) { 116 aim_tlvlist_free(&tlvlist); 117 117 return 0; 118 118 } 119 119 120 redir.group = aim_ gettlv16(tlvlist, 0x000d, 1);121 redir.ip = aim_ gettlv_str(tlvlist, 0x0005, 1);122 redir.cookielen = aim_ gettlv(tlvlist, 0x0006, 1)->length;123 redir.cookie = aim_ gettlv_str(tlvlist, 0x0006, 1);120 redir.group = aim_tlv_get16(tlvlist, 0x000d, 1); 121 redir.ip = aim_tlv_getstr(tlvlist, 0x0005, 1); 122 redir.cookielen = aim_tlv_gettlv(tlvlist, 0x0006, 1)->length; 123 redir.cookie = aim_tlv_getstr(tlvlist, 0x0006, 1); 124 124 125 125 /* Fetch original SNAC so we can get csi if needed */ … … 144 144 free(origsnac); 145 145 146 aim_ freetlvchain(&tlvlist);146 aim_tlvlist_free(&tlvlist); 147 147 148 148 return ret; … … 152 152 faim_internal int aim_reqrates(aim_session_t *sess, aim_conn_t *conn) 153 153 { 154 return aim_genericreq_n (sess, conn, 0x0001, 0x0006);154 return aim_genericreq_n_snacid(sess, conn, 0x0001, 0x0006); 155 155 } 156 156 … … 492 492 faim_export int aim_reqpersonalinfo(aim_session_t *sess, aim_conn_t *conn) 493 493 { 494 return aim_genericreq_n (sess, conn, 0x0001, 0x000e);494 return aim_genericreq_n_snacid(sess, conn, 0x0001, 0x000e); 495 495 } 496 496 … … 544 544 * 545 545 */ 546 faim_export int aim_bos_setidle(aim_session_t *sess, aim_conn_t *conn, fu32_t idletime) 547 { 546 faim_export int aim_srv_setidle(aim_session_t *sess, fu32_t idletime) 547 { 548 aim_conn_t *conn; 549 550 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_BOS))) 551 return -EINVAL; 552 548 553 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime); 549 554 } … … 586 591 } 587 592 588 tl = aim_ readtlvchain(bs);589 590 if (aim_ gettlv(tl, 0x0005, 1))591 ip = aim_ gettlv_str(tl, 0x0005, 1);592 593 cktlv = aim_ gettlv(tl, 0x0006, 1);593 tl = aim_tlvlist_read(bs); 594 595 if (aim_tlv_gettlv(tl, 0x0005, 1)) 596 ip = aim_tlv_getstr(tl, 0x0005, 1); 597 598 cktlv = aim_tlv_gettlv(tl, 0x0006, 1); 594 599 595 600 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 596 601 ret = userfunc(sess, rx, ip, cktlv ? cktlv->value : NULL); 597 602 598 aim_ freetlvchain(&tl);603 aim_tlvlist_free(&tl); 599 604 free(ip); 600 605 … … 627 632 * TLVs follow 628 633 */ 629 tlvlist = aim_ readtlvchain(bs);630 631 msg = aim_ gettlv_str(tlvlist, 0x000b, 1);634 tlvlist = aim_tlvlist_read(bs); 635 636 msg = aim_tlv_getstr(tlvlist, 0x000b, 1); 632 637 633 638 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) … … 636 641 free(msg); 637 642 638 aim_ freetlvchain(&tlvlist);643 aim_tlvlist_free(&tlvlist); 639 644 640 645 return ret; … … 661 666 * really necessary. 662 667 * 668 * Wha? No? Since when? I think WinAIM sends an empty channel 3 669 * SNAC as a no-op... 663 670 */ 664 671 faim_export int aim_nop(aim_session_t *sess, aim_conn_t *conn) … … 761 768 aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid); 762 769 763 aim_ addtlvtochain32(&tl, 0x0006, data);764 aim_ writetlvchain(&fr->data, &tl);765 aim_ freetlvchain(&tl);770 aim_tlvlist_add_32(&tl, 0x0006, data); 771 aim_tlvlist_write(&fr->data, &tl); 772 aim_tlvlist_free(&tl); 766 773 767 774 aim_tx_enqueue(sess, fr); … … 788 795 return -EINVAL; 789 796 790 if (msg ) {797 if (msg != NULL) { 791 798 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + strlen(msg) + 8))) 792 799 return -ENOMEM; … … 795 802 aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid); 796 803 797 aimbs_put16(&fr->data, 0x001d); 798 aimbs_put16(&fr->data, strlen(msg)+8); 804 aimbs_put16(&fr->data, 0x001d); /* userinfo TLV type */ 805 aimbs_put16(&fr->data, strlen(msg)+8); /* total length of userinfo TLV data */ 799 806 aimbs_put16(&fr->data, 0x0002); 800 807 aimbs_put8(&fr->data, 0x04); … … 871 878 offset = aimbs_get32(bs); 872 879 len = aimbs_get32(bs); 873 list = aim_ readtlvchain(bs);874 875 modname = aim_ gettlv_str(list, 0x0001, 1);880 list = aim_tlvlist_read(bs); 881 882 modname = aim_tlv_getstr(list, 0x0001, 1); 876 883 877 884 faimdprintf(sess, 1, "data at 0x%08lx (%d bytes) of requested\n", offset, len, modname ? modname : "aim.exe"); … … 881 888 882 889 free(modname); 883 aim_ freetlvchain(&list);890 aim_tlvlist_free(&list); 884 891 885 892 return ret; … … 1068 1075 } 1069 1076 1070 faim_internal int general_modfirst(aim_session_t *sess, aim_module_t *mod)1077 faim_internal int service_modfirst(aim_session_t *sess, aim_module_t *mod) 1071 1078 { 1072 1079 … … 1076 1083 mod->toolversion = 0x0629; 1077 1084 mod->flags = 0; 1078 strncpy(mod->name, " general", sizeof(mod->name));1085 strncpy(mod->name, "service", sizeof(mod->name)); 1079 1086 mod->snachandler = snachandler; 1080 1087 -
libfaim/ssi.c
ra0a5179 rcf02dd6 22 22 * You don't know the half of it. 23 23 * 24 * XXX - Preserve unknown data in TLV lists25 *26 24 */ 27 25 … … 39 37 static struct aim_ssi_item *aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name) 40 38 { 41 int newlen; 42 struct aim_ssi_item *cur, *group; 43 44 owl_function_debugmsg("aim_ssi_itemlist_rebuildgroup: in for group %s", name?name:"NULL"); 45 46 if (!list) return(NULL); 47 48 /* Find the group */ 49 if (!(group = aim_ssi_itemlist_finditem(list, name, NULL, AIM_SSI_TYPE_GROUP))) return(NULL); 50 51 /* Free the old data */ 52 aim_freetlvchain(&group->data); 53 group->data = NULL; 54 55 /* Find the length for the new additional data */ 56 newlen = 0; 57 if (group->gid == 0x0000) { 58 for (cur=list; cur; cur=cur->next) 59 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 60 newlen += 2; 61 } else { 62 for (cur=list; cur; cur=cur->next) 63 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 64 newlen += 2; 65 } 66 owl_function_debugmsg("aim_ssi_itemlist_rebuildgroup: newlen is %i", newlen); 67 68 /* Build the new TLV list */ 69 if (newlen > 0) { 70 fu8_t *newdata; 71 72 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t)))) return NULL; 73 newlen = 0; 74 if (group->gid == 0x0000) { 75 for (cur=list; cur; cur=cur->next) 76 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 77 newlen += aimutil_put16(newdata+newlen, cur->gid); 78 } else { 79 for (cur=list; cur; cur=cur->next) 80 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 81 newlen += aimutil_put16(newdata+newlen, cur->bid); 82 } 83 aim_addtlvtochain_raw(&group->data, 0x00c8, newlen, newdata); 84 85 free(newdata); 86 } 87 88 owl_function_debugmsg("aim_ssi_itemlist_rebuildgroup: exiting"); 89 return group; 39 int newlen; 40 struct aim_ssi_item *cur, *group; 41 42 if (!list) 43 return NULL; 44 45 /* Find the group */ 46 if (!(group = aim_ssi_itemlist_finditem(list, name, NULL, AIM_SSI_TYPE_GROUP))) 47 return NULL; 48 49 /* Find the length for the new additional data */ 50 newlen = 0; 51 if (group->gid == 0x0000) { 52 for (cur=list; cur; cur=cur->next) 53 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 54 newlen += 2; 55 } else { 56 for (cur=list; cur; cur=cur->next) 57 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 58 newlen += 2; 59 } 60 61 /* Build the new TLV list */ 62 if (newlen > 0) { 63 fu8_t *newdata; 64 65 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t)))) 66 return NULL; 67 newlen = 0; 68 if (group->gid == 0x0000) { 69 for (cur=list; cur; cur=cur->next) 70 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 71 newlen += aimutil_put16(newdata+newlen, cur->gid); 72 } else { 73 for (cur=list; cur; cur=cur->next) 74 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 75 newlen += aimutil_put16(newdata+newlen, cur->bid); 76 } 77 aim_tlvlist_replace_raw(&group->data, 0x00c8, newlen, newdata); 78 79 free(newdata); 80 } 81 82 return group; 90 83 } 91 84 … … 104 97 static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, fu16_t gid, fu16_t bid, fu16_t type, aim_tlvlist_t *data) 105 98 { 106 int i; 107 struct aim_ssi_item *cur, *new; 108 109 if (!list) return(NULL); 110 111 if (!(new = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) return(NULL); 112 113 /* Set the name */ 114 if (name) { 115 new->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 116 strcpy(new->name, name); 117 } else { 118 new->name = NULL; 119 } 120 121 /* Set the group ID# and buddy ID# */ 122 new->gid = gid; 123 new->bid = bid; 124 if (type == AIM_SSI_TYPE_GROUP) { 125 if ((new->gid == 0xFFFF) && name) { 126 do { 127 new->gid += 0x0001; 128 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 129 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) 130 i=1; 131 } while (i); 132 } 133 } else { 134 if (new->bid == 0xFFFF) { 135 do { 136 new->bid += 0x0001; 137 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 138 if ((cur->bid == new->bid) && (cur->gid == new->gid)) 139 i=1; 140 } while (i); 141 } 142 } 143 144 /* Set the type */ 145 new->type = type; 146 147 /* Set the TLV list */ 148 new->data = aim_tlvlist_copy(data); 149 150 /* Add the item to the list in the correct numerical position. Fancy, eh? */ 151 if (*list) { 152 if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) { 153 new->next = *list; 154 *list = new; 155 } else { 156 struct aim_ssi_item *prev; 157 for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); 158 new->next = prev->next; 159 prev->next = new; 160 } 161 } else { 162 new->next = *list; 163 *list = new; 164 } 165 166 return(new); 99 int i; 100 struct aim_ssi_item *cur, *new; 101 102 if (!list) 103 return NULL; 104 105 if (!(new = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) 106 return NULL; 107 108 /* Set the name */ 109 if (name) { 110 new->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 111 strcpy(new->name, name); 112 } else 113 new->name = NULL; 114 115 /* Set the group ID# and buddy ID# */ 116 new->gid = gid; 117 new->bid = bid; 118 if (type == AIM_SSI_TYPE_GROUP) { 119 if ((new->gid == 0xFFFF) && name) { 120 do { 121 new->gid += 0x0001; 122 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 123 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) 124 i=1; 125 } while (i); 126 } 127 } else { 128 if (new->bid == 0xFFFF) { 129 do { 130 new->bid += 0x0001; 131 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 132 if ((cur->bid == new->bid) && (cur->gid == new->gid)) 133 i=1; 134 } while (i); 135 } 136 } 137 138 /* Set the type */ 139 new->type = type; 140 141 /* Set the TLV list */ 142 new->data = aim_tlvlist_copy(data); 143 144 /* Add the item to the list in the correct numerical position. Fancy, eh? */ 145 if (*list) { 146 if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) { 147 new->next = *list; 148 *list = new; 149 } else { 150 struct aim_ssi_item *prev; 151 for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); 152 new->next = prev->next; 153 prev->next = new; 154 } 155 } else { 156 new->next = *list; 157 *list = new; 158 } 159 160 return new; 167 161 } 168 162 … … 176 170 static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del) 177 171 { 178 if (!list || !(*list) || !del) return -EINVAL; 179 180 owl_function_debugmsg("aim_ssi_itemlist_del: in"); 181 /* Remove the item from the list */ 182 if (*list == del) { 183 *list = (*list)->next; 184 owl_function_debugmsg("aim_ssi_itemlist_del: deleted %s from beginning of list", del->name); 185 } else { 186 struct aim_ssi_item *cur; 187 for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next); 188 if (cur->next) cur->next=cur->next->next; 189 owl_function_debugmsg("aim_ssi_itemlist_del: deleted %s from middle of list", del->name); 190 } 191 192 /* Free the deleted item */ 193 owl_function_debugmsg("aim_ssi_itemlist_del: freeing"); 194 free(del->name); 195 aim_freetlvchain(&del->data); 196 free(del); 197 198 return(0); 172 if (!list || !(*list) || !del) 173 return -EINVAL; 174 175 /* Remove the item from the list */ 176 if (*list == del) { 177 *list = (*list)->next; 178 } else { 179 struct aim_ssi_item *cur; 180 for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next); 181 if (cur->next) 182 cur->next = del->next; 183 } 184 185 /* Free the removed item */ 186 free(del->name); 187 aim_tlvlist_free(&del->data); 188 free(del); 189 190 return 0; 199 191 } 200 192 … … 208 200 static int aim_ssi_itemlist_cmp(struct aim_ssi_item *cur1, struct aim_ssi_item *cur2) 209 201 { 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 202 if (!cur1 || !cur2) 203 return 1; 204 205 if (cur1->data && !cur2->data) 206 return 2; 207 208 if (!cur1->data && cur2->data) 209 return 3; 210 211 if ((cur1->data && cur2->data) && (aim_tlvlist_cmp(cur1->data, cur2->data))) 212 return 4; 213 214 if (cur1->name && !cur2->name) 215 return 5; 216 217 if (!cur1->name && cur2->name) 218 return 6; 219 220 if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name)) 221 return 7; 222 223 if (cur1->gid != cur2->gid) 224 return 8; 225 226 if (cur1->bid != cur2->bid) 227 return 9; 228 229 if (cur1->type != cur2->type) 230 return 10; 231 232 return 0; 241 233 } 242 234 243 235 faim_export int aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item) 244 236 { 245 246 247 248 249 237 struct aim_ssi_item *cur; 238 for (cur=list; cur; cur=cur->next) 239 if (cur == item) 240 return 1; 241 return 0; 250 242 } 251 243 … … 260 252 faim_export struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, fu16_t gid, fu16_t bid) 261 253 { 262 263 264 265 266 254 struct aim_ssi_item *cur; 255 for (cur=list; cur; cur=cur->next) 256 if ((cur->gid == gid) && (cur->bid == bid)) 257 return cur; 258 return NULL; 267 259 } 268 260 … … 279 271 faim_export struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, fu16_t type) 280 272 { 281 282 283 284 285 286 287 288 struct aim_ssi_item *curg;289 for (curg=list; curg; curg=curg->next)290 291 292 293 294 295 296 297 return cur;298 299 300 301 302 303 304 return cur;305 306 307 308 309 310 311 312 313 314 273 struct aim_ssi_item *cur; 274 if (!list) 275 return NULL; 276 277 if (gn && sn) { /* For finding buddies in groups */ 278 for (cur=list; cur; cur=cur->next) 279 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { 280 struct aim_ssi_item *curg; 281 for (curg=list; curg; curg=curg->next) 282 if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn))) 283 return cur; 284 } 285 286 } else if (gn) { /* For finding groups */ 287 for (cur=list; cur; cur=cur->next) { 288 if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) { 289 return cur; 290 } 291 } 292 293 } else if (sn) { /* For finding permits, denies, and ignores */ 294 for (cur=list; cur; cur=cur->next) { 295 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { 296 return cur; 297 } 298 } 299 300 /* For stuff without names--permit deny setting, visibility mask, etc. */ 301 } else for (cur=list; cur; cur=cur->next) { 302 if ((cur->type == type) && (!cur->name)) 303 return cur; 304 } 305 306 return NULL; 315 307 } 316 308 … … 324 316 faim_export struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn) 325 317 { 326 327 328 329 330 331 332 318 struct aim_ssi_item *cur; 319 if (!list || !sn) 320 return NULL; 321 for (cur=list; cur; cur=cur->next) 322 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->name) && (!aim_sncmp(cur->name, sn))) 323 return cur; 324 return NULL; 333 325 } 334 326 … … 342 334 faim_export char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn) 343 335 { 344 345 346 347 348 349 350 351 336 struct aim_ssi_item *cur, *curg; 337 if (!list || !sn) 338 return NULL; 339 if (!(cur = aim_ssi_itemlist_exists(list, sn))) 340 return NULL; 341 if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000))) 342 return NULL; 343 return curg->name; 352 344 } 353 345 … … 360 352 faim_export int aim_ssi_getpermdeny(struct aim_ssi_item *list) 361 353 { 362 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO); 363 if (cur) { 364 aim_tlvlist_t *tlvlist = cur->data; 365 if (tlvlist) { 366 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00ca, 1); 367 if (tlv && tlv->value) 368 return aimutil_get8(tlv->value); 369 } 370 } 371 return 0; 354 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO); 355 if (cur) { 356 aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00ca, 1); 357 if (tlv && tlv->value) 358 return aimutil_get8(tlv->value); 359 } 360 return 0; 372 361 } 373 362 … … 382 371 faim_export fu32_t aim_ssi_getpresence(struct aim_ssi_item *list) 383 372 { 384 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS); 385 if (cur) { 386 aim_tlvlist_t *tlvlist = cur->data; 387 if (tlvlist) { 388 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00c9, 1); 389 if (tlv && tlv->length) 390 return aimutil_get32(tlv->value); 391 } 392 } 393 return 0xFFFFFFFF; 373 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS); 374 if (cur) { 375 aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c9, 1); 376 if (tlv && tlv->length) 377 return aimutil_get32(tlv->value); 378 } 379 return 0xFFFFFFFF; 394 380 } 395 381 396 382 /** 397 383 * Locally find the alias of the given buddy. 384 * 385 * @param list A pointer to the current list of items. 386 * @param gn The group of the buddy. 387 * @param sn The name of the buddy. 388 * @return A pointer to a NULL terminated string that is the buddy's 389 * alias, or NULL if the buddy has no alias. You should free 390 * this returned value! 391 */ 392 faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn) 393 { 394 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 395 if (cur) { 396 aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1); 397 if (tlv && tlv->length) { 398 char *alias = (char *)malloc((tlv->length+1)*sizeof(char)); 399 strncpy(alias, tlv->value, tlv->length); 400 alias[tlv->length] = 0; 401 return alias; 402 } 403 } 404 return NULL; 405 } 406 407 /** 408 * Locally find the comment of the given buddy. 409 * 410 * @param list A pointer to the current list of items. 411 * @param gn The group of the buddy. 412 * @param sn The name of the buddy. 413 * @return A pointer to a NULL terminated string that is the buddy's 414 * comment, or NULL if the buddy has no comment. You should free 415 * this returned value! 416 */ 417 faim_export char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn) 418 { 419 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 420 if (cur) { 421 aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x013c, 1); 422 if (tlv && tlv->length) { 423 char *alias = (char *)malloc((tlv->length+1)*sizeof(char)); 424 strncpy(alias, tlv->value, tlv->length); 425 alias[tlv->length] = 0; 426 return alias; 427 } 428 } 429 return NULL; 430 } 431 432 /** 433 * Locally find if you are waiting for authorization for a buddy. 398 434 * 399 435 * @param list A pointer to the current list of items. … … 404 440 * this returned value! 405 441 */ 406 faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn)407 {408 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);409 if (cur) {410 aim_tlvlist_t *tlvlist = cur->data;411 if (tlvlist) {412 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x0131, 1);413 if (tlv && tlv->length) {414 char *alias = (char *)malloc((tlv->length+1)*sizeof(char));415 strncpy(alias, tlv->value, tlv->length);416 alias[tlv->length] = 0;417 return alias;418 }419 }420 }421 return NULL;422 }423 424 /**425 * Locally find if you are waiting for authorization for a buddy.426 *427 * @param list A pointer to the current list of items.428 * @param gn The group of the buddy.429 * @param sn The name of the buddy.430 * @return A pointer to a NULL terminated string that is the buddies431 * alias, or NULL if the buddy has no alias. You should free432 * this returned value!433 */434 442 faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn) 435 443 { 436 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 437 if (cur) { 438 aim_tlvlist_t *tlvlist = cur->data; 439 if (tlvlist) 440 if (aim_gettlv(tlvlist, 0x0066, 1)) 441 return 1; 442 } 443 return 0; 444 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 445 if (cur) { 446 if (aim_tlv_gettlv(cur->data, 0x0066, 1)) 447 return 1; 448 } 449 return 0; 444 450 } 445 451 … … 453 459 static int aim_ssi_sync(aim_session_t *sess) 454 460 { 455 struct aim_ssi_item *cur1, *cur2; 456 struct aim_ssi_tmp *cur, *new; 457 458 owl_function_debugmsg("aim_ssi_sync: beginning"); 459 460 if (!sess) return (-EINVAL); 461 462 /* If we're waiting for an ack, we shouldn't do anything else */ 463 if (sess->ssi.waiting_for_ack) { 464 owl_function_debugmsg("Aborting aim_ssi_sync, waiting for ack"); 465 return 0; 466 } 467 468 /* 469 * Compare the 2 lists and create an aim_ssi_tmp for each difference. 470 * We should only send either additions, modifications, or deletions 471 * before waiting for an acknowledgement. So first do deletions, then 472 * additions, then modifications. Also, both the official and the local 473 * list should be in ascending numerical order for the group ID#s and the 474 * buddy ID#s, which makes things more efficient. I think. 475 */ 476 477 /* Additions */ 478 if (!sess->ssi.pending) { 479 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 480 if (!aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid)) { 481 owl_function_debugmsg("aim_ssi_sync: doing addition"); 482 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 483 new->action = AIM_CB_SSI_ADD; 484 new->ack = 0xffff; 485 new->name = NULL; 486 new->item = cur1; 487 new->next = NULL; 488 if (sess->ssi.pending) { 489 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 490 cur->next = new; 491 } else 492 sess->ssi.pending = new; 493 } 494 } 495 } 496 497 /* Deletions */ 498 if (!sess->ssi.pending) { 499 for (cur1=sess->ssi.official; cur1; cur1=cur1->next) { 500 if (!aim_ssi_itemlist_find(sess->ssi.local, cur1->gid, cur1->bid)) { 501 owl_function_debugmsg("aim_ssi_sync: doing deletion"); 502 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 503 new->action = AIM_CB_SSI_DEL; 504 new->ack = 0xffff; 505 new->name = NULL; 506 new->item = cur1; 507 new->next = NULL; 508 if (sess->ssi.pending) { 509 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 510 cur->next = new; 511 } else 512 sess->ssi.pending = new; 513 } 514 } 515 } 516 517 /* Modifications */ 518 if (!sess->ssi.pending) { 519 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 520 cur2 = aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid); 521 if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) { 522 owl_function_debugmsg("aim_ssi_sync: doing modification"); 523 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 524 new->action = AIM_CB_SSI_MOD; 525 new->ack = 0xffff; 526 new->name = NULL; 527 new->item = cur1; 528 new->next = NULL; 529 if (sess->ssi.pending) { 530 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 531 cur->next = new; 532 } else 533 sess->ssi.pending = new; 534 } 535 } 536 } 537 538 /* We're out of stuff to do, so tell the AIM servers we're done and exit */ 539 if (!sess->ssi.pending) { 540 owl_function_debugmsg("aim_ssi_sync: telling server we're done modifying SSI data."); 541 aim_ssi_modend(sess); 542 return 0; 543 } 544 545 /* Make sure we don't send anything else between now 546 * and when we receive the ack for the following operation */ 547 owl_function_debugmsg("aim_ssi_sync: setting SSI waiting_for_ack"); 548 sess->ssi.waiting_for_ack = 1; 549 550 /* Now go mail off our data and wait 4 to 6 weeks */ 551 owl_function_debugmsg("aim_ssi_sync: about to call addmoddel to send SNACs to server"); 552 aim_ssi_addmoddel(sess); 553 554 return 0; 461 struct aim_ssi_item *cur1, *cur2; 462 struct aim_ssi_tmp *cur, *new; 463 464 if (!sess) 465 return -EINVAL; 466 467 /* If we're waiting for an ack, we shouldn't do anything else */ 468 if (sess->ssi.waiting_for_ack) 469 return 0; 470 471 /* 472 * Compare the 2 lists and create an aim_ssi_tmp for each difference. 473 * We should only send either additions, modifications, or deletions 474 * before waiting for an acknowledgement. So first do deletions, then 475 * additions, then modifications. Also, both the official and the local 476 * list should be in ascending numerical order for the group ID#s and the 477 * buddy ID#s, which makes things more efficient. I think. 478 */ 479 480 /* Additions */ 481 if (!sess->ssi.pending) { 482 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 483 if (!aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid)) { 484 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 485 new->action = AIM_CB_SSI_ADD; 486 new->ack = 0xffff; 487 new->name = NULL; 488 new->item = cur1; 489 new->next = NULL; 490 if (sess->ssi.pending) { 491 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 492 cur->next = new; 493 } else 494 sess->ssi.pending = new; 495 } 496 } 497 } 498 499 /* Deletions */ 500 if (!sess->ssi.pending) { 501 for (cur1=sess->ssi.official; cur1; cur1=cur1->next) { 502 if (!aim_ssi_itemlist_find(sess->ssi.local, cur1->gid, cur1->bid)) { 503 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 504 new->action = AIM_CB_SSI_DEL; 505 new->ack = 0xffff; 506 new->name = NULL; 507 new->item = cur1; 508 new->next = NULL; 509 if (sess->ssi.pending) { 510 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 511 cur->next = new; 512 } else 513 sess->ssi.pending = new; 514 } 515 } 516 } 517 518 /* Modifications */ 519 if (!sess->ssi.pending) { 520 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 521 cur2 = aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid); 522 if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) { 523 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 524 new->action = AIM_CB_SSI_MOD; 525 new->ack = 0xffff; 526 new->name = NULL; 527 new->item = cur1; 528 new->next = NULL; 529 if (sess->ssi.pending) { 530 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 531 cur->next = new; 532 } else 533 sess->ssi.pending = new; 534 } 535 } 536 } 537 538 /* We're out of stuff to do, so tell the AIM servers we're done and exit */ 539 if (!sess->ssi.pending) { 540 aim_ssi_modend(sess); 541 return 0; 542 } 543 544 /* Make sure we don't send anything else between now 545 * and when we receive the ack for the following operation */ 546 sess->ssi.waiting_for_ack = 1; 547 548 /* Now go mail off our data and wait 4 to 6 weeks */ 549 aim_ssi_addmoddel(sess); 550 551 return 0; 555 552 } 556 553 … … 565 562 static int aim_ssi_freelist(aim_session_t *sess) 566 563 { 567 568 569 570 571 572 573 574 575 aim_freetlvchain(&del->data);576 577 578 579 580 581 582 583 584 aim_freetlvchain(&del->data);585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 564 struct aim_ssi_item *cur, *del; 565 struct aim_ssi_tmp *curtmp, *deltmp; 566 567 cur = sess->ssi.official; 568 while (cur) { 569 del = cur; 570 cur = cur->next; 571 free(del->name); 572 aim_tlvlist_free(&del->data); 573 free(del); 574 } 575 576 cur = sess->ssi.local; 577 while (cur) { 578 del = cur; 579 cur = cur->next; 580 free(del->name); 581 aim_tlvlist_free(&del->data); 582 free(del); 583 } 584 585 curtmp = sess->ssi.pending; 586 while (curtmp) { 587 deltmp = curtmp; 588 curtmp = curtmp->next; 589 free(deltmp); 590 } 591 592 sess->ssi.numitems = 0; 593 sess->ssi.official = NULL; 594 sess->ssi.local = NULL; 595 sess->ssi.pending = NULL; 596 sess->ssi.timestamp = (time_t)0; 597 598 return 0; 602 599 } 603 600 … … 610 607 faim_export int aim_ssi_deletelist(aim_session_t *sess) 611 608 { 612 struct aim_ssi_item *cur, *del; 613 614 if (!sess) return (-EINVAL); 615 616 /* Free the local list */ 617 cur = sess->ssi.local; 618 while (cur) { 619 del = cur; 620 cur = cur->next; 621 free(del->name); 622 aim_freetlvchain(&del->data); 623 free(del); 624 } 625 sess->ssi.local = NULL; 626 627 /* Sync our local list with the server list */ 628 aim_ssi_sync(sess); 629 630 return 0; 609 struct aim_ssi_item *cur, *del; 610 611 if (!sess) 612 return -EINVAL; 613 614 /* Free the local list */ 615 cur = sess->ssi.local; 616 while (cur) { 617 del = cur; 618 cur = cur->next; 619 free(del->name); 620 aim_tlvlist_free(&del->data); 621 free(del); 622 } 623 sess->ssi.local = NULL; 624 625 /* Sync our local list with the server list */ 626 aim_ssi_sync(sess); 627 628 return 0; 631 629 } 632 630 … … 642 640 faim_export int aim_ssi_cleanlist(aim_session_t *sess) 643 641 { 644 struct aim_ssi_item *cur, *next; 645 646 if (!sess) return -EINVAL; 647 648 /* Delete any buddies, permits, or denies with empty names. */ 649 /* If there are any buddies directly in the master group, add them to a real group. */ 650 /* DESTROY any buddies that are directly in the master group. */ 651 /* Do the same for buddies that are in a non-existant group. */ 652 /* This will kind of mess up if you hit the item limit, but this function isn't too critical */ 653 cur = sess->ssi.local; 654 while (cur) { 655 next = cur->next; 656 if (!cur->name) { 657 if (cur->type == AIM_SSI_TYPE_BUDDY) 658 aim_ssi_delbuddy(sess, NULL, NULL); 659 else if (cur->type == AIM_SSI_TYPE_PERMIT) 660 aim_ssi_delpermit(sess, NULL); 661 else if (cur->type == AIM_SSI_TYPE_DENY) 662 aim_ssi_deldeny(sess, NULL); 663 } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) { 664 aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0); 665 aim_ssi_delbuddy(sess, cur->name, NULL); 666 } 667 cur = next; 668 } 669 670 /* Check if there are empty groups and delete them */ 671 cur = sess->ssi.local; 672 while (cur) { 673 next = cur->next; 674 if (cur->type == AIM_SSI_TYPE_GROUP) { 675 aim_tlv_t *tlv = aim_gettlv(cur->data, 0x00c8, 1); 676 if (!tlv || !tlv->length) 677 aim_ssi_itemlist_del(&sess->ssi.local, cur); 678 } 679 cur = next; 680 } 681 682 /* Check if the master group is empty */ 683 if ((cur = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!cur->data)) 684 aim_ssi_itemlist_del(&sess->ssi.local, cur); 685 686 return 0; 642 struct aim_ssi_item *cur, *next; 643 644 if (!sess) 645 return -EINVAL; 646 647 /* Delete any buddies, permits, or denies with empty names. */ 648 /* If there are any buddies directly in the master group, add them to a real group. */ 649 /* DESTROY any buddies that are directly in the master group. */ 650 /* Do the same for buddies that are in a non-existant group. */ 651 /* This will kind of mess up if you hit the item limit, but this function isn't too critical */ 652 cur = sess->ssi.local; 653 while (cur) { 654 next = cur->next; 655 if (!cur->name) { 656 if (cur->type == AIM_SSI_TYPE_BUDDY) 657 aim_ssi_delbuddy(sess, NULL, NULL); 658 else if (cur->type == AIM_SSI_TYPE_PERMIT) 659 aim_ssi_delpermit(sess, NULL); 660 else if (cur->type == AIM_SSI_TYPE_DENY) 661 aim_ssi_deldeny(sess, NULL); 662 } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) { 663 aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0); 664 aim_ssi_delbuddy(sess, cur->name, NULL); 665 } 666 cur = next; 667 } 668 669 /* Check if there are empty groups and delete them */ 670 cur = sess->ssi.local; 671 while (cur) { 672 next = cur->next; 673 if (cur->type == AIM_SSI_TYPE_GROUP) { 674 aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c8, 1); 675 if (!tlv || !tlv->length) 676 aim_ssi_itemlist_del(&sess->ssi.local, cur); 677 } 678 cur = next; 679 } 680 681 /* Check if the master group is empty */ 682 if ((cur = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!cur->data)) 683 aim_ssi_itemlist_del(&sess->ssi.local, cur); 684 685 return 0; 687 686 } 688 687 … … 700 699 faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth) 701 700 { 702 struct aim_ssi_item *parent; 703 aim_tlvlist_t *data = NULL; 704 705 if (!sess || !name || !group) return (-EINVAL); 706 707 /* Find the parent */ 708 if (!(parent = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { 709 /* Find the parent's parent (the master group) */ 710 if (!(parent = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000))) { 711 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) { 712 return -ENOMEM; 713 } 714 } 715 /* Add the parent */ 716 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) { 717 return -ENOMEM; 718 } 719 720 /* Modify the parent's parent (the master group) */ 721 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 722 } 723 724 /* Create a TLV list for the new buddy */ 725 if (needauth) aim_addtlvtochain_noval(&data, 0x0066); 726 if (alias) aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias); 727 if (smsnum) aim_addtlvtochain_raw(&data, 0x013a, strlen(smsnum), smsnum); 728 if (comment) aim_addtlvtochain_raw(&data, 0x013c, strlen(comment), comment); 729 730 /* Add that bad boy */ 731 aim_ssi_itemlist_add(&sess->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); 732 aim_freetlvchain(&data); 733 734 /* Modify the parent group */ 735 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 736 737 /* Sync our local list with the server list */ 738 aim_ssi_sync(sess); 739 740 return(0); 701 struct aim_ssi_item *parent; 702 aim_tlvlist_t *data = NULL; 703 704 if (!sess || !name || !group) 705 return -EINVAL; 706 707 /* Find the parent */ 708 if (!(parent = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { 709 /* Find the parent's parent (the master group) */ 710 if (!(parent = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000))) 711 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) 712 return -ENOMEM; 713 /* Add the parent */ 714 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) 715 return -ENOMEM; 716 717 /* Modify the parent's parent (the master group) */ 718 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 719 } 720 721 /* Create a TLV list for the new buddy */ 722 if (needauth) 723 aim_tlvlist_add_noval(&data, 0x0066); 724 if (alias) 725 aim_tlvlist_add_raw(&data, 0x0131, strlen(alias), alias); 726 if (smsnum) 727 aim_tlvlist_add_raw(&data, 0x013a, strlen(smsnum), smsnum); 728 if (comment) 729 aim_tlvlist_add_raw(&data, 0x013c, strlen(comment), comment); 730 731 /* Add that bad boy */ 732 aim_ssi_itemlist_add(&sess->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); 733 aim_tlvlist_free(&data); 734 735 /* Modify the parent group */ 736 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 737 738 /* Sync our local list with the server list */ 739 aim_ssi_sync(sess); 740 741 return 0; 741 742 } 742 743 … … 751 752 { 752 753 753 if (!sess || !name) return -EINVAL; 754 755 /* Add that bad boy */ 756 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL); 757 758 /* Sync our local list with the server list */ 759 aim_ssi_sync(sess); 760 761 return(0); 754 if (!sess || !name) 755 return -EINVAL; 756 757 /* Add that bad boy */ 758 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL); 759 760 /* Sync our local list with the server list */ 761 aim_ssi_sync(sess); 762 763 return 0; 762 764 } 763 765 … … 772 774 { 773 775 774 if (!sess || !name) return (-EINVAL); 775 776 /* Add that bad boy */ 777 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); 778 779 /* Sync our local list with the server list */ 780 aim_ssi_sync(sess); 781 782 return(0); 776 if (!sess || !name) 777 return -EINVAL; 778 779 /* Add that bad boy */ 780 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); 781 782 /* Sync our local list with the server list */ 783 aim_ssi_sync(sess); 784 785 return 0; 783 786 } 784 787 … … 793 796 faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group) 794 797 { 795 796 797 if (!sess) return -EINVAL; 798 799 /* Find the buddy */ 800 del=aim_ssi_itemlist_finditem(sess->ssi.local, group, name, AIM_SSI_TYPE_BUDDY); 801 if (!del) return(-EINVAL); 802 803 /* Remove the item from the list */ 804 aim_ssi_itemlist_del(&sess->ssi.local, del); 805 806 /* Modify the parent group */ 807 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 808 809 /* Check if we should delete the parent group */ 810 if ((del = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) { 811 aim_ssi_itemlist_del(&sess->ssi.local, del); 812 813 /* Modify the parent group */ 814 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 815 816 /* Check if we should delete the parent's parent (the master group) */ 817 if ((del = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!del->data)) { 818 aim_ssi_itemlist_del(&sess->ssi.local, del); 819 } 820 821 822 /* Sync our local list with the server list */ 823 owl_function_debugmsg("aim_ssi_delbuddy: about to sync"); 824 825 826 return(0);798 struct aim_ssi_item *del; 799 800 if (!sess) 801 return -EINVAL; 802 803 /* Find the buddy */ 804 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, group, name, AIM_SSI_TYPE_BUDDY))) 805 return -EINVAL; 806 807 /* Remove the item from the list */ 808 aim_ssi_itemlist_del(&sess->ssi.local, del); 809 810 /* Modify the parent group */ 811 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 812 813 /* Check if we should delete the parent group */ 814 if ((del = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) { 815 aim_ssi_itemlist_del(&sess->ssi.local, del); 816 817 /* Modify the parent group */ 818 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 819 820 /* Check if we should delete the parent's parent (the master group) */ 821 if ((del = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!del->data)) { 822 aim_ssi_itemlist_del(&sess->ssi.local, del); 823 } 824 } 825 826 /* Sync our local list with the server list */ 827 aim_ssi_sync(sess); 828 829 return 0; 827 830 } 828 831 … … 836 839 faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name) 837 840 { 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 841 struct aim_ssi_item *del; 842 843 if (!sess) 844 return -EINVAL; 845 846 /* Find the item */ 847 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT))) 848 return -EINVAL; 849 850 /* Remove the item from the list */ 851 aim_ssi_itemlist_del(&sess->ssi.local, del); 852 853 /* Sync our local list with the server list */ 854 aim_ssi_sync(sess); 855 856 return 0; 854 857 } 855 858 … … 863 866 faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name) 864 867 { 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 868 struct aim_ssi_item *del; 869 870 if (!sess) 871 return -EINVAL; 872 873 /* Find the item */ 874 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_DENY))) 875 return -EINVAL; 876 877 /* Remove the item from the list */ 878 aim_ssi_itemlist_del(&sess->ssi.local, del); 879 880 /* Sync our local list with the server list */ 881 aim_ssi_sync(sess); 882 883 return 0; 881 884 } 882 885 … … 893 896 faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn) 894 897 { 895 896 897 898 aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn)); 899 aim_ssi_delbuddy(sess, sn, oldgn); 900 return 0; 898 901 } 899 902 … … 904 907 * @param gn The group that the buddy is currently in. 905 908 * @param sn The screen name of the buddy. 906 * @param alias The new alias for the buddy. 909 * @param alias The new alias for the buddy, or NULL if you want to remove 910 * a buddy's comment. 907 911 * @return Return 0 if no errors, otherwise return the error number. 908 912 */ 909 913 faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias) 910 914 { 911 struct aim_ssi_item *tmp; 912 aim_tlvlist_t *data = NULL; 913 914 if (!sess || !gn || !sn) 915 return -EINVAL; 916 917 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) 918 return -EINVAL; 919 920 if (alias && !strlen(alias)) 921 alias = NULL; 922 923 /* Need to add the x0131 TLV to the TLV chain */ 924 if (alias) 925 aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias); 926 927 aim_freetlvchain(&tmp->data); 928 tmp->data = data; 929 930 /* Sync our local list with the server list */ 931 aim_ssi_sync(sess); 932 933 return 0; 915 struct aim_ssi_item *tmp; 916 917 if (!sess || !gn || !sn) 918 return -EINVAL; 919 920 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) 921 return -EINVAL; 922 923 /* Either add or remove the 0x0131 TLV from the TLV chain */ 924 if ((alias != NULL) && (strlen(alias) > 0)) 925 aim_tlvlist_replace_raw(&tmp->data, 0x0131, strlen(alias), alias); 926 else 927 aim_tlvlist_remove(&tmp->data, 0x0131); 928 929 /* Sync our local list with the server list */ 930 aim_ssi_sync(sess); 931 932 return 0; 933 } 934 935 /** 936 * Change the comment stored on the server for a given buddy. 937 * 938 * @param sess The oscar session. 939 * @param gn The group that the buddy is currently in. 940 * @param sn The screen name of the buddy. 941 * @param alias The new comment for the buddy, or NULL if you want to remove 942 * a buddy's comment. 943 * @return Return 0 if no errors, otherwise return the error number. 944 */ 945 faim_export int aim_ssi_editcomment(aim_session_t *sess, const char *gn, const char *sn, const char *comment) 946 { 947 struct aim_ssi_item *tmp; 948 949 if (!sess || !gn || !sn) 950 return -EINVAL; 951 952 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) 953 return -EINVAL; 954 955 /* Either add or remove the 0x0131 TLV from the TLV chain */ 956 if ((comment != NULL) && (strlen(comment) > 0)) 957 aim_tlvlist_replace_raw(&tmp->data, 0x013c, strlen(comment), comment); 958 else 959 aim_tlvlist_remove(&tmp->data, 0x013c); 960 961 /* Sync our local list with the server list */ 962 aim_ssi_sync(sess); 963 964 return 0; 934 965 } 935 966 … … 944 975 faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn) 945 976 { 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 977 struct aim_ssi_item *group; 978 979 if (!sess || !oldgn || !newgn) 980 return -EINVAL; 981 982 if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP))) 983 return -EINVAL; 984 985 free(group->name); 986 group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char)); 987 strcpy(group->name, newgn); 988 989 /* Sync our local list with the server list */ 990 aim_ssi_sync(sess); 991 992 return 0; 962 993 } 963 994 … … 978 1009 faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask) 979 1010 { 980 struct aim_ssi_item *tmp; 981 aim_tlvlist_t *data = NULL; 982 983 if (!sess) 984 return -EINVAL; 985 986 /* Need to add the x00ca TLV to the TLV chain */ 987 aim_addtlvtochain8(&data, 0x00ca, permdeny); 988 989 /* Need to add the x00cb TLV to the TLV chain */ 990 aim_addtlvtochain32(&data, 0x00cb, vismask); 991 992 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) { 993 aim_freetlvchain(&tmp->data); 994 tmp->data = data; 995 } else { 996 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, data); 997 aim_freetlvchain(&data); 998 } 999 1000 /* Sync our local list with the server list */ 1001 aim_ssi_sync(sess); 1002 1003 return 0; 1011 struct aim_ssi_item *tmp; 1012 1013 if (!sess) 1014 return -EINVAL; 1015 1016 /* Find the PDINFO item, or add it if it does not exist */ 1017 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) 1018 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, NULL); 1019 1020 /* Need to add the 0x00ca TLV to the TLV chain */ 1021 aim_tlvlist_replace_8(&tmp->data, 0x00ca, permdeny); 1022 1023 /* Need to add the 0x00cb TLV to the TLV chain */ 1024 aim_tlvlist_replace_32(&tmp->data, 0x00cb, vismask); 1025 1026 /* Sync our local list with the server list */ 1027 aim_ssi_sync(sess); 1028 1029 return 0; 1004 1030 } 1005 1031 … … 1014 1040 faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen) 1015 1041 { 1016 struct aim_ssi_item *tmp; 1017 aim_tlvlist_t *data = NULL; 1018 fu8_t *csumdata; 1019 1020 if (!sess || !iconsum || !iconsumlen) 1021 return -EINVAL; 1022 1023 if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t)))) 1024 return -ENOMEM; 1025 csumdata[0] = 0x00; 1026 csumdata[1] = 0x10; 1027 memcpy(&csumdata[2], iconsum, iconsumlen); 1028 1029 /* Need to add the x00d5 TLV to the TLV chain */ 1030 aim_addtlvtochain_raw(&data, 0x00d5, (iconsumlen+2) * sizeof(fu8_t), csumdata); 1031 1032 /* This TLV is added to cache the icon. */ 1033 aim_addtlvtochain_noval(&data, 0x0131); 1034 1035 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { 1036 /* If the new tlvchain and oldtlvchain are the same, then do nothing */ 1037 if (!aim_tlvlist_cmp(tmp->data, data)) { 1038 /* The new tlvlist is the identical to the old one */ 1039 aim_freetlvchain(&data); 1040 free(csumdata); 1041 return 0; 1042 } 1043 aim_freetlvchain(&tmp->data); 1044 tmp->data = data; 1045 } else { 1046 tmp = aim_ssi_itemlist_add(&sess->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, data); 1047 aim_freetlvchain(&data); 1048 } 1049 1050 /* Sync our local list with the server list */ 1051 aim_ssi_sync(sess); 1052 free(csumdata); 1053 return 0; 1042 struct aim_ssi_item *tmp; 1043 fu8_t *csumdata; 1044 1045 if (!sess || !iconsum || !iconsumlen) 1046 return -EINVAL; 1047 1048 /* Find the ICONINFO item, or add it if it does not exist */ 1049 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { 1050 tmp = aim_ssi_itemlist_add(&sess->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, NULL); 1051 } 1052 1053 /* Need to add the 0x00d5 TLV to the TLV chain */ 1054 if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t)))) 1055 return -ENOMEM; 1056 csumdata[0] = 0x00; 1057 csumdata[1] = 0x10; 1058 memcpy(&csumdata[2], iconsum, iconsumlen); 1059 aim_tlvlist_replace_raw(&tmp->data, 0x00d5, (iconsumlen+2) * sizeof(fu8_t), csumdata); 1060 free(csumdata); 1061 1062 /* Need to add the 0x0131 TLV to the TLV chain, used to cache the icon */ 1063 aim_tlvlist_replace_noval(&tmp->data, 0x0131); 1064 1065 /* Sync our local list with the server list */ 1066 aim_ssi_sync(sess); 1067 return 0; 1068 } 1069 1070 /** 1071 * Remove a reference to a server stored buddy icon. This will make your 1072 * icon stop showing up to other people. 1073 * 1074 * @param sess The oscar session. 1075 * @return Return 0 if no errors, otherwise return the error number. 1076 */ 1077 faim_export int aim_ssi_delicon(aim_session_t *sess) 1078 { 1079 struct aim_ssi_item *tmp; 1080 1081 if (!sess) 1082 return -EINVAL; 1083 1084 /* Find the ICONINFO item and delete it if it exists*/ 1085 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) 1086 aim_ssi_itemlist_del(&sess->ssi.local, tmp); 1087 1088 /* Sync our local list with the server list */ 1089 aim_ssi_sync(sess); 1090 return 0; 1054 1091 } 1055 1092 … … 1059 1096 * @param sess The oscar session. 1060 1097 * @param presence I think it's a bitmask, but I only know what one of the bits is: 1098 * 0x00000002 - Hide wireless? 1061 1099 * 0x00000400 - Allow others to see your idle time 1062 1100 * @return Return 0 if no errors, otherwise return the error number. 1063 1101 */ 1064 1102 faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence) { 1065 struct aim_ssi_item *tmp; 1066 aim_tlvlist_t *data = NULL; 1067 1068 if (!sess) 1069 return -EINVAL; 1070 1071 /* Need to add the x00c9 TLV to the TLV chain */ 1072 aim_addtlvtochain32(&data, 0x00c9, presence); 1073 1074 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) { 1075 aim_freetlvchain(&tmp->data); 1076 tmp->data = data; 1077 } else { 1078 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, data); 1079 aim_freetlvchain(&data); 1080 } 1081 1082 /* Sync our local list with the server list */ 1083 aim_ssi_sync(sess); 1084 1085 return 0; 1103 struct aim_ssi_item *tmp; 1104 1105 if (!sess) 1106 return -EINVAL; 1107 1108 /* Find the PRESENCEPREFS item, or add it if it does not exist */ 1109 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) 1110 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, NULL); 1111 1112 /* Need to add the x00c9 TLV to the TLV chain */ 1113 aim_tlvlist_replace_32(&tmp->data, 0x00c9, presence); 1114 1115 /* Sync our local list with the server list */ 1116 aim_ssi_sync(sess); 1117 1118 return 0; 1086 1119 } 1087 1120 … … 1091 1124 faim_export int aim_ssi_reqrights(aim_session_t *sess) 1092 1125 { 1093 1094 1095 1096 1097 1098 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS);1126 aim_conn_t *conn; 1127 1128 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1129 return -EINVAL; 1130 1131 return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS); 1099 1132 } 1100 1133 … … 1104 1137 static int parserights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1105 1138 { 1106 1107 1108 1109 1110 1111 1112 1113 1114 tlvlist = aim_readtlvchain(bs);1115 1116 1117 if (!(tlv = aim_gettlv(tlvlist, 0x0004, 1))) {1118 aim_freetlvchain(&tlvlist);1119 1120 1121 1122 1123 1124 1125 aim_freetlvchain(&tlvlist);1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 aim_freetlvchain(&tlvlist);1136 1137 1138 1139 int ret = 0, i; 1140 aim_rxcallback_t userfunc; 1141 aim_tlvlist_t *tlvlist; 1142 aim_tlv_t *tlv; 1143 aim_bstream_t bstream; 1144 fu16_t *maxitems; 1145 1146 /* This SNAC is made up of a bunch of TLVs */ 1147 tlvlist = aim_tlvlist_read(bs); 1148 1149 /* TLV 0x0004 contains the maximum number of each item */ 1150 if (!(tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) { 1151 aim_tlvlist_free(&tlvlist); 1152 return 0; 1153 } 1154 1155 aim_bstream_init(&bstream, tlv->value, tlv->length); 1156 1157 if (!(maxitems = (fu16_t *)malloc((tlv->length/2)*sizeof(fu16_t)))) { 1158 aim_tlvlist_free(&tlvlist); 1159 return 0; 1160 } 1161 1162 for (i=0; i<(tlv->length/2); i++) 1163 maxitems[i] = aimbs_get16(&bstream); 1164 1165 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1166 ret = userfunc(sess, rx, tlv->length/2, maxitems); 1167 1168 aim_tlvlist_free(&tlvlist); 1169 free(maxitems); 1170 1171 return ret; 1139 1172 } 1140 1173 … … 1146 1179 faim_export int aim_ssi_reqdata(aim_session_t *sess) 1147 1180 { 1148 1149 1150 1151 1152 1153 1154 1155 1156 1181 aim_conn_t *conn; 1182 1183 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1184 return -EINVAL; 1185 1186 /* Free any current data, just in case */ 1187 aim_ssi_freelist(sess); 1188 1189 return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQDATA); 1157 1190 } 1158 1191 … … 1169 1202 faim_export int aim_ssi_reqifchanged(aim_session_t *sess, time_t timestamp, fu16_t numitems) 1170 1203 { 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1204 aim_conn_t *conn; 1205 aim_frame_t *fr; 1206 aim_snacid_t snacid; 1207 1208 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1209 return -EINVAL; 1210 1211 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2))) 1212 return -ENOMEM; 1213 1214 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, NULL, 0); 1215 1216 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, snacid); 1217 aimbs_put32(&fr->data, timestamp); 1218 aimbs_put16(&fr->data, numitems); 1219 1220 aim_tx_enqueue(sess, fr); 1221 1222 /* Free any current data, just in case */ 1223 aim_ssi_freelist(sess); 1224 1225 return 0; 1193 1226 } 1194 1227 … … 1198 1231 static int parsedata(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1199 1232 { 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 data = aim_readtlvchain_len(bs, aimbs_get16(bs));1220 1221 1222 aim_freetlvchain(&data);1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1233 int ret = 0; 1234 aim_rxcallback_t userfunc; 1235 fu8_t fmtver; /* guess */ 1236 fu16_t namelen, gid, bid, type; 1237 char *name; 1238 aim_tlvlist_t *data; 1239 1240 fmtver = aimbs_get8(bs); /* Version of ssi data. Should be 0x00 */ 1241 sess->ssi.numitems += aimbs_get16(bs); /* # of items in this SSI SNAC */ 1242 1243 /* Read in the list */ 1244 while (aim_bstream_empty(bs) > 4) { /* last four bytes are timestamp */ 1245 if ((namelen = aimbs_get16(bs))) 1246 name = aimbs_getstr(bs, namelen); 1247 else 1248 name = NULL; 1249 gid = aimbs_get16(bs); 1250 bid = aimbs_get16(bs); 1251 type = aimbs_get16(bs); 1252 data = aim_tlvlist_readlen(bs, aimbs_get16(bs)); 1253 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data); 1254 free(name); 1255 aim_tlvlist_free(&data); 1256 } 1257 1258 /* Read in the timestamp */ 1259 sess->ssi.timestamp = aimbs_get32(bs); 1260 1261 if (!(snac->flags & 0x0001)) { 1262 /* Make a copy of the list */ 1263 struct aim_ssi_item *cur; 1264 for (cur=sess->ssi.official; cur; cur=cur->next) 1265 aim_ssi_itemlist_add(&sess->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data); 1266 1267 sess->ssi.received_data = 1; 1268 1269 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1270 ret = userfunc(sess, rx, fmtver, sess->ssi.numitems, sess->ssi.official, sess->ssi.timestamp); 1271 } 1272 1273 return ret; 1241 1274 } 1242 1275 … … 1252 1285 faim_export int aim_ssi_enable(aim_session_t *sess) 1253 1286 { 1254 1255 1256 1257 1258 1259 1287 aim_conn_t *conn; 1288 1289 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1290 return -EINVAL; 1291 1292 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007); 1260 1293 } 1261 1294 … … 1270 1303 faim_export int aim_ssi_addmoddel(aim_session_t *sess) 1271 1304 { 1272 aim_conn_t *conn; 1273 aim_frame_t *fr; 1274 aim_snacid_t snacid; 1275 int snaclen; 1276 struct aim_ssi_tmp *cur; 1277 1278 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item) { 1279 owl_function_debugmsg("aim_ssi_addmoddel: aborting early"); 1280 return -EINVAL; 1281 } 1282 1283 /* Calculate total SNAC size */ 1284 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ 1285 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1286 snaclen += 10; /* For length, GID, BID, type, and length */ 1287 if (cur->item->name) snaclen += strlen(cur->item->name); 1288 if (cur->item->data) snaclen += aim_sizetlvchain(&cur->item->data); 1289 } 1290 1291 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) return (-ENOMEM); 1292 1293 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, NULL, 0); 1294 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, snacid); 1295 1296 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1297 aimbs_put16(&fr->data, cur->item->name ? strlen(cur->item->name) : 0); 1298 if (cur->item->name) aimbs_putraw(&fr->data, cur->item->name, strlen(cur->item->name)); 1299 aimbs_put16(&fr->data, cur->item->gid); 1300 aimbs_put16(&fr->data, cur->item->bid); 1301 aimbs_put16(&fr->data, cur->item->type); 1302 aimbs_put16(&fr->data, cur->item->data ? aim_sizetlvchain(&cur->item->data) : 0); 1303 if (cur->item->data) aim_writetlvchain(&fr->data, &cur->item->data); 1304 } 1305 1306 aim_tx_enqueue(sess, fr); 1307 1308 owl_function_debugmsg("aim_ssi_addmoddel: exiting normally"); 1309 return 0; 1305 aim_conn_t *conn; 1306 aim_frame_t *fr; 1307 aim_snacid_t snacid; 1308 int snaclen; 1309 struct aim_ssi_tmp *cur; 1310 1311 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item) 1312 return -EINVAL; 1313 1314 /* Calculate total SNAC size */ 1315 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ 1316 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1317 snaclen += 10; /* For length, GID, BID, type, and length */ 1318 if (cur->item->name) 1319 snaclen += strlen(cur->item->name); 1320 if (cur->item->data) 1321 snaclen += aim_tlvlist_size(&cur->item->data); 1322 } 1323 1324 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) 1325 return -ENOMEM; 1326 1327 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, NULL, 0); 1328 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, snacid); 1329 1330 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1331 aimbs_put16(&fr->data, cur->item->name ? strlen(cur->item->name) : 0); 1332 if (cur->item->name) 1333 aimbs_putraw(&fr->data, cur->item->name, strlen(cur->item->name)); 1334 aimbs_put16(&fr->data, cur->item->gid); 1335 aimbs_put16(&fr->data, cur->item->bid); 1336 aimbs_put16(&fr->data, cur->item->type); 1337 aimbs_put16(&fr->data, cur->item->data ? aim_tlvlist_size(&cur->item->data) : 0); 1338 if (cur->item->data) 1339 aim_tlvlist_write(&fr->data, &cur->item->data); 1340 } 1341 1342 aim_tx_enqueue(sess, fr); 1343 1344 return 0; 1310 1345 } 1311 1346 … … 1317 1352 static int parseadd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1318 1353 { 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 data = aim_readtlvchain_len(bs, len);1335 1336 1337 1338 1339 1340 1341 aim_freetlvchain(&data);1342 1343 1344 1345 1346 1347 1348 1349 1354 int ret = 0; 1355 aim_rxcallback_t userfunc; 1356 char *name; 1357 fu16_t len, gid, bid, type; 1358 aim_tlvlist_t *data; 1359 1360 while (aim_bstream_empty(bs)) { 1361 if ((len = aimbs_get16(bs))) 1362 name = aimbs_getstr(bs, len); 1363 else 1364 name = NULL; 1365 gid = aimbs_get16(bs); 1366 bid = aimbs_get16(bs); 1367 type = aimbs_get16(bs); 1368 if ((len = aimbs_get16(bs))) 1369 data = aim_tlvlist_readlen(bs, len); 1370 else 1371 data = NULL; 1372 1373 aim_ssi_itemlist_add(&sess->ssi.local, name, gid, bid, type, data); 1374 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data); 1375 free(name); 1376 aim_tlvlist_free(&data); 1377 1378 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1379 ret = userfunc(sess, rx); 1380 1381 free(name); 1382 } 1383 1384 return ret; 1350 1385 } 1351 1386 … … 1357 1392 static int parsemod(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1358 1393 { 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 data = aim_readtlvchain_len(bs, len);1376 1377 1378 1379 1380 1381 1382 1383 1384 item->name = (char *)malloc((strlen(name)+1)*sizeof(char));1385 strcpy(item->name, name);1386 1387 item->name = NULL;1388 aim_freetlvchain(&item->data);1389 1390 1391 1392 1393 1394 1395 1396 item->name = (char *)malloc((strlen(name)+1)*sizeof(char));1397 strcpy(item->name, name);1398 1399 item->name = NULL;1400 aim_freetlvchain(&item->data);1401 1402 1403 1404 1405 1406 1407 1408 aim_freetlvchain(&data);1409 1410 1411 1394 int ret = 0; 1395 aim_rxcallback_t userfunc; 1396 char *name; 1397 fu16_t len, gid, bid, type; 1398 aim_tlvlist_t *data; 1399 struct aim_ssi_item *item; 1400 1401 while (aim_bstream_empty(bs)) { 1402 if ((len = aimbs_get16(bs))) 1403 name = aimbs_getstr(bs, len); 1404 else 1405 name = NULL; 1406 gid = aimbs_get16(bs); 1407 bid = aimbs_get16(bs); 1408 type = aimbs_get16(bs); 1409 if ((len = aimbs_get16(bs))) 1410 data = aim_tlvlist_readlen(bs, len); 1411 else 1412 data = NULL; 1413 1414 /* Replace the 2 local items with the given one */ 1415 if ((item = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) { 1416 item->type = type; 1417 free(item->name); 1418 if (name) { 1419 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1420 strcpy(item->name, name); 1421 } else 1422 item->name = NULL; 1423 aim_tlvlist_free(&item->data); 1424 item->data = aim_tlvlist_copy(data); 1425 } 1426 1427 if ((item = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) { 1428 item->type = type; 1429 free(item->name); 1430 if (name) { 1431 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1432 strcpy(item->name, name); 1433 } else 1434 item->name = NULL; 1435 aim_tlvlist_free(&item->data); 1436 item->data = aim_tlvlist_copy(data); 1437 } 1438 1439 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1440 ret = userfunc(sess, rx); 1441 1442 free(name); 1443 aim_tlvlist_free(&data); 1444 } 1445 1446 return ret; 1412 1447 } 1413 1448 … … 1419 1454 static int parsedel(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1420 1455 { 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1456 int ret = 0; 1457 aim_rxcallback_t userfunc; 1458 fu16_t gid, bid; 1459 struct aim_ssi_item *del; 1460 1461 while (aim_bstream_empty(bs)) { 1462 aim_bstream_advance(bs, aimbs_get16(bs)); 1463 gid = aimbs_get16(bs); 1464 bid = aimbs_get16(bs); 1465 aimbs_get16(bs); 1466 aim_bstream_advance(bs, aimbs_get16(bs)); 1467 1468 if ((del = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) 1469 aim_ssi_itemlist_del(&sess->ssi.local, del); 1470 if ((del = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) 1471 aim_ssi_itemlist_del(&sess->ssi.official, del); 1472 1473 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1474 ret = userfunc(sess, rx); 1475 } 1476 1477 return ret; 1443 1478 } 1444 1479 … … 1451 1486 static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1452 1487 { 1453 int ret = 0; 1454 aim_rxcallback_t userfunc; 1455 struct aim_ssi_tmp *cur, *del; 1456 1457 owl_function_debugmsg("Handling SNAC SSI ACK"); 1458 1459 /* Read in the success/failure flags from the ack SNAC */ 1460 cur = sess->ssi.pending; 1461 while (cur && (aim_bstream_empty(bs)>0)) { 1462 cur->ack = aimbs_get16(bs); 1463 cur = cur->next; 1464 } 1465 1466 /* 1467 * If outcome is 0, then add the item to the item list, or replace the other item, 1468 * or remove the old item. If outcome is non-zero, then remove the item from the 1469 * local list, or unmodify it, or add it. 1470 */ 1471 for (cur=sess->ssi.pending; (cur && (cur->ack != 0xffff)); cur=cur->next) { 1472 owl_function_debugmsg("parseack: processing a change"); 1473 if (cur->item) { 1474 if (cur->ack) { 1475 /* Our action was unsuccessful, so change the local list back to how it was */ 1476 if (cur->action == AIM_CB_SSI_ADD) { 1477 owl_function_debugmsg("parseack: unsuccesful add, reverting"); 1478 /* Remove the item from the local list */ 1479 /* Make sure cur->item is still valid memory */ 1480 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1481 if (cur->item->name) { 1482 cur->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1483 strcpy(cur->name, cur->item->name); 1484 } 1485 aim_ssi_itemlist_del(&sess->ssi.local, cur->item); 1486 } 1487 cur->item = NULL; 1488 1489 } else if (cur->action == AIM_CB_SSI_MOD) { 1490 /* Replace the local item with the item from the official list */ 1491 owl_function_debugmsg("parseack: unsuccesful modify, reverting"); 1492 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1493 struct aim_ssi_item *cur1; 1494 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1495 free(cur->item->name); 1496 if (cur1->name) { 1497 cur->item->name = (char *)malloc((strlen(cur1->name)+1)*sizeof(char)); 1498 strcpy(cur->item->name, cur1->name); 1499 } else 1500 cur->item->name = NULL; 1501 aim_freetlvchain(&cur->item->data); 1502 cur->item->data = aim_tlvlist_copy(cur1->data); 1503 } 1504 } else 1505 cur->item = NULL; 1506 1507 } else if (cur->action == AIM_CB_SSI_DEL) { 1508 /* Add the item back into the local list */ 1509 owl_function_debugmsg("parseack: unsuccesful delete, reverting"); 1510 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) { 1511 aim_ssi_itemlist_add(&sess->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1512 } else 1513 cur->item = NULL; 1514 } 1515 1516 } else { 1517 /* Do the exact opposite */ 1518 if (cur->action == AIM_CB_SSI_ADD) { 1519 /* Add the local item to the official list */ 1520 owl_function_debugmsg("parseack: succesful add"); 1521 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1522 aim_ssi_itemlist_add(&sess->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1523 } else 1524 cur->item = NULL; 1525 1526 } else if (cur->action == AIM_CB_SSI_MOD) { 1527 /* Replace the official item with the item from the local list */ 1528 owl_function_debugmsg("parseack: succesful modify"); 1529 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1530 struct aim_ssi_item *cur1; 1531 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1532 free(cur1->name); 1533 if (cur->item->name) { 1534 cur1->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1535 strcpy(cur1->name, cur->item->name); 1536 } else 1537 cur1->name = NULL; 1538 aim_freetlvchain(&cur1->data); 1539 cur1->data = aim_tlvlist_copy(cur->item->data); 1540 } 1541 } else 1542 cur->item = NULL; 1543 1544 } else if (cur->action == AIM_CB_SSI_DEL) { 1545 /* Remove the item from the official list */ 1546 owl_function_debugmsg("parseack: succesful delete"); 1547 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) 1548 aim_ssi_itemlist_del(&sess->ssi.official, cur->item); 1549 cur->item = NULL; 1550 } 1551 1552 } 1553 } /* End if (cur->item) */ 1554 } /* End for loop */ 1555 1556 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1557 ret = userfunc(sess, rx, sess->ssi.pending); 1558 1559 /* Free all aim_ssi_tmp's with an outcome */ 1560 cur = sess->ssi.pending; 1561 while (cur && (cur->ack != 0xffff)) { 1562 del = cur; 1563 cur = cur->next; 1564 free(del->name); 1565 free(del); 1566 } 1567 sess->ssi.pending = cur; 1568 1569 /* If we're not waiting for any more acks, then send more SNACs */ 1570 1571 if (!sess->ssi.pending) { 1572 sess->ssi.pending = NULL; 1573 sess->ssi.waiting_for_ack = 0; 1574 owl_function_debugmsg("parseack: Clearing SSI waiting_for_ack"); 1575 aim_ssi_sync(sess); 1576 } 1577 1578 owl_function_debugmsg("parseack: returning with %i", ret); 1579 1580 return ret; 1488 int ret = 0; 1489 aim_rxcallback_t userfunc; 1490 struct aim_ssi_tmp *cur, *del; 1491 1492 /* Read in the success/failure flags from the ack SNAC */ 1493 cur = sess->ssi.pending; 1494 while (cur && (aim_bstream_empty(bs)>0)) { 1495 cur->ack = aimbs_get16(bs); 1496 cur = cur->next; 1497 } 1498 1499 /* 1500 * If outcome is 0, then add the item to the item list, or replace the other item, 1501 * or remove the old item. If outcome is non-zero, then remove the item from the 1502 * local list, or unmodify it, or add it. 1503 */ 1504 for (cur=sess->ssi.pending; (cur && (cur->ack != 0xffff)); cur=cur->next) { 1505 if (cur->item) { 1506 if (cur->ack) { 1507 /* Our action was unsuccessful, so change the local list back to how it was */ 1508 if (cur->action == AIM_CB_SSI_ADD) { 1509 /* Remove the item from the local list */ 1510 /* Make sure cur->item is still valid memory */ 1511 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1512 if (cur->item->name) { 1513 cur->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1514 strcpy(cur->name, cur->item->name); 1515 } 1516 aim_ssi_itemlist_del(&sess->ssi.local, cur->item); 1517 } 1518 cur->item = NULL; 1519 1520 } else if (cur->action == AIM_CB_SSI_MOD) { 1521 /* Replace the local item with the item from the official list */ 1522 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1523 struct aim_ssi_item *cur1; 1524 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1525 free(cur->item->name); 1526 if (cur1->name) { 1527 cur->item->name = (char *)malloc((strlen(cur1->name)+1)*sizeof(char)); 1528 strcpy(cur->item->name, cur1->name); 1529 } else 1530 cur->item->name = NULL; 1531 aim_tlvlist_free(&cur->item->data); 1532 cur->item->data = aim_tlvlist_copy(cur1->data); 1533 } 1534 } else 1535 cur->item = NULL; 1536 1537 } else if (cur->action == AIM_CB_SSI_DEL) { 1538 /* Add the item back into the local list */ 1539 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) { 1540 aim_ssi_itemlist_add(&sess->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1541 } else 1542 cur->item = NULL; 1543 } 1544 1545 } else { 1546 /* Do the exact opposite */ 1547 if (cur->action == AIM_CB_SSI_ADD) { 1548 /* Add the local item to the official list */ 1549 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1550 aim_ssi_itemlist_add(&sess->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1551 } else 1552 cur->item = NULL; 1553 1554 } else if (cur->action == AIM_CB_SSI_MOD) { 1555 /* Replace the official item with the item from the local list */ 1556 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1557 struct aim_ssi_item *cur1; 1558 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1559 free(cur1->name); 1560 if (cur->item->name) { 1561 cur1->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1562 strcpy(cur1->name, cur->item->name); 1563 } else 1564 cur1->name = NULL; 1565 aim_tlvlist_free(&cur1->data); 1566 cur1->data = aim_tlvlist_copy(cur->item->data); 1567 } 1568 } else 1569 cur->item = NULL; 1570 1571 } else if (cur->action == AIM_CB_SSI_DEL) { 1572 /* Remove the item from the official list */ 1573 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) 1574 aim_ssi_itemlist_del(&sess->ssi.official, cur->item); 1575 cur->item = NULL; 1576 } 1577 1578 } 1579 } /* End if (cur->item) */ 1580 } /* End for loop */ 1581 1582 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1583 ret = userfunc(sess, rx, sess->ssi.pending); 1584 1585 /* Free all aim_ssi_tmp's with an outcome */ 1586 cur = sess->ssi.pending; 1587 while (cur && (cur->ack != 0xffff)) { 1588 del = cur; 1589 cur = cur->next; 1590 free(del->name); 1591 free(del); 1592 } 1593 sess->ssi.pending = cur; 1594 1595 /* If we're not waiting for any more acks, then send more SNACs */ 1596 if (!sess->ssi.pending) { 1597 sess->ssi.pending = NULL; 1598 sess->ssi.waiting_for_ack = 0; 1599 aim_ssi_sync(sess); 1600 } 1601 1602 return ret; 1581 1603 } 1582 1604 … … 1590 1612 static int parsedataunchanged(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1591 1613 { 1592 1593 1594 1595 1596 1597 1598 1599 1600 1614 int ret = 0; 1615 aim_rxcallback_t userfunc; 1616 1617 sess->ssi.received_data = 1; 1618 1619 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1620 ret = userfunc(sess, rx); 1621 1622 return ret; 1601 1623 } 1602 1624 … … 1609 1631 faim_export int aim_ssi_modbegin(aim_session_t *sess) 1610 1632 { 1611 1612 1613 1614 1615 1616 1633 aim_conn_t *conn; 1634 1635 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1636 return -EINVAL; 1637 1638 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART); 1617 1639 } 1618 1640 … … 1625 1647 faim_export int aim_ssi_modend(aim_session_t *sess) 1626 1648 { 1627 aim_conn_t *conn; 1628 1629 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) return -EINVAL; 1630 1631 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP); 1649 aim_conn_t *conn; 1650 1651 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1652 return -EINVAL; 1653 1654 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP); 1632 1655 } 1633 1656 … … 1640 1663 faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg) 1641 1664 { 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1665 aim_conn_t *conn; 1666 aim_frame_t *fr; 1667 aim_snacid_t snacid; 1668 1669 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1670 return -EINVAL; 1671 1672 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2))) 1673 return -ENOMEM; 1674 1675 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, NULL, 0); 1676 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, snacid); 1677 1678 /* Screen name */ 1679 aimbs_put8(&fr->data, strlen(sn)); 1680 aimbs_putraw(&fr->data, sn, strlen(sn)); 1681 1682 /* Message (null terminated) */ 1683 aimbs_put16(&fr->data, msg ? strlen(msg) : 0); 1684 if (msg) { 1685 aimbs_putraw(&fr->data, msg, strlen(msg)); 1686 aimbs_put8(&fr->data, 0x00); 1687 } 1688 1689 /* Unknown */ 1690 aimbs_put16(&fr->data, 0x0000); 1691 1692 aim_tx_enqueue(sess, fr); 1693 1694 return 0; 1672 1695 } 1673 1696 … … 1677 1700 static int receiveauthgrant(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1678 1701 { 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1702 int ret = 0; 1703 aim_rxcallback_t userfunc; 1704 fu16_t tmp; 1705 char *sn, *msg; 1706 1707 /* Read screen name */ 1708 if ((tmp = aimbs_get8(bs))) 1709 sn = aimbs_getstr(bs, tmp); 1710 else 1711 sn = NULL; 1712 1713 /* Read message (null terminated) */ 1714 if ((tmp = aimbs_get16(bs))) 1715 msg = aimbs_getstr(bs, tmp); 1716 else 1717 msg = NULL; 1718 1719 /* Unknown */ 1720 tmp = aimbs_get16(bs); 1721 1722 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1723 ret = userfunc(sess, rx, sn, msg); 1724 1725 free(sn); 1726 free(msg); 1727 1728 return ret; 1706 1729 } 1707 1730 … … 1715 1738 faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg) 1716 1739 { 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1740 aim_conn_t *conn; 1741 aim_frame_t *fr; 1742 aim_snacid_t snacid; 1743 1744 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1745 return -EINVAL; 1746 1747 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2))) 1748 return -ENOMEM; 1749 1750 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, NULL, 0); 1751 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, snacid); 1752 1753 /* Screen name */ 1754 aimbs_put8(&fr->data, strlen(sn)); 1755 aimbs_putraw(&fr->data, sn, strlen(sn)); 1756 1757 /* Message (null terminated) */ 1758 aimbs_put16(&fr->data, msg ? strlen(msg) : 0); 1759 if (msg) { 1760 aimbs_putraw(&fr->data, msg, strlen(msg)); 1761 aimbs_put8(&fr->data, 0x00); 1762 } 1763 1764 /* Unknown */ 1765 aimbs_put16(&fr->data, 0x0000); 1766 1767 aim_tx_enqueue(sess, fr); 1768 1769 return 0; 1747 1770 } 1748 1771 … … 1752 1775 static int receiveauthrequest(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1753 1776 { 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1777 int ret = 0; 1778 aim_rxcallback_t userfunc; 1779 fu16_t tmp; 1780 char *sn, *msg; 1781 1782 /* Read screen name */ 1783 if ((tmp = aimbs_get8(bs))) 1784 sn = aimbs_getstr(bs, tmp); 1785 else 1786 sn = NULL; 1787 1788 /* Read message (null terminated) */ 1789 if ((tmp = aimbs_get16(bs))) 1790 msg = aimbs_getstr(bs, tmp); 1791 else 1792 msg = NULL; 1793 1794 /* Unknown */ 1795 tmp = aimbs_get16(bs); 1796 1797 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1798 ret = userfunc(sess, rx, sn, msg); 1799 1800 free(sn); 1801 free(msg); 1802 1803 return ret; 1781 1804 } 1782 1805 … … 1793 1816 faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg) 1794 1817 { 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1818 aim_conn_t *conn; 1819 aim_frame_t *fr; 1820 aim_snacid_t snacid; 1821 1822 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1823 return -EINVAL; 1824 1825 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2))) 1826 return -ENOMEM; 1827 1828 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, NULL, 0); 1829 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, snacid); 1830 1831 /* Screen name */ 1832 aimbs_put8(&fr->data, strlen(sn)); 1833 aimbs_putraw(&fr->data, sn, strlen(sn)); 1834 1835 /* Grant or deny */ 1836 aimbs_put8(&fr->data, reply); 1837 1838 /* Message (null terminated) */ 1839 aimbs_put16(&fr->data, msg ? (strlen(msg)+1) : 0); 1840 if (msg) { 1841 aimbs_putraw(&fr->data, msg, strlen(msg)); 1842 aimbs_put8(&fr->data, 0x00); 1843 } 1844 1845 /* Unknown */ 1846 aimbs_put16(&fr->data, 0x0000); 1847 1848 aim_tx_enqueue(sess, fr); 1849 1850 return 0; 1828 1851 } 1829 1852 … … 1835 1858 static int receiveauthreply(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1836 1859 { 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1860 int ret = 0; 1861 aim_rxcallback_t userfunc; 1862 fu16_t tmp; 1863 fu8_t reply; 1864 char *sn, *msg; 1865 1866 /* Read screen name */ 1867 if ((tmp = aimbs_get8(bs))) 1868 sn = aimbs_getstr(bs, tmp); 1869 else 1870 sn = NULL; 1871 1872 /* Read reply */ 1873 reply = aimbs_get8(bs); 1874 1875 /* Read message (null terminated) */ 1876 if ((tmp = aimbs_get16(bs))) 1877 msg = aimbs_getstr(bs, tmp); 1878 else 1879 msg = NULL; 1880 1881 /* Unknown */ 1882 tmp = aimbs_get16(bs); 1883 1884 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1885 ret = userfunc(sess, rx, sn, reply, msg); 1886 1887 free(sn); 1888 free(msg); 1889 1890 return ret; 1868 1891 } 1869 1892 … … 1873 1896 static int receiveadded(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1874 1897 { 1875 int ret = 0; 1876 aim_rxcallback_t userfunc; 1877 fu16_t tmp; 1878 char *sn; 1879 1880 /* Read screen name */ 1881 if ((tmp = aimbs_get8(bs))) { 1882 sn = aimbs_getstr(bs, tmp); 1883 } else { 1884 sn = NULL; 1885 } 1886 1887 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1888 ret = userfunc(sess, rx, sn); 1889 } 1890 1891 free(sn); 1892 return(ret); 1898 int ret = 0; 1899 aim_rxcallback_t userfunc; 1900 fu16_t tmp; 1901 char *sn; 1902 1903 /* Read screen name */ 1904 if ((tmp = aimbs_get8(bs))) 1905 sn = aimbs_getstr(bs, tmp); 1906 else 1907 sn = NULL; 1908 1909 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1910 ret = userfunc(sess, rx, sn); 1911 1912 free(sn); 1913 1914 return ret; 1893 1915 } 1894 1916 1895 1917 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1896 1918 { 1897 if (snac->subtype == AIM_CB_SSI_RIGHTSINFO) { 1898 return parserights(sess, mod, rx, snac, bs); 1899 } else if (snac->subtype == AIM_CB_SSI_LIST) { 1900 return parsedata(sess, mod, rx, snac, bs); 1901 } else if (snac->subtype == AIM_CB_SSI_ADD) { 1902 return parseadd(sess, mod, rx, snac, bs); 1903 } else if (snac->subtype == AIM_CB_SSI_MOD) { 1904 return parsemod(sess, mod, rx, snac, bs); 1905 } else if (snac->subtype == AIM_CB_SSI_DEL) { 1906 return parsedel(sess, mod, rx, snac, bs); 1907 } else if (snac->subtype == AIM_CB_SSI_SRVACK) { 1908 return parseack(sess, mod, rx, snac, bs); 1909 } else if (snac->subtype == AIM_CB_SSI_NOLIST) { 1910 return parsedataunchanged(sess, mod, rx, snac, bs); 1911 } else if (snac->subtype == AIM_CB_SSI_RECVAUTH) { 1912 return receiveauthgrant(sess, mod, rx, snac, bs); 1913 } else if (snac->subtype == AIM_CB_SSI_RECVAUTHREQ) { 1914 return receiveauthrequest(sess, mod, rx, snac, bs); 1915 } else if (snac->subtype == AIM_CB_SSI_RECVAUTHREP) { 1916 return receiveauthreply(sess, mod, rx, snac, bs); 1917 } else if (snac->subtype == AIM_CB_SSI_ADDED) { 1918 return receiveadded(sess, mod, rx, snac, bs); 1919 } 1920 return(0); 1919 1920 if (snac->subtype == AIM_CB_SSI_RIGHTSINFO) 1921 return parserights(sess, mod, rx, snac, bs); 1922 else if (snac->subtype == AIM_CB_SSI_LIST) 1923 return parsedata(sess, mod, rx, snac, bs); 1924 else if (snac->subtype == AIM_CB_SSI_ADD) 1925 return parseadd(sess, mod, rx, snac, bs); 1926 else if (snac->subtype == AIM_CB_SSI_MOD) 1927 return parsemod(sess, mod, rx, snac, bs); 1928 else if (snac->subtype == AIM_CB_SSI_DEL) 1929 return parsedel(sess, mod, rx, snac, bs); 1930 else if (snac->subtype == AIM_CB_SSI_SRVACK) 1931 return parseack(sess, mod, rx, snac, bs); 1932 else if (snac->subtype == AIM_CB_SSI_NOLIST) 1933 return parsedataunchanged(sess, mod, rx, snac, bs); 1934 else if (snac->subtype == AIM_CB_SSI_RECVAUTH) 1935 return receiveauthgrant(sess, mod, rx, snac, bs); 1936 else if (snac->subtype == AIM_CB_SSI_RECVAUTHREQ) 1937 return receiveauthrequest(sess, mod, rx, snac, bs); 1938 else if (snac->subtype == AIM_CB_SSI_RECVAUTHREP) 1939 return receiveauthreply(sess, mod, rx, snac, bs); 1940 else if (snac->subtype == AIM_CB_SSI_ADDED) 1941 return receiveadded(sess, mod, rx, snac, bs); 1942 1943 return 0; 1921 1944 } 1922 1945 1923 1946 static void ssi_shutdown(aim_session_t *sess, aim_module_t *mod) 1924 1947 { 1925 aim_ssi_freelist(sess); 1926 return; 1948 aim_ssi_freelist(sess); 1927 1949 } 1928 1950 1929 1951 faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod) 1930 1952 { 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 } 1953 1954 mod->family = AIM_CB_FAM_SSI; 1955 mod->version = 0x0004; 1956 mod->toolid = 0x0110; 1957 mod->toolversion = 0x0629; 1958 mod->flags = 0; 1959 strncpy(mod->name, "ssi", sizeof(mod->name)); 1960 mod->snachandler = snachandler; 1961 mod->shutdown = ssi_shutdown; 1962 1963 return 0; 1964 } -
libfaim/tlv.c
re374dee rcf02dd6 3 3 #include <aim.h> 4 4 5 static aim_tlv_t *createtlv( void)6 { 7 aim_tlv_t * newtlv;8 9 if (!( newtlv= (aim_tlv_t *)malloc(sizeof(aim_tlv_t))))5 static aim_tlv_t *createtlv(fu16_t type, fu16_t length, fu8_t *value) 6 { 7 aim_tlv_t *ret; 8 9 if (!(ret = (aim_tlv_t *)malloc(sizeof(aim_tlv_t)))) 10 10 return NULL; 11 memset(newtlv, 0, sizeof(aim_tlv_t)); 12 13 return newtlv; 11 ret->type = type; 12 ret->length = length; 13 ret->value = value; 14 15 return ret; 14 16 } 15 17 … … 28 30 29 31 /** 30 * aim_readtlvchain - Read a TLV chain from a buffer. 31 * @param bs Input bstream 32 * Read a TLV chain from a buffer. 32 33 * 33 34 * Reads and parses a series of TLV patterns from a data buffer; the 34 35 * returned structure is manipulatable with the rest of the TLV 35 * routines. When done with a TLV chain, aim_ freetlvchain() should36 * routines. When done with a TLV chain, aim_tlvlist_free() should 36 37 * be called to free the dynamic substructures. 37 38 * … … 42 43 * in libfaim. 43 44 * 44 */ 45 faim_internal aim_tlvlist_t *aim_readtlvchain(aim_bstream_t *bs) 45 * @param bs Input bstream 46 */ 47 faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs) 46 48 { 47 49 aim_tlvlist_t *list = NULL, *cur; … … 71 73 72 74 if (length > aim_bstream_empty(bs)) { 73 aim_ freetlvchain(&list);75 aim_tlvlist_free(&list); 74 76 return NULL; 75 77 } … … 77 79 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); 78 80 if (!cur) { 79 aim_ freetlvchain(&list);81 aim_tlvlist_free(&list); 80 82 return NULL; 81 83 } … … 83 85 memset(cur, 0, sizeof(aim_tlvlist_t)); 84 86 85 cur->tlv = createtlv( );87 cur->tlv = createtlv(type, length, NULL); 86 88 if (!cur->tlv) { 87 89 free(cur); 88 aim_ freetlvchain(&list);90 aim_tlvlist_free(&list); 89 91 return NULL; 90 92 } 91 cur->tlv->type = type; 92 if ((cur->tlv->length = length)) { 93 cur->tlv->value = aimbs_getraw(bs, length); 94 if (!cur->tlv->value) { 95 freetlv(&cur->tlv); 96 free(cur); 97 aim_freetlvchain(&list); 98 return NULL; 99 } 93 if (cur->tlv->length > 0) { 94 cur->tlv->value = aimbs_getraw(bs, length); 95 if (!cur->tlv->value) { 96 freetlv(&cur->tlv); 97 free(cur); 98 aim_tlvlist_free(&list); 99 return NULL; 100 } 100 101 } 101 102 … … 109 110 110 111 /** 111 * aim_readtlvchain_num - Read a TLV chain from a buffer. 112 * Read a TLV chain from a buffer. 113 * 114 * Reads and parses a series of TLV patterns from a data buffer; the 115 * returned structure is manipulatable with the rest of the TLV 116 * routines. When done with a TLV chain, aim_tlvlist_free() should 117 * be called to free the dynamic substructures. 118 * 119 * XXX There should be a flag setable here to have the tlvlist contain 120 * bstream references, so that at least the ->value portion of each 121 * element doesn't need to be malloc/memcpy'd. This could prove to be 122 * just as effecient as the in-place TLV parsing used in a couple places 123 * in libfaim. 124 * 112 125 * @param bs Input bstream 113 126 * @param num The max number of TLVs that will be read, or -1 if unlimited. … … 115 128 * but the chain is not at the end of the SNAC, and the chain is 116 129 * preceeded by the number of TLVs. So you can limit that with this. 130 */ 131 faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num) 132 { 133 aim_tlvlist_t *list = NULL, *cur; 134 135 while ((aim_bstream_empty(bs) > 0) && (num != 0)) { 136 fu16_t type, length; 137 138 type = aimbs_get16(bs); 139 length = aimbs_get16(bs); 140 141 if (length > aim_bstream_empty(bs)) { 142 aim_tlvlist_free(&list); 143 return NULL; 144 } 145 146 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); 147 if (!cur) { 148 aim_tlvlist_free(&list); 149 return NULL; 150 } 151 152 memset(cur, 0, sizeof(aim_tlvlist_t)); 153 154 cur->tlv = createtlv(type, length, NULL); 155 if (!cur->tlv) { 156 free(cur); 157 aim_tlvlist_free(&list); 158 return NULL; 159 } 160 if (cur->tlv->length > 0) { 161 cur->tlv->value = aimbs_getraw(bs, length); 162 if (!cur->tlv->value) { 163 freetlv(&cur->tlv); 164 free(cur); 165 aim_tlvlist_free(&list); 166 return NULL; 167 } 168 } 169 170 if (num > 0) 171 num--; 172 cur->next = list; 173 list = cur; 174 } 175 176 return list; 177 } 178 179 /** 180 * Read a TLV chain from a buffer. 117 181 * 118 182 * Reads and parses a series of TLV patterns from a data buffer; the 119 183 * returned structure is manipulatable with the rest of the TLV 120 * routines. When done with a TLV chain, aim_ freetlvchain() should184 * routines. When done with a TLV chain, aim_tlvlist_free() should 121 185 * be called to free the dynamic substructures. 122 186 * … … 127 191 * in libfaim. 128 192 * 129 */130 faim_internal aim_tlvlist_t *aim_readtlvchain_num(aim_bstream_t *bs, fu16_t num)131 {132 aim_tlvlist_t *list = NULL, *cur;133 134 while ((aim_bstream_empty(bs) > 0) && (num != 0)) {135 fu16_t type, length;136 137 type = aimbs_get16(bs);138 length = aimbs_get16(bs);139 140 if (length > aim_bstream_empty(bs)) {141 aim_freetlvchain(&list);142 return NULL;143 }144 145 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t));146 if (!cur) {147 aim_freetlvchain(&list);148 return NULL;149 }150 151 memset(cur, 0, sizeof(aim_tlvlist_t));152 153 cur->tlv = createtlv();154 if (!cur->tlv) {155 free(cur);156 aim_freetlvchain(&list);157 return NULL;158 }159 cur->tlv->type = type;160 if ((cur->tlv->length = length)) {161 cur->tlv->value = aimbs_getraw(bs, length);162 if (!cur->tlv->value) {163 freetlv(&cur->tlv);164 free(cur);165 aim_freetlvchain(&list);166 return NULL;167 }168 }169 170 num--;171 cur->next = list;172 list = cur;173 }174 175 return list;176 }177 178 /**179 * aim_readtlvchain_len - Read a TLV chain from a buffer.180 193 * @param bs Input bstream 181 194 * @param len The max length in bytes that will be read. … … 183 196 * but the chain is not at the end of the SNAC, and the chain is 184 197 * preceeded by the length of the TLVs. So you can limit that with this. 185 * 186 * Reads and parses a series of TLV patterns from a data buffer; the 187 * returned structure is manipulatable with the rest of the TLV 188 * routines. When done with a TLV chain, aim_freetlvchain() should 189 * be called to free the dynamic substructures. 190 * 191 * XXX There should be a flag setable here to have the tlvlist contain 192 * bstream references, so that at least the ->value portion of each 193 * element doesn't need to be malloc/memcpy'd. This could prove to be 194 * just as effecient as the in-place TLV parsing used in a couple places 195 * in libfaim. 196 * 197 */ 198 faim_internal aim_tlvlist_t *aim_readtlvchain_len(aim_bstream_t *bs, fu16_t len) 198 */ 199 faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len) 199 200 { 200 201 aim_tlvlist_t *list = NULL, *cur; … … 207 208 208 209 if (length > aim_bstream_empty(bs)) { 209 aim_ freetlvchain(&list);210 aim_tlvlist_free(&list); 210 211 return NULL; 211 212 } … … 213 214 cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t)); 214 215 if (!cur) { 215 aim_ freetlvchain(&list);216 aim_tlvlist_free(&list); 216 217 return NULL; 217 218 } … … 219 220 memset(cur, 0, sizeof(aim_tlvlist_t)); 220 221 221 cur->tlv = createtlv( );222 cur->tlv = createtlv(type, length, NULL); 222 223 if (!cur->tlv) { 223 224 free(cur); 224 aim_ freetlvchain(&list);225 aim_tlvlist_free(&list); 225 226 return NULL; 226 227 } 227 cur->tlv->type = type; 228 if ((cur->tlv->length = length)) { 229 cur->tlv->value = aimbs_getraw(bs, length); 230 if (!cur->tlv->value) { 231 freetlv(&cur->tlv); 232 free(cur); 233 aim_freetlvchain(&list); 234 return NULL; 235 } 236 } 237 238 len -= aim_sizetlvchain(&cur); 228 if (cur->tlv->length > 0) { 229 cur->tlv->value = aimbs_getraw(bs, length); 230 if (!cur->tlv->value) { 231 freetlv(&cur->tlv); 232 free(cur); 233 aim_tlvlist_free(&list); 234 return NULL; 235 } 236 } 237 238 len -= aim_tlvlist_size(&cur); 239 239 cur->next = list; 240 240 list = cur; … … 245 245 246 246 /** 247 * aim_tlvlist_copy - Duplicate a TLV chain. 248 * @param orig 249 * 247 * Duplicate a TLV chain. 250 248 * This is pretty pelf exslanatory. 251 249 * 250 * @param orig The TLV chain you want to make a copy of. 251 * @return A newly allocated TLV chain. 252 252 */ 253 253 faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) … … 256 256 257 257 while (orig) { 258 aim_ addtlvtochain_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value);258 aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); 259 259 orig = orig->next; 260 260 } … … 275 275 aim_bstream_t bs1, bs2; 276 276 277 if (aim_ sizetlvchain(&one) != aim_sizetlvchain(&two))277 if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) 278 278 return 1; 279 279 280 aim_bstream_init(&bs1, ((fu8_t *)malloc(aim_ sizetlvchain(&one)*sizeof(fu8_t))), aim_sizetlvchain(&one));281 aim_bstream_init(&bs2, ((fu8_t *)malloc(aim_ sizetlvchain(&two)*sizeof(fu8_t))), aim_sizetlvchain(&two));282 283 aim_ writetlvchain(&bs1, &one);284 aim_ writetlvchain(&bs2, &two);280 aim_bstream_init(&bs1, ((fu8_t *)malloc(aim_tlvlist_size(&one)*sizeof(fu8_t))), aim_tlvlist_size(&one)); 281 aim_bstream_init(&bs2, ((fu8_t *)malloc(aim_tlvlist_size(&two)*sizeof(fu8_t))), aim_tlvlist_size(&two)); 282 283 aim_tlvlist_write(&bs1, &one); 284 aim_tlvlist_write(&bs2, &two); 285 285 286 286 if (memcmp(bs1.data, bs2.data, bs1.len)) { … … 297 297 298 298 /** 299 * aim_freetlvchain -Free a TLV chain structure299 * Free a TLV chain structure 300 300 * @list: Chain to be freed 301 301 * … … 305 305 * 306 306 */ 307 faim_internal void aim_ freetlvchain(aim_tlvlist_t **list)307 faim_internal void aim_tlvlist_free(aim_tlvlist_t **list) 308 308 { 309 309 aim_tlvlist_t *cur; … … 328 328 329 329 /** 330 * aim_counttlvchain - Count the number of TLVs in a chain 331 * @list: Chain to be counted 332 * 333 * Returns the number of TLVs stored in the passed chain. 334 * 335 */ 336 faim_internal int aim_counttlvchain(aim_tlvlist_t **list) 330 * Count the number of TLVs in a chain. 331 * 332 * @param list Chain to be counted. 333 * @return The number of TLVs stored in the passed chain. 334 */ 335 faim_internal int aim_tlvlist_count(aim_tlvlist_t **list) 337 336 { 338 337 aim_tlvlist_t *cur; … … 349 348 350 349 /** 351 * aim_sizetlvchain - Count the number of bytes in a TLV chain 352 * @list: Chain to be sized 353 * 354 * Returns the number of bytes that would be needed to 355 * write the passed TLV chain to a data buffer. 356 * 357 */ 358 faim_internal int aim_sizetlvchain(aim_tlvlist_t **list) 350 * Count the number of bytes in a TLV chain. 351 * 352 * @param list Chain to be sized 353 * @return The number of bytes that would be needed to 354 * write the passed TLV chain to a data buffer. 355 */ 356 faim_internal int aim_tlvlist_size(aim_tlvlist_t **list) 359 357 { 360 358 aim_tlvlist_t *cur; … … 371 369 372 370 /** 373 * aim_addtlvtochain_raw - Add a string to a TLV chain374 * @list: Desination chain (%NULL pointer if empty)375 * @t: TLV type376 * @l: Length of string to add (not including %NULL)377 * @v: String to add378 *379 371 * Adds the passed string as a TLV element of the passed type 380 372 * to the TLV chain. 381 373 * 382 */ 383 faim_internal int aim_addtlvtochain_raw(aim_tlvlist_t **list, const fu16_t t, const fu16_t l, const fu8_t *v) 374 * @param list Desination chain (%NULL pointer if empty). 375 * @param type TLV type. 376 * @length Length of string to add (not including %NULL). 377 * @value String to add. 378 * @retun The size of the value added. 379 */ 380 faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) 384 381 { 385 382 aim_tlvlist_t *newtlv, *cur; 386 383 387 if ( !list)384 if (list == NULL) 388 385 return 0; 389 386 … … 392 389 memset(newtlv, 0x00, sizeof(aim_tlvlist_t)); 393 390 394 if (!(newtlv->tlv = createtlv( ))) {391 if (!(newtlv->tlv = createtlv(type, length, NULL))) { 395 392 free(newtlv); 396 393 return 0; 397 394 } 398 newtlv->tlv->type = t; 399 if ((newtlv->tlv->length = l)) { 395 if (newtlv->tlv->length > 0) { 400 396 newtlv->tlv->value = (fu8_t *)malloc(newtlv->tlv->length); 401 memcpy(newtlv->tlv->value, v , newtlv->tlv->length);397 memcpy(newtlv->tlv->value, value, newtlv->tlv->length); 402 398 } 403 399 … … 414 410 415 411 /** 416 * aim_addtlvtochain8 - Add a 8bit integer to a TLV chain 417 * @list: Destination chain 418 * @type: TLV type to add 419 * @val: Value to add 420 * 421 * Adds a one-byte unsigned integer to a TLV chain. 422 * 423 */ 424 faim_internal int aim_addtlvtochain8(aim_tlvlist_t **list, const fu16_t t, const fu8_t v) 412 * Add a one byte integer to a TLV chain. 413 * 414 * @param list Destination chain. 415 * @param type TLV type to add. 416 * @param value Value to add. 417 * @retun The size of the value added. 418 */ 419 faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) 425 420 { 426 421 fu8_t v8[1]; 427 422 428 aimutil_put8(v8, v); 429 430 return aim_addtlvtochain_raw(list, t, 1, v8); 431 } 432 433 /** 434 * aim_addtlvtochain16 - Add a 16bit integer to a TLV chain 435 * @list: Destination chain 436 * @t: TLV type to add 437 * @v: Value to add 438 * 439 * Adds a two-byte unsigned integer to a TLV chain. 440 * 441 */ 442 faim_internal int aim_addtlvtochain16(aim_tlvlist_t **list, const fu16_t t, const fu16_t v) 423 aimutil_put8(v8, value); 424 425 return aim_tlvlist_add_raw(list, type, 1, v8); 426 } 427 428 /** 429 * Add a two byte integer to a TLV chain. 430 * 431 * @param list Destination chain. 432 * @param type TLV type to add. 433 * @param value Value to add. 434 * @retun The size of the value added. 435 */ 436 faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value) 443 437 { 444 438 fu8_t v16[2]; 445 439 446 aimutil_put16(v16, v); 447 448 return aim_addtlvtochain_raw(list, t, 2, v16); 449 } 450 451 /** 452 * aim_addtlvtochain32 - Add a 32bit integer to a TLV chain 453 * @list: Destination chain 454 * @type: TLV type to add 455 * @val: Value to add 456 * 457 * Adds a four-byte unsigned integer to a TLV chain. 458 * 459 */ 460 faim_internal int aim_addtlvtochain32(aim_tlvlist_t **list, const fu16_t t, const fu32_t v) 440 aimutil_put16(v16, value); 441 442 return aim_tlvlist_add_raw(list, type, 2, v16); 443 } 444 445 /** 446 * Add a four byte integer to a TLV chain. 447 * 448 * @param list Destination chain. 449 * @param type TLV type to add. 450 * @param value Value to add. 451 * @retun The size of the value added. 452 */ 453 faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) 461 454 { 462 455 fu8_t v32[4]; 463 456 464 aimutil_put32(v32, v); 465 466 return aim_addtlvtochain_raw(list, t, 4, v32); 467 } 468 469 /** 470 * aim_addtlvtochain_caps - Add a capability block to a TLV chain 471 * @list: Destination chain 472 * @type: TLV type to add 473 * @caps: Bitfield of capability flags to send 474 * 457 aimutil_put32(v32, value); 458 459 return aim_tlvlist_add_raw(list, type, 4, v32); 460 } 461 462 /** 475 463 * Adds a block of capability blocks to a TLV chain. The bitfield 476 464 * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: 477 465 * 478 * %AIM_CAPS_BUDDYICON Supports Buddy Icons 479 * 480 * %AIM_CAPS_VOICE Supports Voice Chat 481 * 482 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage 483 * 484 * %AIM_CAPS_CHAT Supports Chat 485 * 486 * %AIM_CAPS_GETFILE Supports Get File functions 487 * 488 * %AIM_CAPS_SENDFILE Supports Send File functions 489 * 490 */ 491 faim_internal int aim_addtlvtochain_caps(aim_tlvlist_t **list, const fu16_t t, const fu32_t caps) 466 * %AIM_CAPS_BUDDYICON Supports Buddy Icons 467 * %AIM_CAPS_VOICE Supports Voice Chat 468 * %AIM_CAPS_IMIMAGE Supports DirectIM/IMImage 469 * %AIM_CAPS_CHAT Supports Chat 470 * %AIM_CAPS_GETFILE Supports Get File functions 471 * %AIM_CAPS_SENDFILE Supports Send File functions 472 * 473 * @param list Destination chain 474 * @param type TLV type to add 475 * @param caps Bitfield of capability flags to send 476 * @retun The size of the value added. 477 */ 478 faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps) 492 479 { 493 480 fu8_t buf[16*16]; /* XXX icky fixed length buffer */ … … 501 488 aim_putcap(&bs, caps); 502 489 503 return aim_addtlvtochain_raw(list, t, aim_bstream_curpos(&bs), buf); 504 } 505 506 faim_internal int aim_addtlvtochain_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *ui) 490 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); 491 } 492 493 /** 494 * Adds the given userinfo struct to a TLV chain. 495 * 496 * @param list Destination chain. 497 * @param type TLV type to add. 498 * @retun The size of the value added. 499 */ 500 faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo) 507 501 { 508 502 fu8_t buf[1024]; /* bleh */ … … 511 505 aim_bstream_init(&bs, buf, sizeof(buf)); 512 506 513 aim_putuserinfo(&bs, ui); 514 515 return aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf); 516 } 517 518 /** 519 * aim_addtlvtochain_noval - Add a blank TLV to a TLV chain 520 * @list: Destination chain 521 * @type: TLV type to add 522 * 507 aim_putuserinfo(&bs, userinfo); 508 509 return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); 510 } 511 512 /** 523 513 * Adds a TLV with a zero length to a TLV chain. 524 514 * 525 */ 526 faim_internal int aim_addtlvtochain_noval(aim_tlvlist_t **list, const fu16_t t) 527 { 528 return aim_addtlvtochain_raw(list, t, 0, NULL); 515 * @param list Destination chain. 516 * @param type TLV type to add. 517 * @retun The size of the value added. 518 */ 519 faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type) 520 { 521 return aim_tlvlist_add_raw(list, type, 0, NULL); 529 522 } 530 523 … … 539 532 * 540 533 */ 541 faim_internal int aim_ addtlvtochain_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl)534 faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl) 542 535 { 543 536 fu8_t *buf; … … 545 538 aim_bstream_t bs; 546 539 547 buflen = aim_ sizetlvchain(tl);540 buflen = aim_tlvlist_size(tl); 548 541 549 542 if (buflen <= 0) … … 555 548 aim_bstream_init(&bs, buf, buflen); 556 549 557 aim_ writetlvchain(&bs, tl);558 559 aim_ addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);550 aim_tlvlist_write(&bs, tl); 551 552 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); 560 553 561 554 free(buf); … … 565 558 566 559 /** 567 * aim_writetlvchain - Write a TLV chain into a data buffer. 560 * Substitute a TLV of a given type with a new TLV of the same type. If 561 * you attempt to replace a TLV that does not exist, this function will 562 * just add a new TLV as if you called aim_tlvlist_add_raw(). 563 * 564 * @param list Desination chain (%NULL pointer if empty). 565 * @param type TLV type. 566 * @param length Length of string to add (not including %NULL). 567 * @param value String to add. 568 * @return The length of the TLV. 569 */ 570 faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value) 571 { 572 aim_tlvlist_t *cur; 573 574 if (list == NULL) 575 return 0; 576 577 for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next); 578 if (cur == NULL) 579 return aim_tlvlist_add_raw(list, type, length, value); 580 581 free(cur->tlv->value); 582 cur->tlv->length = length; 583 if (cur->tlv->length > 0) { 584 cur->tlv->value = (fu8_t *)malloc(cur->tlv->length); 585 memcpy(cur->tlv->value, value, cur->tlv->length); 586 } else 587 cur->tlv->value = NULL; 588 589 return cur->tlv->length; 590 } 591 592 /** 593 * Substitute a TLV of a given type with a new TLV of the same type. If 594 * you attempt to replace a TLV that does not exist, this function will 595 * just add a new TLV as if you called aim_tlvlist_add_raw(). 596 * 597 * @param list Desination chain (%NULL pointer if empty). 598 * @param type TLV type. 599 * @return The length of the TLV. 600 */ 601 faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type) 602 { 603 return aim_tlvlist_replace_raw(list, type, 0, NULL); 604 } 605 606 /** 607 * Substitute a TLV of a given type with a new TLV of the same type. If 608 * you attempt to replace a TLV that does not exist, this function will 609 * just add a new TLV as if you called aim_tlvlist_add_raw(). 610 * 611 * @param list Desination chain (%NULL pointer if empty). 612 * @param type TLV type. 613 * @param value 8 bit value to add. 614 * @return The length of the TLV. 615 */ 616 faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value) 617 { 618 fu8_t v8[1]; 619 620 aimutil_put8(v8, value); 621 622 return aim_tlvlist_replace_raw(list, type, 1, v8); 623 } 624 625 /** 626 * Substitute a TLV of a given type with a new TLV of the same type. If 627 * you attempt to replace a TLV that does not exist, this function will 628 * just add a new TLV as if you called aim_tlvlist_add_raw(). 629 * 630 * @param list Desination chain (%NULL pointer if empty). 631 * @param type TLV type. 632 * @param value 32 bit value to add. 633 * @return The length of the TLV. 634 */ 635 faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value) 636 { 637 fu8_t v32[4]; 638 639 aimutil_put32(v32, value); 640 641 return aim_tlvlist_replace_raw(list, type, 4, v32); 642 } 643 644 /** 645 * Remove a TLV of a given type. If you attempt to remove a TLV that 646 * does not exist, nothing happens. 647 * 648 * @param list Desination chain (%NULL pointer if empty). 649 * @param type TLV type. 650 */ 651 faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type) 652 { 653 aim_tlvlist_t *del; 654 655 if (!list || !(*list)) 656 return; 657 658 /* Remove the item from the list */ 659 if ((*list)->tlv->type == type) { 660 del = *list; 661 *list = (*list)->next; 662 } else { 663 aim_tlvlist_t *cur; 664 for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next); 665 if (!cur->next) 666 return; 667 del = cur->next; 668 cur->next = del->next; 669 } 670 671 /* Free the removed item */ 672 free(del->tlv->value); 673 free(del->tlv); 674 free(del); 675 } 676 677 /** 678 * aim_tlvlist_write - Write a TLV chain into a data buffer. 568 679 * @buf: Destination buffer 569 680 * @buflen: Maximum number of bytes that will be written to buffer … … 572 683 * Copies a TLV chain into a raw data buffer, writing only the number 573 684 * of bytes specified. This operation does not free the chain; 574 * aim_ freetlvchain() must still be called to free up the memory used685 * aim_tlvlist_free() must still be called to free up the memory used 575 686 * by the chain structures. 576 687 * 577 688 * XXX clean this up, make better use of bstreams 578 689 */ 579 faim_internal int aim_ writetlvchain(aim_bstream_t *bs, aim_tlvlist_t **list)690 faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list) 580 691 { 581 692 int goodbuflen; … … 583 694 584 695 /* do an initial run to test total length */ 585 goodbuflen = aim_ sizetlvchain(list);696 goodbuflen = aim_tlvlist_size(list); 586 697 587 698 if (goodbuflen > aim_bstream_empty(bs)) … … 601 712 602 713 /** 603 * aim_gettlv - Grab the Nth TLV of type type in the TLV list list. 604 * @list: Source chain 605 * @type: Requested TLV type 606 * @nth: Index of TLV of type to get 714 * Grab the Nth TLV of type type in the TLV list list. 607 715 * 608 716 * Returns a pointer to an aim_tlv_t of the specified type; … … 611 719 * in a chain. 612 720 * 613 */ 614 faim_internal aim_tlv_t *aim_gettlv(aim_tlvlist_t *list, const fu16_t t, const int n) 721 * @param list Source chain. 722 * @param type Requested TLV type. 723 * @param nth Index of TLV of type to get. 724 * @return The TLV you were looking for, or NULL if one could not be found. 725 */ 726 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const fu16_t type, const int nth) 615 727 { 616 728 aim_tlvlist_t *cur; … … 619 731 for (cur = list, i = 0; cur; cur = cur->next) { 620 732 if (cur && cur->tlv) { 621 if (cur->tlv->type == t )733 if (cur->tlv->type == type) 622 734 i++; 623 if (i >= n )735 if (i >= nth) 624 736 return cur->tlv; 625 737 } … … 630 742 631 743 /** 632 * aim_gettlv_str - Retrieve the Nth TLV in chain as a string. 633 * @list: Source TLV chain 634 * @type: TLV type to search for 635 * @nth: Index of TLV to return 636 * 637 * Same as aim_gettlv(), except that the return value is a %NULL- 638 * terminated string instead of an aim_tlv_t. This is a 639 * dynamic buffer and must be freed by the caller. 640 * 641 */ 642 faim_internal char *aim_gettlv_str(aim_tlvlist_t *list, const fu16_t t, const int n) 744 * Retrieve the data from the nth TLV in the given TLV chain as a string. 745 * 746 * @param list Source TLV chain. 747 * @param type TLV type to search for. 748 * @param nth Index of TLV to return. 749 * @return The value of the TLV you were looking for, or NULL if one could 750 * not be found. This is a dynamic buffer and must be freed by the 751 * caller. 752 */ 753 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth) 643 754 { 644 755 aim_tlv_t *tlv; 645 756 char *newstr; 646 757 647 if (!(tlv = aim_ gettlv(list, t, n)))758 if (!(tlv = aim_tlv_gettlv(list, type, nth))) 648 759 return NULL; 649 760 650 761 newstr = (char *) malloc(tlv->length + 1); 651 762 memcpy(newstr, tlv->value, tlv->length); 652 *(newstr + tlv->length)= '\0';763 newstr[tlv->length] = '\0'; 653 764 654 765 return newstr; … … 656 767 657 768 /** 658 * aim_gettlv8 - Retrieve the Nth TLV in chain as a 8bit integer.659 * @list: Source TLV chain660 * @type: TLV type to search for661 * @ nth: Index of TLV to return662 * 663 * Same as aim_gettlv(), except that the return value is a664 * 8bit integer instead of an aim_tlv_t.665 * 666 */ 667 faim_internal fu8_t aim_ gettlv8(aim_tlvlist_t *list, const fu16_t t, const int n)769 * Retrieve the data from the nth TLV in the given TLV chain as an 8bit 770 * integer. 771 * 772 * @param list Source TLV chain. 773 * @param type TLV type to search for. 774 * @param nth Index of TLV to return. 775 * @return The value the TLV you were looking for, or 0 if one could 776 * not be found. 777 */ 778 faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth) 668 779 { 669 780 aim_tlv_t *tlv; 670 781 671 if (!(tlv = aim_ gettlv(list, t, n)))782 if (!(tlv = aim_tlv_gettlv(list, type, nth))) 672 783 return 0; /* erm */ 673 784 return aimutil_get8(tlv->value); … … 675 786 676 787 /** 677 * aim_gettlv16 - Retrieve the Nth TLV in chain as a 16bit integer.678 * @list: Source TLV chain679 * @type: TLV type to search for680 * @ nth: Index of TLV to return681 * 682 * Same as aim_gettlv(), except that the return value is a683 * 16bit integer instead of an aim_tlv_t.684 * 685 */ 686 faim_internal fu16_t aim_ gettlv16(aim_tlvlist_t *list, const fu16_t t, const int n)788 * Retrieve the data from the nth TLV in the given TLV chain as a 16bit 789 * integer. 790 * 791 * @param list Source TLV chain. 792 * @param type TLV type to search for. 793 * @param nth Index of TLV to return. 794 * @return The value the TLV you were looking for, or 0 if one could 795 * not be found. 796 */ 797 faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth) 687 798 { 688 799 aim_tlv_t *tlv; 689 800 690 if (!(tlv = aim_ gettlv(list, t, n)))801 if (!(tlv = aim_tlv_gettlv(list, type, nth))) 691 802 return 0; /* erm */ 692 803 return aimutil_get16(tlv->value); … … 694 805 695 806 /** 696 * aim_gettlv32 - Retrieve the Nth TLV in chain as a 32bit integer.697 * @list: Source TLV chain698 * @type: TLV type to search for699 * @ nth: Index of TLV to return700 * 701 * Same as aim_gettlv(), except that the return value is a702 * 32bit integer instead of an aim_tlv_t.703 * 704 */ 705 faim_internal fu32_t aim_ gettlv32(aim_tlvlist_t *list, const fu16_t t, const int n)807 * Retrieve the data from the nth TLV in the given TLV chain as a 32bit 808 * integer. 809 * 810 * @param list Source TLV chain. 811 * @param type TLV type to search for. 812 * @param nth Index of TLV to return. 813 * @return The value the TLV you were looking for, or 0 if one could 814 * not be found. 815 */ 816 faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth) 706 817 { 707 818 aim_tlv_t *tlv; 708 819 709 if (!(tlv = aim_ gettlv(list, t, n)))820 if (!(tlv = aim_tlv_gettlv(list, type, nth))) 710 821 return 0; /* erm */ 711 822 return aimutil_get32(tlv->value); 712 823 } 713 714 #if 0715 /**716 * aim_puttlv_8 - Write a one-byte TLV.717 * @buf: Destination buffer718 * @t: TLV type719 * @v: Value720 *721 * Writes a TLV with a one-byte integer value portion.722 *723 */724 faim_export int aim_puttlv_8(fu8_t *buf, const fu16_t t, const fu8_t v)725 {726 fu8_t v8[1];727 728 aimutil_put8(v8, v);729 730 return aim_puttlv_raw(buf, t, 1, v8);731 }732 733 /**734 * aim_puttlv_16 - Write a two-byte TLV.735 * @buf: Destination buffer736 * @t: TLV type737 * @v: Value738 *739 * Writes a TLV with a two-byte integer value portion.740 *741 */742 faim_export int aim_puttlv_16(fu8_t *buf, const fu16_t t, const fu16_t v)743 {744 fu8_t v16[2];745 746 aimutil_put16(v16, v);747 748 return aim_puttlv_raw(buf, t, 2, v16);749 }750 751 752 /**753 * aim_puttlv_32 - Write a four-byte TLV.754 * @buf: Destination buffer755 * @t: TLV type756 * @v: Value757 *758 * Writes a TLV with a four-byte integer value portion.759 *760 */761 faim_export int aim_puttlv_32(fu8_t *buf, const fu16_t t, const fu32_t v)762 {763 fu8_t v32[4];764 765 aimutil_put32(v32, v);766 767 return aim_puttlv_raw(buf, t, 4, v32);768 }769 770 /**771 * aim_puttlv_raw - Write a raw TLV.772 * @buf: Destination buffer773 * @t: TLV type774 * @l: Length of string775 * @v: String to write776 *777 * Writes a TLV with a raw value portion. (Only the first @l778 * bytes of the passed buffer will be written, which should not779 * include a terminating NULL.)780 *781 */782 faim_export int aim_puttlv_raw(fu8_t *buf, const fu16_t t, const fu16_t l, const fu8_t *v)783 {784 int i;785 786 i = aimutil_put16(buf, t);787 i += aimutil_put16(buf+i, l);788 if (l)789 memcpy(buf+i, v, l);790 i += l;791 792 return i;793 }794 #endif -
libfaim/txqueue.c
r1e34e40 rcf02dd6 29 29 faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen) 30 30 { 31 aim_frame_t *fr; 32 33 if (!conn) { 34 faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n"); 35 return NULL; 36 } 37 38 /* For sanity... */ 39 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_LISTENER)) { 40 if (framing != AIM_FRAMETYPE_OFT) { 41 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); 42 return NULL; 43 } 44 } else { 45 if (framing != AIM_FRAMETYPE_FLAP) { 46 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); 47 return NULL; 48 } 49 } 50 51 if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t)))) return NULL; 52 memset(fr, 0, sizeof(aim_frame_t)); 53 54 fr->conn = conn; 55 fr->hdrtype = framing; 56 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 57 fr->hdr.flap.type = chan; 58 } else if (fr->hdrtype == AIM_FRAMETYPE_OFT) { 59 fr->hdr.rend.type = chan; 60 } else { 61 faimdprintf(sess, 0, "tx_new: unknown framing\n"); 62 } 63 64 if (datalen > 0) { 65 fu8_t *data; 66 if (!(data = (unsigned char *)malloc(datalen))) { 67 aim_frame_destroy(fr); 68 return NULL; 69 } 70 aim_bstream_init(&fr->data, data, datalen); 71 } 72 73 return fr; 31 aim_frame_t *fr; 32 33 if (!conn) { 34 faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n"); 35 return NULL; 36 } 37 38 /* For sanity... */ 39 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_LISTENER)) { 40 if (framing != AIM_FRAMETYPE_OFT) { 41 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); 42 return NULL; 43 } 44 } else { 45 if (framing != AIM_FRAMETYPE_FLAP) { 46 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); 47 return NULL; 48 } 49 } 50 51 if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t)))) 52 return NULL; 53 memset(fr, 0, sizeof(aim_frame_t)); 54 55 fr->conn = conn; 56 57 fr->hdrtype = framing; 58 59 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 60 61 fr->hdr.flap.type = chan; 62 63 } else if (fr->hdrtype == AIM_FRAMETYPE_OFT) { 64 65 fr->hdr.rend.type = chan; 66 67 } else 68 faimdprintf(sess, 0, "tx_new: unknown framing\n"); 69 70 if (datalen > 0) { 71 fu8_t *data; 72 73 if (!(data = (unsigned char *)malloc(datalen))) { 74 aim_frame_destroy(fr); 75 return NULL; 76 } 77 78 aim_bstream_init(&fr->data, data, datalen); 79 } 80 81 return fr; 74 82 } 75 83 … … 90 98 static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr) 91 99 { 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 100 101 if (!fr->conn) { 102 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); 103 fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); 104 } 105 106 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 107 /* assign seqnum -- XXX should really not assign until hardxmit */ 108 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 109 } 110 111 fr->handled = 0; /* not sent yet */ 112 113 /* see overhead note in aim_rxqueue counterpart */ 114 if (!sess->queue_outgoing) 115 sess->queue_outgoing = fr; 116 else { 117 aim_frame_t *cur; 118 119 for (cur = sess->queue_outgoing; cur->next; cur = cur->next) 120 ; 121 cur->next = fr; 122 } 123 124 return 0; 117 125 } 118 126 … … 131 139 { 132 140 133 if (!fr->conn) { 134 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); 135 aim_frame_destroy(fr); 136 return 0; 137 } 138 139 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 140 fr->handled = 0; /* not sent yet */ 141 aim_tx_sendframe(sess, fr); 142 aim_frame_destroy(fr); 143 144 return 0; 141 if (!fr->conn) { 142 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); 143 aim_frame_destroy(fr); 144 return 0; 145 } 146 147 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) 148 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 149 150 fr->handled = 0; /* not sent yet */ 151 152 aim_tx_sendframe(sess, fr); 153 154 aim_frame_destroy(fr); 155 156 return 0; 145 157 } 146 158 147 159 faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *)) 148 160 { 149 if (what == AIM_TX_QUEUED) { 150 sess->tx_enqueue = &aim_tx_enqueue__queuebased; 151 } else if (what == AIM_TX_IMMEDIATE) { 152 sess->tx_enqueue = &aim_tx_enqueue__immediate; 153 } else if (what == AIM_TX_USER) { 154 if (!func) return -EINVAL; 155 sess->tx_enqueue = func; 156 } else { 157 return -EINVAL; /* unknown action */ 158 } 159 160 return 0; 161 162 if (what == AIM_TX_QUEUED) 163 sess->tx_enqueue = &aim_tx_enqueue__queuebased; 164 else if (what == AIM_TX_IMMEDIATE) 165 sess->tx_enqueue = &aim_tx_enqueue__immediate; 166 else if (what == AIM_TX_USER) { 167 if (!func) 168 return -EINVAL; 169 sess->tx_enqueue = func; 170 } else 171 return -EINVAL; /* unknown action */ 172 173 return 0; 161 174 } 162 175 163 176 faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr) 164 177 { 165 166 167 168 169 170 171 172 173 174 175 176 178 179 /* 180 * If we want to send a connection thats inprogress, we have to force 181 * them to use the queue based version. Otherwise, use whatever they 182 * want. 183 */ 184 if (fr && fr->conn && 185 (fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) { 186 return aim_tx_enqueue__queuebased(sess, fr); 187 } 188 189 return (*sess->tx_enqueue)(sess, fr); 177 190 } 178 191 … … 188 201 faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn) 189 202 { 190 flap_seqnum_t ret; 191 ret = ++conn->seqnum; 192 return ret; 203 flap_seqnum_t ret; 204 205 ret = ++conn->seqnum; 206 207 return ret; 193 208 } 194 209 195 210 static int aim_send(int fd, const void *buf, size_t count) 196 211 { 197 int left, cur; 198 199 for (cur = 0, left = count; left; ) { 200 int ret; 201 202 ret = send(fd, ((unsigned char *)buf)+cur, left, 0); 203 if (ret == -1) { 204 return -1; 205 } else if (ret == 0) { 206 return cur; 207 } 208 209 cur += ret; 210 left -= ret; 211 } 212 213 return cur; 212 int left, cur; 213 214 for (cur = 0, left = count; left; ) { 215 int ret; 216 217 ret = send(fd, ((unsigned char *)buf)+cur, left, 0); 218 if (ret == -1) 219 return -1; 220 else if (ret == 0) 221 return cur; 222 223 cur += ret; 224 left -= ret; 225 } 226 227 return cur; 214 228 } 215 229 216 230 static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count) 217 231 { 218 int wrote = 0; 219 int rv = 0; 220 if (!bs || !conn || (count < 0)) 221 return -EINVAL; 222 223 if (count > aim_bstream_empty(bs)) 224 count = aim_bstream_empty(bs); /* truncate to remaining space */ 225 226 if (count) { 227 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 228 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 229 /* I strongly suspect that this is a horrible thing to do 230 * and I feel really guilty doing it. */ 231 const char *sn = aim_odc_getsn(conn); 232 aim_rxcallback_t userfunc; 233 while (count - wrote > 1024) { 234 rv = aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 235 if (rv < 0) { 236 fprintf(stderr, "aim_bstream_send: aim_send failed...\n"); 237 return -EINVAL; 238 } 239 wrote = wrote + rv; 240 241 if ((userfunc=aim_callhandler(conn->sessv, conn, 242 AIM_CB_FAM_SPECIAL, 243 AIM_CB_SPECIAL_IMAGETRANSFER))) 244 userfunc(conn->sessv, NULL, sn, 245 count-wrote>1024 ? ((double)wrote / count) : 1); 246 } 247 } 248 if (count - wrote) { 249 rv = aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 250 if (rv < 0) { 251 fprintf(stderr, "aim_bstream_send: aim_send failed...\n"); 252 return -EINVAL; 253 } 254 wrote = wrote + rv; 255 } 256 257 } 258 259 if (((aim_session_t *)conn->sessv)->debug >= 2) { 260 int i; 261 aim_session_t *sess = (aim_session_t *)conn->sessv; 262 263 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 264 for (i = 0; i < wrote; i++) { 265 if (!(i % 8)) 266 faimdprintf(sess, 2, "\n\t"); 267 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 268 } 269 faimdprintf(sess, 2, "\n"); 270 } 271 272 bs->offset += wrote; 273 274 return wrote; 232 int wrote = 0; 233 if (!bs || !conn || (count < 0)) 234 return -EINVAL; 235 236 if (count > aim_bstream_empty(bs)) 237 count = aim_bstream_empty(bs); /* truncate to remaining space */ 238 239 if (count) { 240 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 241 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 242 /* I strongly suspect that this is a horrible thing to do 243 * and I feel really guilty doing it. */ 244 const char *sn = aim_odc_getsn(conn); 245 aim_rxcallback_t userfunc; 246 while (count - wrote > 1024) { 247 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 248 if ((userfunc=aim_callhandler(conn->sessv, conn, 249 AIM_CB_FAM_SPECIAL, 250 AIM_CB_SPECIAL_IMAGETRANSFER))) 251 userfunc(conn->sessv, NULL, sn, 252 count-wrote>1024 ? ((double)wrote / count) : 1); 253 } 254 } 255 if (count - wrote) { 256 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 257 } 258 259 } 260 261 if (((aim_session_t *)conn->sessv)->debug >= 2) { 262 int i; 263 aim_session_t *sess = (aim_session_t *)conn->sessv; 264 265 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 266 for (i = 0; i < wrote; i++) { 267 if (!(i % 8)) 268 faimdprintf(sess, 2, "\n\t"); 269 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 270 } 271 faimdprintf(sess, 2, "\n"); 272 } 273 274 bs->offset += wrote; 275 276 return wrote; 275 277 } 276 278 277 279 static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr) 278 280 { 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 281 aim_bstream_t obs; 282 fu8_t *obs_raw; 283 int payloadlen, err = 0, obslen; 284 285 payloadlen = aim_bstream_curpos(&fr->data); 286 287 if (!(obs_raw = malloc(6 + payloadlen))) 288 return -ENOMEM; 289 290 aim_bstream_init(&obs, obs_raw, 6 + payloadlen); 291 292 /* FLAP header */ 293 aimbs_put8(&obs, 0x2a); 294 aimbs_put8(&obs, fr->hdr.flap.type); 295 aimbs_put16(&obs, fr->hdr.flap.seqnum); 296 aimbs_put16(&obs, payloadlen); 297 298 /* payload */ 299 aim_bstream_rewind(&fr->data); 300 aimbs_putbs(&obs, &fr->data, payloadlen); 301 302 obslen = aim_bstream_curpos(&obs); 303 aim_bstream_rewind(&obs); 304 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen) 305 err = -errno; 306 307 free(obs_raw); /* XXX aim_bstream_free */ 308 309 fr->handled = 1; 310 fr->conn->lastactivity = time(NULL); 311 312 return err; 311 313 } 312 314
Note: See TracChangeset
for help on using the changeset viewer.