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

📄 odc.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				break;			}			size = atol(sizestr);			g_datalist_clear(&attributes);			if ((size > 0) && (tmp + size > dataend))				break;			embedded_data = g_new(struct embedded_data, 1);			embedded_data->size = size;			embedded_data->data = (const guint8 *)tmp;			tmp += size;			/* Skip past the closing </data> tag */			if (strncasecmp(tmp, "</data>", 7))			{				g_free(embedded_data);				break;			}			tmp += 7;			g_hash_table_insert(embedded_datas,					GINT_TO_POINTER(id), embedded_data);		}	}	/*	 * Loop through the message, replacing OSCAR img tags with the	 * equivalent Purple img tag.	 */	images = NULL;	newmsg = g_string_new("");	tmp = msg;	while (purple_markup_find_tag("img", tmp, &start, &end, &attributes))	{		int imgid = 0;		idstr   = g_datalist_get_data(&attributes, "id");		src     = g_datalist_get_data(&attributes, "src");		sizestr = g_datalist_get_data(&attributes, "datasize");		if ((idstr != NULL) && (src != NULL) && (sizestr!= NULL))		{			unsigned int id;			size_t size;			id = atoi(idstr);			size = atol(sizestr);			embedded_data = g_hash_table_lookup(embedded_datas,					GINT_TO_POINTER(id));			if ((embedded_data != NULL) && (embedded_data->size == size))			{				imgid = purple_imgstore_add_with_id(g_memdup(embedded_data->data, size), size, src);				/* Record the image number */				images = g_slist_append(images, GINT_TO_POINTER(imgid));			}		}		/* Delete the attribute list */		g_datalist_clear(&attributes);		/* Append the message up to the tag */		utf8 = purple_plugin_oscar_decode_im_part(account, conn->sn,				encoding, 0x0000, tmp, start - tmp);		if (utf8 != NULL) {			g_string_append(newmsg, utf8);			g_free(utf8);		}		if (imgid != 0)		{			/* Write the new image tag */			g_string_append_printf(newmsg, "<IMG ID=\"%d\">", imgid);		}		/* Continue from the end of the tag */		tmp = end + 1;	}	/* Append any remaining message data */	if (tmp <= msgend)	{		utf8 = purple_plugin_oscar_decode_im_part(account, conn->sn,				encoding, 0x0000, tmp, msgend - tmp);		if (utf8 != NULL) {			g_string_append(newmsg, utf8);			g_free(utf8);		}	}	/* Send the message */	imflags = 0;	if (images != NULL)		imflags |= PURPLE_MESSAGE_IMAGES;	if (autoreply)		imflags |= PURPLE_MESSAGE_AUTO_RESP;	serv_got_im(gc, conn->sn, newmsg->str, imflags, time(NULL));	g_string_free(newmsg, TRUE);	/* unref any images we allocated */	if (images)	{		GSList *l;		for (l = images; l != NULL; l = l->next)			purple_imgstore_unref_by_id(GPOINTER_TO_INT(l->data));		g_slist_free(images);	}	/* Delete our list of pointers to embedded images */	g_hash_table_destroy(embedded_datas);}/** * This is a purple_input_add() watcher callback function for reading * direct IM payload data.  "Payload data" is always an IM and * maybe some embedded images or files or something.  The actual * ODC frame is read using peer_connection_recv_cb().  We temporarily * switch to this watcher callback ONLY to read the payload, and we * switch back once we're done. */static voidpeer_odc_recv_cb(gpointer data, gint source, PurpleInputCondition cond){	PeerConnection *conn;	OdcFrame *frame;	ByteStream *bs;	ssize_t read;	conn = data;	frame = conn->frame;	bs = &frame->payload;	/* Read data into the temporary buffer until it is complete */	read = recv(conn->fd,				&bs->data[bs->offset],				bs->len - bs->offset,				0);	/* Check if the remote user closed the connection */	if (read == 0)	{		peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL);		return;	}	if (read < 0)	{		if ((errno == EAGAIN) || (errno == EWOULDBLOCK))			/* No worries */			return;		peer_connection_destroy(conn,				OSCAR_DISCONNECT_LOST_CONNECTION, strerror(errno));		return;	}	bs->offset += read;	if (bs->offset < bs->len)		/* Waiting for more data to arrive */		return;	/* We have a complete ODC/OFT frame!  Handle it and continue reading */	byte_stream_rewind(bs);	peer_odc_handle_payload(conn, (const char *)bs->data,			bs->len, frame->encoding, frame->flags & 0x0001);	g_free(bs->data);	bs->data = NULL;	g_free(frame);	conn->frame = NULL;	purple_input_remove(conn->watcher_incoming);	conn->watcher_incoming = purple_input_add(conn->fd,			PURPLE_INPUT_READ, peer_connection_recv_cb, conn);}/** * Handle an incoming OdcFrame.  If there is a payload associated * with this frame, then we remove the old watcher and add the * ODC watcher to read in the payload. */voidpeer_odc_recv_frame(PeerConnection *conn, ByteStream *bs){	PurpleConnection *gc;	OdcFrame *frame;	gc = conn->od->gc;	frame = g_new0(OdcFrame, 1);	frame->type = byte_stream_get16(bs);	frame->subtype = byte_stream_get16(bs);	byte_stream_advance(bs, 2);	byte_stream_getrawbuf(bs, frame->cookie, 8);	byte_stream_advance(bs, 8);	frame->payload.len = byte_stream_get32(bs);	frame->encoding = byte_stream_get16(bs);	byte_stream_advance(bs, 4);	frame->flags = byte_stream_get16(bs);	byte_stream_advance(bs, 4);	byte_stream_getrawbuf(bs, frame->sn, 32);	purple_debug_info("oscar", "Incoming ODC frame from %s with "			"type=0x%04x, flags=0x%04x, payload length=%u\n",			frame->sn, frame->type, frame->flags, frame->payload.len);	if (!conn->ready)	{		/*		 * We need to verify the cookie so that we know we are		 * connected to our friend and not a malicious middle man.		 */		PurpleAccount *account;		PurpleConversation *conv;		if (conn->flags & PEER_CONNECTION_FLAG_IS_INCOMING)		{			if (memcmp(conn->cookie, frame->cookie, 8))			{				/*				 * Oh no!  The user that connected to us did not send				 * the correct cookie!  They are not our friend.  Go try				 * to accept another connection?				 */				purple_debug_info("oscar", "Received an incorrect cookie.  "					"Closing connection.\n");				peer_connection_destroy(conn,						OSCAR_DISCONNECT_INVALID_DATA, NULL);				g_free(frame);				return;			}			/*			 * Ok, we know they are legit.  Now be courteous and			 * send them our cookie.  Note: This doesn't seem			 * to be necessary, but it also doesn't seem to hurt.			 */			peer_odc_send_cookie(conn);		}		conn->ready = TRUE;		/*		 * If they connected to us then close the listener socket		 * and send them our cookie.		 */		if (conn->listenerfd != -1)		{			close(conn->listenerfd);			conn->listenerfd = -1;		}		/* Tell the local user that we are connected */		account = purple_connection_get_account(gc);		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn);		purple_conversation_write(conv, NULL, _("Direct IM established"),				PURPLE_MESSAGE_SYSTEM, time(NULL));	}	if ((frame->type != 0x0001) && (frame->subtype != 0x0006))	{		purple_debug_info("oscar", "Unknown ODC frame type 0x%04hx, "				"subtype 0x%04hx.\n", frame->type, frame->subtype);		return;	}	if (frame->flags & 0x0008)	{		/* I had to leave this. It's just too funny. It reminds me of my sister. */		purple_debug_info("oscar", "ohmigod! %s has started typing "			"(DirectIM). He's going to send you a message! "			"*squeal*\n", conn->sn);		serv_got_typing(gc, conn->sn, 0, PURPLE_TYPING);	}	else if (frame->flags & 0x0004)	{		serv_got_typing(gc, conn->sn, 0, PURPLE_TYPED);	}	else	{		serv_got_typing_stopped(gc, conn->sn);	}	if (frame->payload.len > 0)	{		/* We have payload data!  Switch to the ODC watcher to read it. */		frame->payload.data = g_new(guint8, frame->payload.len);		frame->payload.offset = 0;		conn->frame = frame;		purple_input_remove(conn->watcher_incoming);		conn->watcher_incoming = purple_input_add(conn->fd,				PURPLE_INPUT_READ, peer_odc_recv_cb, conn);		return;	}	g_free(frame);}

⌨️ 快捷键说明

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