Mercurial > pidgin.yaz
comparison libpurple/protocols/oscar/family_icbm.c @ 27782:9cd7892b2c8b
propagate from branch 'im.pidgin.pidgin' (head dfdceb0b08475c3e5750b3e6430d154e9a747d67)
to branch 'im.pidgin.pidgin.yaz' (head 7982395e45644f3f5d8b4a39018946e19ea9572f)
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Tue, 04 Mar 2008 18:12:32 +0000 |
parents | 0f3a131d23da 75d53b0fae6c |
children | 8dfe3a985fc1 |
comparison
equal
deleted
inserted
replaced
27781:11713f052640 | 27782:9cd7892b2c8b |
---|---|
2369 flap_connection_send(conn, frame); | 2369 flap_connection_send(conn, frame); |
2370 | 2370 |
2371 return 0; | 2371 return 0; |
2372 } | 2372 } |
2373 | 2373 |
2374 static void parse_status_note_text(OscarData *od, guchar *cookie, char *sn, ByteStream *bs) | |
2375 { | |
2376 struct aim_icq_info *info; | |
2377 struct aim_icq_info *prev_info; | |
2378 char *response; | |
2379 char *encoding; | |
2380 char *stripped_encoding; | |
2381 char *status_note_title; | |
2382 char *status_note_text; | |
2383 char *stripped_status_note_text; | |
2384 char *status_note; | |
2385 guint32 length; | |
2386 guint16 version; | |
2387 guint32 capability; | |
2388 guint8 message_type; | |
2389 guint16 status_code; | |
2390 guint16 text_length; | |
2391 guint32 request_length; | |
2392 guint32 response_length; | |
2393 guint32 encoding_length; | |
2394 PurpleAccount *account; | |
2395 PurpleBuddy *buddy; | |
2396 PurplePresence *presence; | |
2397 PurpleStatus *status; | |
2398 | |
2399 for (prev_info = NULL, info = od->icq_info; info != NULL; prev_info = info, info = info->next) | |
2400 { | |
2401 if (memcmp(&info->icbm_cookie, cookie, 8) == 0) | |
2402 { | |
2403 if (prev_info == NULL) | |
2404 od->icq_info = info->next; | |
2405 else | |
2406 prev_info->next = info->next; | |
2407 | |
2408 break; | |
2409 } | |
2410 } | |
2411 | |
2412 if (info == NULL) | |
2413 return; | |
2414 | |
2415 status_note_title = info->status_note_title; | |
2416 g_free(info); | |
2417 | |
2418 length = byte_stream_getle16(bs); | |
2419 if (length != 27) { | |
2420 purple_debug_misc("oscar", "clientautoresp: incorrect header " | |
2421 "size; expected 27, received %u.\n", length); | |
2422 g_free(status_note_title); | |
2423 return; | |
2424 } | |
2425 | |
2426 version = byte_stream_getle16(bs); | |
2427 if (version != 9) { | |
2428 purple_debug_misc("oscar", "clientautoresp: incorrect version; " | |
2429 "expected 9, received %u.\n", version); | |
2430 g_free(status_note_title); | |
2431 return; | |
2432 } | |
2433 | |
2434 capability = aim_locate_getcaps(od, bs, 0x10); | |
2435 if (capability != OSCAR_CAPABILITY_EMPTY) { | |
2436 purple_debug_misc("oscar", "clientautoresp: plugin ID is not null.\n"); | |
2437 g_free(status_note_title); | |
2438 return; | |
2439 } | |
2440 | |
2441 byte_stream_advance(bs, 2); /* unknown */ | |
2442 byte_stream_advance(bs, 4); /* client capabilities flags */ | |
2443 byte_stream_advance(bs, 1); /* unknown */ | |
2444 byte_stream_advance(bs, 2); /* downcouner? */ | |
2445 | |
2446 length = byte_stream_getle16(bs); | |
2447 if (length != 14) { | |
2448 purple_debug_misc("oscar", "clientautoresp: incorrect header " | |
2449 "size; expected 14, received %u.\n", length); | |
2450 g_free(status_note_title); | |
2451 return; | |
2452 } | |
2453 | |
2454 byte_stream_advance(bs, 2); /* downcounter? */ | |
2455 byte_stream_advance(bs, 12); /* unknown */ | |
2456 | |
2457 message_type = byte_stream_get8(bs); | |
2458 if (message_type != 0x1a) { | |
2459 purple_debug_misc("oscar", "clientautoresp: incorrect message " | |
2460 "type; expected 0x1a, received 0x%x.\n", message_type); | |
2461 g_free(status_note_title); | |
2462 return; | |
2463 } | |
2464 | |
2465 byte_stream_advance(bs, 1); /* message flags */ | |
2466 | |
2467 status_code = byte_stream_getle16(bs); | |
2468 if (status_code != 0) { | |
2469 purple_debug_misc("oscar", "clientautoresp: incorrect status " | |
2470 "code; expected 0, received %u.\n", status_code); | |
2471 g_free(status_note_title); | |
2472 return; | |
2473 } | |
2474 | |
2475 byte_stream_advance(bs, 2); /* priority code */ | |
2476 | |
2477 text_length = byte_stream_getle16(bs); | |
2478 byte_stream_advance(bs, text_length); /* text */ | |
2479 | |
2480 length = byte_stream_getle16(bs); | |
2481 byte_stream_advance(bs, 18); /* unknown */ | |
2482 | |
2483 request_length = byte_stream_getle32(bs); | |
2484 if (length != 18 + 4 + request_length + 17) { | |
2485 purple_debug_misc("oscar", "clientautoresp: incorrect block; " | |
2486 "expected length is %u, got %u.\n", | |
2487 18 + 4 + request_length + 17, length); | |
2488 g_free(status_note_title); | |
2489 return; | |
2490 } | |
2491 | |
2492 byte_stream_advance(bs, request_length); /* x request */ | |
2493 byte_stream_advance(bs, 17); /* unknown */ | |
2494 | |
2495 length = byte_stream_getle32(bs); | |
2496 response_length = byte_stream_getle32(bs); | |
2497 response = byte_stream_getstr(bs, response_length); | |
2498 encoding_length = byte_stream_getle32(bs); | |
2499 if (length != 4 + response_length + 4 + encoding_length) { | |
2500 purple_debug_misc("oscar", "clientautoresp: incorrect block; " | |
2501 "expected length is %u, got %u.\n", | |
2502 4 + response_length + 4 + encoding_length, length); | |
2503 g_free(status_note_title); | |
2504 g_free(response); | |
2505 return; | |
2506 } | |
2507 | |
2508 encoding = byte_stream_getstr(bs, encoding_length); | |
2509 | |
2510 account = purple_connection_get_account(od->gc); | |
2511 | |
2512 stripped_encoding = oscar_encoding_extract(encoding); | |
2513 status_note_text = oscar_encoding_to_utf8(account, stripped_encoding, response, response_length); | |
2514 stripped_status_note_text = purple_markup_strip_html(status_note_text); | |
2515 | |
2516 if (stripped_status_note_text != NULL && stripped_status_note_text[0] != 0) | |
2517 status_note = g_strdup_printf("%s: %s", status_note_title, stripped_status_note_text); | |
2518 else | |
2519 status_note = g_strdup(status_note_title); | |
2520 | |
2521 g_free(status_note_title); | |
2522 g_free(response); | |
2523 g_free(encoding); | |
2524 g_free(stripped_encoding); | |
2525 g_free(status_note_text); | |
2526 g_free(stripped_status_note_text); | |
2527 | |
2528 buddy = purple_find_buddy(account, sn); | |
2529 if (buddy == NULL) | |
2530 { | |
2531 purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", sn); | |
2532 g_free(status_note); | |
2533 return; | |
2534 } | |
2535 | |
2536 purple_debug_misc("oscar", "clientautoresp: setting status " | |
2537 "message to \"%s\".\n", status_note); | |
2538 | |
2539 presence = purple_buddy_get_presence(buddy); | |
2540 status = purple_presence_get_active_status(presence); | |
2541 | |
2542 purple_prpl_got_user_status(account, sn, | |
2543 purple_status_get_id(status), | |
2544 "message", status_note, NULL); | |
2545 | |
2546 g_free(status_note); | |
2547 } | |
2548 | |
2374 /* | 2549 /* |
2375 * Subtype 0x000b - Receive the response from an ICQ status message | 2550 * Subtype 0x000b - Receive the response from an ICQ status message |
2376 * request (in which case this contains the ICQ status message) or | 2551 * request (in which case this contains the ICQ status message) or |
2377 * a file transfer or direct IM request was declined. | 2552 * a file transfer or direct IM request was declined. |
2378 */ | 2553 */ |
2391 sn = byte_stream_getstr(bs, snlen); | 2566 sn = byte_stream_getstr(bs, snlen); |
2392 reason = byte_stream_get16(bs); | 2567 reason = byte_stream_get16(bs); |
2393 | 2568 |
2394 if (channel == 0x0002) | 2569 if (channel == 0x0002) |
2395 { | 2570 { |
2396 /* parse status note text */ | 2571 if (reason == 0x0003) /* channel-specific */ |
2397 | 2572 /* parse status note text */ |
2398 struct aim_icq_info *info = NULL; | 2573 parse_status_note_text(od, cookie, sn, bs); |
2399 struct aim_icq_info *prev_info = NULL; | |
2400 char *response = NULL; | |
2401 char *encoding = NULL; | |
2402 char *stripped_encoding = NULL; | |
2403 char *status_note_text = NULL; | |
2404 char *stripped_status_note_text = NULL; | |
2405 char *status_note = NULL; | |
2406 | |
2407 /* | |
2408 * TODO: Using a while statement here is kind of an ugly hack | |
2409 * to be able to use 'break'. We might as well be using | |
2410 * 'goto'. Should probably get rid of this. | |
2411 */ | |
2412 while (reason == 0x0003) /* channel-specific */ | |
2413 { | |
2414 guint32 length; | |
2415 guint16 version; | |
2416 guint32 capability; | |
2417 guint8 message_type; | |
2418 guint16 status_code; | |
2419 guint16 text_length; | |
2420 guint32 request_length; | |
2421 guint32 response_length; | |
2422 guint32 encoding_length; | |
2423 PurpleAccount *account; | |
2424 PurpleBuddy *buddy; | |
2425 PurplePresence *presence; | |
2426 PurpleStatus *status; | |
2427 | |
2428 for (info = od->icq_info; info != NULL; info = info->next) | |
2429 { | |
2430 if (memcmp(&info->icbm_cookie, cookie, 8) == 0) | |
2431 { | |
2432 if (prev_info == NULL) | |
2433 od->icq_info = info->next; | |
2434 else | |
2435 prev_info->next = info->next; | |
2436 | |
2437 break; | |
2438 } | |
2439 | |
2440 prev_info = info; | |
2441 } | |
2442 | |
2443 if (info == NULL) | |
2444 break; | |
2445 | |
2446 if ((length = byte_stream_getle16(bs)) != 27) | |
2447 { | |
2448 purple_debug_misc("oscar", "clientautoresp: incorrect header size; expected 27, received %u.\n", length); | |
2449 break; | |
2450 } | |
2451 if ((version = byte_stream_getle16(bs)) != 9) | |
2452 { | |
2453 purple_debug_misc("oscar", "clientautoresp: incorrect version; expected 9, received %u.\n", version); | |
2454 break; | |
2455 } | |
2456 capability = aim_locate_getcaps(od, bs, 0x10); | |
2457 if (capability != OSCAR_CAPABILITY_EMPTY) | |
2458 { | |
2459 purple_debug_misc("oscar", "clientautoresp: plugin ID is not null.\n"); | |
2460 break; | |
2461 } | |
2462 byte_stream_advance(bs, 2); /* unknown */ | |
2463 byte_stream_advance(bs, 4); /* client capabilities flags */ | |
2464 byte_stream_advance(bs, 1); /* unknown */ | |
2465 byte_stream_advance(bs, 2); /* downcouner? */ | |
2466 | |
2467 if ((length = byte_stream_getle16(bs)) != 14) | |
2468 { | |
2469 purple_debug_misc("oscar", "clientautoresp: incorrect header size; expected 14, received %u.\n", length); | |
2470 break; | |
2471 } | |
2472 byte_stream_advance(bs, 2); /* downcounter? */ | |
2473 byte_stream_advance(bs, 12); /* unknown */ | |
2474 | |
2475 if ((message_type = byte_stream_get8(bs)) != 0x1a) | |
2476 { | |
2477 purple_debug_misc("oscar", "clientautoresp: incorrect message type; expected 0x1a, received 0x%x.\n", message_type); | |
2478 break; | |
2479 } | |
2480 byte_stream_advance(bs, 1); /* message flags */ | |
2481 if ((status_code = byte_stream_getle16(bs)) != 0) | |
2482 { | |
2483 purple_debug_misc("oscar", "clientautoresp: incorrect status code; expected 0, received %u.\n", status_code); | |
2484 break; | |
2485 } | |
2486 byte_stream_advance(bs, 2); /* priority code */ | |
2487 | |
2488 text_length = byte_stream_getle16(bs); | |
2489 byte_stream_advance(bs, text_length); /* text */ | |
2490 | |
2491 length = byte_stream_getle16(bs); | |
2492 byte_stream_advance(bs, 18); /* unknown */ | |
2493 if (length != 18 + 4 + (request_length = byte_stream_getle32(bs)) + 17) | |
2494 { | |
2495 purple_debug_misc("oscar", "clientautoresp: incorrect block; expected length is %u, got %u.\n", 18 + 4 + request_length + 17, length); | |
2496 break; | |
2497 } | |
2498 byte_stream_advance(bs, request_length); /* x request */ | |
2499 byte_stream_advance(bs, 17); /* unknown */ | |
2500 | |
2501 length = byte_stream_getle32(bs); | |
2502 response_length = byte_stream_getle32(bs); | |
2503 response = byte_stream_getstr(bs, response_length); | |
2504 if (length != 4 + response_length + 4 + (encoding_length = byte_stream_getle32(bs))) | |
2505 { | |
2506 purple_debug_misc("oscar", "clientautoresp: incorrect block; expected length is %u, got %u.\n", 4 + response_length + 4 + encoding_length, length); | |
2507 break; | |
2508 } | |
2509 encoding = byte_stream_getstr(bs, encoding_length); | |
2510 | |
2511 account = purple_connection_get_account(od->gc); | |
2512 stripped_encoding = oscar_encoding_extract(encoding); | |
2513 status_note_text = oscar_encoding_to_utf8(account, stripped_encoding, response, response_length); | |
2514 stripped_status_note_text = purple_markup_strip_html(status_note_text); | |
2515 | |
2516 if (stripped_status_note_text != NULL && stripped_status_note_text[0] != 0) | |
2517 status_note = g_strdup_printf("%s: %s", info->status_note_title, stripped_status_note_text); | |
2518 else | |
2519 status_note = g_strdup(info->status_note_title); | |
2520 | |
2521 buddy = purple_find_buddy(account, sn); | |
2522 if (buddy == NULL) | |
2523 { | |
2524 purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", sn); | |
2525 break; | |
2526 } | |
2527 | |
2528 purple_debug_misc("oscar", "clientautoresp: setting status message to \"%s\".\n", status_note); | |
2529 | |
2530 presence = purple_buddy_get_presence(buddy); | |
2531 status = purple_presence_get_active_status(presence); | |
2532 | |
2533 purple_prpl_got_user_status(account, sn, | |
2534 purple_status_get_id(status), | |
2535 "message", status_note, NULL); | |
2536 | |
2537 break; | |
2538 } | |
2539 | |
2540 g_free(status_note); | |
2541 g_free(stripped_status_note_text); | |
2542 g_free(status_note_text); | |
2543 g_free(stripped_encoding); | |
2544 g_free(encoding); | |
2545 g_free(response); | |
2546 g_free(info->status_note_title); | |
2547 g_free(info); | |
2548 | 2574 |
2549 byte_stream_get16(bs); /* Unknown */ | 2575 byte_stream_get16(bs); /* Unknown */ |
2550 byte_stream_get16(bs); /* Unknown */ | 2576 byte_stream_get16(bs); /* Unknown */ |
2551 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) | 2577 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) |
2552 ret = userfunc(od, conn, frame, channel, sn, reason, cookie); | 2578 ret = userfunc(od, conn, frame, channel, sn, reason, cookie); |