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

📄 yahoo.c

📁 yahoo message protocol stack
💻 C
📖 第 1 页 / 共 5 页
字号:
	while (1) {		struct yahoo_packet *pkt;		int pos = 0;		int pktlen;		if (yd->rxlen < YAHOO_PACKET_HDRLEN)			return;		pos += 4; /* YMSG */		pos += 2;		pos += 2;		pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2;		gaim_debug(GAIM_DEBUG_MISC, "yahoo",				   "%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen);		if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen))			return;		yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen);		pkt = yahoo_packet_new(0, 0, 0);		pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2;		pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4;		gaim_debug(GAIM_DEBUG_MISC, "yahoo",				   "Yahoo Service: 0x%02x Status: %d\n",				   pkt->service, pkt->status);		pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4;		yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen);		yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen;		if (yd->rxlen) {			char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen);			g_free(yd->rxqueue);			yd->rxqueue = tmp;		} else {			g_free(yd->rxqueue);			yd->rxqueue = NULL;		}		yahoo_packet_process(gc, pkt);		yahoo_packet_free(pkt);	}}static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond){	GaimConnection *gc = data;	struct yahoo_data *yd;	struct yahoo_packet *pkt;	if (!g_list_find(gaim_connections_get_all(), gc)) {		close(source);		return;	}	if (source < 0) {		gaim_connection_error(gc, _("Unable to connect."));		return;	}	yd = gc->proto_data;	yd->fd = source;	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0);	yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))));	yahoo_send_packet(yd, pkt);	yahoo_packet_free(pkt);	gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc);}static void yahoo_got_web_connected(gpointer data, gint source, GaimInputCondition cond){	GaimConnection *gc = data;	struct yahoo_data *yd;	struct yahoo_packet *pkt;	if (!g_list_find(gaim_connections_get_all(), gc)) {		close(source);		return;	}	if (source < 0) {		gaim_connection_error(gc, _("Unable to connect."));		return;	}	yd = gc->proto_data;	yd->fd = source;	pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, 0);	yahoo_packet_hash(pkt, 0, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))));	yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc))));	yahoo_packet_hash(pkt, 6, yd->auth);	yahoo_send_packet(yd, pkt);	yahoo_packet_free(pkt);	g_free(yd->auth);	gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc);}static void yahoo_web_pending(gpointer data, gint source, GaimInputCondition cond){	GaimConnection *gc = data;	GaimAccount *account = gaim_connection_get_account(gc);	struct yahoo_data *yd = gc->proto_data;	char buf[2048], *i = buf;	int len;	GString *s;	len = read(source, buf, sizeof(buf)-1);	if (len <= 0  || (strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) &&			  strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) {		gaim_connection_error(gc, _("Unable to read"));		return;	}	s = g_string_sized_new(len);	buf[sizeof(buf)-1] = '\0';	while ((i = strstr(i, "Set-Cookie: "))) {		i += strlen("Set-Cookie: ");		for (;*i != ';' && *i != '\0'; i++)			g_string_append_c(s, *i);		g_string_append(s, "; ");	}	yd->auth = g_string_free(s, FALSE);	gaim_input_remove(gc->inpa);	close(source);	/* Now we have our cookies to login with.  I'll go get the milk. */	if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com",			       gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),			       yahoo_got_web_connected, gc) != 0) {		gaim_connection_error(gc, _("Connection problem"));		return;	}	}static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond){	GaimConnection *gc = data;	struct yahoo_data *yd = gc->proto_data;	if (source < 0) {		gaim_connection_error(gc, _("Unable to connect."));		return;	}	write(source, yd->auth, strlen(yd->auth));	g_free(yd->auth);	gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc);}static void yahoo_login_page_hash_iter(const char *key, const char *val, GString *url){	if (!strcmp(key, "passwd"))		return;	url = g_string_append_c(url, '&');	url = g_string_append(url, key);	url = g_string_append_c(url, '=');	if (!strcmp(key, ".save") || !strcmp(key, ".js"))		url = g_string_append_c(url, '1');	else if (!strcmp(key, ".challenge"))		url = g_string_append(url, val);	else		url = g_string_append(url, gaim_url_encode(val));}static GHashTable *yahoo_login_page_hash(const char *buf, size_t len){	GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);	const char *c = buf;	char *d;	char name[64], value[64];	int count = sizeof(name)-1;	while ((c < (buf + len)) && (c = strstr(c, "<input "))) {		c = strstr(c, "name=\"") + strlen("name=\"");		for (d = name; *c!='"' && count; c++, d++, count--) 			*d = *c;		*d = '\0';		count = sizeof(value)-1;		d = strstr(c, "value=\"") + strlen("value=\"");		if (strchr(c, '>') < d)			break;		for (c = d, d = value; *c!='"' && count; c++, d++, count--)			*d = *c;		*d = '\0';		g_hash_table_insert(hash, g_strdup(name), g_strdup(value));	}	return hash;}static void yahoo_login_page_cb(void *user_data, const char *buf, size_t len){	GaimConnection *gc = (GaimConnection *)user_data;	GaimAccount *account = gaim_connection_get_account(gc);	struct yahoo_data *yd = gc->proto_data;	const char *sn = gaim_account_get_username(account);	const char *pass = gaim_account_get_password(account);	GHashTable *hash = yahoo_login_page_hash(buf, len);	GString *url = g_string_new("GET /config/login?login=");	char md5[33], *hashp = md5, *chal;	int i;	md5_byte_t result[16];	md5_state_t ctx;	url = g_string_append(url, sn);	url = g_string_append(url, "&passwd=");	md5_init(&ctx);	md5_append(&ctx, pass, strlen(pass));	md5_finish(&ctx, result);	for (i = 0; i < 16; ++i) {		g_snprintf(hashp, 3, "%02x", result[i]);		hashp += 2;	}	chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL);	md5_init(&ctx);	md5_append(&ctx, chal, strlen(chal));	md5_finish(&ctx, result);	hashp = md5;	for (i = 0; i < 16; ++i) {		g_snprintf(hashp, 3, "%02x", result[i]);		hashp += 2;	}	/*	md5_init(&ctx);	md5_append(&ctx, md5, strlen(md5));	md5_finish(&ctx, result);	hashp = md5;	for (i = 0; i < 16; ++i) {		g_snprintf(hashp, 3, "%02x", result[i]);		hashp += 2;	}	*/	g_free(chal);		url = g_string_append(url, md5);	g_hash_table_foreach(hash, (GHFunc)yahoo_login_page_hash_iter, url);		url = g_string_append(url, "&.hash=1&.md5=1 HTTP/1.1\r\n"			      "Host: login.yahoo.com\r\n\r\n");	g_hash_table_destroy(hash);	yd->auth = g_string_free(url, FALSE);	if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) {		gaim_connection_error(gc, _("Connection problem"));		return;	}}static void yahoo_server_check(GaimAccount *account){	const char *server;	server = gaim_account_get_string(account, "server", YAHOO_PAGER_HOST);	if (strcmp(server, "scs.yahoo.com") == 0)		gaim_account_set_string(account, "server", YAHOO_PAGER_HOST);}static void yahoo_picture_check(GaimAccount *account){	GaimConnection *gc = gaim_account_get_connection(account);	const char *buddyicon;	buddyicon = gaim_account_get_buddy_icon(account);	yahoo_set_buddy_icon(gc, buddyicon);}static void yahoo_login(GaimAccount *account) {	GaimConnection *gc = gaim_account_get_connection(account);	struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1);	gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC;	gaim_connection_update_progress(gc, _("Connecting"), 1, 2);	gaim_connection_set_display_name(gc, gaim_account_get_username(account));	yd->fd = -1;	yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free);	yd->confs = NULL;	yd->conf_id = 2;	yahoo_server_check(account);	yahoo_picture_check(account);	if (gaim_account_get_bool(account, "yahoojp", FALSE)) {		yd->jp = TRUE;		if (gaim_proxy_connect(account,		                       gaim_account_get_string(account, "serverjp",  YAHOOJP_PAGER_HOST),		                       gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),		                       yahoo_got_connected, gc) != 0)		{			gaim_connection_error(gc, _("Connection problem"));			return;		}	} else {		yd->jp = FALSE;		if (gaim_proxy_connect(account,		                       gaim_account_get_string(account, "server",  YAHOO_PAGER_HOST),		                       gaim_account_get_int(account, "port", YAHOO_PAGER_PORT),		                       yahoo_got_connected, gc) != 0)		{			gaim_connection_error(gc, _("Connection problem"));			return;		}	}}static void yahoo_close(GaimConnection *gc) {	struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;	GSList *l;	for (l = yd->confs; l; l = l->next) {		GaimConversation *conv = l->data;		yahoo_conf_leave(yd, gaim_conversation_get_name(conv),		                 gaim_connection_get_display_name(gc),				 gaim_conv_chat_get_users(GAIM_CONV_CHAT(conv)));	}	g_slist_free(yd->confs);	g_hash_table_destroy(yd->friends);	if (yd->chat_name)		g_free(yd->chat_name);	if (yd->cookie_y)		g_free(yd->cookie_y);	if (yd->cookie_t)		g_free(yd->cookie_t);	if (yd->fd >= 0)		close(yd->fd);	if (yd->rxqueue)		g_free(yd->rxqueue);	yd->rxlen = 0;	if (yd->picture_url)		g_free(yd->picture_url);	if (yd->picture_upload_todo)		yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo);	if (yd->ycht)		ycht_connection_close(yd->ycht);	if (gc->inpa)		gaim_input_remove(gc->inpa);	g_free(yd);}static const char *yahoo_list_icon(GaimAccount *a, GaimBuddy *b){	return "yahoo";}static void yahoo_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne){	int i = 0;	char *emblems[4] = {NULL,NULL,NULL,NULL};	GaimAccount *account;	GaimConnection *gc;	struct yahoo_data *yd;	YahooFriend *f;	if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) ||	  				     !(yd = gc->proto_data))		return;	f = yahoo_friend_find(gc, b->name);	if (!f) {		*se = "notauthorized";		return;	}	if (b->present == GAIM_BUDDY_OFFLINE) {		*se = "offline";		return;	} else {		if (f->away)			emblems[i++] = "away";		if (f->sms)			emblems[i++] = "wireless";		if (yahoo_friend_get_game(f))			emblems[i++] = "game";	}	*se = emblems[0];	*sw = emblems[1];	*nw = emblems[2];	*ne = emblems[3];}static char *yahoo_get_status_string(enum yahoo_status a){	switch (a) {	case YAHOO_STATUS_BRB:		return _("Be Right Back");	case YAHOO_STATUS_BUSY:		return _("Busy");	case YAHOO_STATUS_NOTATHOME:		return _("Not At Home");	case YAHOO_STATUS_NOTATDESK:		return _("Not At Desk");	case YAHOO_STATUS_NOTINOFFICE:		return _("Not In Office");	case YAHOO_STATUS_ONPHONE:		return _("On The Phone");	case YAHOO_STATUS_ONVACATION:		return _("On Vacation");	case YAHOO_STATUS_OUTTOLUNCH:		return _("Out To Lunch");	case YAHOO_STATUS_STEPPEDOUT:		return _("Stepped Out");	case YAHOO_STATUS_INVISIBLE:		return _("Invisible");	case YAHOO_STATUS_IDLE:		return _("Idle");	case YAHOO_STATUS_OFFLINE:		return _("Offline");	default:		return _("Online");	}}static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) {	GaimBuddy *buddy;	GaimConnection *gc;	GHashTable *components;	struct yahoo_data *yd;	int id;	g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));	buddy = (GaimBuddy *) node;	gc = gaim_account_get_connection(buddy->account);	yd = gc->proto_data;	id = yd->conf_id;	components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);	g_hash_table_replace(components, g_strdup("room"),		g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id));	g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference..."));	g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));	yahoo_c_join(gc, components);	g_hash_table_destroy(components);	yahoo_c_invite(gc, id, "Join my conference...", buddy->name);}static void yahoo_game(GaimBlistNode *node, gpointer data) {	GaimBuddy *buddy;	GaimConnection *gc;	struct yahoo_data *yd;	const char *game;	char *game2;	char *t;	char url[256];	YahooFriend *f;	g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node));	buddy = (GaimBuddy *) node;	gc = gaim_account_get_connection(buddy->account);	yd = (struct yahoo_data *) gc->proto_data;	f = yahoo_friend_find(gc, buddy->name);	if (!f)		return;	game = yahoo_friend_get_game(f);	if (!game)		return;	t = game2 = g_strdup(strstr(game, "ante?room="));	while (*t && *t != '\t')		t++;	*t = 0;	g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2);	gaim_notify_uri(gc, url);	g_free(game2);}static char *yahoo_status_text(GaimBuddy *b){	YahooFriend *f = NULL;	const char *msg;	f = yahoo_friend_find(b->account->gc, b->name);	if (!f)		return g_strdup(_("Not on server list"));	switch (f->status) {	case YAHOO_STATUS_AVAILABLE:		return NULL;	case YAHOO_STATUS_IDLE:		if (f->idle == -1)			return g_strdup(yahoo_get_status_string(f->status));		return NULL;	case YAHOO_STATUS_CUSTOM:		if (!(msg = yahoo_friend_get_status_message(f)))			return NULL;		return g_markup_escape_text(msg, strlen(msg));	default:		return g_strdup(yahoo_get_status_string(f->status)); 	}}char *yahoo_tooltip_text(GaimBuddy *b){	YahooFriend *f;	char *escaped, *status, *ret;	f = yahoo_friend_find(b->account->gc, b->name);	if (!f)		status = g_strdup_printf("\n%s", _("Not on server list"));	else		switch (f->status) {		case YAHOO_STATUS_IDLE:			if (f->idle == -1) {				status = g_strdup(yahoo_get_status_string(f->status));				break;			}			return NULL;		case 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -