comparison src/protocols/yahoo/yahoo.c @ 10400:6a043ae92db6

[gaim-migrate @ 11631] I'm about to go home for the holidays, so I figured I'd commit this before I left so someone else could pick up on it while I'm gone. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Sun, 19 Dec 2004 20:32:32 +0000
parents 45a0a07e8b25
children 3e4ecbdf8d0a
comparison
equal deleted inserted replaced
10399:aab0c9508318 10400:6a043ae92db6
1462 if (lookup >= strlen(delimit_lookup)) 1462 if (lookup >= strlen(delimit_lookup))
1463 break; 1463 break;
1464 sprintf(byte, "%c", delimit_lookup[lookup]); 1464 sprintf(byte, "%c", delimit_lookup[lookup]);
1465 strcat(resp_96, byte); 1465 strcat(resp_96, byte);
1466 } 1466 }
1467 1467 printf("yahoo status : %d\n", yd->current_status);
1468 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); 1468 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->current_status, 0);
1469 yahoo_packet_hash(pack, "sssss", 0, name, 6, resp_6, 96, resp_96, 1, 1469 yahoo_packet_hash(pack, "sssss", 0, name, 6, resp_6, 96, resp_96, 1,
1470 name, 135, "6,0,0,1710"); 1470 name, 135, "6,0,0,1710");
1471 if (yd->picture_checksum) 1471 if (yd->picture_checksum)
1472 yahoo_packet_hash_int(pack, 192, yd->picture_checksum); 1472 yahoo_packet_hash_int(pack, 192, yd->picture_checksum);
1473 1473
1995 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) 1995 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond)
1996 { 1996 {
1997 GaimConnection *gc = data; 1997 GaimConnection *gc = data;
1998 struct yahoo_data *yd; 1998 struct yahoo_data *yd;
1999 struct yahoo_packet *pkt; 1999 struct yahoo_packet *pkt;
2000 2000
2001 if (!g_list_find(gaim_connections_get_all(), gc)) { 2001 if (!g_list_find(gaim_connections_get_all(), gc)) {
2002 close(source); 2002 close(source);
2003 return; 2003 return;
2004 } 2004 }
2005 2005
2008 return; 2008 return;
2009 } 2009 }
2010 2010
2011 yd = gc->proto_data; 2011 yd = gc->proto_data;
2012 yd->fd = source; 2012 yd->fd = source;
2013 2013
2014 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); 2014 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0);
2015 2015
2016 yahoo_packet_hash_str(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); 2016 yahoo_packet_hash_str(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))));
2017 yahoo_packet_send_and_free(pkt, yd); 2017 yahoo_packet_send_and_free(pkt, yd);
2018 2018
2217 buddyicon = gaim_account_get_buddy_icon(account); 2217 buddyicon = gaim_account_get_buddy_icon(account);
2218 yahoo_set_buddy_icon(gc, buddyicon); 2218 yahoo_set_buddy_icon(gc, buddyicon);
2219 } 2219 }
2220 2220
2221 2221
2222 static void yahoo_login(GaimAccount *account) { 2222 static void yahoo_login(GaimAccount *account, GaimStatus *status) {
2223 GaimConnection *gc = gaim_account_get_connection(account); 2223 GaimConnection *gc = gaim_account_get_connection(account);
2224 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); 2224 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1);
2225 2225 char *id = gaim_status_get_id(status);
2226 gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC; 2226 gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC;
2227 2227
2228 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); 2228 gaim_connection_update_progress(gc, _("Connecting"), 1, 2);
2229 2229
2230 gaim_connection_set_display_name(gc, gaim_account_get_username(account)); 2230 gaim_connection_set_display_name(gc, gaim_account_get_username(account));
2231 2231
2232 yd->fd = -1; 2232 yd->fd = -1;
2233 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); 2233 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free);
2234 yd->confs = NULL; 2234 yd->confs = NULL;
2235 yd->conf_id = 2; 2235 yd->conf_id = 2;
2236 2236
2237 yahoo_server_check(account); 2237 if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE) || !strcmp(id, YAHOO_STATUS_TYPE_ONLINE)) {
2238 yahoo_picture_check(account);
2239
2240 if (gaim_account_get_bool(account, "yahoojp", FALSE)) {
2241 yd->jp = TRUE;
2242 if (gaim_proxy_connect(account,
2243 gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST),
2244 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),
2245 yahoo_got_connected, gc) != 0)
2246 {
2247 gaim_connection_error(gc, _("Connection problem"));
2248 return;
2249 }
2250 } else {
2251 yd->jp = FALSE;
2252 if (gaim_proxy_connect(account,
2253 gaim_account_get_string(account, "server", YAHOO_PAGER_HOST),
2254 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),
2255 yahoo_got_connected, gc) != 0)
2256 {
2257 gaim_connection_error(gc, _("Connection problem"));
2258 return;
2259 }
2260 }
2261
2262
2263 }
2264
2265 static void yahoo_close(GaimConnection *gc) {
2266 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;
2267 GSList *l;
2268
2269 for (l = yd->confs; l; l = l->next) {
2270 GaimConversation *conv = l->data;
2271
2272 yahoo_conf_leave(yd, gaim_conversation_get_name(conv),
2273 gaim_connection_get_display_name(gc),
2274 gaim_conv_chat_get_users(GAIM_CONV_CHAT(conv)));
2275 }
2276 g_slist_free(yd->confs);
2277
2278 g_hash_table_destroy(yd->friends);
2279 if (yd->chat_name)
2280 g_free(yd->chat_name);
2281
2282 if (yd->cookie_y)
2283 g_free(yd->cookie_y);
2284 if (yd->cookie_t)
2285 g_free(yd->cookie_t);
2286
2287 if (yd->fd >= 0)
2288 close(yd->fd);
2289
2290 if (yd->rxqueue)
2291 g_free(yd->rxqueue);
2292 yd->rxlen = 0;
2293 if (yd->picture_url)
2294 g_free(yd->picture_url);
2295 if (yd->picture_upload_todo)
2296 yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo);
2297 if (yd->ycht)
2298 ycht_connection_close(yd->ycht);
2299 if (gc->inpa)
2300 gaim_input_remove(gc->inpa);
2301 g_free(yd);
2302 }
2303
2304 static const char *yahoo_list_icon(GaimAccount *a, GaimBuddy *b)
2305 {
2306 return "yahoo";
2307 }
2308
2309 static void yahoo_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
2310 {
2311 int i = 0;
2312 char *emblems[4] = {NULL,NULL,NULL,NULL};
2313 GaimAccount *account;
2314 GaimConnection *gc;
2315 struct yahoo_data *yd;
2316 YahooFriend *f;
2317 GaimPresence *presence;
2318 GaimStatus *status;
2319 const char *status_id;
2320
2321 if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) ||
2322 !(yd = gc->proto_data))
2323 return;
2324
2325 f = yahoo_friend_find(gc, b->name);
2326 if (!f) {
2327 *se = "notauthorized";
2328 return;
2329 }
2330
2331 presence = gaim_buddy_get_presence(b);
2332 status = gaim_presence_get_active_status(presence);
2333 status_id = gaim_status_get_id(status);
2334
2335 if (gaim_presence_is_online(presence) == FALSE) {
2336 *se = "offline";
2337 return;
2338 } else {
2339 if (f->away)
2340 emblems[i++] = "away";
2341 if (f->sms)
2342 emblems[i++] = "wireless";
2343 if (yahoo_friend_get_game(f))
2344 emblems[i++] = "game";
2345 }
2346 *se = emblems[0];
2347 *sw = emblems[1];
2348 *nw = emblems[2];
2349 *ne = emblems[3];
2350 }
2351
2352 static char *yahoo_get_status_string(enum yahoo_status a)
2353 {
2354 switch (a) {
2355 case YAHOO_STATUS_BRB:
2356 return _("Be Right Back");
2357 case YAHOO_STATUS_BUSY:
2358 return _("Busy");
2359 case YAHOO_STATUS_NOTATHOME:
2360 return _("Not At Home");
2361 case YAHOO_STATUS_NOTATDESK:
2362 return _("Not At Desk");
2363 case YAHOO_STATUS_NOTINOFFICE:
2364 return _("Not In Office");
2365 case YAHOO_STATUS_ONPHONE:
2366 return _("On The Phone");
2367 case YAHOO_STATUS_ONVACATION:
2368 return _("On Vacation");
2369 case YAHOO_STATUS_OUTTOLUNCH:
2370 return _("Out To Lunch");
2371 case YAHOO_STATUS_STEPPEDOUT:
2372 return _("Stepped Out");
2373 case YAHOO_STATUS_INVISIBLE:
2374 return _("Invisible");
2375 case YAHOO_STATUS_IDLE:
2376 return _("Idle");
2377 case YAHOO_STATUS_OFFLINE:
2378 return _("Offline");
2379 default:
2380 return _("Online");
2381 }
2382 }
2383
2384 static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) {
2385
2386 GaimBuddy *buddy;
2387 GaimConnection *gc;
2388
2389 GHashTable *components;
2390 struct yahoo_data *yd;
2391 int id;
2392
2393 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2394
2395 buddy = (GaimBuddy *) node;
2396 gc = gaim_account_get_connection(buddy->account);
2397 yd = gc->proto_data;
2398 id = yd->conf_id;
2399
2400 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
2401 g_hash_table_replace(components, g_strdup("room"),
2402 g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id));
2403 g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference..."));
2404 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
2405 yahoo_c_join(gc, components);
2406 g_hash_table_destroy(components);
2407
2408 yahoo_c_invite(gc, id, "Join my conference...", buddy->name);
2409 }
2410
2411 static void yahoo_game(GaimBlistNode *node, gpointer data) {
2412
2413 GaimBuddy *buddy;
2414 GaimConnection *gc;
2415
2416 struct yahoo_data *yd;
2417 const char *game;
2418 char *game2;
2419 char *t;
2420 char url[256];
2421 YahooFriend *f;
2422
2423 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2424
2425 buddy = (GaimBuddy *) node;
2426 gc = gaim_account_get_connection(buddy->account);
2427 yd = (struct yahoo_data *) gc->proto_data;
2428
2429 f = yahoo_friend_find(gc, buddy->name);
2430 if (!f)
2431 return;
2432
2433 game = yahoo_friend_get_game(f);
2434 if (!game)
2435 return;
2436
2437 t = game2 = g_strdup(strstr(game, "ante?room="));
2438 while (*t && *t != '\t')
2439 t++;
2440 *t = 0;
2441 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2);
2442 gaim_notify_uri(gc, url);
2443 g_free(game2);
2444 }
2445
2446 static char *yahoo_status_text(GaimBuddy *b)
2447 {
2448 YahooFriend *f = NULL;
2449 const char *msg;
2450
2451 f = yahoo_friend_find(b->account->gc, b->name);
2452 if (!f)
2453 return g_strdup(_("Not on server list"));
2454
2455 switch (f->status) {
2456 case YAHOO_STATUS_AVAILABLE:
2457 return NULL;
2458 case YAHOO_STATUS_IDLE:
2459 if (f->idle == -1)
2460 return g_strdup(yahoo_get_status_string(f->status));
2461 return NULL;
2462 case YAHOO_STATUS_CUSTOM:
2463 if (!(msg = yahoo_friend_get_status_message(f)))
2464 return NULL;
2465 return g_markup_escape_text(msg, strlen(msg));
2466
2467 default:
2468 return g_strdup(yahoo_get_status_string(f->status));
2469 }
2470 }
2471
2472 char *yahoo_tooltip_text(GaimBuddy *b)
2473 {
2474 YahooFriend *f;
2475 char *escaped, *status, *ret;
2476
2477 f = yahoo_friend_find(b->account->gc, b->name);
2478 if (!f)
2479 status = g_strdup_printf("\n%s", _("Not on server list"));
2480 else
2481 switch (f->status) {
2482 case YAHOO_STATUS_IDLE:
2483 if (f->idle == -1) {
2484 status = g_strdup(yahoo_get_status_string(f->status));
2485 break;
2486 }
2487 return NULL;
2488 case YAHOO_STATUS_CUSTOM:
2489 if (!yahoo_friend_get_status_message(f))
2490 return NULL;
2491 status = g_strdup(yahoo_friend_get_status_message(f));
2492 break;
2493 default:
2494 status = g_strdup(yahoo_get_status_string(f->status));
2495 break;
2496 }
2497
2498 escaped = g_markup_escape_text(status, strlen(status));
2499 ret = g_strdup_printf(_("\n<b>%s:</b> %s"), _("Status"), escaped);
2500 g_free(status);
2501 g_free(escaped);
2502
2503 return ret;
2504 }
2505
2506 static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data)
2507 {
2508 GaimBuddy *buddy;
2509 GaimConnection *gc;
2510
2511 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2512
2513 buddy = (GaimBuddy *) node;
2514 gc = gaim_account_get_connection(buddy->account);
2515
2516 yahoo_add_buddy(gc, buddy, NULL);
2517 }
2518
2519
2520 static void yahoo_chat_goto_menu(GaimBlistNode *node, gpointer data)
2521 {
2522 GaimBuddy *buddy;
2523 GaimConnection *gc;
2524
2525 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2526
2527 buddy = (GaimBuddy *) node;
2528 gc = gaim_account_get_connection(buddy->account);
2529
2530 yahoo_chat_goto(gc, buddy->name);
2531 }
2532
2533
2534 static GList *yahoo_buddy_menu(GaimBuddy *buddy)
2535 {
2536 GList *m = NULL;
2537 GaimBlistNodeAction *act;
2538
2539 GaimConnection *gc = gaim_account_get_connection(buddy->account);
2540 struct yahoo_data *yd = gc->proto_data;
2541 static char buf2[1024];
2542 YahooFriend *f;
2543
2544 f = yahoo_friend_find(gc, buddy->name);
2545
2546 if (!f && !yd->wm) {
2547 act = gaim_blist_node_action_new(_("Add Buddy"),
2548 yahoo_addbuddyfrommenu_cb, NULL);
2549 m = g_list_append(m, act);
2550
2551 return m;
2552
2553 } else if (f->status == YAHOO_STATUS_OFFLINE) {
2554 return NULL;
2555 }
2556
2557 if (!yd->wm) {
2558 act = gaim_blist_node_action_new(_("Join in Chat"),
2559 yahoo_chat_goto_menu, NULL);
2560 m = g_list_append(m, act);
2561 }
2562
2563 act = gaim_blist_node_action_new(_("Initiate Conference"),
2564 yahoo_initiate_conference, NULL);
2565 m = g_list_append(m, act);
2566
2567 if (yahoo_friend_get_game(f)) {
2568 const char *game = yahoo_friend_get_game(f);
2569 char *room;
2570 char *t;
2571
2572 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */
2573 return m;
2574 while (*room && *room != '\t') /* skip to the tab */
2575 room++;
2576 t = room++; /* room as now at the name */
2577 while (*t != '\n')
2578 t++; /* replace the \n with a space */
2579 *t = ' ';
2580 g_snprintf(buf2, sizeof buf2, "%s", room);
2581
2582 act = gaim_blist_node_action_new(buf2, yahoo_game, NULL);
2583 m = g_list_append(m, act);
2584 }
2585
2586 return m;
2587 }
2588
2589
2590 static GList *yahoo_blist_node_menu(GaimBlistNode *node)
2591 {
2592 if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
2593 return yahoo_buddy_menu((GaimBuddy *) node);
2594 } else {
2595 return NULL;
2596 }
2597 }
2598
2599
2600 static void yahoo_act_id(GaimConnection *gc, const char *entry)
2601 {
2602 struct yahoo_data *yd = gc->proto_data;
2603
2604 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0);
2605 yahoo_packet_hash_str(pkt, 3, entry);
2606 yahoo_packet_send_and_free(pkt, yd);
2607
2608 gaim_connection_set_display_name(gc, entry);
2609 }
2610
2611 static void yahoo_show_act_id(GaimPluginAction *action)
2612 {
2613 GaimConnection *gc = (GaimConnection *) action->context;
2614 gaim_request_input(gc, NULL, _("Active which ID?"), NULL,
2615 gaim_connection_get_display_name(gc), FALSE, FALSE, NULL,
2616 _("OK"), G_CALLBACK(yahoo_act_id),
2617 _("Cancel"), NULL, gc);
2618 }
2619
2620 static void yahoo_show_chat_goto(GaimPluginAction *action)
2621 {
2622 GaimConnection *gc = (GaimConnection *) action->context;
2623 gaim_request_input(gc, NULL, _("Join who in chat?"), NULL,
2624 "", FALSE, FALSE, NULL,
2625 _("OK"), G_CALLBACK(yahoo_chat_goto),
2626 _("Cancel"), NULL, gc);
2627 }
2628
2629 static GList *yahoo_actions(GaimPlugin *plugin, gpointer context) {
2630 GList *m = NULL;
2631 GaimPluginAction *act;
2632
2633 act = gaim_plugin_action_new(_("Activate ID..."),
2634 yahoo_show_act_id);
2635 m = g_list_append(m, act);
2636
2637 act = gaim_plugin_action_new(_("Join user in chat..."),
2638 yahoo_show_chat_goto);
2639 m = g_list_append(m, act);
2640
2641 return m;
2642 }
2643
2644 static int yahoo_send_im(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags)
2645 {
2646 struct yahoo_data *yd = gc->proto_data;
2647 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0);
2648 char *msg = yahoo_html_to_codes(what);
2649 char *msg2;
2650 gboolean utf8 = TRUE;
2651 int ret = 1;
2652
2653 msg2 = yahoo_string_encode(gc, msg, &utf8);
2654
2655 yahoo_packet_hash(pkt, "ss", 1, gaim_connection_get_display_name(gc), 5, who);
2656 if (utf8)
2657 yahoo_packet_hash_str(pkt, 97, "1");
2658 yahoo_packet_hash_str(pkt, 14, msg2);
2659
2660 yahoo_packet_hash_str(pkt, 63, ";0"); /* IMvironment */
2661 yahoo_packet_hash_str(pkt, 64, "0"); /* no idea */
2662 yahoo_packet_hash_str(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */
2663 if (!yd->picture_url)
2664 yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */
2665 else
2666 yahoo_packet_hash_str(pkt, 206, "2");
2667
2668 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */
2669 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000)
2670 yahoo_packet_send(pkt, yd);
2671 else
2672 ret = -E2BIG;
2673
2674 yahoo_packet_free(pkt);
2675
2676 g_free(msg);
2677 g_free(msg2);
2678
2679 return ret;
2680 }
2681
2682 int yahoo_send_typing(GaimConnection *gc, const char *who, int typ)
2683 {
2684 struct yahoo_data *yd = gc->proto_data;
2685 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0);
2686 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, gaim_connection_get_display_name(gc),
2687 14, " ", 13, typ == GAIM_TYPING ? "1" : "0",
2688 5, who, 1002, "1");
2689
2690 yahoo_packet_send_and_free(pkt, yd);
2691
2692 return 0;
2693 }
2694
2695 static void yahoo_set_status(GaimAccount *account, GaimStatus *status)
2696 {
2697 GaimConnection *gc = gaim_account_get_connection(account);
2698 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;
2699 struct yahoo_packet *pkt;
2700 int old_status = yd->current_status;
2701 const char *id;
2702 char *conv_msg = NULL;
2703 char *conv_msg2 = NULL;
2704
2705 id = gaim_status_get_id(status);
2706
2707 if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE)) {
2708 yd->current_status = YAHOO_STATUS_AVAILABLE; 2238 yd->current_status = YAHOO_STATUS_AVAILABLE;
2709 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BRB)) { 2239 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BRB)) {
2710 yd->current_status = YAHOO_STATUS_BRB; 2240 yd->current_status = YAHOO_STATUS_BRB;
2711 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BUSY)) { 2241 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BUSY)) {
2712 yd->current_status = YAHOO_STATUS_BUSY; 2242 yd->current_status = YAHOO_STATUS_BUSY;
2734 yd->current_status = YAHOO_STATUS_IDLE; 2264 yd->current_status = YAHOO_STATUS_IDLE;
2735 } else { 2265 } else {
2736 gaim_debug_error("yahoo", "Unexpected GaimStatus passed to yahoo_set_status!\n"); 2266 gaim_debug_error("yahoo", "Unexpected GaimStatus passed to yahoo_set_status!\n");
2737 yd->current_status = YAHOO_STATUS_AVAILABLE; 2267 yd->current_status = YAHOO_STATUS_AVAILABLE;
2738 } 2268 }
2269 yahoo_server_check(account);
2270 yahoo_picture_check(account);
2271
2272 if (gaim_account_get_bool(account, "yahoojp", FALSE)) {
2273 yd->jp = TRUE;
2274 if (gaim_proxy_connect(account,
2275 gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST),
2276 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),
2277 yahoo_got_connected, gc) != 0)
2278 {
2279 gaim_connection_error(gc, _("Connection problem"));
2280 return;
2281 }
2282 } else {
2283 yd->jp = FALSE;
2284 if (gaim_proxy_connect(account,
2285 gaim_account_get_string(account, "server", YAHOO_PAGER_HOST),
2286 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),
2287 yahoo_got_connected, gc) != 0)
2288 {
2289 gaim_connection_error(gc, _("Connection problem"));
2290 return;
2291 }
2292 }
2293
2294
2295 }
2296
2297 static void yahoo_close(GaimConnection *gc) {
2298 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;
2299 GSList *l;
2300
2301 for (l = yd->confs; l; l = l->next) {
2302 GaimConversation *conv = l->data;
2303
2304 yahoo_conf_leave(yd, gaim_conversation_get_name(conv),
2305 gaim_connection_get_display_name(gc),
2306 gaim_conv_chat_get_users(GAIM_CONV_CHAT(conv)));
2307 }
2308 g_slist_free(yd->confs);
2309
2310 g_hash_table_destroy(yd->friends);
2311 if (yd->chat_name)
2312 g_free(yd->chat_name);
2313
2314 if (yd->cookie_y)
2315 g_free(yd->cookie_y);
2316 if (yd->cookie_t)
2317 g_free(yd->cookie_t);
2318
2319 if (yd->fd >= 0)
2320 close(yd->fd);
2321
2322 if (yd->rxqueue)
2323 g_free(yd->rxqueue);
2324 yd->rxlen = 0;
2325 if (yd->picture_url)
2326 g_free(yd->picture_url);
2327 if (yd->picture_upload_todo)
2328 yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo);
2329 if (yd->ycht)
2330 ycht_connection_close(yd->ycht);
2331 if (gc->inpa)
2332 gaim_input_remove(gc->inpa);
2333 g_free(yd);
2334 }
2335
2336 static const char *yahoo_list_icon(GaimAccount *a, GaimBuddy *b)
2337 {
2338 return "yahoo";
2339 }
2340
2341 static void yahoo_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
2342 {
2343 int i = 0;
2344 char *emblems[4] = {NULL,NULL,NULL,NULL};
2345 GaimAccount *account;
2346 GaimConnection *gc;
2347 struct yahoo_data *yd;
2348 YahooFriend *f;
2349 GaimPresence *presence;
2350 GaimStatus *status;
2351 const char *status_id;
2352
2353 if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) ||
2354 !(yd = gc->proto_data))
2355 return;
2356
2357 f = yahoo_friend_find(gc, b->name);
2358 if (!f) {
2359 *se = "notauthorized";
2360 return;
2361 }
2362
2363 presence = gaim_buddy_get_presence(b);
2364 status = gaim_presence_get_active_status(presence);
2365 status_id = gaim_status_get_id(status);
2366
2367 if (gaim_presence_is_online(presence) == FALSE) {
2368 *se = "offline";
2369 return;
2370 } else {
2371 if (f->away)
2372 emblems[i++] = "away";
2373 if (f->sms)
2374 emblems[i++] = "wireless";
2375 if (yahoo_friend_get_game(f))
2376 emblems[i++] = "game";
2377 }
2378 *se = emblems[0];
2379 *sw = emblems[1];
2380 *nw = emblems[2];
2381 *ne = emblems[3];
2382 }
2383
2384 static char *yahoo_get_status_string(enum yahoo_status a)
2385 {
2386 switch (a) {
2387 case YAHOO_STATUS_BRB:
2388 return _("Be Right Back");
2389 case YAHOO_STATUS_BUSY:
2390 return _("Busy");
2391 case YAHOO_STATUS_NOTATHOME:
2392 return _("Not At Home");
2393 case YAHOO_STATUS_NOTATDESK:
2394 return _("Not At Desk");
2395 case YAHOO_STATUS_NOTINOFFICE:
2396 return _("Not In Office");
2397 case YAHOO_STATUS_ONPHONE:
2398 return _("On The Phone");
2399 case YAHOO_STATUS_ONVACATION:
2400 return _("On Vacation");
2401 case YAHOO_STATUS_OUTTOLUNCH:
2402 return _("Out To Lunch");
2403 case YAHOO_STATUS_STEPPEDOUT:
2404 return _("Stepped Out");
2405 case YAHOO_STATUS_INVISIBLE:
2406 return _("Invisible");
2407 case YAHOO_STATUS_IDLE:
2408 return _("Idle");
2409 case YAHOO_STATUS_OFFLINE:
2410 return _("Offline");
2411 default:
2412 return _("Online");
2413 }
2414 }
2415
2416 static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) {
2417
2418 GaimBuddy *buddy;
2419 GaimConnection *gc;
2420
2421 GHashTable *components;
2422 struct yahoo_data *yd;
2423 int id;
2424
2425 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2426
2427 buddy = (GaimBuddy *) node;
2428 gc = gaim_account_get_connection(buddy->account);
2429 yd = gc->proto_data;
2430 id = yd->conf_id;
2431
2432 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
2433 g_hash_table_replace(components, g_strdup("room"),
2434 g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id));
2435 g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference..."));
2436 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
2437 yahoo_c_join(gc, components);
2438 g_hash_table_destroy(components);
2439
2440 yahoo_c_invite(gc, id, "Join my conference...", buddy->name);
2441 }
2442
2443 static void yahoo_game(GaimBlistNode *node, gpointer data) {
2444
2445 GaimBuddy *buddy;
2446 GaimConnection *gc;
2447
2448 struct yahoo_data *yd;
2449 const char *game;
2450 char *game2;
2451 char *t;
2452 char url[256];
2453 YahooFriend *f;
2454
2455 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2456
2457 buddy = (GaimBuddy *) node;
2458 gc = gaim_account_get_connection(buddy->account);
2459 yd = (struct yahoo_data *) gc->proto_data;
2460
2461 f = yahoo_friend_find(gc, buddy->name);
2462 if (!f)
2463 return;
2464
2465 game = yahoo_friend_get_game(f);
2466 if (!game)
2467 return;
2468
2469 t = game2 = g_strdup(strstr(game, "ante?room="));
2470 while (*t && *t != '\t')
2471 t++;
2472 *t = 0;
2473 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2);
2474 gaim_notify_uri(gc, url);
2475 g_free(game2);
2476 }
2477
2478 static char *yahoo_status_text(GaimBuddy *b)
2479 {
2480 YahooFriend *f = NULL;
2481 const char *msg;
2482
2483 f = yahoo_friend_find(b->account->gc, b->name);
2484 if (!f)
2485 return g_strdup(_("Not on server list"));
2486
2487 switch (f->status) {
2488 case YAHOO_STATUS_AVAILABLE:
2489 return NULL;
2490 case YAHOO_STATUS_IDLE:
2491 if (f->idle == -1)
2492 return g_strdup(yahoo_get_status_string(f->status));
2493 return NULL;
2494 case YAHOO_STATUS_CUSTOM:
2495 if (!(msg = yahoo_friend_get_status_message(f)))
2496 return NULL;
2497 return g_markup_escape_text(msg, strlen(msg));
2498
2499 default:
2500 return g_strdup(yahoo_get_status_string(f->status));
2501 }
2502 }
2503
2504 char *yahoo_tooltip_text(GaimBuddy *b)
2505 {
2506 YahooFriend *f;
2507 char *escaped, *status, *ret;
2508
2509 f = yahoo_friend_find(b->account->gc, b->name);
2510 if (!f)
2511 status = g_strdup_printf("\n%s", _("Not on server list"));
2512 else
2513 switch (f->status) {
2514 case YAHOO_STATUS_IDLE:
2515 if (f->idle == -1) {
2516 status = g_strdup(yahoo_get_status_string(f->status));
2517 break;
2518 }
2519 return NULL;
2520 case YAHOO_STATUS_CUSTOM:
2521 if (!yahoo_friend_get_status_message(f))
2522 return NULL;
2523 status = g_strdup(yahoo_friend_get_status_message(f));
2524 break;
2525 default:
2526 status = g_strdup(yahoo_get_status_string(f->status));
2527 break;
2528 }
2529
2530 escaped = g_markup_escape_text(status, strlen(status));
2531 ret = g_strdup_printf(_("\n<b>%s:</b> %s"), _("Status"), escaped);
2532 g_free(status);
2533 g_free(escaped);
2534
2535 return ret;
2536 }
2537
2538 static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data)
2539 {
2540 GaimBuddy *buddy;
2541 GaimConnection *gc;
2542
2543 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2544
2545 buddy = (GaimBuddy *) node;
2546 gc = gaim_account_get_connection(buddy->account);
2547
2548 yahoo_add_buddy(gc, buddy, NULL);
2549 }
2550
2551
2552 static void yahoo_chat_goto_menu(GaimBlistNode *node, gpointer data)
2553 {
2554 GaimBuddy *buddy;
2555 GaimConnection *gc;
2556
2557 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));
2558
2559 buddy = (GaimBuddy *) node;
2560 gc = gaim_account_get_connection(buddy->account);
2561
2562 yahoo_chat_goto(gc, buddy->name);
2563 }
2564
2565
2566 static GList *yahoo_buddy_menu(GaimBuddy *buddy)
2567 {
2568 GList *m = NULL;
2569 GaimBlistNodeAction *act;
2570
2571 GaimConnection *gc = gaim_account_get_connection(buddy->account);
2572 struct yahoo_data *yd = gc->proto_data;
2573 static char buf2[1024];
2574 YahooFriend *f;
2575
2576 f = yahoo_friend_find(gc, buddy->name);
2577
2578 if (!f && !yd->wm) {
2579 act = gaim_blist_node_action_new(_("Add Buddy"),
2580 yahoo_addbuddyfrommenu_cb, NULL);
2581 m = g_list_append(m, act);
2582
2583 return m;
2584
2585 } else if (f->status == YAHOO_STATUS_OFFLINE) {
2586 return NULL;
2587 }
2588
2589 if (!yd->wm) {
2590 act = gaim_blist_node_action_new(_("Join in Chat"),
2591 yahoo_chat_goto_menu, NULL);
2592 m = g_list_append(m, act);
2593 }
2594
2595 act = gaim_blist_node_action_new(_("Initiate Conference"),
2596 yahoo_initiate_conference, NULL);
2597 m = g_list_append(m, act);
2598
2599 if (yahoo_friend_get_game(f)) {
2600 const char *game = yahoo_friend_get_game(f);
2601 char *room;
2602 char *t;
2603
2604 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */
2605 return m;
2606 while (*room && *room != '\t') /* skip to the tab */
2607 room++;
2608 t = room++; /* room as now at the name */
2609 while (*t != '\n')
2610 t++; /* replace the \n with a space */
2611 *t = ' ';
2612 g_snprintf(buf2, sizeof buf2, "%s", room);
2613
2614 act = gaim_blist_node_action_new(buf2, yahoo_game, NULL);
2615 m = g_list_append(m, act);
2616 }
2617
2618 return m;
2619 }
2620
2621
2622 static GList *yahoo_blist_node_menu(GaimBlistNode *node)
2623 {
2624 if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
2625 return yahoo_buddy_menu((GaimBuddy *) node);
2626 } else {
2627 return NULL;
2628 }
2629 }
2630
2631
2632 static void yahoo_act_id(GaimConnection *gc, const char *entry)
2633 {
2634 struct yahoo_data *yd = gc->proto_data;
2635
2636 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0);
2637 yahoo_packet_hash_str(pkt, 3, entry);
2638 yahoo_packet_send_and_free(pkt, yd);
2639
2640 gaim_connection_set_display_name(gc, entry);
2641 }
2642
2643 static void yahoo_show_act_id(GaimPluginAction *action)
2644 {
2645 GaimConnection *gc = (GaimConnection *) action->context;
2646 gaim_request_input(gc, NULL, _("Active which ID?"), NULL,
2647 gaim_connection_get_display_name(gc), FALSE, FALSE, NULL,
2648 _("OK"), G_CALLBACK(yahoo_act_id),
2649 _("Cancel"), NULL, gc);
2650 }
2651
2652 static void yahoo_show_chat_goto(GaimPluginAction *action)
2653 {
2654 GaimConnection *gc = (GaimConnection *) action->context;
2655 gaim_request_input(gc, NULL, _("Join who in chat?"), NULL,
2656 "", FALSE, FALSE, NULL,
2657 _("OK"), G_CALLBACK(yahoo_chat_goto),
2658 _("Cancel"), NULL, gc);
2659 }
2660
2661 static GList *yahoo_actions(GaimPlugin *plugin, gpointer context) {
2662 GList *m = NULL;
2663 GaimPluginAction *act;
2664
2665 act = gaim_plugin_action_new(_("Activate ID..."),
2666 yahoo_show_act_id);
2667 m = g_list_append(m, act);
2668
2669 act = gaim_plugin_action_new(_("Join user in chat..."),
2670 yahoo_show_chat_goto);
2671 m = g_list_append(m, act);
2672
2673 return m;
2674 }
2675
2676 static int yahoo_send_im(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags)
2677 {
2678 struct yahoo_data *yd = gc->proto_data;
2679 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0);
2680 char *msg = yahoo_html_to_codes(what);
2681 char *msg2;
2682 gboolean utf8 = TRUE;
2683 int ret = 1;
2684
2685 msg2 = yahoo_string_encode(gc, msg, &utf8);
2686
2687 yahoo_packet_hash(pkt, "ss", 1, gaim_connection_get_display_name(gc), 5, who);
2688 if (utf8)
2689 yahoo_packet_hash_str(pkt, 97, "1");
2690 yahoo_packet_hash_str(pkt, 14, msg2);
2691
2692 yahoo_packet_hash_str(pkt, 63, ";0"); /* IMvironment */
2693 yahoo_packet_hash_str(pkt, 64, "0"); /* no idea */
2694 yahoo_packet_hash_str(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */
2695 if (!yd->picture_url)
2696 yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */
2697 else
2698 yahoo_packet_hash_str(pkt, 206, "2");
2699
2700 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */
2701 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000)
2702 yahoo_packet_send(pkt, yd);
2703 else
2704 ret = -E2BIG;
2705
2706 yahoo_packet_free(pkt);
2707
2708 g_free(msg);
2709 g_free(msg2);
2710
2711 return ret;
2712 }
2713
2714 int yahoo_send_typing(GaimConnection *gc, const char *who, int typ)
2715 {
2716 struct yahoo_data *yd = gc->proto_data;
2717 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0);
2718 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, gaim_connection_get_display_name(gc),
2719 14, " ", 13, typ == GAIM_TYPING ? "1" : "0",
2720 5, who, 1002, "1");
2721
2722 yahoo_packet_send_and_free(pkt, yd);
2723
2724 return 0;
2725 }
2726
2727 static void yahoo_set_status(GaimAccount *account, GaimStatus *status)
2728 {
2729 GaimConnection *gc = gaim_account_get_connection(account);
2730 struct yahoo_data *yd;
2731 struct yahoo_packet *pkt;
2732 int old_status;
2733 const char *id;
2734 char *conv_msg = NULL;
2735 char *conv_msg2 = NULL;
2736
2737 id = gaim_status_get_id(status);
2738 if (!gaim_status_is_active(status))
2739 return;
2740 if (strcmp(id, YAHOO_STATUS_TYPE_OFFLINE) && !gc) {
2741 gaim_account_connect(account, status);
2742 return;
2743 } else if (!strcmp(id, YAHOO_STATUS_TYPE_OFFLINE) && gc) {
2744 gaim_account_disconnect(account);
2745 return;
2746 }
2747
2748 yd = (struct yahoo_data *)gc->proto_data;
2749 old_status = yd->current_status;
2750
2751 if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE)) {
2752 yd->current_status = YAHOO_STATUS_AVAILABLE;
2753 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BRB)) {
2754 yd->current_status = YAHOO_STATUS_BRB;
2755 } else if (!strcmp(id, YAHOO_STATUS_TYPE_BUSY)) {
2756 yd->current_status = YAHOO_STATUS_BUSY;
2757 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTATHOME)) {
2758 yd->current_status = YAHOO_STATUS_NOTATHOME;
2759 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTATDESK)) {
2760 yd->current_status = YAHOO_STATUS_NOTATDESK;
2761 } else if (!strcmp(id, YAHOO_STATUS_TYPE_NOTINOFFICE)) {
2762 yd->current_status = YAHOO_STATUS_NOTINOFFICE;
2763 } else if (!strcmp(id, YAHOO_STATUS_TYPE_ONPHONE)) {
2764 yd->current_status = YAHOO_STATUS_ONPHONE;
2765 } else if (!strcmp(id, YAHOO_STATUS_TYPE_ONVACATION)) {
2766 yd->current_status = YAHOO_STATUS_ONVACATION;
2767 } else if (!strcmp(id, YAHOO_STATUS_TYPE_OUTTOLUNCH)) {
2768 yd->current_status = YAHOO_STATUS_OUTTOLUNCH;
2769 } else if (!strcmp(id, YAHOO_STATUS_TYPE_STEPPEDOUT)) {
2770 yd->current_status = YAHOO_STATUS_STEPPEDOUT;
2771 } else if (!strcmp(id, YAHOO_STATUS_TYPE_INVISIBLE)) {
2772 yd->current_status = YAHOO_STATUS_INVISIBLE;
2773 } else if (!strcmp(id, YAHOO_STATUS_TYPE_AWAY)) {
2774 yd->current_status = YAHOO_STATUS_CUSTOM;
2775 } else if (!strcmp(id, YAHOO_STATUS_TYPE_AVAILABLE_WM)) {
2776 yd->current_status = YAHOO_STATUS_CUSTOM;
2777 } else if (gc->is_idle) { /* i think this is broken */
2778 yd->current_status = YAHOO_STATUS_IDLE;
2779 } else {
2780 gaim_debug_error("yahoo", "Unexpected GaimStatus passed to yahoo_login!\n");
2781 yd->current_status = YAHOO_STATUS_AVAILABLE;
2782 }
2739 2783
2740 if (yd->current_status == YAHOO_STATUS_INVISIBLE) { 2784 if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
2741 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0); 2785 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0);
2742 yahoo_packet_hash_str(pkt, 13, "2"); 2786 yahoo_packet_hash_str(pkt, 13, "2");
2743 yahoo_packet_send_and_free(pkt, yd); 2787 yahoo_packet_send_and_free(pkt, yd);
2825 GList *types = NULL; 2869 GList *types = NULL;
2826 2870
2827 if (gc) 2871 if (gc)
2828 yd = gc->proto_data; 2872 yd = gc->proto_data;
2829 2873
2830 type = gaim_status_type_new(GAIM_STATUS_OFFLINE, YAHOO_STATUS_TYPE_OFFLINE, _("Offline"), FALSE); 2874 type = gaim_status_type_new(GAIM_STATUS_OFFLINE, YAHOO_STATUS_TYPE_OFFLINE, _("Offline"), TRUE);
2831 types = g_list_append(types, type); 2875 types = g_list_append(types, type);
2832 2876
2833 type = gaim_status_type_new(GAIM_STATUS_ONLINE, YAHOO_STATUS_TYPE_ONLINE, _("Online"), FALSE); 2877 type = gaim_status_type_new(GAIM_STATUS_ONLINE, YAHOO_STATUS_TYPE_ONLINE, _("Online"), TRUE);
2834 types = g_list_append(types, type); 2878 types = g_list_append(types, type);
2835 2879
2836 type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE, _("Available"), TRUE); 2880 type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE, _("Available"), TRUE);
2837 types = g_list_append(types, type); 2881 types = g_list_append(types, type);
2838 2882