Changeset 862371b for libfaim/chat.c
- Timestamp:
- Jun 29, 2003, 1:47:04 PM (21 years ago)
- Branches:
- master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- e016fc2
- Parents:
- 03ad7b2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfaim/chat.c
r5e53c4a r862371b 1 1 /* 2 * aim_chat.c 3 * 4 * Routines for the Chat service. 2 * Family 0x000e - Routines for the Chat service. 5 3 * 6 4 */ … … 16 14 }; 17 15 18 static void dumpbox(aim_session_t *sess, unsigned char *buf, int len)19 {20 int i;21 22 if (!sess || !buf || !len)23 return;24 25 faimdprintf(sess, 1, "\nDump of %d bytes at %p:", len, buf);26 27 for (i = 0; i < len; i++) {28 if ((i % 8) == 0)29 faimdprintf(sess, 1, "\n\t");30 31 faimdprintf(sess, 1, "0x%2x ", buf[i]);32 }33 34 faimdprintf(sess, 1, "\n\n");35 36 return;37 }38 39 16 faim_internal void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn) 40 17 { … … 107 84 } 108 85 86 static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance) 87 { 88 fu8_t *buf; 89 int buflen; 90 aim_bstream_t bs; 91 92 buflen = 2 + 1 + strlen(roomname) + 2; 93 94 if (!(buf = malloc(buflen))) 95 return 0; 96 97 aim_bstream_init(&bs, buf, buflen); 98 99 aimbs_put16(&bs, exchange); 100 aimbs_put8(&bs, strlen(roomname)); 101 aimbs_putraw(&bs, roomname, strlen(roomname)); 102 aimbs_put16(&bs, instance); 103 104 aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf); 105 106 free(buf); 107 108 return 0; 109 } 110 109 111 /* 110 * Send a Chat Message. 112 * Join a room of name roomname. This is the first step to joining an 113 * already created room. It's basically a Service Request for 114 * family 0x000e, with a little added on to specify the exchange and room 115 * name. 116 */ 117 faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance) 118 { 119 aim_frame_t *fr; 120 aim_snacid_t snacid; 121 aim_tlvlist_t *tl = NULL; 122 struct chatsnacinfo csi; 123 124 if (!sess || !conn || !roomname || !strlen(roomname)) 125 return -EINVAL; 126 127 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) 128 return -ENOMEM; 129 130 memset(&csi, 0, sizeof(csi)); 131 csi.exchange = exchange; 132 strncpy(csi.name, roomname, sizeof(csi.name)); 133 csi.instance = instance; 134 135 snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi)); 136 aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid); 137 138 /* 139 * Requesting service chat (0x000e) 140 */ 141 aimbs_put16(&fr->data, 0x000e); 142 143 aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance); 144 aim_writetlvchain(&fr->data, &tl); 145 aim_freetlvchain(&tl); 146 147 aim_tx_enqueue(sess, fr); 148 149 return 0; 150 } 151 152 faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo) 153 { 154 int namelen; 155 156 if (!bs || !outinfo) 157 return 0; 158 159 outinfo->exchange = aimbs_get16(bs); 160 namelen = aimbs_get8(bs); 161 outinfo->name = aimbs_getstr(bs, namelen); 162 outinfo->instance = aimbs_get16(bs); 163 164 return 0; 165 } 166 167 faim_export int aim_chat_leaveroom(aim_session_t *sess, const char *name) 168 { 169 aim_conn_t *conn; 170 171 if (!(conn = aim_chat_getconn(sess, name))) 172 return -ENOENT; 173 174 aim_conn_close(conn); 175 176 return 0; 177 } 178 179 /* 180 * conn must be a BOS connection! 181 */ 182 faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance) 183 { 184 int i; 185 aim_frame_t *fr; 186 aim_msgcookie_t *cookie; 187 struct aim_invite_priv *priv; 188 fu8_t ckstr[8]; 189 aim_snacid_t snacid; 190 aim_tlvlist_t *otl = NULL, *itl = NULL; 191 fu8_t *hdr; 192 int hdrlen; 193 aim_bstream_t hdrbs; 194 195 if (!sess || !conn || !sn || !msg || !roomname) 196 return -EINVAL; 197 198 if (conn->type != AIM_CONN_TYPE_BOS) 199 return -EINVAL; 200 201 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) 202 return -ENOMEM; 203 204 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1); 205 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); 206 207 208 /* 209 * Cookie 210 */ 211 for (i = 0; i < sizeof(ckstr); i++) 212 aimutil_put8(ckstr, (fu8_t) rand()); 213 214 /* XXX should be uncached by an unwritten 'invite accept' handler */ 215 if ((priv = malloc(sizeof(struct aim_invite_priv)))) { 216 priv->sn = strdup(sn); 217 priv->roomname = strdup(roomname); 218 priv->exchange = exchange; 219 priv->instance = instance; 220 } 221 222 if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv))) 223 aim_cachecookie(sess, cookie); 224 else 225 free(priv); 226 227 for (i = 0; i < sizeof(ckstr); i++) 228 aimbs_put8(&fr->data, ckstr[i]); 229 230 231 /* 232 * Channel (2) 233 */ 234 aimbs_put16(&fr->data, 0x0002); 235 236 /* 237 * Dest sn 238 */ 239 aimbs_put8(&fr->data, strlen(sn)); 240 aimbs_putraw(&fr->data, sn, strlen(sn)); 241 242 /* 243 * TLV t(0005) 244 * 245 * Everything else is inside this TLV. 246 * 247 * Sigh. AOL was rather inconsistent right here. So we have 248 * to play some minor tricks. Right inside the type 5 is some 249 * raw data, followed by a series of TLVs. 250 * 251 */ 252 hdrlen = 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2; 253 hdr = malloc(hdrlen); 254 aim_bstream_init(&hdrbs, hdr, hdrlen); 255 256 aimbs_put16(&hdrbs, 0x0000); /* Unknown! */ 257 aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */ 258 aim_putcap(&hdrbs, AIM_CAPS_CHAT); 259 260 aim_addtlvtochain16(&itl, 0x000a, 0x0001); 261 aim_addtlvtochain_noval(&itl, 0x000f); 262 aim_addtlvtochain_raw(&itl, 0x000c, strlen(msg), msg); 263 aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance); 264 aim_writetlvchain(&hdrbs, &itl); 265 266 aim_addtlvtochain_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); 267 268 aim_writetlvchain(&fr->data, &otl); 269 270 free(hdr); 271 aim_freetlvchain(&itl); 272 aim_freetlvchain(&otl); 273 274 aim_tx_enqueue(sess, fr); 275 276 return 0; 277 } 278 279 /* 280 * Subtype 0x0002 - General room information. Lots of stuff. 281 * 282 * Values I know are in here but I havent attached 283 * them to any of the 'Unknown's: 284 * - Language (English) 285 * 286 */ 287 static int infoupdate(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 288 { 289 aim_userinfo_t *userinfo = NULL; 290 aim_rxcallback_t userfunc; 291 int ret = 0; 292 int usercount = 0; 293 fu8_t detaillevel = 0; 294 char *roomname = NULL; 295 struct aim_chat_roominfo roominfo; 296 fu16_t tlvcount = 0; 297 aim_tlvlist_t *tlvlist; 298 char *roomdesc = NULL; 299 fu16_t flags = 0; 300 fu32_t creationtime = 0; 301 fu16_t maxmsglen = 0, maxvisiblemsglen = 0; 302 fu16_t unknown_d2 = 0, unknown_d5 = 0; 303 304 aim_chat_readroominfo(bs, &roominfo); 305 306 detaillevel = aimbs_get8(bs); 307 308 if (detaillevel != 0x02) { 309 faimdprintf(sess, 0, "faim: chat_roomupdateinfo: detail level %d not supported\n", detaillevel); 310 return 1; 311 } 312 313 tlvcount = aimbs_get16(bs); 314 315 /* 316 * Everything else are TLVs. 317 */ 318 tlvlist = aim_readtlvchain(bs); 319 320 /* 321 * TLV type 0x006a is the room name in Human Readable Form. 322 */ 323 if (aim_gettlv(tlvlist, 0x006a, 1)) 324 roomname = aim_gettlv_str(tlvlist, 0x006a, 1); 325 326 /* 327 * Type 0x006f: Number of occupants. 328 */ 329 if (aim_gettlv(tlvlist, 0x006f, 1)) 330 usercount = aim_gettlv16(tlvlist, 0x006f, 1); 331 332 /* 333 * Type 0x0073: Occupant list. 334 */ 335 if (aim_gettlv(tlvlist, 0x0073, 1)) { 336 int curoccupant = 0; 337 aim_tlv_t *tmptlv; 338 aim_bstream_t occbs; 339 340 tmptlv = aim_gettlv(tlvlist, 0x0073, 1); 341 342 /* Allocate enough userinfo structs for all occupants */ 343 userinfo = calloc(usercount, sizeof(aim_userinfo_t)); 344 345 aim_bstream_init(&occbs, tmptlv->value, tmptlv->length); 346 347 while (curoccupant < usercount) 348 aim_extractuserinfo(sess, &occbs, &userinfo[curoccupant++]); 349 } 350 351 /* 352 * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG) 353 */ 354 if (aim_gettlv(tlvlist, 0x00c9, 1)) 355 flags = aim_gettlv16(tlvlist, 0x00c9, 1); 356 357 /* 358 * Type 0x00ca: Creation time (4 bytes) 359 */ 360 if (aim_gettlv(tlvlist, 0x00ca, 1)) 361 creationtime = aim_gettlv32(tlvlist, 0x00ca, 1); 362 363 /* 364 * Type 0x00d1: Maximum Message Length 365 */ 366 if (aim_gettlv(tlvlist, 0x00d1, 1)) 367 maxmsglen = aim_gettlv16(tlvlist, 0x00d1, 1); 368 369 /* 370 * Type 0x00d2: Unknown. (2 bytes) 371 */ 372 if (aim_gettlv(tlvlist, 0x00d2, 1)) 373 unknown_d2 = aim_gettlv16(tlvlist, 0x00d2, 1); 374 375 /* 376 * Type 0x00d3: Room Description 377 */ 378 if (aim_gettlv(tlvlist, 0x00d3, 1)) 379 roomdesc = aim_gettlv_str(tlvlist, 0x00d3, 1); 380 381 /* 382 * Type 0x000d4: Unknown (flag only) 383 */ 384 if (aim_gettlv(tlvlist, 0x000d4, 1)) 385 ; 386 387 /* 388 * Type 0x00d5: Unknown. (1 byte) 389 */ 390 if (aim_gettlv(tlvlist, 0x00d5, 1)) 391 unknown_d5 = aim_gettlv8(tlvlist, 0x00d5, 1); 392 393 394 /* 395 * Type 0x00d6: Encoding 1 ("us-ascii") 396 */ 397 if (aim_gettlv(tlvlist, 0x000d6, 1)) 398 ; 399 400 /* 401 * Type 0x00d7: Language 1 ("en") 402 */ 403 if (aim_gettlv(tlvlist, 0x000d7, 1)) 404 ; 405 406 /* 407 * Type 0x00d8: Encoding 2 ("us-ascii") 408 */ 409 if (aim_gettlv(tlvlist, 0x000d8, 1)) 410 ; 411 412 /* 413 * Type 0x00d9: Language 2 ("en") 414 */ 415 if (aim_gettlv(tlvlist, 0x000d9, 1)) 416 ; 417 418 /* 419 * Type 0x00da: Maximum visible message length 420 */ 421 if (aim_gettlv(tlvlist, 0x000da, 1)) 422 maxvisiblemsglen = aim_gettlv16(tlvlist, 0x00da, 1); 423 424 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 425 ret = userfunc(sess, 426 rx, 427 &roominfo, 428 roomname, 429 usercount, 430 userinfo, 431 roomdesc, 432 flags, 433 creationtime, 434 maxmsglen, 435 unknown_d2, 436 unknown_d5, 437 maxvisiblemsglen); 438 } 439 440 free(roominfo.name); 441 free(userinfo); 442 free(roomname); 443 free(roomdesc); 444 aim_freetlvchain(&tlvlist); 445 446 return ret; 447 } 448 449 /* Subtypes 0x0003 and 0x0004 */ 450 static int userlistchange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 451 { 452 aim_userinfo_t *userinfo = NULL; 453 aim_rxcallback_t userfunc; 454 int curcount = 0, ret = 0; 455 456 while (aim_bstream_empty(bs)) { 457 curcount++; 458 userinfo = realloc(userinfo, curcount * sizeof(aim_userinfo_t)); 459 aim_extractuserinfo(sess, bs, &userinfo[curcount-1]); 460 } 461 462 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 463 ret = userfunc(sess, rx, curcount, userinfo); 464 465 free(userinfo); 466 467 return ret; 468 } 469 470 /* 471 * Subtype 0x0005 - Send a Chat Message. 111 472 * 112 473 * Possible flags: … … 204 565 } 205 566 206 static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance)207 {208 fu8_t *buf;209 int buflen;210 aim_bstream_t bs;211 212 buflen = 2 + 1 + strlen(roomname) + 2;213 214 if (!(buf = malloc(buflen)))215 return 0;216 217 aim_bstream_init(&bs, buf, buflen);218 219 aimbs_put16(&bs, exchange);220 aimbs_put8(&bs, strlen(roomname));221 aimbs_putraw(&bs, roomname, strlen(roomname));222 aimbs_put16(&bs, instance);223 224 aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);225 226 free(buf);227 228 return 0;229 }230 231 567 /* 232 * Join a room of name roomname. This is the first step to joining an 233 * already created room. It's basically a Service Request for 234 * family 0x000e, with a little added on to specify the exchange and room 235 * name. 236 */ 237 faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance) 238 { 239 aim_frame_t *fr; 240 aim_snacid_t snacid; 241 aim_tlvlist_t *tl = NULL; 242 struct chatsnacinfo csi; 243 244 if (!sess || !conn || !roomname || !strlen(roomname)) 245 return -EINVAL; 246 247 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) 248 return -ENOMEM; 249 250 memset(&csi, 0, sizeof(csi)); 251 csi.exchange = exchange; 252 strncpy(csi.name, roomname, sizeof(csi.name)); 253 csi.instance = instance; 254 255 snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi)); 256 aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid); 257 258 /* 259 * Requesting service chat (0x000e) 260 */ 261 aimbs_put16(&fr->data, 0x000e); 262 263 aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance); 264 aim_writetlvchain(&fr->data, &tl); 265 aim_freetlvchain(&tl); 266 267 aim_tx_enqueue(sess, fr); 268 269 return 0; 270 } 271 272 faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo) 273 { 274 int namelen; 275 276 if (!bs || !outinfo) 277 return 0; 278 279 outinfo->exchange = aimbs_get16(bs); 280 namelen = aimbs_get8(bs); 281 outinfo->name = aimbs_getstr(bs, namelen); 282 outinfo->instance = aimbs_get16(bs); 283 284 return 0; 285 } 286 287 faim_export int aim_chat_leaveroom(aim_session_t *sess, const char *name) 288 { 289 aim_conn_t *conn; 290 291 if (!(conn = aim_chat_getconn(sess, name))) 292 return -ENOENT; 293 294 aim_conn_close(conn); 295 296 return 0; 297 } 298 299 /* 300 * conn must be a BOS connection! 301 */ 302 faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance) 303 { 304 int i; 305 aim_frame_t *fr; 306 aim_msgcookie_t *cookie; 307 struct aim_invite_priv *priv; 308 fu8_t ckstr[8]; 309 aim_snacid_t snacid; 310 aim_tlvlist_t *otl = NULL, *itl = NULL; 311 fu8_t *hdr; 312 int hdrlen; 313 aim_bstream_t hdrbs; 314 315 if (!sess || !conn || !sn || !msg || !roomname) 316 return -EINVAL; 317 318 if (conn->type != AIM_CONN_TYPE_BOS) 319 return -EINVAL; 320 321 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) 322 return -ENOMEM; 323 324 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1); 325 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); 326 327 328 /* 329 * Cookie 330 */ 331 for (i = 0; i < sizeof(ckstr); i++) 332 aimutil_put8(ckstr, (fu8_t) rand()); 333 334 /* XXX should be uncached by an unwritten 'invite accept' handler */ 335 if ((priv = malloc(sizeof(struct aim_invite_priv)))) { 336 priv->sn = strdup(sn); 337 priv->roomname = strdup(roomname); 338 priv->exchange = exchange; 339 priv->instance = instance; 340 } 341 342 if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv))) 343 aim_cachecookie(sess, cookie); 344 else 345 free(priv); 346 347 for (i = 0; i < sizeof(ckstr); i++) 348 aimbs_put8(&fr->data, ckstr[i]); 349 350 351 /* 352 * Channel (2) 353 */ 354 aimbs_put16(&fr->data, 0x0002); 355 356 /* 357 * Dest sn 358 */ 359 aimbs_put8(&fr->data, strlen(sn)); 360 aimbs_putraw(&fr->data, sn, strlen(sn)); 361 362 /* 363 * TLV t(0005) 364 * 365 * Everything else is inside this TLV. 366 * 367 * Sigh. AOL was rather inconsistent right here. So we have 368 * to play some minor tricks. Right inside the type 5 is some 369 * raw data, followed by a series of TLVs. 370 * 371 */ 372 hdrlen = 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2; 373 hdr = malloc(hdrlen); 374 aim_bstream_init(&hdrbs, hdr, hdrlen); 375 376 aimbs_put16(&hdrbs, 0x0000); /* Unknown! */ 377 aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */ 378 aim_putcap(&hdrbs, AIM_CAPS_CHAT); 379 380 aim_addtlvtochain16(&itl, 0x000a, 0x0001); 381 aim_addtlvtochain_noval(&itl, 0x000f); 382 aim_addtlvtochain_raw(&itl, 0x000c, strlen(msg), msg); 383 aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance); 384 aim_writetlvchain(&hdrbs, &itl); 385 386 aim_addtlvtochain_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); 387 388 aim_writetlvchain(&fr->data, &otl); 389 390 free(hdr); 391 aim_freetlvchain(&itl); 392 aim_freetlvchain(&otl); 393 394 aim_tx_enqueue(sess, fr); 395 396 return 0; 397 } 398 399 /* 400 * General room information. Lots of stuff. 568 * Subtype 0x0006 401 569 * 402 * Values I know are in here but I havent attached403 * them to any of the 'Unknown's:404 * - Language (English)405 *406 * SNAC 000e/0002407 */408 static int infoupdate(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)409 {410 aim_userinfo_t *userinfo = NULL;411 aim_rxcallback_t userfunc;412 int ret = 0;413 int usercount = 0;414 fu8_t detaillevel = 0;415 char *roomname = NULL;416 struct aim_chat_roominfo roominfo;417 fu16_t tlvcount = 0;418 aim_tlvlist_t *tlvlist;419 char *roomdesc = NULL;420 fu16_t flags = 0;421 fu32_t creationtime = 0;422 fu16_t maxmsglen = 0, maxvisiblemsglen = 0;423 fu16_t unknown_d2 = 0, unknown_d5 = 0;424 425 dumpbox(sess, bs->data + bs->offset, aim_bstream_empty(bs));426 427 aim_chat_readroominfo(bs, &roominfo);428 429 detaillevel = aimbs_get8(bs);430 431 if (detaillevel != 0x02) {432 faimdprintf(sess, 0, "faim: chat_roomupdateinfo: detail level %d not supported\n", detaillevel);433 return 1;434 }435 436 tlvcount = aimbs_get16(bs);437 438 /*439 * Everything else are TLVs.440 */441 tlvlist = aim_readtlvchain(bs);442 443 /*444 * TLV type 0x006a is the room name in Human Readable Form.445 */446 if (aim_gettlv(tlvlist, 0x006a, 1))447 roomname = aim_gettlv_str(tlvlist, 0x006a, 1);448 449 /*450 * Type 0x006f: Number of occupants.451 */452 if (aim_gettlv(tlvlist, 0x006f, 1))453 usercount = aim_gettlv16(tlvlist, 0x006f, 1);454 455 /*456 * Type 0x0073: Occupant list.457 */458 if (aim_gettlv(tlvlist, 0x0073, 1)) {459 int curoccupant = 0;460 aim_tlv_t *tmptlv;461 aim_bstream_t occbs;462 463 tmptlv = aim_gettlv(tlvlist, 0x0073, 1);464 465 /* Allocate enough userinfo structs for all occupants */466 userinfo = calloc(usercount, sizeof(aim_userinfo_t));467 468 aim_bstream_init(&occbs, tmptlv->value, tmptlv->length);469 470 while (curoccupant < usercount)471 aim_extractuserinfo(sess, &occbs, &userinfo[curoccupant++]);472 }473 474 /*475 * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG)476 */477 if (aim_gettlv(tlvlist, 0x00c9, 1))478 flags = aim_gettlv16(tlvlist, 0x00c9, 1);479 480 /*481 * Type 0x00ca: Creation time (4 bytes)482 */483 if (aim_gettlv(tlvlist, 0x00ca, 1))484 creationtime = aim_gettlv32(tlvlist, 0x00ca, 1);485 486 /*487 * Type 0x00d1: Maximum Message Length488 */489 if (aim_gettlv(tlvlist, 0x00d1, 1))490 maxmsglen = aim_gettlv16(tlvlist, 0x00d1, 1);491 492 /*493 * Type 0x00d2: Unknown. (2 bytes)494 */495 if (aim_gettlv(tlvlist, 0x00d2, 1))496 unknown_d2 = aim_gettlv16(tlvlist, 0x00d2, 1);497 498 /*499 * Type 0x00d3: Room Description500 */501 if (aim_gettlv(tlvlist, 0x00d3, 1))502 roomdesc = aim_gettlv_str(tlvlist, 0x00d3, 1);503 504 /*505 * Type 0x000d4: Unknown (flag only)506 */507 if (aim_gettlv(tlvlist, 0x000d4, 1))508 ;509 510 /*511 * Type 0x00d5: Unknown. (1 byte)512 */513 if (aim_gettlv(tlvlist, 0x00d5, 1))514 unknown_d5 = aim_gettlv8(tlvlist, 0x00d5, 1);515 516 517 /*518 * Type 0x00d6: Encoding 1 ("us-ascii")519 */520 if (aim_gettlv(tlvlist, 0x000d6, 1))521 ;522 523 /*524 * Type 0x00d7: Language 1 ("en")525 */526 if (aim_gettlv(tlvlist, 0x000d7, 1))527 ;528 529 /*530 * Type 0x00d8: Encoding 2 ("us-ascii")531 */532 if (aim_gettlv(tlvlist, 0x000d8, 1))533 ;534 535 /*536 * Type 0x00d9: Language 2 ("en")537 */538 if (aim_gettlv(tlvlist, 0x000d9, 1))539 ;540 541 /*542 * Type 0x00da: Maximum visible message length543 */544 if (aim_gettlv(tlvlist, 0x000da, 1))545 maxvisiblemsglen = aim_gettlv16(tlvlist, 0x00da, 1);546 547 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {548 ret = userfunc(sess,549 rx,550 &roominfo,551 roomname,552 usercount,553 userinfo,554 roomdesc,555 flags,556 creationtime,557 maxmsglen,558 unknown_d2,559 unknown_d5,560 maxvisiblemsglen);561 }562 563 free(roominfo.name);564 free(userinfo);565 free(roomname);566 free(roomdesc);567 aim_freetlvchain(&tlvlist);568 569 return ret;570 }571 572 static int userlistchange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)573 {574 aim_userinfo_t *userinfo = NULL;575 aim_rxcallback_t userfunc;576 int curcount = 0, ret = 0;577 578 while (aim_bstream_empty(bs)) {579 curcount++;580 userinfo = realloc(userinfo, curcount * sizeof(aim_userinfo_t));581 aim_extractuserinfo(sess, bs, &userinfo[curcount-1]);582 }583 584 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))585 ret = userfunc(sess, rx, curcount, userinfo);586 587 free(userinfo);588 589 return ret;590 }591 592 /*593 570 * We could probably include this in the normal ICBM parsing 594 571 * code as channel 0x0003, however, since only the start … … 734 711 return 0; 735 712 } 736 737
Note: See TracChangeset
for help on using the changeset viewer.