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

📄 yahoo_filexfer.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @file yahoo_filexfer.c Yahoo Filetransfer * * Purple is the legal property of its developers, whose names are too numerous * to list here.  Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "prpl.h"#include "internal.h"#include "util.h"#include "debug.h"#include "notify.h"#include "proxy.h"#include "ft.h"#include "yahoo.h"#include "yahoo_packet.h"#include "yahoo_filexfer.h"#include "yahoo_doodle.h"struct yahoo_xfer_data {	gchar *host;	gchar *path;	int port;	PurpleConnection *gc;	long expires;	gboolean started;	gchar *txbuf;	gsize txbuflen;	gsize txbuf_written;	guint tx_handler;	gchar *rxqueue;	guint rxlen;};static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd){	g_free(xd->host);	g_free(xd->path);	g_free(xd->txbuf);	if (xd->tx_handler)		purple_input_remove(xd->tx_handler);	g_free(xd);}static void yahoo_receivefile_send_cb(gpointer data, gint source, PurpleInputCondition condition){	PurpleXfer *xfer;	struct yahoo_xfer_data *xd;	int remaining, written;	xfer = data;	xd = xfer->data;	remaining = xd->txbuflen - xd->txbuf_written;	written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);	if (written < 0 && errno == EAGAIN)		written = 0;	else if (written <= 0) {		purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);		purple_xfer_cancel_remote(xfer);		return;	}	if (written < remaining) {		xd->txbuf_written += written;		return;	}	purple_input_remove(xd->tx_handler);	xd->tx_handler = 0;	g_free(xd->txbuf);	xd->txbuf = NULL;	xd->txbuflen = 0;	purple_xfer_start(xfer, source, NULL, 0);}static void yahoo_receivefile_connected(gpointer data, gint source, const gchar *error_message){	PurpleXfer *xfer;	struct yahoo_xfer_data *xd;	purple_debug(PURPLE_DEBUG_INFO, "yahoo",			   "AAA - in yahoo_receivefile_connected\n");	if (!(xfer = data))		return;	if (!(xd = xfer->data))		return;	if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {		purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),				xfer->who, _("Unable to connect."));		purple_xfer_cancel_remote(xfer);		return;	}	xfer->fd = source;	/* The first time we get here, assemble the tx buffer */	if (xd->txbuflen == 0) {		xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",			      xd->path, xd->host);		xd->txbuflen = strlen(xd->txbuf);		xd->txbuf_written = 0;	}	if (!xd->tx_handler)	{		xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE,			yahoo_receivefile_send_cb, xfer);		yahoo_receivefile_send_cb(xfer, source, PURPLE_INPUT_WRITE);	}}static void yahoo_sendfile_send_cb(gpointer data, gint source, PurpleInputCondition condition){	PurpleXfer *xfer;	struct yahoo_xfer_data *xd;	int written, remaining;	xfer = data;	xd = xfer->data;	remaining = xd->txbuflen - xd->txbuf_written;	written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);	if (written < 0 && errno == EAGAIN)		written = 0;	else if (written <= 0) {		purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);		purple_xfer_cancel_remote(xfer);		return;	}	if (written < remaining) {		xd->txbuf_written += written;		return;	}	purple_input_remove(xd->tx_handler);	xd->tx_handler = 0;	g_free(xd->txbuf);	xd->txbuf = NULL;	xd->txbuflen = 0;	purple_xfer_start(xfer, source, NULL, 0);}static void yahoo_sendfile_connected(gpointer data, gint source, const gchar *error_message){	PurpleXfer *xfer;	struct yahoo_xfer_data *xd;	struct yahoo_packet *pkt;	gchar *size, *filename, *encoded_filename, *header;	guchar *pkt_buf;	const char *host;	int port;	size_t content_length, header_len, pkt_buf_len;	PurpleConnection *gc;	PurpleAccount *account;	struct yahoo_data *yd;	purple_debug(PURPLE_DEBUG_INFO, "yahoo",			   "AAA - in yahoo_sendfile_connected\n");	if (!(xfer = data))		return;	if (!(xd = xfer->data))		return;	if (source < 0) {		purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),				xfer->who, _("Unable to connect."));		purple_xfer_cancel_remote(xfer);		return;	}	xfer->fd = source;	/* Assemble the tx buffer */	gc = xd->gc;	account = purple_connection_get_account(gc);	yd = gc->proto_data;	pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER,		YAHOO_STATUS_AVAILABLE, yd->session_id);	size = g_strdup_printf("%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));	filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));	encoded_filename = yahoo_string_encode(gc, filename, NULL);	yahoo_packet_hash(pkt, "sssss", 0, purple_connection_get_display_name(gc),	  5, xfer->who, 14, "", 27, encoded_filename, 28, size);	g_free(size);	g_free(encoded_filename);	g_free(filename);	content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);	pkt_buf_len = yahoo_packet_build(pkt, 8, FALSE, yd->jp, &pkt_buf);	yahoo_packet_free(pkt);	host = purple_account_get_string(account, "xfer_host", YAHOO_XFER_HOST);	port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);	header = g_strdup_printf(		"POST http://%s:%d/notifyft HTTP/1.0\r\n"		"Content-length: %" G_GSIZE_FORMAT "\r\n"		"Host: %s:%d\r\n"		"Cookie: Y=%s; T=%s\r\n"		"\r\n",		host, port, content_length + 4 + purple_xfer_get_size(xfer),		host, port, yd->cookie_y, yd->cookie_t);	header_len = strlen(header);	xd->txbuflen = header_len + pkt_buf_len + 4;	xd->txbuf = g_malloc(xd->txbuflen);	memcpy(xd->txbuf, header, header_len);	g_free(header);	memcpy(xd->txbuf + header_len, pkt_buf, pkt_buf_len);	g_free(pkt_buf);	memcpy(xd->txbuf + header_len + pkt_buf_len, "29\xc0\x80", 4);	xd->txbuf_written = 0;	if (xd->tx_handler == 0)	{		xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE,										yahoo_sendfile_send_cb, xfer);		yahoo_sendfile_send_cb(xfer, source, PURPLE_INPUT_WRITE);	}}static void yahoo_xfer_init(PurpleXfer *xfer){	struct yahoo_xfer_data *xfer_data;	PurpleConnection *gc;	PurpleAccount *account;	struct yahoo_data *yd;	xfer_data = xfer->data;	gc = xfer_data->gc;	yd = gc->proto_data;	account = purple_connection_get_account(gc);	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {		if (yd->jp) {			if (purple_proxy_connect(NULL, account, purple_account_get_string(account, "xferjp_host",  YAHOOJP_XFER_HOST),			                       purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),			                       yahoo_sendfile_connected, xfer) == NULL)			{				purple_notify_error(gc, NULL, _("File Transfer Failed"),				                _("Unable to establish file descriptor."));				purple_xfer_cancel_remote(xfer);			}		} else {			if (purple_proxy_connect(NULL, account, purple_account_get_string(account, "xfer_host",  YAHOO_XFER_HOST),			                       purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),			                       yahoo_sendfile_connected, xfer) == NULL)			{				purple_notify_error(gc, NULL, _("File Transfer Failed"),				                _("Unable to establish file descriptor."));				purple_xfer_cancel_remote(xfer);			}		}	} else {		/* TODO: Using xfer->fd like this is probably a bad thing... */		if (purple_proxy_connect(NULL, account, xfer_data->host, xfer_data->port,		                              yahoo_receivefile_connected, xfer) == NULL)			xfer->fd = -1;		else			xfer->fd = 0;		if (xfer->fd == -1) {			purple_notify_error(gc, NULL, _("File Transfer Failed"),			             _("Unable to establish file descriptor."));			purple_xfer_cancel_remote(xfer);		}	}}static void yahoo_xfer_start(PurpleXfer *xfer){	/* We don't need to do anything here, do we? */}static void yahoo_xfer_end(PurpleXfer *xfer){	struct yahoo_xfer_data *xfer_data;	xfer_data = xfer->data;	if (xfer_data)		yahoo_xfer_data_free(xfer_data);	xfer->data = NULL;}static guint calculate_length(const gchar *l, size_t len){	int i;	for (i = 0; i < len; i++) {		if (!g_ascii_isdigit(l[i]))			continue;		return strtol(l + i, NULL, 10);	}	return 0;}static gssize yahoo_xfer_read(guchar **buffer, PurpleXfer *xfer){	gchar buf[4096];	gssize len;	gchar *start = NULL;	gchar *length;

⌨️ 快捷键说明

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