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

📄 ycht.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		written = -1;		errno = EAGAIN;	}	if (written < 0 && errno == EAGAIN)		written = 0;	else if (written <= 0) {		/* TODO: Error handling (was none before NBIO changes) */		written = 0;	}	if (written < len) {		if (!ycht->tx_handler)			ycht->tx_handler = purple_input_add(ycht->fd,				PURPLE_INPUT_WRITE, ycht_packet_send_write_cb,				ycht);		purple_circ_buffer_append(ycht->txbuf, buf + written,			len - written);	}	g_free(buf);}static void ycht_packet_read(YchtPkt *pkt, const char *buf, int len){	const char *pos = buf;	const char *needle;	char *tmp, *tmp2;	int i = 0;	while (len > 0 && (needle = g_strstr_len(pos, len, YCHT_SEP))) {		tmp = g_strndup(pos, needle - pos);		pkt->data = g_list_append(pkt->data, tmp);		len -= needle - pos + strlen(YCHT_SEP);		pos = needle + strlen(YCHT_SEP);		tmp2 = g_strescape(tmp, NULL);		purple_debug_misc("yahoo", "Data[%d]:\t%s\n", i++, tmp2);		g_free(tmp2);	}	if (len) {		tmp = g_strndup(pos, len);		pkt->data = g_list_append(pkt->data, tmp);		tmp2 = g_strescape(tmp, NULL);		purple_debug_misc("yahoo", "Data[%d]:\t%s\n", i, tmp2);		g_free(tmp2);	};	purple_debug_misc("yahoo", "--==End of incoming YCHT packet==--\n");}static void ycht_packet_process(YchtConn *ycht, YchtPkt *pkt){	if (pkt->data && !strncmp(pkt->data->data, "*** Danger Will Robinson!!!", strlen("*** Danger Will Robinson!!!")))		return;	switch (pkt->service) {	case YCHT_SERVICE_LOGIN:		ycht_process_login(ycht, pkt);		break;	case YCHT_SERVICE_LOGOUT:		ycht_process_logout(ycht, pkt);		break;	case YCHT_SERVICE_CHATJOIN:		ycht_process_chatjoin(ycht, pkt);		break;	case YCHT_SERVICE_CHATPART:		ycht_process_chatpart(ycht, pkt);		break;	case YCHT_SERVICE_CHATMSG:	case YCHT_SERVICE_CHATMSG_EMOTE:		ycht_progress_chatmsg(ycht, pkt);		break;	case YCHT_SERVICE_ONLINE_FRIENDS:		ycht_progress_online_friends(ycht, pkt);		break;	default:		purple_debug_warning("yahoo", "YCHT: warning, unhandled service 0x%02x\n", pkt->service);	}}static void ycht_packet_free(YchtPkt *pkt){	GList *l;	g_return_if_fail(pkt != NULL);	for (l = pkt->data; l; l = l->next)		g_free(l->data);	g_list_free(pkt->data);	g_free(pkt);}/************************************************************************************ * Functions dealing with connecting and disconnecting and reading data into YchtPkt * structs, and all that stuff. ************************************************************************************/void ycht_connection_close(YchtConn *ycht){	struct yahoo_data *yd = ycht->gc->proto_data;	if (yd) {		yd->ycht = NULL;		yd->chat_online = FALSE;	}	if (ycht->fd > 0)		close(ycht->fd);	if (ycht->inpa)		purple_input_remove(ycht->inpa);	if (ycht->tx_handler)		purple_input_remove(ycht->tx_handler);	purple_circ_buffer_destroy(ycht->txbuf);	g_free(ycht->rxqueue);	g_free(ycht);}static void ycht_connection_error(YchtConn *ycht, const gchar *error){	purple_notify_info(ycht->gc, NULL, _("Connection problem with the YCHT server."), error);	ycht_connection_close(ycht);}static void ycht_pending(gpointer data, gint source, PurpleInputCondition cond){	YchtConn *ycht = data;	char buf[1024];	int len;	len = read(ycht->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));		ycht_connection_error(ycht, tmp);		g_free(tmp);		return;	} else if (len == 0) {		ycht_connection_error(ycht, _("Server closed the connection."));		return;	}	ycht->rxqueue = g_realloc(ycht->rxqueue, len + ycht->rxlen);	memcpy(ycht->rxqueue + ycht->rxlen, buf, len);	ycht->rxlen += len;	while (1) {		YchtPkt *pkt;		int pos = 0;		int pktlen;		guint service;		guint version;		gint status;		if (ycht->rxlen < YCHT_HEADER_LEN)			return;		if (strncmp("YCHT", (char *)ycht->rxqueue, 4) != 0)			purple_debug_error("yahoo", "YCHT: protocol error.\n");		pos += 4; /* YCHT */		version = yahoo_get32(ycht->rxqueue + pos); pos += 4;		service = yahoo_get32(ycht->rxqueue + pos); pos += 4;		status = yahoo_get16(ycht->rxqueue + pos); pos += 2;		pktlen  = yahoo_get16(ycht->rxqueue + pos); pos += 2;		purple_debug(PURPLE_DEBUG_MISC, "yahoo",				   "ycht: %d bytes to read, rxlen is %d\n", pktlen, ycht->rxlen);		if (ycht->rxlen < (YCHT_HEADER_LEN + pktlen))			return;		purple_debug_misc("yahoo", "--==Incoming YCHT packet==--\n");		purple_debug(PURPLE_DEBUG_MISC, "yahoo",			   "YCHT Service: 0x%02x Version: 0x%02x Status: 0x%02x\n",			   service, version, status);		ycht_packet_dump(ycht->rxqueue, YCHT_HEADER_LEN + pktlen);		pkt = ycht_packet_new(version, service, status);		ycht_packet_read(pkt, (char *)ycht->rxqueue + pos, pktlen);		ycht->rxlen -= YCHT_HEADER_LEN + pktlen;		if (ycht->rxlen) {			guchar *tmp = g_memdup(ycht->rxqueue + YCHT_HEADER_LEN + pktlen, ycht->rxlen);			g_free(ycht->rxqueue);			ycht->rxqueue = tmp;		} else {			g_free(ycht->rxqueue);			ycht->rxqueue = NULL;		}		ycht_packet_process(ycht, pkt);		ycht_packet_free(pkt);	}}static void ycht_got_connected(gpointer data, gint source, const gchar *error_message){	YchtConn *ycht = data;	PurpleConnection *gc = ycht->gc;	struct yahoo_data *yd = gc->proto_data;	YchtPkt *pkt;	char *buf;	if (source < 0) {		ycht_connection_error(ycht, _("Unable to connect."));		return;	}	ycht->fd = source;	pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_LOGIN, 0);	buf = g_strdup_printf("%s\001Y=%s; T=%s", purple_connection_get_display_name(gc), yd->cookie_y, yd->cookie_t);	ycht_packet_append(pkt, buf);	g_free(buf);	ycht_packet_send(ycht, pkt);	ycht_packet_free(pkt);	ycht->inpa = purple_input_add(ycht->fd, PURPLE_INPUT_READ, ycht_pending, ycht);}void ycht_connection_open(PurpleConnection *gc){	YchtConn *ycht;	struct yahoo_data *yd = gc->proto_data;	PurpleAccount *account = purple_connection_get_account(gc);	ycht = g_new0(YchtConn, 1);	ycht->gc = gc;	ycht->fd = -1;	yd->ycht = ycht;	if (purple_proxy_connect(NULL, account,	                       purple_account_get_string(account, "ycht-server",  YAHOO_YCHT_HOST),	                       purple_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT),	                       ycht_got_connected, ycht) == NULL)	{		ycht_connection_error(ycht, _("Connection problem"));		return;	}}/******************************************************************************************* * These are functions called because the user did something. *******************************************************************************************/void ycht_chat_join(YchtConn *ycht, const char *room){	YchtPkt *pkt;	char *tmp;	tmp = g_strdup(room);	g_free(ycht->room);	ycht->room = tmp;	if (!ycht->logged_in)		return;	ycht->changing_rooms = TRUE;	pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATJOIN, 0);	ycht_packet_append(pkt, ycht->room);	ycht_packet_send(ycht, pkt);	ycht_packet_free(pkt);}int ycht_chat_send(YchtConn *ycht, const char *room, const char *what){	YchtPkt *pkt;	char *msg1, *msg2, *buf;	if (strcmp(room, ycht->room))		purple_debug_warning("yahoo", "uhoh, sending to the wrong room!\n");	pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATMSG, 0);	msg1 = yahoo_html_to_codes(what);	msg2 = yahoo_string_encode(ycht->gc, msg1, NULL);	g_free(msg1);	buf = g_strdup_printf("%s\001%s", ycht->room, msg2);	ycht_packet_append(pkt, buf);	g_free(msg2);	g_free(buf);	ycht_packet_send(ycht, pkt);	ycht_packet_free(pkt);	return 1;}void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout){	if (logout)		ycht_connection_close(ycht);}void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg){}void ycht_chat_goto_user(YchtConn *ycht, const char *name){}void ycht_chat_send_keepalive(YchtConn *ycht){	YchtPkt *pkt;	pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_PING, 0);	ycht_packet_send(ycht, pkt);	ycht_packet_free(pkt);}

⌨️ 快捷键说明

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