📄 yahoo.c
字号:
onlist = 1; break; } } if (!onlist) { gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group); if (!(g = gaim_find_group(group))) { g = gaim_group_new(group); gaim_blist_add_group(g, NULL); } b = gaim_buddy_new(account, name, NULL); gaim_blist_add_buddy(b, NULL, g, NULL); } if (list) { if (!oname) oname = g_strdup(gaim_normalize(account, name)); g_hash_table_insert(ht, oname, list); } else if (oname) g_free(oname);}static void yahoo_do_group_cleanup(gpointer key, gpointer value, gpointer user_data){ char *name = key; GSList *list = value, *i; GaimBuddy *b; GaimGroup *g; for (i = list; i; i = i->next) { b = i->data; g = gaim_find_buddys_group(b); gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Deleting Buddy %s from group %s.\n", name, g->name); gaim_blist_remove_buddy(b); }}static char *_getcookie(char *rawcookie){ char *cookie = NULL; char *tmpcookie; char *cookieend; if (strlen(rawcookie) < 2) return NULL; tmpcookie = g_strdup(rawcookie+2); cookieend = strchr(tmpcookie, ';'); if (cookieend) *cookieend = '\0'; cookie = g_strdup(tmpcookie); g_free(tmpcookie); return cookie;}static void yahoo_process_cookie(struct yahoo_data *yd, char *c){ if (c[0] == 'Y') { if (yd->cookie_y) g_free(yd->cookie_y); yd->cookie_y = _getcookie(c); } else if (c[0] == 'T') { if (yd->cookie_t) g_free(yd->cookie_t); yd->cookie_t = _getcookie(c); }}static void yahoo_process_list(GaimConnection *gc, struct yahoo_packet *pkt){ GSList *l = pkt->hash; gboolean export = FALSE; gboolean got_serv_list = FALSE; GaimBuddy *b; GaimGroup *g; YahooFriend *f = NULL; GaimAccount *account = gaim_connection_get_account(gc); struct yahoo_data *yd = gc->proto_data; GHashTable *ht; char **lines; char **split; char **buddies; char **tmp, **bud, *norm_bud; char *grp = NULL; if (pkt->id) yd->session_id = pkt->id; while (l) { struct yahoo_pair *pair = l->data; l = l->next; switch (pair->key) { case 87: if (!yd->tmp_serv_blist) yd->tmp_serv_blist = g_string_new(pair->value); else g_string_append(yd->tmp_serv_blist, pair->value); break; case 88: if (!yd->tmp_serv_ilist) yd->tmp_serv_ilist = g_string_new(pair->value); else g_string_append(yd->tmp_serv_ilist, pair->value); break; case 59: /* cookies, yum */ yahoo_process_cookie(yd, pair->value); break; } } if (pkt->status != 0) return; if (yd->tmp_serv_blist) { ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); lines = g_strsplit(yd->tmp_serv_blist->str, "\n", -1); for (tmp = lines; *tmp; tmp++) { split = g_strsplit(*tmp, ":", 2); if (!split) continue; if (!split[0] || !split[1]) { g_strfreev(split); continue; } grp = yahoo_string_decode(gc, split[0], FALSE); buddies = g_strsplit(split[1], ",", -1); for (bud = buddies; bud && *bud; bud++) { norm_bud = g_strdup(gaim_normalize(account, *bud)); f = yahoo_friend_find_or_new(gc, norm_bud); if (!(b = gaim_find_buddy(account, norm_bud))) { if (!(g = gaim_find_group(grp))) { g = gaim_group_new(grp); gaim_blist_add_group(g, NULL); } b = gaim_buddy_new(account, norm_bud, NULL); gaim_blist_add_buddy(b, NULL, g, NULL); export = TRUE; } yahoo_do_group_check(account, ht, norm_bud, grp); g_free(norm_bud); } g_strfreev(buddies); g_strfreev(split); g_free(grp); } g_strfreev(lines); g_string_free(yd->tmp_serv_blist, TRUE); yd->tmp_serv_blist = NULL; g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); g_hash_table_destroy(ht); } if (yd->tmp_serv_ilist) { buddies = g_strsplit(yd->tmp_serv_ilist->str, ",", -1); for (bud = buddies; bud && *bud; bud++) { /* The server is already ignoring the user */ got_serv_list = TRUE; gaim_privacy_deny_add(gc->account, *bud, 1); } g_strfreev(buddies); g_string_free(yd->tmp_serv_ilist, TRUE); yd->tmp_serv_ilist = NULL; } if (got_serv_list) { gc->account->perm_deny = 4; serv_set_permit_deny(gc); }}static void yahoo_process_notify(GaimConnection *gc, struct yahoo_packet *pkt){ char *msg = NULL; char *from = NULL; char *stat = NULL; char *game = NULL; YahooFriend *f = NULL; GSList *l = pkt->hash; while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 4) from = pair->value; if (pair->key == 49) msg = pair->value; if (pair->key == 13) stat = pair->value; if (pair->key == 14) game = pair->value; l = l->next; } if (!from || !msg) return; if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))) { if (*stat == '1') serv_got_typing(gc, from, 0, GAIM_TYPING); else serv_got_typing_stopped(gc, from); } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { GaimBuddy *bud = gaim_find_buddy(gc->account, from); if (!bud) { gaim_debug(GAIM_DEBUG_WARNING, "yahoo", "%s is playing a game, and doesn't want " "you to know.\n", from); } f = yahoo_friend_find(gc, from); if (!f) return; /* if they're not on the list, don't bother */ yahoo_friend_set_game(f, NULL); if (*stat == '1') { yahoo_friend_set_game(f, game); if (bud) yahoo_update_status(gc, from, f); } }}struct _yahoo_im { char *from; int time; int utf8; int buddy_icon; char *msg;};static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt){ GSList *l = pkt->hash; GSList *list = NULL; struct _yahoo_im *im = NULL; if (pkt->status <= 1 || pkt->status == 5) { while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 4) { im = g_new0(struct _yahoo_im, 1); list = g_slist_append(list, im); im->from = pair->value; im->time = time(NULL); } if (pair->key == 97) if (im) im->utf8 = strtol(pair->value, NULL, 10); if (pair->key == 15) if (im) im->time = strtol(pair->value, NULL, 10); if (pair->key == 206) if (im) im->buddy_icon = strtol(pair->value, NULL, 10); if (pair->key == 14) { if (im) im->msg = pair->value; } l = l->next; } } else if (pkt->status == 2) { gaim_notify_error(gc, NULL, _("Your Yahoo! message did not get sent."), NULL); } for (l = list; l; l = l->next) { YahooFriend *f; char *m, *m2; im = l->data; if (!im->from || !im->msg) { g_free(im); continue; } m = yahoo_string_decode(gc, im->msg, im->utf8); gaim_str_strip_cr(m); if (!strcmp(m, "<ding>")) { GaimConversation *c = gaim_conversation_new(GAIM_CONV_IM, gaim_connection_get_account(gc), im->from); gaim_conv_im_write(GAIM_CONV_IM(c), "", _("Buzz!!"), GAIM_MESSAGE_NICK|GAIM_MESSAGE_RECV, im->time); g_free(m); g_free(im); continue; } m2 = yahoo_codes_to_html(m); g_free(m); serv_got_im(gc, im->from, m2, 0, im->time); g_free(m2); if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { if (yahoo_friend_get_buddy_icon_need_request(f)) { yahoo_send_picture_request(gc, im->from); yahoo_friend_set_buddy_icon_need_request(f, FALSE); } } g_free(im); } g_slist_free(list);}static void yahoo_process_sysmessage(GaimConnection *gc, struct yahoo_packet *pkt){ GSList *l = pkt->hash; char *prim, *me = NULL, *msg = NULL, *escmsg = NULL; while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 5) me = pair->value; if (pair->key == 14) msg = pair->value; l = l->next; } if (!msg || !g_utf8_validate(msg, -1, NULL)) return; escmsg = gaim_escape_html(msg); prim = g_strdup_printf(_("Yahoo! system message for %s:"), me?me:gaim_connection_get_display_name(gc)); gaim_notify_info(NULL, NULL, prim, escmsg); g_free(prim); g_free(escmsg);}static void yahoo_buddy_added_us(GaimConnection *gc, struct yahoo_packet *pkt) { char *id = NULL; char *who = NULL; char *msg = NULL, *tmpmsg = NULL; GSList *l = pkt->hash; while (l) { struct yahoo_pair *pair = l->data; switch (pair->key) { case 1: id = pair->value; break; case 3: who = pair->value; break; case 15: /* time, for when they add us and we're offline */ break; case 14: msg = pair->value; break; } l = l->next; } if (id) { if (msg) tmpmsg = yahoo_string_decode(gc, msg, FALSE); gaim_account_notify_added(gc->account, id, who, NULL, tmpmsg); if (tmpmsg) g_free(tmpmsg); }}static void yahoo_buddy_denied_our_add(GaimConnection *gc, struct yahoo_packet *pkt){ char *who = NULL; char *msg = NULL; GSList *l = pkt->hash; GString *buf = NULL; struct yahoo_data *yd = gc->proto_data; while (l) { struct yahoo_pair *pair = l->data; switch (pair->key) { case 3: who = pair->value; break; case 14: msg = pair->value; break; } l = l->next; } if (who) { char *msg2; buf = g_string_sized_new(0); if (!msg) { g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list."), who); } else { msg2 = yahoo_string_decode(gc, msg, FALSE); g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2); g_free(msg2); } gaim_notify_info(gc, NULL, _("Add buddy rejected"), buf->str); g_string_free(buf, TRUE); g_hash_table_remove(yd->friends, who); serv_got_update(gc, who, FALSE, 0, 0, 0, 0); }}static void yahoo_process_contact(GaimConnection *gc, struct yahoo_packet *pkt){ switch (pkt->status) { case 1: yahoo_process_status(gc, pkt); return; case 3: yahoo_buddy_added_us(gc, pkt); break; case 7: yahoo_buddy_denied_our_add(gc, pkt); break; default: break; }}#define OUT_CHARSET "utf-8"static char *yahoo_decode(const char *text){ char *converted = NULL; char *n, *new; const char *end, *p; int i, k; n = new = g_malloc(strlen (text) + 1); end = text + strlen(text); for (p = text; p < end; p++, n++) { if (*p == '\\') { if (p[1] >= '0' && p[1] <= '7') { p += 1; for (i = 0, k = 0; k < 3; k += 1) { char c = p[k]; if (c < '0' || c > '7') break; i *= 8; i += c - '0'; } *n = i; p += k - 1; } else { /* bug 959248 */ /* If we see a \ not followed by an octal number, * it means that it is actually a \\ with one \ * already eaten by some unknown function. * This is arguably broken. * * I think wing is wrong here, there is no function * called that I see that could have done it. I guess * it is just really sending single \'s. That's yahoo * for you. */ *n = *p; } } else *n = *p; } *n = '\0'; if (strstr(text, "\033$B")) converted = g_convert(new, n - new, OUT_CHARSET, "iso-2022-jp", NULL, NULL, NULL); if (!converted) converted = g_convert(new, n - new, OUT_CHARSET, "iso-8859-1", NULL, NULL, NULL); g_free(new); return converted;}static void yahoo_process_mail(GaimConnection *gc, struct yahoo_packet *pkt){ GaimAccount *account = gaim_connection_get_account(gc); struct yahoo_data *yd = gc->proto_data; char *who = NULL; char *email = NULL; char *subj = NULL; char *yahoo_mail_url = (yd->jp? YAHOOJP_MAIL_URL: YAHOO_MAIL_URL); int count = 0; GSList *l = pkt->hash; if (!gaim_account_get_check_mail(account)) return; while (l) { struct yahoo_pair *pair = l->data; if (pair->key == 9) count = strtol(pair->value, NULL, 10); else if (pair->key == 43) who = pair->value; else if (pair->key == 42) email = pair->value; else if (pair->key == 18) subj = pair->value; l = l->next; } if (who && subj && email && *email) { char *dec_who = yahoo_decode(who); char *dec_subj = yahoo_decode(subj); char *from = g_strdup_printf("%s (%s)", dec_who, email); gaim_notify_email(gc, dec_subj, from, gaim_account_get_username(account), yahoo_mail_url, NULL, NULL); g_free(dec_who); g_free(dec_subj); g_free(from); } else if (count > 0) { const char *to = gaim_account_get_username(account); const char *url = yahoo_mail_url; gaim_notify_emails(gc, count, FALSE, NULL, NULL, &to, &url, NULL, NULL); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -