Changeset 5ebff60 for protocols/oscar/im.c
- Timestamp:
- 2015-02-20T22:50:54Z (10 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/im.c
raf359b4 r5ebff60 25 25 26 26 /* 27 * Send an ICBM (instant message). 27 * Send an ICBM (instant message). 28 28 * 29 29 * … … 39 39 * what you're doing. 40 40 * AIM_IMFLAGS_ISO_8859_1 -- The message contains the ASCII8 subset 41 * known as ISO-8859-1. 41 * known as ISO-8859-1. 42 42 * 43 43 * Generally, you should use the lowest encoding possible to send 44 44 * your message. If you only use basic punctuation and the generic 45 45 * Latin alphabet, use ASCII7 (no flags). If you happen to use non-ASCII7 46 * characters, but they are all clearly defined in ISO-8859-1, then 46 * characters, but they are all clearly defined in ISO-8859-1, then 47 47 * use that. Keep in mind that not all characters in the PC ASCII8 48 48 * character set are defined in the ISO standard. For those cases (most … … 56 56 * of the clients I use can parse those messages (and besides that, 57 57 * wchars are difficult and non-portable to handle in most UNIX environments). 58 * If you really need to include special characters, use the HTML UNICODE 59 * entities. These are of the form ߪ where 2026 is the hex 60 * representation of the UNICODE index (in this case, UNICODE 58 * If you really need to include special characters, use the HTML UNICODE 59 * entities. These are of the form ߪ where 2026 is the hex 60 * representation of the UNICODE index (in this case, UNICODE 61 61 * "Horizontal Ellipsis", or 133 in in ASCII8). 62 62 * … … 64 64 * in all of libfaim, it is written with performance in mind. As such, 65 65 * it is not as clear as it could be in respect to how this message is 66 * supposed to be layed out. Most obviously, tlvlists should be used 67 * instead of writing out the bytes manually. 66 * supposed to be layed out. Most obviously, tlvlists should be used 67 * instead of writing out the bytes manually. 68 68 * 69 69 * XXX more precise verification that we never send SNACs larger than 8192 … … 81 81 aim_snacid_t snacid; 82 82 83 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) 83 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) { 84 84 return -EINVAL; 85 86 if (!args) 85 } 86 87 if (!args) { 87 88 return -EINVAL; 89 } 88 90 89 91 if (args->flags & AIM_IMFLAGS_MULTIPART) { 90 if (args->mpmsg->numparts <= 0) 92 if (args->mpmsg->numparts <= 0) { 91 93 return -EINVAL; 94 } 92 95 } else { 93 if (!args->msg || (args->msglen <= 0)) 96 if (!args->msg || (args->msglen <= 0)) { 94 97 return -EINVAL; 95 96 if (args->msglen >= MAXMSGLEN) 98 } 99 100 if (args->msglen >= MAXMSGLEN) { 97 101 return -E2BIG; 102 } 98 103 } 99 104 … … 101 106 msgtlvlen = 1 + 1; /* 0501 */ 102 107 103 if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) 108 if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) { 104 109 msgtlvlen += 2 + args->featureslen; 105 else110 } else { 106 111 msgtlvlen += 2 + sizeof(deffeatures); 112 } 107 113 108 114 if (args->flags & AIM_IMFLAGS_MULTIPART) { … … 120 126 121 127 122 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, msgtlvlen +128)))128 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, msgtlvlen + 128))) { 123 129 return -ENOMEM; 124 125 /* XXX should be optional */ 126 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1); 130 } 131 132 /* XXX should be optional */ 133 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn) + 1); 127 134 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); 128 135 129 /* 130 * Generate a random message cookie 131 * 132 * We could cache these like we do SNAC IDs. (In fact, it 133 * might be a good idea.) In the message error functions, 134 * the 8byte message cookie is returned as well as the 136 /* 137 * Generate a random message cookie 138 * 139 * We could cache these like we do SNAC IDs. (In fact, it 140 * might be a good idea.) In the message error functions, 141 * the 8byte message cookie is returned as well as the 135 142 * SNAC ID. 136 143 * 137 144 */ 138 for (i = 0; i < 8; i++) 145 for (i = 0; i < 8; i++) { 139 146 aimbs_put8(&fr->data, (guint8) rand()); 147 } 140 148 141 149 /* … … 148 156 */ 149 157 aimbs_put8(&fr->data, strlen(args->destsn)); 150 aimbs_putraw(&fr->data, (guint8 *) args->destsn, strlen(args->destsn));158 aimbs_putraw(&fr->data, (guint8 *) args->destsn, strlen(args->destsn)); 151 159 152 160 /* … … 157 165 158 166 /* 159 * Features 167 * Features 160 168 * 161 169 */ … … 186 194 aimbs_put16(&fr->data, 0x0101); 187 195 188 /* 196 /* 189 197 * Message block length. 190 198 */ … … 200 208 201 209 } else { 202 if (args->flags & AIM_IMFLAGS_UNICODE) 210 if (args->flags & AIM_IMFLAGS_UNICODE) { 203 211 aimbs_put16(&fr->data, 0x0002); 204 else if (args->flags & AIM_IMFLAGS_ISO_8859_1)212 } else if (args->flags & AIM_IMFLAGS_ISO_8859_1) { 205 213 aimbs_put16(&fr->data, 0x0003); 206 else214 } else { 207 215 aimbs_put16(&fr->data, 0x0000); 216 } 208 217 209 218 aimbs_put16(&fr->data, 0x0000); … … 213 222 * Message. Not terminated. 214 223 */ 215 aimbs_putraw(&fr->data, (guint8 *) args->msg, args->msglen);216 } 217 218 /* 219 * Set the Request Acknowledge flag. 224 aimbs_putraw(&fr->data, (guint8 *) args->msg, args->msglen); 225 } 226 227 /* 228 * Set the Request Acknowledge flag. 220 229 */ 221 230 if (args->flags & AIM_IMFLAGS_ACK) { … … 259 268 aim_tx_enqueue(sess, fr); 260 269 261 if (!(sess->flags & AIM_SESS_FLAGS_DONTTIMEOUTONICBM)) 270 if (!(sess->flags & AIM_SESS_FLAGS_DONTTIMEOUTONICBM)) { 262 271 aim_cleansnacs(sess, 60); /* clean out SNACs over 60sec old */ 263 272 273 } 264 274 return 0; 265 275 } 266 276 267 277 /* 268 * Simple wrapper for aim_send_im_ext() 278 * Simple wrapper for aim_send_im_ext() 269 279 * 270 280 * You cannot use aim_send_im if you need the HASICON flag. You must … … 300 310 */ 301 311 int aim_send_im_ch2_statusmessage(aim_session_t *sess, const char *sender, const guint8 *cookie, 302 const char *message, const guint8 state, const guint16 dc) 303 { 304 aim_conn_t *conn; 305 aim_frame_t *fr; 306 aim_snacid_t snacid; 307 308 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) 309 return -EINVAL; 310 311 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 312 10+8+2+1+strlen(sender)+2+0x1d+0x10+9+strlen(message)+1))) 313 return -ENOMEM; 314 315 snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0); 316 aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid); 317 318 aimbs_putraw(&fr->data, cookie, 8); 319 320 aimbs_put16(&fr->data, 0x0002); /* channel */ 321 aimbs_put8(&fr->data, strlen(sender)); 322 aimbs_putraw(&fr->data, (guint8 *)sender, strlen(sender)); 323 324 aimbs_put16(&fr->data, 0x0003); /* reason: channel specific */ 325 326 aimbs_putle16(&fr->data, 0x001b); /* length of data SEQ1 */ 327 aimbs_putle16(&fr->data, 0x0008); /* protocol version */ 328 329 aimbs_putle32(&fr->data, 0x0000); /* no plugin -> 16 times 0x00 */ 330 aimbs_putle32(&fr->data, 0x0000); 331 aimbs_putle32(&fr->data, 0x0000); 332 aimbs_putle32(&fr->data, 0x0000); 333 334 aimbs_putle16(&fr->data, 0x0000); /* unknown */ 335 aimbs_putle32(&fr->data, 0x0003); /* client features */ 336 aimbs_putle8(&fr->data, 0x00); /* unknown */ 337 aimbs_putle16(&fr->data, dc); /* Sequence number? XXX - This should decrement by 1 with each request */ 338 /* end of SEQ1 */ 339 340 aimbs_putle16(&fr->data, 0x000e); /* Length of SEQ2 */ 341 aimbs_putle16(&fr->data, dc); /* Sequence number? same as above 342 * XXX - This should decrement by 1 with each request */ 343 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 344 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 345 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 346 /* end of SEQ2 */ 347 348 /* now for the real fun */ 349 aimbs_putle8(&fr->data, state); /* away state */ 350 aimbs_putle8(&fr->data, 0x03); /* msg-flag: 03 for states */ 351 aimbs_putle16(&fr->data, 0x0000); /* status code ? */ 352 aimbs_putle16(&fr->data, 0x0000); /* priority code */ 353 aimbs_putle16(&fr->data, strlen(message) + 1); /* message length + termination */ 354 aimbs_putraw(&fr->data, (guint8 *) message, strlen(message) + 1); /* null terminated string */ 355 356 aim_tx_enqueue(sess, fr); 357 358 359 return 0; 312 const char *message, const guint8 state, const guint16 dc) 313 { 314 aim_conn_t *conn; 315 aim_frame_t *fr; 316 aim_snacid_t snacid; 317 318 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) { 319 return -EINVAL; 320 } 321 322 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 323 10 + 8 + 2 + 1 + strlen(sender) + 2 + 0x1d + 0x10 + 9 + strlen(message) + 1))) { 324 return -ENOMEM; 325 } 326 327 snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0); 328 aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid); 329 330 aimbs_putraw(&fr->data, cookie, 8); 331 332 aimbs_put16(&fr->data, 0x0002); /* channel */ 333 aimbs_put8(&fr->data, strlen(sender)); 334 aimbs_putraw(&fr->data, (guint8 *) sender, strlen(sender)); 335 336 aimbs_put16(&fr->data, 0x0003); /* reason: channel specific */ 337 338 aimbs_putle16(&fr->data, 0x001b); /* length of data SEQ1 */ 339 aimbs_putle16(&fr->data, 0x0008); /* protocol version */ 340 341 aimbs_putle32(&fr->data, 0x0000); /* no plugin -> 16 times 0x00 */ 342 aimbs_putle32(&fr->data, 0x0000); 343 aimbs_putle32(&fr->data, 0x0000); 344 aimbs_putle32(&fr->data, 0x0000); 345 346 aimbs_putle16(&fr->data, 0x0000); /* unknown */ 347 aimbs_putle32(&fr->data, 0x0003); /* client features */ 348 aimbs_putle8(&fr->data, 0x00); /* unknown */ 349 aimbs_putle16(&fr->data, dc); /* Sequence number? XXX - This should decrement by 1 with each request */ 350 /* end of SEQ1 */ 351 352 aimbs_putle16(&fr->data, 0x000e); /* Length of SEQ2 */ 353 aimbs_putle16(&fr->data, dc); /* Sequence number? same as above 354 * XXX - This should decrement by 1 with each request */ 355 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 356 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 357 aimbs_putle32(&fr->data, 0x00000000); /* Unknown */ 358 /* end of SEQ2 */ 359 360 /* now for the real fun */ 361 aimbs_putle8(&fr->data, state); /* away state */ 362 aimbs_putle8(&fr->data, 0x03); /* msg-flag: 03 for states */ 363 aimbs_putle16(&fr->data, 0x0000); /* status code ? */ 364 aimbs_putle16(&fr->data, 0x0000); /* priority code */ 365 aimbs_putle16(&fr->data, strlen(message) + 1); /* message length + termination */ 366 aimbs_putraw(&fr->data, (guint8 *) message, strlen(message) + 1); /* null terminated string */ 367 368 aim_tx_enqueue(sess, fr); 369 370 371 return 0; 360 372 } 361 373 … … 375 387 376 388 /* ICBM Cookie. */ 377 for (i = 0; i < 8; i++) 389 for (i = 0; i < 8; i++) { 378 390 aimbs_get8(bs); 391 } 379 392 380 393 /* Channel ID */ … … 391 404 tlvlist = aim_readtlvchain(bs); 392 405 393 if (aim_gettlv(tlvlist, 0x0003, 1)) 406 if (aim_gettlv(tlvlist, 0x0003, 1)) { 394 407 icbmflags |= AIM_IMFLAGS_ACK; 395 if (aim_gettlv(tlvlist, 0x0004, 1)) 408 } 409 if (aim_gettlv(tlvlist, 0x0004, 1)) { 396 410 icbmflags |= AIM_IMFLAGS_AWAY; 411 } 397 412 398 413 if ((msgblock = aim_gettlv(tlvlist, 0x0002, 1))) { … … 404 419 aimbs_get8(&mbs); 405 420 aimbs_get8(&mbs); 406 for (featurelen = aimbs_get16(&mbs); featurelen; featurelen--) 421 for (featurelen = aimbs_get16(&mbs); featurelen; featurelen--) { 407 422 aimbs_get8(&mbs); 423 } 408 424 aimbs_get8(&mbs); 409 425 aimbs_get8(&mbs); … … 417 433 } 418 434 419 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 435 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 420 436 ret = userfunc(sess, rx, channel, sn, msg, icbmflags, flag1, flag2); 437 } 421 438 422 439 g_free(sn); … … 430 447 * 431 448 * Not only do AIM ICBM's support multiple channels. Not only do they 432 * support multiple character sets. But they support multiple character 449 * support multiple character sets. But they support multiple character 433 450 * sets / encodings within the same ICBM. 434 451 * … … 436 453 * seem utterly unnecessary by today's standards. In fact, there is only 437 454 * one client still in popular use that still uses this method: AOL for the 438 * Macintosh, Version 5.0. Obscure, yes, I know. 455 * Macintosh, Version 5.0. Obscure, yes, I know. 439 456 * 440 457 * In modern (non-"legacy") clients, if the user tries to send a character … … 444 461 * Multipart messages prevent this wasted space by allowing the client to 445 462 * only send the characters in UNICODE that need to be sent that way, and 446 * the rest of the message can be sent in whatever the native character 463 * the rest of the message can be sent in whatever the native character 447 464 * set is (probably ASCII). 448 465 * … … 471 488 } 472 489 473 static int mpmsg_addsection(aim_session_t *sess, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, guint8 *data, guint16 datalen) 474 { 475 aim_mpmsg_section_t *sec; 476 477 if (!(sec = g_new0(aim_mpmsg_section_t,1))) 490 static int mpmsg_addsection(aim_session_t *sess, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, guint8 *data, 491 guint16 datalen) 492 { 493 aim_mpmsg_section_t *sec; 494 495 if (!(sec = g_new0(aim_mpmsg_section_t, 1))) { 478 496 return -1; 497 } 479 498 480 499 sec->charset = charset; … … 484 503 sec->next = NULL; 485 504 486 if (!mpm->parts) 505 if (!mpm->parts) { 487 506 mpm->parts = sec; 488 else {507 } else { 489 508 aim_mpmsg_section_t *cur; 490 509 491 for (cur = mpm->parts; cur->next; cur = cur->next) 510 for (cur = mpm->parts; cur->next; cur = cur->next) { 492 511 ; 512 } 493 513 cur->next = sec; 494 514 } … … 505 525 for (cur = mpm->parts; cur; ) { 506 526 aim_mpmsg_section_t *tmp; 507 527 508 528 tmp = cur->next; 509 529 g_free(cur->data); … … 511 531 cur = tmp; 512 532 } 513 533 514 534 mpm->numparts = 0; 515 535 mpm->parts = NULL; … … 519 539 520 540 /* 521 * Start by building the multipart structures, then pick the first 541 * Start by building the multipart structures, then pick the first 522 542 * human-readable section and stuff it into args->msg so no one gets 523 543 * suspicious. … … 569 589 */ 570 590 msgbuf = aimbs_getstr(&mbs, msglen); 571 mpmsg_addsection(sess, &args->mpmsg, flag1, flag2, (guint8 *) msgbuf, (guint16) msglen);591 mpmsg_addsection(sess, &args->mpmsg, flag1, flag2, (guint8 *) msgbuf, (guint16) msglen); 572 592 573 593 } /* while */ … … 590 610 for (sec = args->mpmsg.parts; sec; sec = sec->next) { 591 611 592 if (sec->charset != charsetpri[i]) 612 if (sec->charset != charsetpri[i]) { 593 613 continue; 614 } 594 615 595 616 /* Great. We found one. Fill it in. */ … … 599 620 600 621 /* Set up the simple flags */ 601 if (args->charset == 0x0000) 622 if (args->charset == 0x0000) { 602 623 ; /* ASCII */ 603 else if (args->charset == 0x0002)624 } else if (args->charset == 0x0002) { 604 625 args->icbmflags |= AIM_IMFLAGS_UNICODE; 605 else if (args->charset == 0x0003)626 } else if (args->charset == 0x0003) { 606 627 args->icbmflags |= AIM_IMFLAGS_ISO_8859_1; 607 else if (args->charset == 0xffff)628 } else if (args->charset == 0xffff) { 608 629 ; /* no encoding (yeep!) */ 609 630 610 if (args->charsubset == 0x0000) 631 } 632 if (args->charsubset == 0x0000) { 611 633 ; /* standard subencoding? */ 612 else if (args->charsubset == 0x000b)634 } else if (args->charsubset == 0x000b) { 613 635 args->icbmflags |= AIM_IMFLAGS_SUBENC_MACINTOSH; 614 else if (args->charsubset == 0xffff)636 } else if (args->charsubset == 0xffff) { 615 637 ; /* no subencoding */ 638 } 616 639 #if 0 617 /* XXX this isn't really necesary... */ 618 if ( ((args.flag1 != 0x0000) && 619 (args.flag1 != 0x0002) && 620 (args.flag1 != 0x0003) && 621 (args.flag1 != 0xffff)) || 622 ((args.flag2 != 0x0000) && 623 (args.flag2 != 0x000b) && 624 (args.flag2 != 0xffff))) { 625 faimdprintf(sess, 0, "icbm: **warning: encoding flags are being used! {%04x, %04x}\n", args.flag1, args.flag2); 640 /* XXX this isn't really necesary... */ 641 if (((args.flag1 != 0x0000) && 642 (args.flag1 != 0x0002) && 643 (args.flag1 != 0x0003) && 644 (args.flag1 != 0xffff)) || 645 ((args.flag2 != 0x0000) && 646 (args.flag2 != 0x000b) && 647 (args.flag2 != 0xffff))) { 648 faimdprintf(sess, 0, "icbm: **warning: encoding flags are being used! {%04x, %04x}\n", 649 args.flag1, args.flag2); 626 650 } 627 651 #endif 628 652 629 args->msg = (char *) sec->data;653 args->msg = (char *) sec->data; 630 654 args->msglen = sec->datalen; 631 655 … … 642 666 } 643 667 644 static int incomingim_ch1(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, aim_bstream_t *bs, guint8 *cookie) 668 static int incomingim_ch1(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, 669 aim_userinfo_t *userinfo, aim_bstream_t *bs, guint8 *cookie) 645 670 { 646 671 guint16 type, length; … … 690 715 * blocks... 691 716 */ 692 incomingim_ch1_parsemsgs(sess, bs->data + bs->offset /* XXX evil!!! */, length - 2 - 2 - args.featureslen, &args); 717 incomingim_ch1_parsemsgs(sess, bs->data + bs->offset /* XXX evil!!! */, 718 length - 2 - 2 - args.featureslen, &args); 693 719 694 720 } else if (type == 0x0003) { /* Server Ack Requested */ … … 720 746 * You really shouldn't advertise a zero-length icon 721 747 * anyway. 722 * 748 * 723 749 */ 724 if (args.iconlen) 750 if (args.iconlen) { 725 751 args.icbmflags |= AIM_IMFLAGS_HASICON; 752 } 726 753 727 754 } else if (type == 0x0009) { … … 750 777 751 778 752 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 779 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 753 780 ret = userfunc(sess, rx, channel, userinfo, &args); 781 } 754 782 755 783 aim_mpmsg_free(sess, &args.mpmsg); … … 769 797 } 770 798 771 static void incomingim_ch2_chat(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata) 799 static void incomingim_ch2_chat(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, 800 aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata) 772 801 { 773 802 … … 775 804 * Chat room info. 776 805 */ 777 if (servdata) 806 if (servdata) { 778 807 aim_chat_readroominfo(servdata, &args->info.chat.roominfo); 779 780 args->destructor = (void *)incomingim_ch2_chat_free; 808 } 809 810 args->destructor = (void *) incomingim_ch2_chat_free; 781 811 782 812 return; … … 786 816 { 787 817 788 g_free((char *) args->info.rtfmsg.rtfmsg);818 g_free((char *) args->info.rtfmsg.rtfmsg); 789 819 790 820 return; … … 792 822 793 823 /* 794 * The relationship between AIM_CAPS_ICQSERVERRELAY and AIM_CAPS_ICQRTF is 824 * The relationship between AIM_CAPS_ICQSERVERRELAY and AIM_CAPS_ICQRTF is 795 825 * kind of odd. This sends the client ICQRTF since that is all that I've seen 796 826 * SERVERRELAY used for. … … 801 831 * 802 832 */ 803 static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata) 833 static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, 834 aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, 835 aim_bstream_t *servdata) 804 836 { 805 837 guint16 hdrlen, msglen, dc; 806 838 guint8 msgtype; 807 guint8 *plugin; 808 int i = 0, tmp = 0; 809 struct im_connection *ic = sess->aux_data; 810 811 /* at the moment we just can deal with requests, not with cancel or accept */ 812 if (args->status != 0) return; 839 guint8 *plugin; 840 int i = 0, tmp = 0; 841 struct im_connection *ic = sess->aux_data; 842 843 /* at the moment we just can deal with requests, not with cancel or accept */ 844 if (args->status != 0) { 845 return; 846 } 813 847 814 848 hdrlen = aimbs_getle16(servdata); 815 849 816 817 plugin = aimbs_getraw(servdata, 0x10); /* following data is a message or 818 819 820 850 aim_bstream_advance(servdata, 0x02); /* protocol version */ 851 plugin = aimbs_getraw(servdata, 0x10); /* following data is a message or 852 something plugin specific */ 853 /* as there is no plugin handling, just skip the rest */ 854 aim_bstream_advance(servdata, hdrlen - 0x12); 821 855 822 856 hdrlen = aimbs_getle16(servdata); 823 857 dc = aimbs_getle16(servdata); /* save the sequence number */ 824 858 aim_bstream_advance(servdata, hdrlen - 0x02); 825 859 826 827 828 829 830 831 832 833 834 835 836 837 838 839 args->info.rtfmsg.rtfmsg = aimbs_getstr(servdata, msglen);840 841 switch(msgtype) {842 843 844 845 846 847 848 849 850 851 852 853 854 case AIM_MTYPE_AUTOAWAY: 855 856 857 858 859 case 0x9c:/* ICQ 5 seems to send this */860 861 ic->away ? ic->away : "", sess->aim_icq_state, dc);862 863 864 865 866 867 868 args->destructor = (void *) incomingim_ch2_icqserverrelay_free;860 /* TODO is it a message or something for a plugin? */ 861 for (i = 0; i < 0x10; i++) { 862 tmp |= plugin[i]; 863 } 864 865 if (!tmp) { /* message follows */ 866 867 msgtype = aimbs_getle8(servdata); 868 aimbs_getle8(servdata); /* msgflags */ 869 870 aim_bstream_advance(servdata, 0x04); /* status code and priority code */ 871 872 msglen = aimbs_getle16(servdata); /* message string length */ 873 args->info.rtfmsg.rtfmsg = aimbs_getstr(servdata, msglen); 874 875 switch (msgtype) { 876 case AIM_MTYPE_PLAIN: 877 878 args->info.rtfmsg.fgcolor = aimbs_getle32(servdata); 879 args->info.rtfmsg.bgcolor = aimbs_getle32(servdata); 880 881 hdrlen = aimbs_getle32(servdata); 882 aim_bstream_advance(servdata, hdrlen); 883 884 /* XXX This is such a hack. */ 885 args->reqclass = AIM_CAPS_ICQRTF; 886 break; 887 888 case AIM_MTYPE_AUTOAWAY: 889 case AIM_MTYPE_AUTOBUSY: 890 case AIM_MTYPE_AUTONA: 891 case AIM_MTYPE_AUTODND: 892 case AIM_MTYPE_AUTOFFC: 893 case 0x9c: /* ICQ 5 seems to send this */ 894 aim_send_im_ch2_statusmessage(sess, userinfo->sn, args->cookie, 895 ic->away ? ic->away : "", sess->aim_icq_state, dc); 896 break; 897 898 } 899 } /* message or plugin specific */ 900 901 g_free(plugin); 902 args->destructor = (void *) incomingim_ch2_icqserverrelay_free; 869 903 870 904 return; … … 873 907 typedef void (*ch2_args_destructor_t)(aim_session_t *sess, struct aim_incomingim_ch2_args *args); 874 908 875 static int incomingim_ch2(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) 909 static int incomingim_ch2(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, 910 aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) 876 911 { 877 912 aim_rxcallback_t userfunc; … … 883 918 int ret = 0; 884 919 885 char clientip1[30] = { ""};886 char clientip2[30] = { ""};887 char verifiedip[30] = { ""};920 char clientip1[30] = { "" }; 921 char clientip2[30] = { "" }; 922 char verifiedip[30] = { "" }; 888 923 889 924 memset(&args, 0, sizeof(args)); 890 925 891 926 /* 892 * There's another block of TLVs embedded in the type 5 here. 927 * There's another block of TLVs embedded in the type 5 here. 893 928 */ 894 929 block1 = aim_gettlv(tlvlist, 0x0005, 1); … … 899 934 * 900 935 * 0 is a request, 1 is a deny (?), 2 is an accept 901 */ 936 */ 902 937 args.status = aimbs_get16(&bbs); 903 938 … … 906 941 */ 907 942 cookie2 = aimbs_getraw(&bbs, 8); 908 if (memcmp(cookie, cookie2, 8) != 0) 943 if (memcmp(cookie, cookie2, 8) != 0) { 909 944 imcb_error(sess->aux_data, "rend: warning cookies don't match!"); 945 } 910 946 memcpy(args.cookie, cookie2, 8); 911 947 g_free(cookie2); … … 917 953 args.reqclass = aim_getcap(sess, &bbs, 0x10); 918 954 919 /* 955 /* 920 956 * What follows may be TLVs or nothing, depending on the 921 957 * purpose of the message. … … 934 970 935 971 g_snprintf(clientip1, sizeof(clientip1), "%d.%d.%d.%d", 936 aimutil_get8(iptlv->value+0),937 aimutil_get8(iptlv->value+1),938 aimutil_get8(iptlv->value+2),939 aimutil_get8(iptlv->value+3));972 aimutil_get8(iptlv->value + 0), 973 aimutil_get8(iptlv->value + 1), 974 aimutil_get8(iptlv->value + 2), 975 aimutil_get8(iptlv->value + 3)); 940 976 } 941 977 … … 949 985 950 986 g_snprintf(clientip2, sizeof(clientip2), "%d.%d.%d.%d", 951 aimutil_get8(iptlv->value+0),952 aimutil_get8(iptlv->value+1),953 aimutil_get8(iptlv->value+2),954 aimutil_get8(iptlv->value+3));987 aimutil_get8(iptlv->value + 0), 988 aimutil_get8(iptlv->value + 1), 989 aimutil_get8(iptlv->value + 2), 990 aimutil_get8(iptlv->value + 3)); 955 991 } 956 992 … … 966 1002 967 1003 g_snprintf(verifiedip, sizeof(verifiedip), "%d.%d.%d.%d", 968 aimutil_get8(iptlv->value+0),969 aimutil_get8(iptlv->value+1),970 aimutil_get8(iptlv->value+2),971 aimutil_get8(iptlv->value+3));1004 aimutil_get8(iptlv->value + 0), 1005 aimutil_get8(iptlv->value + 1), 1006 aimutil_get8(iptlv->value + 2), 1007 aimutil_get8(iptlv->value + 3)); 972 1008 } 973 1009 … … 975 1011 * Port number for something. 976 1012 */ 977 if (aim_gettlv(list2, 0x0005, 1)) 1013 if (aim_gettlv(list2, 0x0005, 1)) { 978 1014 args.port = aim_gettlv16(list2, 0x0005, 1); 1015 } 979 1016 980 1017 /* 981 1018 * Error code. 982 1019 */ 983 if (aim_gettlv(list2, 0x000b, 1)) 1020 if (aim_gettlv(list2, 0x000b, 1)) { 984 1021 args.errorcode = aim_gettlv16(list2, 0x000b, 1); 1022 } 985 1023 986 1024 /* 987 1025 * Invitation message / chat description. 988 1026 */ 989 if (aim_gettlv(list2, 0x000c, 1)) 1027 if (aim_gettlv(list2, 0x000c, 1)) { 990 1028 args.msg = aim_gettlv_str(list2, 0x000c, 1); 1029 } 991 1030 992 1031 /* 993 1032 * Character set. 994 1033 */ 995 if (aim_gettlv(list2, 0x000d, 1)) 1034 if (aim_gettlv(list2, 0x000d, 1)) { 996 1035 args.encoding = aim_gettlv_str(list2, 0x000d, 1); 997 1036 } 1037 998 1038 /* 999 1039 * Language. 1000 1040 */ 1001 if (aim_gettlv(list2, 0x000e, 1)) 1041 if (aim_gettlv(list2, 0x000e, 1)) { 1002 1042 args.language = aim_gettlv_str(list2, 0x000e, 1); 1043 } 1003 1044 1004 1045 /* Unknown -- two bytes = 0x0001 */ 1005 if (aim_gettlv(list2, 0x000a, 1)) 1046 if (aim_gettlv(list2, 0x000a, 1)) { 1006 1047 ; 1048 } 1007 1049 1008 1050 /* Unknown -- no value */ 1009 if (aim_gettlv(list2, 0x000f, 1)) 1051 if (aim_gettlv(list2, 0x000f, 1)) { 1010 1052 ; 1011 1012 if (strlen(clientip1)) 1013 args.clientip = (char *)clientip1; 1014 if (strlen(clientip2)) 1015 args.clientip2 = (char *)clientip2; 1016 if (strlen(verifiedip)) 1017 args.verifiedip = (char *)verifiedip; 1053 } 1054 1055 if (strlen(clientip1)) { 1056 args.clientip = (char *) clientip1; 1057 } 1058 if (strlen(clientip2)) { 1059 args.clientip2 = (char *) clientip2; 1060 } 1061 if (strlen(verifiedip)) { 1062 args.verifiedip = (char *) verifiedip; 1063 } 1018 1064 1019 1065 /* … … 1029 1075 } 1030 1076 1031 if (args.reqclass & AIM_CAPS_ICQSERVERRELAY) 1077 if (args.reqclass & AIM_CAPS_ICQSERVERRELAY) { 1032 1078 incomingim_ch2_icqserverrelay(sess, mod, rx, snac, userinfo, &args, sdbsptr); 1033 else if (args.reqclass & AIM_CAPS_CHAT)1079 } else if (args.reqclass & AIM_CAPS_CHAT) { 1034 1080 incomingim_ch2_chat(sess, mod, rx, snac, userinfo, &args, sdbsptr); 1035 1036 1037 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1081 } 1082 1083 1084 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1038 1085 ret = userfunc(sess, rx, channel, userinfo, &args); 1039 1040 1041 if (args.destructor) 1042 ((ch2_args_destructor_t)args.destructor)(sess, &args); 1043 1044 g_free((char *)args.msg); 1045 g_free((char *)args.encoding); 1046 g_free((char *)args.language); 1086 } 1087 1088 1089 if (args.destructor) { 1090 ((ch2_args_destructor_t) args.destructor)(sess, &args); 1091 } 1092 1093 g_free((char *) args.msg); 1094 g_free((char *) args.encoding); 1095 g_free((char *) args.language); 1047 1096 1048 1097 aim_freetlvchain(&list2); … … 1051 1100 } 1052 1101 1053 static int incomingim_ch4(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) 1102 static int incomingim_ch4(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, guint16 channel, 1103 aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) 1054 1104 { 1055 1105 aim_bstream_t meat; … … 1062 1112 * Make a bstream for the meaty part. Yum. Meat. 1063 1113 */ 1064 if (!(block = aim_gettlv(tlvlist, 0x0005, 1))) 1114 if (!(block = aim_gettlv(tlvlist, 0x0005, 1))) { 1065 1115 return -1; 1116 } 1066 1117 aim_bstream_init(&meat, block->value, block->length); 1067 1118 1068 1119 args.uin = aimbs_getle32(&meat); 1069 1120 args.type = aimbs_getle16(&meat); 1070 args.msg = (char *) aimbs_getraw(&meat, aimbs_getle16(&meat));1071 1072 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1121 args.msg = (char *) aimbs_getraw(&meat, aimbs_getle16(&meat)); 1122 1123 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1073 1124 ret = userfunc(sess, rx, channel, userinfo, &args); 1125 } 1074 1126 1075 1127 g_free(args.msg); … … 1101 1153 * Read ICBM Cookie. And throw away. 1102 1154 */ 1103 for (i = 0; i < 8; i++) 1155 for (i = 0; i < 8; i++) { 1104 1156 cookie[i] = aimbs_get8(bs); 1157 } 1105 1158 1106 1159 /* 1107 1160 * Channel ID. 1108 1161 * 1109 * Channel 0x0001 is the message channel. There are 1162 * Channel 0x0001 is the message channel. There are 1110 1163 * other channels for things called "rendevous" 1111 1164 * which represent chat and some of the other new 1112 * features of AIM2/3/3.5. 1165 * features of AIM2/3/3.5. 1113 1166 * 1114 1167 * Channel 0x0002 is the Rendevous channel, which … … 1116 1169 * connection negotiations come from. 1117 1170 * 1118 * Channel 0x0004 is used for ICQ authorization, or 1171 * Channel 0x0004 is used for ICQ authorization, or 1119 1172 * possibly any system notice. 1120 1173 * … … 1131 1184 * aim_extractuserinfo() returns the number of bytes used by the 1132 1185 * userinfo tlvs, so you can start reading the rest of them right 1133 * afterward. 1186 * afterward. 1134 1187 * 1135 1188 * That also means that TLV types can be duplicated between the 1136 1189 * userinfo block and the rest of the message, however there should 1137 1190 * never be two TLVs of the same type in one block. 1138 * 1191 * 1139 1192 */ 1140 1193 aim_extractuserinfo(sess, bs, &userinfo); … … 1155 1208 1156 1209 /* 1157 * Read block of TLVs (not including the userinfo data). All 1210 * Read block of TLVs (not including the userinfo data). All 1158 1211 * further data is derived from what is parsed here. 1159 1212 */ … … 1191 1244 aim_conn_t *conn; 1192 1245 1193 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) 1246 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) { 1194 1247 return -EINVAL; 1248 } 1195 1249 1196 1250 return aim_genericreq_n(sess, conn, 0x0004, 0x0004); … … 1201 1255 * I definitly recommend sending this. If you don't, you'll be stuck 1202 1256 * with the rather unreasonable defaults. You don't want those. Send this. 1203 * 1257 * 1204 1258 */ 1205 1259 int aim_seticbmparam(aim_session_t *sess, struct aim_icbmparameters *params) … … 1209 1263 aim_snacid_t snacid; 1210 1264 1211 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) 1265 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004))) { 1212 1266 return -EINVAL; 1213 1214 if (!params) 1267 } 1268 1269 if (!params) { 1215 1270 return -EINVAL; 1216 1217 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+16))) 1271 } 1272 1273 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 16))) { 1218 1274 return -ENOMEM; 1275 } 1219 1276 1220 1277 snacid = aim_cachesnac(sess, 0x0004, 0x0002, 0x0000, NULL, 0); … … 1225 1282 1226 1283 /* These are all read-write */ 1227 aimbs_put32(&fr->data, params->flags); 1284 aimbs_put32(&fr->data, params->flags); 1228 1285 aimbs_put16(&fr->data, params->maxmsglen); 1229 aimbs_put16(&fr->data, params->maxsenderwarn); 1230 aimbs_put16(&fr->data, params->maxrecverwarn); 1286 aimbs_put16(&fr->data, params->maxsenderwarn); 1287 aimbs_put16(&fr->data, params->maxrecverwarn); 1231 1288 aimbs_put32(&fr->data, params->minmsginterval); 1232 1289 … … 1247 1304 params.maxrecverwarn = aimbs_get16(bs); 1248 1305 params.minmsginterval = aimbs_get32(bs); 1249 1250 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1306 1307 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1251 1308 return userfunc(sess, rx, ¶ms); 1309 } 1252 1310 1253 1311 return 0; … … 1261 1319 aim_userinfo_t userinfo; 1262 1320 1263 while (aim_bstream_empty(bs)) { 1321 while (aim_bstream_empty(bs)) { 1264 1322 1265 1323 channel = aimbs_get16(bs); … … 1268 1326 reason = aimbs_get16(bs); 1269 1327 1270 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1271 ret = userfunc(sess, rx, channel, &userinfo, nummissed, reason); 1328 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1329 ret = userfunc(sess, rx, channel, &userinfo, nummissed, reason); 1330 } 1272 1331 } 1273 1332 … … 1276 1335 1277 1336 /* 1278 * Receive the response from an ICQ status message request. This contains the 1337 * Receive the response from an ICQ status message request. This contains the 1279 1338 * ICQ status message. Go figure. 1280 1339 */ 1281 static int clientautoresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1340 static int clientautoresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, 1341 aim_bstream_t *bs) 1282 1342 { 1283 1343 int ret = 0; … … 1294 1354 1295 1355 switch (reason) { 1296 case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ 1297 guint8 statusmsgtype, *msg; 1298 guint16 len; 1299 guint32 state; 1300 1301 len = aimbs_getle16(bs); /* Should be 0x001b */ 1302 aim_bstream_advance(bs, len); /* Unknown */ 1303 1304 len = aimbs_getle16(bs); /* Should be 0x000e */ 1305 aim_bstream_advance(bs, len); /* Unknown */ 1306 1307 statusmsgtype = aimbs_getle8(bs); 1308 switch (statusmsgtype) { 1309 case 0xe8: 1310 state = AIM_ICQ_STATE_AWAY; 1311 break; 1312 case 0xe9: 1313 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY; 1314 break; 1315 case 0xea: 1316 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_OUT; 1317 break; 1318 case 0xeb: 1319 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY; 1320 break; 1321 case 0xec: 1322 state = AIM_ICQ_STATE_CHAT; 1323 break; 1324 default: 1325 state = 0; 1326 break; 1327 } 1328 1329 aimbs_getle8(bs); /* Unknown - 0x03 Maybe this means this is an auto-reply */ 1330 aimbs_getle16(bs); /* Unknown - 0x0000 */ 1331 aimbs_getle16(bs); /* Unknown - 0x0000 */ 1332 1333 len = aimbs_getle16(bs); 1334 msg = aimbs_getraw(bs, len); 1335 1336 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1337 ret = userfunc(sess, rx, channel, sn, reason, state, msg); 1338 1339 g_free(msg); 1340 } break; 1341 1342 default: { 1343 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1344 ret = userfunc(sess, rx, channel, sn, reason); 1345 } break; 1356 case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ 1357 guint8 statusmsgtype, *msg; 1358 guint16 len; 1359 guint32 state; 1360 1361 len = aimbs_getle16(bs); /* Should be 0x001b */ 1362 aim_bstream_advance(bs, len); /* Unknown */ 1363 1364 len = aimbs_getle16(bs); /* Should be 0x000e */ 1365 aim_bstream_advance(bs, len); /* Unknown */ 1366 1367 statusmsgtype = aimbs_getle8(bs); 1368 switch (statusmsgtype) { 1369 case 0xe8: 1370 state = AIM_ICQ_STATE_AWAY; 1371 break; 1372 case 0xe9: 1373 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY; 1374 break; 1375 case 0xea: 1376 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_OUT; 1377 break; 1378 case 0xeb: 1379 state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY; 1380 break; 1381 case 0xec: 1382 state = AIM_ICQ_STATE_CHAT; 1383 break; 1384 default: 1385 state = 0; 1386 break; 1387 } 1388 1389 aimbs_getle8(bs); /* Unknown - 0x03 Maybe this means this is an auto-reply */ 1390 aimbs_getle16(bs); /* Unknown - 0x0000 */ 1391 aimbs_getle16(bs); /* Unknown - 0x0000 */ 1392 1393 len = aimbs_getle16(bs); 1394 msg = aimbs_getraw(bs, len); 1395 1396 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1397 ret = userfunc(sess, rx, channel, sn, reason, state, msg); 1398 } 1399 1400 g_free(msg); 1401 } break; 1402 1403 default: { 1404 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1405 ret = userfunc(sess, rx, channel, sn, reason); 1406 } 1407 } break; 1346 1408 } /* end switch */ 1347 1409 … … 1365 1427 sn = aimbs_getstr(bs, snlen); 1366 1428 1367 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1429 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1368 1430 ret = userfunc(sess, rx, type, sn); 1431 } 1369 1432 1370 1433 g_free(sn); … … 1377 1440 * Subtype 0x0014 - Send a mini typing notification (mtn) packet. 1378 1441 * 1379 * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 1442 * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 1380 1443 * and Gaim 0.60 and newer. 1381 1444 * … … 1387 1450 aim_snacid_t snacid; 1388 1451 1389 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002))) 1452 if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002))) { 1390 1453 return -EINVAL; 1391 1392 if (!sn) 1454 } 1455 1456 if (!sn) { 1393 1457 return -EINVAL; 1394 1395 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+11+strlen(sn)+2))) 1458 } 1459 1460 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11 + strlen(sn) + 2))) { 1396 1461 return -ENOMEM; 1462 } 1397 1463 1398 1464 snacid = aim_cachesnac(sess, 0x0004, 0x0014, 0x0000, NULL, 0); … … 1417 1483 */ 1418 1484 aimbs_put8(&fr->data, strlen(sn)); 1419 aimbs_putraw(&fr->data, (const guint8 *)sn, strlen(sn));1485 aimbs_putraw(&fr->data, (const guint8 *) sn, strlen(sn)); 1420 1486 1421 1487 /* … … 1432 1498 * Subtype 0x0014 - Receive a mini typing notification (mtn) packet. 1433 1499 * 1434 * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 1500 * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 1435 1501 * and Gaim 0.60 and newer. 1436 1502 * … … 1450 1516 type2 = aimbs_get16(bs); 1451 1517 1452 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1518 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1453 1519 ret = userfunc(sess, rx, type1, sn, type2); 1520 } 1454 1521 1455 1522 g_free(sn); … … 1461 1528 { 1462 1529 1463 if (snac->subtype == 0x0005) 1530 if (snac->subtype == 0x0005) { 1464 1531 return paraminfo(sess, mod, rx, snac, bs); 1465 else if (snac->subtype == 0x0006)1532 } else if (snac->subtype == 0x0006) { 1466 1533 return outgoingim(sess, mod, rx, snac, bs); 1467 else if (snac->subtype == 0x0007)1534 } else if (snac->subtype == 0x0007) { 1468 1535 return incomingim(sess, mod, rx, snac, bs); 1469 else if (snac->subtype == 0x000a)1536 } else if (snac->subtype == 0x000a) { 1470 1537 return missedcall(sess, mod, rx, snac, bs); 1471 else if (snac->subtype == 0x000b)1538 } else if (snac->subtype == 0x000b) { 1472 1539 return clientautoresp(sess, mod, rx, snac, bs); 1473 else if (snac->subtype == 0x000c)1540 } else if (snac->subtype == 0x000c) { 1474 1541 return msgack(sess, mod, rx, snac, bs); 1475 else if (snac->subtype == 0x0014)1542 } else if (snac->subtype == 0x0014) { 1476 1543 return mtn_receive(sess, mod, rx, snac, bs); 1544 } 1477 1545 1478 1546 return 0;
Note: See TracChangeset
for help on using the changeset viewer.