- Timestamp:
- Dec 10, 2003, 3:20:45 PM (23 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
-
Makefile.in (modified) (1 diff)
-
admin.c (modified) (4 diffs)
-
aim.h (modified) (24 diffs)
-
aim_cbtypes.h (modified) (1 diff)
-
aim_internal.h (modified) (5 diffs)
-
auth.c (modified) (15 diffs)
-
bos.c (modified) (2 diffs)
-
buddylist.c (modified) (10 diffs)
-
chat.c (modified) (20 diffs)
-
chatnav.c (modified) (25 diffs)
-
conn.c (modified) (9 diffs)
-
email.c (modified) (5 diffs)
-
ft.c (modified) (1 diff)
-
icq.c (modified) (3 diffs)
-
im.c (modified) (28 diffs)
-
info.c (deleted)
-
meta.c (deleted)
-
misc.c (modified) (1 diff)
-
newsearch.c (deleted)
-
odir.c (modified) (4 diffs)
-
oscar.c (modified) (214 diffs)
-
popups.c (modified) (1 diff)
-
rxhandlers.c (modified) (1 diff)
-
search.c (modified) (2 diffs)
-
service.c (modified) (16 diffs)
-
ssi.c (modified) (49 diffs)
-
tlv.c (modified) (38 diffs)
-
txqueue.c (modified) (4 diffs)
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 0x0001 /* "damned transients" */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 0x0400953 #define AIM_FLAG_UNKNOWN800 0x0800954 #define AIM_FLAG_ABINTERNAL 0x1000955 #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 if (!cur1 || !cur2)211 return 1;212 213 if (cur1->data && !cur2->data)214 return 2;215 216 if (!cur1->data && cur2->data)217 return 3;218 219 if ((cur1->data && cur2->data) && (aim_tlvlist_cmp(cur1->data, cur2->data)))220 return 4;221 222 if (cur1->name && !cur2->name)223 return 5;224 225 if (!cur1->name && cur2->name)226 return 6;227 228 if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name))229 return 7;230 231 if (cur1->gid != cur2->gid)232 return 8;233 234 if (cur1->bid != cur2->bid)235 return 9;236 237 if (cur1->type != cur2->type)238 return 10;239 240 return 0;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 struct aim_ssi_item *cur;246 for (cur=list; cur; cur=cur->next)247 if (cur == item)248 return 1;249 return 0;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 struct aim_ssi_item *cur;263 for (cur=list; cur; cur=cur->next)264 if ((cur->gid == gid) && (cur->bid == bid))265 return cur;266 return NULL;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 struct aim_ssi_item *cur;282 if (!list)283 return NULL;284 285 if (gn && sn) { /* For finding buddies in groups */286 for (cur=list; cur; cur=cur->next)287 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {288 struct aim_ssi_item *curg;289 for (curg=list; curg; curg=curg->next)290 if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn)))291 return cur;292 }293 294 } else if (gn) { /* For finding groups */295 for (cur=list; cur; cur=cur->next) {296 if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) {297 return cur;298 }299 }300 301 } else if (sn) { /* For finding permits, denies, and ignores */302 for (cur=list; cur; cur=cur->next) {303 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {304 return cur;305 }306 }307 308 /* For stuff without names--permit deny setting, visibility mask, etc. */309 } else for (cur=list; cur; cur=cur->next) {310 if ((cur->type == type) && (!cur->name))311 return cur;312 }313 314 return NULL;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 struct aim_ssi_item *cur;327 if (!list || !sn)328 return NULL;329 for (cur=list; cur; cur=cur->next)330 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->name) && (!aim_sncmp(cur->name, sn)))331 return cur;332 return NULL;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 struct aim_ssi_item *cur, *curg;345 if (!list || !sn)346 return NULL;347 if (!(cur = aim_ssi_itemlist_exists(list, sn)))348 return NULL;349 if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000)))350 return NULL;351 return curg->name;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 struct aim_ssi_item *cur, *del;568 struct aim_ssi_tmp *curtmp, *deltmp;569 570 cur = sess->ssi.official;571 while (cur) {572 del = cur;573 cur = cur->next;574 free(del->name);575 aim_freetlvchain(&del->data);576 free(del);577 }578 579 cur = sess->ssi.local;580 while (cur) {581 del = cur;582 cur = cur->next;583 free(del->name);584 aim_freetlvchain(&del->data);585 free(del);586 }587 588 curtmp = sess->ssi.pending;589 while (curtmp) {590 deltmp = curtmp;591 curtmp = curtmp->next;592 free(deltmp);593 }594 595 sess->ssi.numitems = 0;596 sess->ssi.official = NULL;597 sess->ssi.local = NULL;598 sess->ssi.pending = NULL;599 sess->ssi.timestamp = (time_t)0;600 601 return 0;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 struct aim_ssi_item *del;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 aim_ssi_sync(sess);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 struct aim_ssi_item *del;839 840 if (!sess)841 return -EINVAL;842 843 /* Find the item */844 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT)))845 return -EINVAL;846 847 /* Remove the item from the list */848 aim_ssi_itemlist_del(&sess->ssi.local, del);849 850 /* Sync our local list with the server list */851 aim_ssi_sync(sess);852 853 return 0;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 struct aim_ssi_item *del;866 867 if (!sess)868 return -EINVAL;869 870 /* Find the item */871 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_DENY)))872 return -EINVAL;873 874 /* Remove the item from the list */875 aim_ssi_itemlist_del(&sess->ssi.local, del);876 877 /* Sync our local list with the server list */878 aim_ssi_sync(sess);879 880 return 0;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 aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn));896 aim_ssi_delbuddy(sess, sn, oldgn);897 return 0;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 struct aim_ssi_item *group;947 948 if (!sess || !oldgn || !newgn)949 return -EINVAL;950 951 if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))952 return -EINVAL;953 954 free(group->name);955 group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char));956 strcpy(group->name, newgn);957 958 /* Sync our local list with the server list */959 aim_ssi_sync(sess);960 961 return 0;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 aim_conn_t *conn;1094 1095 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1096 return -EINVAL;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 int ret = 0, i;1107 aim_rxcallback_t userfunc;1108 aim_tlvlist_t *tlvlist;1109 aim_tlv_t *tlv;1110 aim_bstream_t bstream;1111 fu16_t *maxitems;1112 1113 /* This SNAC is made up of a bunch of TLVs */1114 tlvlist = aim_readtlvchain(bs);1115 1116 /* TLV 0x0004 contains the maximum number of each item */1117 if (!(tlv = aim_gettlv(tlvlist, 0x0004, 1))) {1118 aim_freetlvchain(&tlvlist);1119 return 0;1120 }1121 1122 aim_bstream_init(&bstream, tlv->value, tlv->length);1123 1124 if (!(maxitems = (fu16_t *)malloc((tlv->length/2)*sizeof(fu16_t)))) {1125 aim_freetlvchain(&tlvlist);1126 return 0;1127 }1128 1129 for (i=0; i<(tlv->length/2); i++)1130 maxitems[i] = aimbs_get16(&bstream);1131 1132 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1133 ret = userfunc(sess, rx, tlv->length/2, maxitems);1134 1135 aim_freetlvchain(&tlvlist);1136 free(maxitems);1137 1138 return ret;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 aim_conn_t *conn;1149 1150 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1151 return -EINVAL;1152 1153 /* Free any current data, just in case */1154 aim_ssi_freelist(sess);1155 1156 return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQDATA);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 aim_conn_t *conn;1172 aim_frame_t *fr;1173 aim_snacid_t snacid;1174 1175 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1176 return -EINVAL;1177 1178 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))1179 return -ENOMEM;1180 1181 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, NULL, 0);1182 1183 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, snacid);1184 aimbs_put32(&fr->data, timestamp);1185 aimbs_put16(&fr->data, numitems);1186 1187 aim_tx_enqueue(sess, fr);1188 1189 /* Free any current data, just in case */1190 aim_ssi_freelist(sess);1191 1192 return 0;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 int ret = 0;1201 aim_rxcallback_t userfunc;1202 fu8_t fmtver; /* guess */1203 fu16_t namelen, gid, bid, type;1204 char *name;1205 aim_tlvlist_t *data;1206 1207 fmtver = aimbs_get8(bs); /* Version of ssi data. Should be 0x00 */1208 sess->ssi.numitems += aimbs_get16(bs); /* # of items in this SSI SNAC */1209 1210 /* Read in the list */1211 while (aim_bstream_empty(bs) > 4) { /* last four bytes are timestamp */1212 if ((namelen = aimbs_get16(bs)))1213 name = aimbs_getstr(bs, namelen);1214 else1215 name = NULL;1216 gid = aimbs_get16(bs);1217 bid = aimbs_get16(bs);1218 type = aimbs_get16(bs);1219 data = aim_readtlvchain_len(bs, aimbs_get16(bs));1220 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data);1221 free(name);1222 aim_freetlvchain(&data);1223 }1224 1225 /* Read in the timestamp */1226 sess->ssi.timestamp = aimbs_get32(bs);1227 1228 if (!(snac->flags & 0x0001)) {1229 /* Make a copy of the list */1230 struct aim_ssi_item *cur;1231 for (cur=sess->ssi.official; cur; cur=cur->next)1232 aim_ssi_itemlist_add(&sess->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data);1233 1234 sess->ssi.received_data = 1;1235 1236 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1237 ret = userfunc(sess, rx, fmtver, sess->ssi.numitems, sess->ssi.official, sess->ssi.timestamp);1238 }1239 1240 return ret;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 aim_conn_t *conn;1255 1256 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1257 return -EINVAL;1258 1259 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007);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 int ret = 0;1320 aim_rxcallback_t userfunc;1321 char *name;1322 fu16_t len, gid, bid, type;1323 aim_tlvlist_t *data;1324 1325 while (aim_bstream_empty(bs)) {1326 if ((len = aimbs_get16(bs)))1327 name = aimbs_getstr(bs, len);1328 else1329 name = NULL;1330 gid = aimbs_get16(bs);1331 bid = aimbs_get16(bs);1332 type = aimbs_get16(bs);1333 if ((len = aimbs_get16(bs)))1334 data = aim_readtlvchain_len(bs, len);1335 else1336 data = NULL;1337 1338 aim_ssi_itemlist_add(&sess->ssi.local, name, gid, bid, type, data);1339 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data);1340 free(name);1341 aim_freetlvchain(&data);1342 1343 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1344 ret = userfunc(sess, rx);1345 1346 free(name);1347 }1348 1349 return ret;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 int ret = 0;1360 aim_rxcallback_t userfunc;1361 char *name;1362 fu16_t len, gid, bid, type;1363 aim_tlvlist_t *data;1364 struct aim_ssi_item *item;1365 1366 while (aim_bstream_empty(bs)) {1367 if ((len = aimbs_get16(bs)))1368 name = aimbs_getstr(bs, len);1369 else1370 name = NULL;1371 gid = aimbs_get16(bs);1372 bid = aimbs_get16(bs);1373 type = aimbs_get16(bs);1374 if ((len = aimbs_get16(bs)))1375 data = aim_readtlvchain_len(bs, len);1376 else1377 data = NULL;1378 1379 /* Replace the 2 local items with the given one */1380 if ((item = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) {1381 item->type = type;1382 free(item->name);1383 if (name) {1384 item->name = (char *)malloc((strlen(name)+1)*sizeof(char));1385 strcpy(item->name, name);1386 } else1387 item->name = NULL;1388 aim_freetlvchain(&item->data);1389 item->data = aim_tlvlist_copy(data);1390 }1391 1392 if ((item = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) {1393 item->type = type;1394 free(item->name);1395 if (name) {1396 item->name = (char *)malloc((strlen(name)+1)*sizeof(char));1397 strcpy(item->name, name);1398 } else1399 item->name = NULL;1400 aim_freetlvchain(&item->data);1401 item->data = aim_tlvlist_copy(data);1402 }1403 1404 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1405 ret = userfunc(sess, rx);1406 1407 free(name);1408 aim_freetlvchain(&data);1409 }1410 1411 return ret;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 int ret = 0;1422 aim_rxcallback_t userfunc;1423 fu16_t gid, bid;1424 struct aim_ssi_item *del;1425 1426 while (aim_bstream_empty(bs)) {1427 aim_bstream_advance(bs, aimbs_get16(bs));1428 gid = aimbs_get16(bs);1429 bid = aimbs_get16(bs);1430 aimbs_get16(bs);1431 aim_bstream_advance(bs, aimbs_get16(bs));1432 1433 if ((del = aim_ssi_itemlist_find(sess->ssi.local, gid, bid)))1434 aim_ssi_itemlist_del(&sess->ssi.local, del);1435 if ((del = aim_ssi_itemlist_find(sess->ssi.official, gid, bid)))1436 aim_ssi_itemlist_del(&sess->ssi.official, del);1437 1438 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1439 ret = userfunc(sess, rx);1440 }1441 1442 return ret;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 int ret = 0;1593 aim_rxcallback_t userfunc;1594 1595 sess->ssi.received_data = 1;1596 1597 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1598 ret = userfunc(sess, rx);1599 1600 return ret;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 aim_conn_t *conn;1612 1613 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1614 return -EINVAL;1615 1616 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART);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 aim_conn_t *conn;1643 aim_frame_t *fr;1644 aim_snacid_t snacid;1645 1646 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1647 return -EINVAL;1648 1649 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))1650 return -ENOMEM;1651 1652 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, NULL, 0);1653 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, snacid);1654 1655 /* Screen name */1656 aimbs_put8(&fr->data, strlen(sn));1657 aimbs_putraw(&fr->data, sn, strlen(sn));1658 1659 /* Message (null terminated) */1660 aimbs_put16(&fr->data, msg ? strlen(msg) : 0);1661 if (msg) {1662 aimbs_putraw(&fr->data, msg, strlen(msg));1663 aimbs_put8(&fr->data, 0x00);1664 }1665 1666 /* Unknown */1667 aimbs_put16(&fr->data, 0x0000);1668 1669 aim_tx_enqueue(sess, fr);1670 1671 return 0;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 int ret = 0;1680 aim_rxcallback_t userfunc;1681 fu16_t tmp;1682 char *sn, *msg;1683 1684 /* Read screen name */1685 if ((tmp = aimbs_get8(bs)))1686 sn = aimbs_getstr(bs, tmp);1687 else1688 sn = NULL;1689 1690 /* Read message (null terminated) */1691 if ((tmp = aimbs_get16(bs)))1692 msg = aimbs_getstr(bs, tmp);1693 else1694 msg = NULL;1695 1696 /* Unknown */1697 tmp = aimbs_get16(bs);1698 1699 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1700 ret = userfunc(sess, rx, sn, msg);1701 1702 free(sn);1703 free(msg);1704 1705 return ret;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 aim_conn_t *conn;1718 aim_frame_t *fr;1719 aim_snacid_t snacid;1720 1721 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1722 return -EINVAL;1723 1724 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))1725 return -ENOMEM;1726 1727 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, NULL, 0);1728 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, snacid);1729 1730 /* Screen name */1731 aimbs_put8(&fr->data, strlen(sn));1732 aimbs_putraw(&fr->data, sn, strlen(sn));1733 1734 /* Message (null terminated) */1735 aimbs_put16(&fr->data, msg ? strlen(msg) : 0);1736 if (msg) {1737 aimbs_putraw(&fr->data, msg, strlen(msg));1738 aimbs_put8(&fr->data, 0x00);1739 }1740 1741 /* Unknown */1742 aimbs_put16(&fr->data, 0x0000);1743 1744 aim_tx_enqueue(sess, fr);1745 1746 return 0;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 int ret = 0;1755 aim_rxcallback_t userfunc;1756 fu16_t tmp;1757 char *sn, *msg;1758 1759 /* Read screen name */1760 if ((tmp = aimbs_get8(bs)))1761 sn = aimbs_getstr(bs, tmp);1762 else1763 sn = NULL;1764 1765 /* Read message (null terminated) */1766 if ((tmp = aimbs_get16(bs)))1767 msg = aimbs_getstr(bs, tmp);1768 else1769 msg = NULL;1770 1771 /* Unknown */1772 tmp = aimbs_get16(bs);1773 1774 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1775 ret = userfunc(sess, rx, sn, msg);1776 1777 free(sn);1778 free(msg);1779 1780 return ret;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 aim_conn_t *conn;1796 aim_frame_t *fr;1797 aim_snacid_t snacid;1798 1799 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1800 return -EINVAL;1801 1802 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2)))1803 return -ENOMEM;1804 1805 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, NULL, 0);1806 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, snacid);1807 1808 /* Screen name */1809 aimbs_put8(&fr->data, strlen(sn));1810 aimbs_putraw(&fr->data, sn, strlen(sn));1811 1812 /* Grant or deny */1813 aimbs_put8(&fr->data, reply);1814 1815 /* Message (null terminated) */1816 aimbs_put16(&fr->data, msg ? (strlen(msg)+1) : 0);1817 if (msg) {1818 aimbs_putraw(&fr->data, msg, strlen(msg));1819 aimbs_put8(&fr->data, 0x00);1820 }1821 1822 /* Unknown */1823 aimbs_put16(&fr->data, 0x0000);1824 1825 aim_tx_enqueue(sess, fr);1826 1827 return 0;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 int ret = 0;1838 aim_rxcallback_t userfunc;1839 fu16_t tmp;1840 fu8_t reply;1841 char *sn, *msg;1842 1843 /* Read screen name */1844 if ((tmp = aimbs_get8(bs)))1845 sn = aimbs_getstr(bs, tmp);1846 else1847 sn = NULL;1848 1849 /* Read reply */1850 reply = aimbs_get8(bs);1851 1852 /* Read message (null terminated) */1853 if ((tmp = aimbs_get16(bs)))1854 msg = aimbs_getstr(bs, tmp);1855 else1856 msg = NULL;1857 1858 /* Unknown */1859 tmp = aimbs_get16(bs);1860 1861 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1862 ret = userfunc(sess, rx, sn, reply, msg);1863 1864 free(sn);1865 free(msg);1866 1867 return ret;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 mod->family = AIM_CB_FAM_SSI;1933 mod->version = 0x0004;1934 mod->toolid = 0x0110;1935 mod->toolversion = 0x0629;1936 mod->flags = 0;1937 strncpy(mod->name, "ssi", sizeof(mod->name));1938 mod->snachandler = snachandler;1939 mod->shutdown = ssi_shutdown;1940 1941 return 0;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 if (!fr->conn) {94 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n");95 fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);96 }97 98 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) {99 /* assign seqnum -- XXX should really not assign until hardxmit */100 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn);101 }102 103 fr->handled = 0; /* not sent yet */104 105 /* see overhead note in aim_rxqueue counterpart */106 if (!sess->queue_outgoing)107 sess->queue_outgoing = fr;108 else {109 aim_frame_t *cur;110 111 for (cur = sess->queue_outgoing; cur->next; cur = cur->next)112 ;113 cur->next = fr;114 }115 116 return 0;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 * If we want to send a connection thats inprogress, we have to force168 * them to use the queue based version. Otherwise, use whatever they169 * want.170 */171 if (fr && fr->conn &&172 (fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) {173 return aim_tx_enqueue__queuebased(sess, fr);174 }175 176 return (*sess->tx_enqueue)(sess, fr);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 aim_bstream_t obs;280 fu8_t *obs_raw;281 int payloadlen, err = 0, obslen;282 283 payloadlen = aim_bstream_curpos(&fr->data);284 285 if (!(obs_raw = malloc(6 + payloadlen)))286 return -ENOMEM;287 288 aim_bstream_init(&obs, obs_raw, 6 + payloadlen);289 290 /* FLAP header */291 aimbs_put8(&obs, 0x2a);292 aimbs_put8(&obs, fr->hdr.flap.type);293 aimbs_put16(&obs, fr->hdr.flap.seqnum);294 aimbs_put16(&obs, payloadlen);295 296 /* payload */297 aim_bstream_rewind(&fr->data);298 aimbs_putbs(&obs, &fr->data, payloadlen);299 300 obslen = aim_bstream_curpos(&obs);301 aim_bstream_rewind(&obs);302 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen)303 err = -errno;304 305 free(obs_raw); /* XXX aim_bstream_free */306 307 fr->handled = 1;308 fr->conn->lastactivity = time(NULL);309 310 return err;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.
