⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yahoo.c

📁 yahoo message protocol stack
💻 C
📖 第 1 页 / 共 5 页
字号:
			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 + -