Changeset 5ebff60 for protocols/oscar/chat.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/oscar/chat.c
raf359b4 r5ebff60 6 6 */ 7 7 8 #include <aim.h> 8 #include <aim.h> 9 9 #include <glib.h> 10 10 #include "info.h" … … 19 19 void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn) 20 20 { 21 struct chatconnpriv *ccp = (struct chatconnpriv *) conn->priv;22 23 if (ccp) 21 struct chatconnpriv *ccp = (struct chatconnpriv *) conn->priv; 22 23 if (ccp) { 24 24 g_free(ccp->name); 25 } 25 26 g_free(ccp); 26 27 … … 38 39 * and displays the message as normal.) 39 40 * 40 * XXX convert this to use tlvchains 41 * XXX convert this to use tlvchains 41 42 */ 42 43 int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen) 43 { 44 { 44 45 int i; 45 46 aim_frame_t *fr; … … 49 50 aim_tlvlist_t *otl = NULL, *itl = NULL; 50 51 51 if (!sess || !conn || !msg || (msglen <= 0)) 52 if (!sess || !conn || !msg || (msglen <= 0)) { 52 53 return 0; 53 54 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) 54 } 55 56 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) { 55 57 return -ENOMEM; 58 } 56 59 57 60 snacid = aim_cachesnac(sess, 0x000e, 0x0005, 0x0000, NULL, 0); … … 59 62 60 63 61 /* 64 /* 62 65 * Generate a random message cookie. 63 66 * … … 66 69 * 67 70 */ 68 for (i = 0; i < sizeof(ckstr); i++) 69 (void) aimutil_put8(ckstr+i, (guint8) rand()); 70 71 for (i = 0; i < sizeof(ckstr); i++) { 72 (void) aimutil_put8(ckstr + i, (guint8) rand()); 73 } 74 71 75 72 76 cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_CHAT, NULL); … … 75 79 aim_cachecookie(sess, cookie); 76 80 77 for (i = 0; i < sizeof(ckstr); i++) 81 for (i = 0; i < sizeof(ckstr); i++) { 78 82 aimbs_put8(&fr->data, ckstr[i]); 79 80 81 /* 82 * Channel ID. 83 } 84 85 86 /* 87 * Channel ID. 83 88 */ 84 89 aimbs_put16(&fr->data, 0x0003); … … 93 98 * Type 6: Reflect 94 99 */ 95 if (!(flags & AIM_CHATFLAGS_NOREFLECT)) 100 if (!(flags & AIM_CHATFLAGS_NOREFLECT)) { 96 101 aim_addtlvtochain_noval(&otl, 0x0006); 102 } 97 103 98 104 /* 99 105 * Type 7: Autoresponse 100 106 */ 101 if (flags & AIM_CHATFLAGS_AWAY) 107 if (flags & AIM_CHATFLAGS_AWAY) { 102 108 aim_addtlvtochain_noval(&otl, 0x0007); 103 109 } 110 104 111 /* [WvG] This wasn't there originally, but we really should send 105 112 the right charset flags, as we also do with normal … … 107 114 /* 108 115 if (flags & AIM_CHATFLAGS_UNICODE) 109 116 aimbs_put16(&fr->data, 0x0002); 110 117 else if (flags & AIM_CHATFLAGS_ISO_8859_1) 111 118 aimbs_put16(&fr->data, 0x0003); 112 119 else 113 114 120 aimbs_put16(&fr->data, 0x0000); 121 115 122 aimbs_put16(&fr->data, 0x0000); 116 123 */ 117 124 118 125 /* 119 126 * SubTLV: Type 1: Message 120 127 */ 121 aim_addtlvtochain_raw(&itl, 0x0001, strlen(msg), (guint8 *) msg);128 aim_addtlvtochain_raw(&itl, 0x0001, strlen(msg), (guint8 *) msg); 122 129 123 130 /* … … 125 132 * 126 133 * This could include other information... We just 127 * put in a message TLV however. 128 * 134 * put in a message TLV however. 135 * 129 136 */ 130 137 aim_addtlvtochain_frozentlvlist(&otl, 0x0005, &itl); 131 138 132 139 aim_writetlvchain(&fr->data, &otl); 133 140 134 141 aim_freetlvchain(&itl); 135 142 aim_freetlvchain(&otl); 136 143 137 144 aim_tx_enqueue(sess, fr); 138 145 … … 141 148 142 149 /* 143 * Join a room of name roomname. This is the first step to joining an 144 * already created room. It's basically a Service Request for 145 * family 0x000e, with a little added on to specify the exchange and room 150 * Join a room of name roomname. This is the first step to joining an 151 * already created room. It's basically a Service Request for 152 * family 0x000e, with a little added on to specify the exchange and room 146 153 * name. 147 154 */ … … 152 159 aim_tlvlist_t *tl = NULL; 153 160 struct chatsnacinfo csi; 154 155 if (!sess || !conn || !roomname || !strlen(roomname)) 161 162 if (!sess || !conn || !roomname || !strlen(roomname)) { 156 163 return -EINVAL; 157 158 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) 164 } 165 166 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) { 159 167 return -ENOMEM; 168 } 160 169 161 170 memset(&csi, 0, sizeof(csi)); … … 178 187 aim_tx_enqueue(sess, fr); 179 188 180 return 0; 189 return 0; 181 190 } 182 191 … … 185 194 int namelen; 186 195 187 if (!bs || !outinfo) 196 if (!bs || !outinfo) { 188 197 return 0; 198 } 189 199 190 200 outinfo->exchange = aimbs_get16(bs); … … 199 209 * conn must be a BOS connection! 200 210 */ 201 int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance) 211 int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, guint16 exchange, 212 const char *roomname, guint16 instance) 202 213 { 203 214 int i; … … 211 222 int hdrlen; 212 223 aim_bstream_t hdrbs; 213 214 if (!sess || !conn || !sn || !msg || !roomname) 224 225 if (!sess || !conn || !sn || !msg || !roomname) { 215 226 return -EINVAL; 216 217 if (conn->type != AIM_CONN_TYPE_BOS) 227 } 228 229 if (conn->type != AIM_CONN_TYPE_BOS) { 218 230 return -EINVAL; 219 220 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) 231 } 232 233 if (!(fr = 234 aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152 + strlen(sn) + strlen(roomname) + 235 strlen(msg)))) { 221 236 return -ENOMEM; 222 223 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1); 237 } 238 239 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn) + 1); 224 240 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); 225 241 … … 228 244 * Cookie 229 245 */ 230 for (i = 0; i < sizeof(ckstr); i++) 246 for (i = 0; i < sizeof(ckstr); i++) { 231 247 (void) aimutil_put8(ckstr, (guint8) rand()); 248 } 232 249 233 250 /* XXX should be uncached by an unwritten 'invite accept' handler */ … … 239 256 } 240 257 241 if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv))) 258 if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv))) { 242 259 aim_cachecookie(sess, cookie); 243 else260 } else { 244 261 g_free(priv); 245 246 for (i = 0; i < sizeof(ckstr); i++) 262 } 263 264 for (i = 0; i < sizeof(ckstr); i++) { 247 265 aimbs_put8(&fr->data, ckstr[i]); 266 } 248 267 249 268 … … 257 276 */ 258 277 aimbs_put8(&fr->data, strlen(sn)); 259 aimbs_putraw(&fr->data, (guint8 *) sn, strlen(sn));278 aimbs_putraw(&fr->data, (guint8 *) sn, strlen(sn)); 260 279 261 280 /* … … 266 285 * Sigh. AOL was rather inconsistent right here. So we have 267 286 * to play some minor tricks. Right inside the type 5 is some 268 * raw data, followed by a series of TLVs. 269 * 270 */ 271 hdrlen = 2 +8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2;287 * raw data, followed by a series of TLVs. 288 * 289 */ 290 hdrlen = 2 + 8 + 16 + 6 + 4 + 4 + strlen(msg) + 4 + 2 + 1 + strlen(roomname) + 2; 272 291 hdr = g_malloc(hdrlen); 273 292 aim_bstream_init(&hdrbs, hdr, hdrlen); 274 293 275 294 aimbs_put16(&hdrbs, 0x0000); /* Unknown! */ 276 295 aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */ … … 279 298 aim_addtlvtochain16(&itl, 0x000a, 0x0001); 280 299 aim_addtlvtochain_noval(&itl, 0x000f); 281 aim_addtlvtochain_raw(&itl, 0x000c, strlen(msg), (guint8 *) msg);300 aim_addtlvtochain_raw(&itl, 0x000c, strlen(msg), (guint8 *) msg); 282 301 aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance); 283 302 aim_writetlvchain(&hdrbs, &itl); 284 303 285 304 aim_addtlvtochain_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); 286 305 … … 290 309 aim_freetlvchain(&itl); 291 310 aim_freetlvchain(&otl); 292 311 293 312 aim_tx_enqueue(sess, fr); 294 313 … … 334 353 /* 335 354 * Everything else are TLVs. 336 */ 355 */ 337 356 tlvlist = aim_readtlvchain(bs); 338 357 … … 340 359 * TLV type 0x006a is the room name in Human Readable Form. 341 360 */ 342 if (aim_gettlv(tlvlist, 0x006a, 1)) 361 if (aim_gettlv(tlvlist, 0x006a, 1)) { 343 362 roomname = aim_gettlv_str(tlvlist, 0x006a, 1); 363 } 344 364 345 365 /* 346 366 * Type 0x006f: Number of occupants. 347 367 */ 348 if (aim_gettlv(tlvlist, 0x006f, 1)) 368 if (aim_gettlv(tlvlist, 0x006f, 1)) { 349 369 usercount = aim_gettlv16(tlvlist, 0x006f, 1); 370 } 350 371 351 372 /* 352 373 * Type 0x0073: Occupant list. 353 374 */ 354 if (aim_gettlv(tlvlist, 0x0073, 1)) { 375 if (aim_gettlv(tlvlist, 0x0073, 1)) { 355 376 int curoccupant = 0; 356 377 aim_tlv_t *tmptlv; … … 364 385 aim_bstream_init(&occbs, tmptlv->value, tmptlv->length); 365 386 366 while (curoccupant < usercount) 387 while (curoccupant < usercount) { 367 388 aim_extractuserinfo(sess, &occbs, &userinfo[curoccupant++]); 368 } 369 370 /* 389 } 390 } 391 392 /* 371 393 * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG) 372 394 */ 373 if (aim_gettlv(tlvlist, 0x00c9, 1)) 395 if (aim_gettlv(tlvlist, 0x00c9, 1)) { 374 396 flags = aim_gettlv16(tlvlist, 0x00c9, 1); 375 376 /* 397 } 398 399 /* 377 400 * Type 0x00ca: Creation time (4 bytes) 378 401 */ 379 if (aim_gettlv(tlvlist, 0x00ca, 1)) 402 if (aim_gettlv(tlvlist, 0x00ca, 1)) { 380 403 creationtime = aim_gettlv32(tlvlist, 0x00ca, 1); 381 382 /* 404 } 405 406 /* 383 407 * Type 0x00d1: Maximum Message Length 384 408 */ 385 if (aim_gettlv(tlvlist, 0x00d1, 1)) 409 if (aim_gettlv(tlvlist, 0x00d1, 1)) { 386 410 maxmsglen = aim_gettlv16(tlvlist, 0x00d1, 1); 387 388 /* 411 } 412 413 /* 389 414 * Type 0x00d2: Unknown. (2 bytes) 390 415 */ 391 if (aim_gettlv(tlvlist, 0x00d2, 1)) 416 if (aim_gettlv(tlvlist, 0x00d2, 1)) { 392 417 unknown_d2 = aim_gettlv16(tlvlist, 0x00d2, 1); 393 394 /* 418 } 419 420 /* 395 421 * Type 0x00d3: Room Description 396 422 */ 397 if (aim_gettlv(tlvlist, 0x00d3, 1)) 423 if (aim_gettlv(tlvlist, 0x00d3, 1)) { 398 424 roomdesc = aim_gettlv_str(tlvlist, 0x00d3, 1); 425 } 399 426 400 427 /* 401 428 * Type 0x000d4: Unknown (flag only) 402 429 */ 403 if (aim_gettlv(tlvlist, 0x000d4, 1)) 430 if (aim_gettlv(tlvlist, 0x000d4, 1)) { 404 431 ; 405 406 /* 432 } 433 434 /* 407 435 * Type 0x00d5: Unknown. (1 byte) 408 436 */ 409 if (aim_gettlv(tlvlist, 0x00d5, 1)) 437 if (aim_gettlv(tlvlist, 0x00d5, 1)) { 410 438 unknown_d5 = aim_gettlv8(tlvlist, 0x00d5, 1); 439 } 411 440 412 441 … … 414 443 * Type 0x00d6: Encoding 1 ("us-ascii") 415 444 */ 416 if (aim_gettlv(tlvlist, 0x000d6, 1)) 445 if (aim_gettlv(tlvlist, 0x000d6, 1)) { 417 446 ; 418 447 } 448 419 449 /* 420 450 * Type 0x00d7: Language 1 ("en") 421 451 */ 422 if (aim_gettlv(tlvlist, 0x000d7, 1)) 452 if (aim_gettlv(tlvlist, 0x000d7, 1)) { 423 453 ; 454 } 424 455 425 456 /* 426 457 * Type 0x00d8: Encoding 2 ("us-ascii") 427 458 */ 428 if (aim_gettlv(tlvlist, 0x000d8, 1)) 459 if (aim_gettlv(tlvlist, 0x000d8, 1)) { 429 460 ; 430 461 } 462 431 463 /* 432 464 * Type 0x00d9: Language 2 ("en") 433 465 */ 434 if (aim_gettlv(tlvlist, 0x000d9, 1)) 466 if (aim_gettlv(tlvlist, 0x000d9, 1)) { 435 467 ; 468 } 436 469 437 470 /* 438 471 * Type 0x00da: Maximum visible message length 439 472 */ 440 if (aim_gettlv(tlvlist, 0x000da, 1)) 473 if (aim_gettlv(tlvlist, 0x000da, 1)) { 441 474 maxvisiblemsglen = aim_gettlv16(tlvlist, 0x00da, 1); 475 } 442 476 443 477 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 444 478 ret = userfunc(sess, 445 rx,446 447 448 449 userinfo,450 451 452 453 454 455 456 479 rx, 480 &roominfo, 481 roomname, 482 usercount, 483 userinfo, 484 roomdesc, 485 flags, 486 creationtime, 487 maxmsglen, 488 unknown_d2, 489 unknown_d5, 490 maxvisiblemsglen); 457 491 } 458 492 … … 466 500 } 467 501 468 static int userlistchange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 502 static int userlistchange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, 503 aim_bstream_t *bs) 469 504 { 470 505 aim_userinfo_t *userinfo = NULL; … … 475 510 curcount++; 476 511 userinfo = g_realloc(userinfo, curcount * sizeof(aim_userinfo_t)); 477 aim_extractuserinfo(sess, bs, &userinfo[curcount -1]);478 } 479 480 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 512 aim_extractuserinfo(sess, bs, &userinfo[curcount - 1]); 513 } 514 515 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 481 516 ret = userfunc(sess, rx, curcount, userinfo); 517 } 482 518 483 519 g_free(userinfo); … … 487 523 488 524 /* 489 * We could probably include this in the normal ICBM parsing 525 * We could probably include this in the normal ICBM parsing 490 526 * code as channel 0x0003, however, since only the start 491 527 * would be the same, we might as well do it here. … … 507 543 * message string 508 544 * possibly others 509 * 545 * 510 546 */ 511 547 static int incomingmsg(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 512 548 { 513 549 aim_userinfo_t userinfo; 514 aim_rxcallback_t userfunc; 550 aim_rxcallback_t userfunc; 515 551 int ret = 0; 516 552 guint8 *cookie; … … 549 585 550 586 /* 551 * Start parsing TLVs right away. 587 * Start parsing TLVs right away. 552 588 */ 553 589 otl = aim_readtlvchain(bs); … … 567 603 568 604 /* 569 * Type 0x0001: If present, it means it was a message to the 605 * Type 0x0001: If present, it means it was a message to the 570 606 * room (as opposed to a whisper). 571 607 */ 572 if (aim_gettlv(otl, 0x0001, 1)) 608 if (aim_gettlv(otl, 0x0001, 1)) { 573 609 ; 610 } 574 611 575 612 /* … … 585 622 itl = aim_readtlvchain(&tbs); 586 623 587 /* 624 /* 588 625 * Type 0x0001: Message. 589 */ 590 if (aim_gettlv(itl, 0x0001, 1)) 626 */ 627 if (aim_gettlv(itl, 0x0001, 1)) { 591 628 msg = aim_gettlv_str(itl, 0x0001, 1); 592 593 aim_freetlvchain(&itl); 594 } 595 596 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 629 } 630 631 aim_freetlvchain(&itl); 632 } 633 634 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 597 635 ret = userfunc(sess, rx, &userinfo, msg); 636 } 598 637 599 638 g_free(cookie); … … 607 646 { 608 647 609 if (snac->subtype == 0x0002) 648 if (snac->subtype == 0x0002) { 610 649 return infoupdate(sess, mod, rx, snac, bs); 611 else if ((snac->subtype == 0x0003) || (snac->subtype == 0x0004))650 } else if ((snac->subtype == 0x0003) || (snac->subtype == 0x0004)) { 612 651 return userlistchange(sess, mod, rx, snac, bs); 613 else if (snac->subtype == 0x0006)652 } else if (snac->subtype == 0x0006) { 614 653 return incomingmsg(sess, mod, rx, snac, bs); 654 } 615 655 616 656 return 0;
Note: See TracChangeset
for help on using the changeset viewer.