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

📄 yahoo.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		l = l->next;	}	if (!who)		return;	if (!group)		group = "";	if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */		f = yahoo_friend_find_or_new(gc, who);		yahoo_update_status(gc, who, f);		return;	}	decoded_group = yahoo_string_decode(gc, group, FALSE);	buf = g_strdup_printf(_("Could not add buddy %s to group %s to the server list on account %s."),				who, decoded_group, purple_connection_get_display_name(gc));	if (!purple_conv_present_error(who, purple_connection_get_account(gc), buf))		purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf);	g_free(buf);	g_free(decoded_group);}static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt){	GSList *l = pkt->hash;	char *who = NULL;	char *base64 = NULL;	guchar *decoded;	gsize len;	while (l) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 5:			/* our identity */			break;		case 4:			who = pair->value;			break;		case 1:			/* who again, the master identity this time? */			break;		case 12:			base64 = pair->value;			/* so, this is an ip address. in base64. decoded it's in ascii.			   after strtol, it's in reversed byte order. Who thought this up?*/			break;		/*			TODO: figure these out			yahoo: Key: 61          Value: 0			yahoo: Key: 2   Value:			yahoo: Key: 13          Value: 0			yahoo: Key: 49          Value: PEERTOPEER			yahoo: Key: 140         Value: 1			yahoo: Key: 11          Value: -1786225828		*/		}		l = l->next;	}	if (base64) {		guint32 ip;		char *tmp2;		YahooFriend *f;		decoded = purple_base64_decode(base64, &len);		if (len) {			char *tmp = purple_str_binary_to_ascii(decoded, len);			purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp);			g_free(tmp);		}		tmp2 = g_strndup((const gchar *)decoded, len); /* so its \0 terminated...*/		ip = strtol(tmp2, NULL, 10);		g_free(tmp2);		g_free(decoded);		tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff,		                       (ip >> 24) & 0xff);		f = yahoo_friend_find(gc, who);		if (f)			yahoo_friend_set_ip(f, tmp2);		g_free(tmp2);	}}static void yahoo_process_audible(PurpleConnection *gc, struct yahoo_packet *pkt){	char *who = NULL, *msg = NULL, *id = NULL;	GSList *l = pkt->hash;	while (l) {		struct yahoo_pair *pair = l->data;		switch (pair->key) {		case 4:			who = pair->value;			break;		case 5:			/* us */			break;		case 230:			/* the audible, in foo.locale.bar.baz format			   eg: base.tw.smiley.smiley43 */			id = pair->value;			break;		case 231:			/* the text of the audible */			msg = pair->value;			break;		case 232:			/* weird number (md5 hash?), like 8ebab9094156135f5dcbaccbeee662a5c5fd1420 */			break;		}		l = l->next;	}	if (!msg)		msg = id;	if (!who || !msg)		return;	if (!g_utf8_validate(msg, -1, NULL)) {		purple_debug_misc("yahoo", "Warning, nonutf8 audible, ignoring!\n");		return;	}	if (!yahoo_privacy_check(gc, who)) {		purple_debug_misc("yahoo", "Audible message from %s for %s dropped!\n",		      gc->account->username, who);		return;	}	if (id) {		/* "http://us.dl1.yimg.com/download.yahoo.com/dl/aud/"+locale+"/"+id+".swf" */		char **audible_locale = g_strsplit(id, ".", 0);		char *buf = g_strdup_printf(_("[ Audible %s/%s/%s.swf ] %s"), YAHOO_AUDIBLE_URL, audible_locale[1], id, msg);		g_strfreev(audible_locale);		serv_got_im(gc, who, buf, 0, time(NULL));		g_free(buf);	} else		serv_got_im(gc, who, msg, 0, time(NULL));}static void yahoo_packet_process(PurpleConnection *gc, struct yahoo_packet *pkt){	switch (pkt->service) {	case YAHOO_SERVICE_LOGON:	case YAHOO_SERVICE_LOGOFF:	case YAHOO_SERVICE_ISAWAY:	case YAHOO_SERVICE_ISBACK:	case YAHOO_SERVICE_GAMELOGON:	case YAHOO_SERVICE_GAMELOGOFF:	case YAHOO_SERVICE_CHATLOGON:	case YAHOO_SERVICE_CHATLOGOFF:	case YAHOO_SERVICE_Y6_STATUS_UPDATE:	case YAHOO_SERVICE_STATUS_15:		yahoo_process_status(gc, pkt);		break;	case YAHOO_SERVICE_NOTIFY:		yahoo_process_notify(gc, pkt);		break;	case YAHOO_SERVICE_MESSAGE:	case YAHOO_SERVICE_GAMEMSG:	case YAHOO_SERVICE_CHATMSG:		yahoo_process_message(gc, pkt);		break;	case YAHOO_SERVICE_SYSMESSAGE:		yahoo_process_sysmessage(gc, pkt);			break;	case YAHOO_SERVICE_NEWMAIL:		yahoo_process_mail(gc, pkt);		break;	case YAHOO_SERVICE_NEWCONTACT:		yahoo_process_contact(gc, pkt);		break;	case YAHOO_SERVICE_AUTHRESP:		yahoo_process_authresp(gc, pkt);		break;	case YAHOO_SERVICE_LIST:		yahoo_process_list(gc, pkt);		break;	case YAHOO_SERVICE_LIST_15:		yahoo_process_list_15(gc, pkt);		break;	case YAHOO_SERVICE_AUTH:		yahoo_process_auth(gc, pkt);		break;	case YAHOO_SERVICE_ADDBUDDY:		yahoo_process_addbuddy(gc, pkt);		break;	case YAHOO_SERVICE_IGNORECONTACT:		yahoo_process_ignore(gc, pkt);		break;	case YAHOO_SERVICE_CONFINVITE:	case YAHOO_SERVICE_CONFADDINVITE:		yahoo_process_conference_invite(gc, pkt);		break;	case YAHOO_SERVICE_CONFDECLINE:		yahoo_process_conference_decline(gc, pkt);		break;	case YAHOO_SERVICE_CONFLOGON:		yahoo_process_conference_logon(gc, pkt);		break;	case YAHOO_SERVICE_CONFLOGOFF:		yahoo_process_conference_logoff(gc, pkt);		break;	case YAHOO_SERVICE_CONFMSG:		yahoo_process_conference_message(gc, pkt);		break;	case YAHOO_SERVICE_CHATONLINE:		yahoo_process_chat_online(gc, pkt);		break;	case YAHOO_SERVICE_CHATLOGOUT:		yahoo_process_chat_logout(gc, pkt);		break;	case YAHOO_SERVICE_CHATGOTO:		yahoo_process_chat_goto(gc, pkt);		break;	case YAHOO_SERVICE_CHATJOIN:		yahoo_process_chat_join(gc, pkt);		break;	case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */	case YAHOO_SERVICE_CHATEXIT:		yahoo_process_chat_exit(gc, pkt);		break;	case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */	case YAHOO_SERVICE_CHATADDINVITE:		yahoo_process_chat_addinvite(gc, pkt);		break;	case YAHOO_SERVICE_COMMENT:		yahoo_process_chat_message(gc, pkt);		break;	case YAHOO_SERVICE_PRESENCE_PERM:	case YAHOO_SERVICE_PRESENCE_SESSION:		yahoo_process_presence(gc, pkt);		break;	case YAHOO_SERVICE_P2PFILEXFER:		/* This case had no break and continued; thus keeping it this way.*/		yahoo_process_p2pfilexfer(gc, pkt);	case YAHOO_SERVICE_FILETRANSFER:		yahoo_process_filetransfer(gc, pkt);		break;	case YAHOO_SERVICE_PEERTOPEER:		yahoo_process_p2p(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE:		yahoo_process_picture(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_UPDATE:		yahoo_process_picture_update(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_CHECKSUM:		yahoo_process_picture_checksum(gc, pkt);		break;	case YAHOO_SERVICE_PICTURE_UPLOAD:		yahoo_process_picture_upload(gc, pkt);		break;	case YAHOO_SERVICE_AVATAR_UPDATE:		yahoo_process_avatar_update(gc, pkt);		break;	case YAHOO_SERVICE_AUDIBLE:		yahoo_process_audible(gc, pkt);		break;	default:		purple_debug(PURPLE_DEBUG_ERROR, "yahoo",				   "Unhandled service 0x%02x\n", pkt->service);		break;	}}static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond){	PurpleConnection *gc = data;	struct yahoo_data *yd = gc->proto_data;	char buf[1024];	int len;	len = read(yd->fd, buf, sizeof(buf));	if (len < 0) {		gchar *tmp;		if (errno == EAGAIN)			/* No worries */			return;		tmp = g_strdup_printf(_("Lost connection with server:\n%s"),				strerror(errno));		purple_connection_error(gc, tmp);		g_free(tmp);		return;	} else if (len == 0) {		purple_connection_error(gc, _("Server closed the connection."));		return;	}	yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen);	memcpy(yd->rxqueue + yd->rxlen, buf, len);	yd->rxlen += len;	while (1) {		struct yahoo_packet *pkt;		int pos = 0;		int pktlen;		if (yd->rxlen < YAHOO_PACKET_HDRLEN)			return;		if (strncmp((char *)yd->rxqueue, "YMSG", MIN(4, yd->rxlen)) != 0) {			/* HEY! This isn't even a YMSG packet. What			 * are you trying to pull? */			guchar *start;			purple_debug_warning("yahoo", "Error in YMSG stream, got something not a YMSG packet!\n");			start = memchr(yd->rxqueue + 1, 'Y', yd->rxlen - 1);			if (start) {				g_memmove(yd->rxqueue, start, yd->rxlen - (start - yd->rxqueue));				yd->rxlen -= start - yd->rxqueue;				continue;			} else {				g_free(yd->rxqueue);				yd->rxqueue = NULL;				yd->rxlen = 0;				return;			}		}		pos += 4; /* YMSG */		pos += 2;		pos += 2;		pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2;		purple_debug(PURPLE_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;		purple_debug(PURPLE_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) {			guchar *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, const gchar *error_message){	PurpleConnection *gc = data;	struct yahoo_data *yd;	struct yahoo_packet *pkt;	if (!PURPLE_CONNECTION_IS_VALID(gc)) {		close(source);		return;	}	if (source < 0) {		gchar *tmp;		tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),				error_message);		purple_connection_error(gc, tmp);		g_free(tmp);		return;	}	yd = gc->proto_data;	yd->fd = source;	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, yd->current_status, 0);	yahoo_packet_hash_str(pkt, 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))));	yahoo_packet_send_and_free(pkt, yd);	gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);}#ifdef TRY_WEBMESSENGER_LOGINstatic void yahoo_got_web_connected(gpointer data, gint source, const gchar *error_message){	PurpleConnection *gc = data;	struct yahoo_data *yd;	struct yahoo_packet *pkt;	if (!PURPLE_CONNECTION_IS_VALID(gc)) {		close(source);		return;	}	if (source < 0) {		gchar *tmp;		tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),				error_message);		purple_connection_error(gc, tmp);		g_free(tmp);		return;	}	yd = gc->proto_data;	yd->fd = source;	pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, 0);	yahoo_packet_hash(pkt, "sss", 0,	                  purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),	                  1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),	                  6, yd->auth);	yahoo_packet_send_and_free(pkt, yd);	g_free(yd->auth);	gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);}static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition cond){	PurpleConnection *gc = data;	PurpleAccount *account = purple_connection_get_account(gc);	struct yahoo_data *yd = gc->proto_data;	char bufread[2048], *i = bufread, *buf = bufread;	int len;	GString *s;	len = read(source, bufread, sizeof(bufread) - 1);	if (len < 0) {		gchar *tmp;		if (errno == EAGAIN)			/* No worries */			return;		tmp = g_strdup_printf(_("Lost connection with server:\n%s"),				strerror(errno));		purple_connection_error(gc, tmp);		g_free(tmp);		return;	} else if (len == 0) {		purple_connection_error(gc, _("Server closed the connection."));		return;	}	if (yd->rxlen > 0 || !g_strstr_len(buf, len, "\r\n\r\n")) {		yd->rxqueue = g_realloc(yd->rxqueue, yd->rxlen + len + 1);		memcpy(yd->rxqueue + yd->rxlen, buf, len);		yd->rxlen += len;		i = buf = (char *)yd->rxqueue;		len = yd->rxlen;	}	buf[len] = '\0';	if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) &&			  strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) {		purple_connection_error(gc, _("Received unexpected HTTP response from server."));		return;	}	s = g_string_sized_new(len);	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);	purple_input_remove(gc->inpa);	close(source);	g_free(yd->rxqueue);	yd->rxqueue = NULL;	yd->rxlen = 0;	/* Now we have our cookies to logi

⌨️ 快捷键说明

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