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

📄 yahoo_filexfer.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	gchar *end;	int filelen;	struct yahoo_xfer_data *xd = xfer->data;	if (purple_xfer_get_type(xfer) != PURPLE_XFER_RECEIVE) {		return 0;	}	len = read(xfer->fd, buf, sizeof(buf));	if (len <= 0) {		if ((purple_xfer_get_size(xfer) > 0) &&		    (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))) {			purple_xfer_set_completed(xfer, TRUE);			return 0;		} else			return -1;	}	if (!xd->started) {		xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);		memcpy(xd->rxqueue + xd->rxlen, buf, len);		xd->rxlen += len;		length = g_strstr_len(xd->rxqueue, len, "Content-length:");		/* some proxies re-write this header, changing the capitalization :(		 * technically that's allowed since headers are case-insensitive		 * [RFC 2616, section 4.2] */		if (length == NULL)			length = g_strstr_len(xd->rxqueue, len, "Content-Length:");		if (length) {			end = g_strstr_len(length, length - xd->rxqueue, "\r\n");			if (!end)				return 0;			if ((filelen = calculate_length(length, len - (length - xd->rxqueue))))				purple_xfer_set_size(xfer, filelen);		}		start = g_strstr_len(xd->rxqueue, len, "\r\n\r\n");		if (start)			start += 4;		if (!start || start > (xd->rxqueue + len))			return 0;		xd->started = TRUE;		len -= (start - xd->rxqueue);		*buffer = g_malloc(len);		memcpy(*buffer, start, len);		g_free(xd->rxqueue);		xd->rxqueue = NULL;		xd->rxlen = 0;	} else {		*buffer = g_malloc(len);		memcpy(*buffer, buf, len);	}	return len;}static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer){	gssize len;	struct yahoo_xfer_data *xd = xfer->data;	if (!xd)		return -1;	if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND) {		return -1;	}	len = write(xfer->fd, buffer, size);	if (len == -1) {		if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))			purple_xfer_set_completed(xfer, TRUE);		if ((errno != EAGAIN) && (errno != EINTR))			return -1;		return 0;	}	if ((purple_xfer_get_bytes_sent(xfer) + len) >= purple_xfer_get_size(xfer))		purple_xfer_set_completed(xfer, TRUE);	return len;}static void yahoo_xfer_cancel_send(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 void yahoo_xfer_cancel_recv(PurpleXfer *xfer){	struct yahoo_xfer_data *xfer_data;	xfer_data = xfer->data;	if (xfer_data)		yahoo_xfer_data_free(xfer_data);	xfer->data = NULL;}void yahoo_process_p2pfilexfer(PurpleConnection *gc, struct yahoo_packet *pkt){	GSList *l = pkt->hash;	char *me      = NULL;	char *from    = NULL;	char *service = NULL;	char *message = NULL;	char *command = NULL;	char *imv     = NULL;	char *unknown = NULL;	/* Get all the necessary values from this new packet */	while(l != NULL)	{		struct yahoo_pair *pair = l->data;		if(pair->key == 5)         /* Get who the packet is for */			me = pair->value;		if(pair->key == 4)         /* Get who the packet is from */			from = pair->value;		if(pair->key == 49)        /* Get the type of service */			service = pair->value;		if(pair->key == 14)        /* Get the 'message' of the packet */			message = pair->value;		if(pair->key == 13)        /* Get the command associated with this packet */			command = pair->value;		if(pair->key == 63)        /* IMVironment name and version */			imv = pair->value;		if(pair->key == 64)        /* Not sure, but it does vary with initialization of Doodle */			unknown = pair->value; /* So, I'll keep it (for a little while atleast) */		l = l->next;	}	/* If this packet is an IMVIRONMENT, handle it accordingly */	if(service != NULL && imv != NULL && !strcmp(service, "IMVIRONMENT"))	{		/* Check for a Doodle packet and handle it accordingly */		if(!strcmp(imv, "doodle;11"))			yahoo_doodle_process(gc, me, from, command, message);		/* If an IMVIRONMENT packet comes without a specific imviroment name */		if(!strcmp(imv, ";0"))		{			/* It is unfortunately time to close all IMVironments with the remote client */			yahoo_doodle_command_got_shutdown(gc, from);		}	}}void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt){	char *from = NULL;	char *to = NULL;	char *msg = NULL;	char *url = NULL;	char *imv = NULL;	long expires = 0;	PurpleXfer *xfer;	struct yahoo_data *yd;	struct yahoo_xfer_data *xfer_data;	char *service = NULL;	char *filename = NULL;	unsigned long filesize = 0L;	GSList *l;	yd = gc->proto_data;	for (l = pkt->hash; l; l = l->next) {		struct yahoo_pair *pair = l->data;		if (pair->key == 4)			from = pair->value;		if (pair->key == 5)			to = pair->value;		if (pair->key == 14)			msg = pair->value;		if (pair->key == 20)			url = pair->value;		if (pair->key == 38)			expires = strtol(pair->value, NULL, 10);		if (pair->key == 27)			filename = pair->value;		if (pair->key == 28)			filesize = atol(pair->value);		if (pair->key == 49)			service = pair->value;		if (pair->key == 63)			imv = pair->value;	}	/*	 * The remote user has changed their IMVironment.  We	 * record it for later use.	 */	if (from && imv && service && (strcmp("IMVIRONMENT", service) == 0)) {		g_hash_table_replace(yd->imvironments, g_strdup(from), g_strdup(imv));		return;	}	if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) {		if (service && (strcmp("FILEXFER", service) != 0)) {			purple_debug_misc("yahoo", "unhandled service 0x%02x\n", pkt->service);			return;		}	}	if (msg) {		char *tmp;		tmp = strchr(msg, '\006');		if (tmp)			*tmp = '\0';	}	if (!url || !from)		return;	/* Setup the Yahoo-specific file transfer data */	xfer_data = g_new0(struct yahoo_xfer_data, 1);	xfer_data->gc = gc;	if (!purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) {		g_free(xfer_data);		return;	}	purple_debug_misc("yahoo_filexfer", "Host is %s, port is %d, path is %s, and the full url was %s.\n",	                xfer_data->host, xfer_data->port, xfer_data->path, url);	/* Build the file transfer handle. */	xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);	if (xfer)	{		xfer->data = xfer_data;		/* Set the info about the incoming file. */		if (filename) {			char *utf8_filename = yahoo_string_decode(gc, filename, TRUE);			purple_xfer_set_filename(xfer, utf8_filename);			g_free(utf8_filename);		} else {			gchar *start, *end;			start = g_strrstr(xfer_data->path, "/");			if (start)				start++;			end = g_strrstr(xfer_data->path, "?");			if (start && *start && end) {				char *utf8_filename;				filename = g_strndup(start, end - start);				utf8_filename = yahoo_string_decode(gc, filename, TRUE);				g_free(filename);				purple_xfer_set_filename(xfer, utf8_filename);				g_free(utf8_filename);				filename = NULL;			}		}		purple_xfer_set_size(xfer, filesize);		/* Setup our I/O op functions */		purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init);		purple_xfer_set_start_fnc(xfer,       yahoo_xfer_start);		purple_xfer_set_end_fnc(xfer,         yahoo_xfer_end);		purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);		purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);		purple_xfer_set_read_fnc(xfer,        yahoo_xfer_read);		purple_xfer_set_write_fnc(xfer,       yahoo_xfer_write);		/* Now perform the request */		purple_xfer_request(xfer);	}}PurpleXfer *yahoo_new_xfer(PurpleConnection *gc, const char *who){	PurpleXfer *xfer;	struct yahoo_xfer_data *xfer_data;		g_return_val_if_fail(who != NULL, NULL);		xfer_data = g_new0(struct yahoo_xfer_data, 1);	xfer_data->gc = gc;		/* Build the file transfer handle. */	xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);	if (xfer)	{		xfer->data = xfer_data;		/* Setup our I/O op functions */		purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init);		purple_xfer_set_start_fnc(xfer,       yahoo_xfer_start);		purple_xfer_set_end_fnc(xfer,         yahoo_xfer_end);		purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);		purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);		purple_xfer_set_read_fnc(xfer,        yahoo_xfer_read);		purple_xfer_set_write_fnc(xfer,       yahoo_xfer_write);	}	return xfer;}void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file){	PurpleXfer *xfer = yahoo_new_xfer(gc, who);	g_return_if_fail(xfer != NULL);	/* Now perform the request */	if (file)		purple_xfer_request_accepted(xfer, file);	else		purple_xfer_request(xfer);}

⌨️ 快捷键说明

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