コード例 #1
0
ファイル: fetion.c プロジェクト: Gankraft/fetion
static void sendlater(PurpleConnection * gc, const char *buf)
{
	struct fetion_account_data *sip = gc->proto_data;

	if (!sip->connecting) {
		purple_debug_info("fetion", "connecting to %s port %d\n",
				  sip->
				  realhostname ? sip->realhostname : "{NULL}",
				  sip->realport);
		if (purple_proxy_connect
		    (gc, sip->account, sip->realhostname, sip->realport,
		     send_later_cb, gc) == NULL) {
			purple_connection_error_reason(gc,
						       PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
						       _
						       ("Couldn't create socket"));
		}
		sip->connecting = TRUE;
	}

	if (purple_circ_buffer_get_max_read(sip->txbuf) > 0)
		purple_circ_buffer_append(sip->txbuf, "\r\n", 2);

	purple_circ_buffer_append(sip->txbuf, buf, strlen(buf));
}
コード例 #2
0
ファイル: bosh.c プロジェクト: Lilitana/Pidgin
static void
http_connection_send_request(PurpleHTTPConnection *conn, const GString *req)
{
	char *data;
	int ret;
	size_t len;

	/* Sending something to the server, restart the inactivity timer */
	jabber_stream_restart_inactivity_timer(conn->bosh->js);

	data = g_strdup_printf("POST %s HTTP/1.1\r\n"
	                       "Host: %s\r\n"
	                       "User-Agent: %s\r\n"
	                       "Content-Encoding: text/xml; charset=utf-8\r\n"
	                       "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n"
	                       "%s",
	                       conn->bosh->path, conn->bosh->host, bosh_useragent,
	                       req->len, req->str);

	len = strlen(data);

	++conn->requests;
	++conn->bosh->requests;

	if (purple_debug_is_unsafe() && purple_debug_is_verbose())
		/* Will contain passwords for SASL PLAIN and is verbose */
		purple_debug_misc("jabber", "BOSH (%p): Sending %s\n", conn, data);
	else if (purple_debug_is_verbose())
		purple_debug_misc("jabber", "BOSH (%p): Sending request of "
		                            "%" G_GSIZE_FORMAT " bytes.\n", conn, len);

	if (conn->writeh == 0)
		ret = http_connection_do_send(conn, data, len);
	else {
		ret = -1;
		errno = EAGAIN;
	}

	if (ret < 0 && errno != EAGAIN) {
		/*
		 * TODO: Handle this better. Probably requires a PurpleBOSHConnection
		 * buffer that stores what is "being sent" until the
		 * PurpleHTTPConnection reports it is fully sent.
		 */
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
				g_strerror(errno));
		purple_connection_error_reason(conn->bosh->js->gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				tmp);
		g_free(tmp);
		return;
	} else if (ret < len) {
		if (ret < 0)
			ret = 0;
		if (conn->writeh == 0)
			conn->writeh = purple_input_add(conn->psc ? conn->psc->fd : conn->fd,
					PURPLE_INPUT_WRITE, http_connection_send_cb, conn);
		purple_circ_buffer_append(conn->write_buf, data + ret, len - ret);
	}
}
コード例 #3
0
ファイル: flap_connection.c プロジェクト: Draghtnod/pidgin
static void
flap_connection_send_byte_stream(ByteStream *bs, FlapConnection *conn, size_t count)
{
	if (conn == NULL)
		return;

	/* Make sure we don't send past the end of the bs */
	if (count > byte_stream_bytes_left(bs))
		count = byte_stream_bytes_left(bs); /* truncate to remaining space */

	if (count == 0)
		return;

	/* Add everything to our outgoing buffer */
	purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count);

	/* If we haven't already started writing stuff, then start the cycle */
	if (conn->watcher_outgoing == 0)
	{
		if (conn->gsc) {
			conn->watcher_outgoing = purple_input_add(conn->gsc->fd,
					PURPLE_INPUT_WRITE, send_cb, conn);
			send_cb(conn, -1, 0);
		} else if (conn->fd >= 0) {
			conn->watcher_outgoing = purple_input_add(conn->fd,
					PURPLE_INPUT_WRITE, send_cb, conn);
			send_cb(conn, -1, 0);
		}
	}
}
コード例 #4
0
ファイル: httpconn.c プロジェクト: bf4/pidgin-mac
static gboolean
write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len)
{
	gssize res; /* result of the write operation */

	if (httpconn->tx_handler == 0)
		res = write(httpconn->fd, data, data_len);
	else
	{
		res = -1;
		errno = EAGAIN;
	}

	if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK)))
	{
		msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE);
		return FALSE;
	}

	if (res < 0 || res < data_len)
	{
		if (res < 0)
			res = 0;
		if (httpconn->tx_handler == 0 && httpconn->fd)
			httpconn->tx_handler = purple_input_add(httpconn->fd,
				PURPLE_INPUT_WRITE, httpconn_write_cb, httpconn);
		purple_circ_buffer_append(httpconn->tx_buf, data + res,
			data_len - res);
	}

	return TRUE;
}
コード例 #5
0
ファイル: fetion.c プロジェクト: Gankraft/fetion
static void sendout_pkt(PurpleConnection * gc, const gchar * buf)
{
	struct fetion_account_data *sip = gc->proto_data;
	time_t currtime = time(NULL);
	gint writelen = strlen(buf);
	gint ret;

	purple_debug(PURPLE_DEBUG_MISC, "fetion",
		     "\n\nsending - %s\n######\n%s\n######\n\n",
		     ctime(&currtime), buf);

	if (sip->fd < 0) {
		sendlater(gc, buf);
		return;
	}

	if (sip->tx_handler) {
		ret = -1;
		errno = EAGAIN;
	} else
		ret = write(sip->fd, buf, writelen);

	if (ret < 0 && errno == EAGAIN)
		ret = 0;
	else if (ret <= 0) {	/* XXX: When does this happen legitimately? */
		sendlater(gc, buf);
		return;
	}

	if (ret < writelen) {
		if (!sip->tx_handler)
			sip->tx_handler = purple_input_add(sip->fd,
							   PURPLE_INPUT_WRITE,
							   fetion_canwrite_cb,
							   gc);

		/* XXX: is it OK to do this? You might get part of a request sent
		   with part of another. */
		if (sip->txbuf->bufused > 0)
			purple_circ_buffer_append(sip->txbuf, "\r\n", 2);

		purple_circ_buffer_append(sip->txbuf, buf + ret,
					  writelen - ret);
	}

}
コード例 #6
0
ファイル: qq_network.c プロジェクト: cysfek/openq-ng
static gint tcp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
{
	qq_data *qd;
	qq_connection *conn;
	gint ret;

	g_return_val_if_fail(data != NULL && data_len > 0, -1);

	g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1);
	qd = (qq_data *) gc->proto_data;

	conn = connection_find(qd, qd->fd);
	g_return_val_if_fail(conn, -1);

#if 0
	purple_debug_info("TCP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd);
#endif

	if (conn->can_write_handler == 0) {
		ret = write(qd->fd, data, data_len);
	} else {
		ret = -1;
		errno = EAGAIN;
	}

	/*
	purple_debug_info("TCP_SEND_OUT",
		"Socket %d, total %d bytes is sent %d\n", qd->fd, data_len, ret);
	*/
	if (ret < 0 && errno == EAGAIN) {
		/* socket is busy, send later */
		purple_debug_info("TCP_SEND_OUT", "Socket is busy and send later\n");
		ret = 0;
	} else if (ret <= 0) {
		/* TODO: what to do here - do we really have to disconnect? */
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
				g_strerror(errno));
		purple_debug_error("TCP_SEND_OUT",
			"Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno));
		purple_connection_error_reason(gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
		g_free(tmp);
		return ret;
	}

	if (ret < data_len) {
		purple_debug_info("TCP_SEND_OUT", "Add %d bytes to buffer\n", data_len - ret);
		if (conn->can_write_handler == 0) {
			conn->can_write_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, gc);
		}
		if (conn->tcp_txbuf == NULL) {
			conn->tcp_txbuf = purple_circ_buffer_new(4096);
		}
		purple_circ_buffer_append(conn->tcp_txbuf, data + ret, data_len - ret);
	}
	return ret;
}
コード例 #7
0
ファイル: servconn.c プロジェクト: Mons/libpurple-mini
gssize
msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
{
	gssize ret = 0;

	g_return_val_if_fail(servconn != NULL, 0);

	if (!servconn->session->http_method)
	{
		if (servconn->tx_handler == 0) {
			switch (servconn->type)
			{
				case MSN_SERVCONN_NS:
				case MSN_SERVCONN_SB:
					ret = write(servconn->fd, buf, len);
					break;
#if 0
				case MSN_SERVCONN_DC:
					ret = write(servconn->fd, &buf, sizeof(len));
					ret = write(servconn->fd, buf, len);
					break;
#endif
				default:
					ret = write(servconn->fd, buf, len);
					break;
			}
		} else {
			ret = -1;
			errno = EAGAIN;
		}

		if (ret < 0 && errno == EAGAIN)
			ret = 0;
		if (ret >= 0 && ret < len) {
			if (servconn->tx_handler == 0)
				servconn->tx_handler = purple_input_add(
					servconn->fd, PURPLE_INPUT_WRITE,
					servconn_write_cb, servconn);
			purple_circ_buffer_append(servconn->tx_buf, buf + ret,
				len - ret);
		}
	}
	else
	{
		ret = msn_httpconn_write(servconn->httpconn, buf, len);
	}

	if (ret == -1)
	{
		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE, NULL);
	}

	servconn_timeout_renew(servconn);
	return ret;
}
コード例 #8
0
ファイル: jabber.c プロジェクト: Draghtnod/pidgin
static gint
_send_data(PurpleBuddy *pb, char *message)
{
	gint ret;
	int len = strlen(message);
	BonjourBuddy *bb = purple_buddy_get_protocol_data(pb);
	BonjourJabberConversation *bconv = bb->conversation;

	/* If we're not ready to actually send, append it to the buffer */
	if (bconv->tx_handler != 0
			|| bconv->connect_data != NULL
			|| bconv->sent_stream_start != FULLY_SENT
			|| !bconv->recv_stream_start
			|| purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) {
		ret = -1;
		errno = EAGAIN;
	} else {
		ret = send(bconv->socket, message, len, 0);
	}

	if (ret == -1 && errno == EAGAIN)
		ret = 0;
	else if (ret <= 0) {
		PurpleConversation *conv;
		PurpleAccount *account;
		const char *error = g_strerror(errno);

		purple_debug_error("bonjour", "Error sending message to buddy %s error: %s\n",
				   purple_buddy_get_name(pb), error ? error : "(null)");

		account = purple_buddy_get_account(pb);

		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account);
		if (conv != NULL)
			purple_conversation_write(conv, NULL,
				  _("Unable to send message."),
				  PURPLE_MESSAGE_SYSTEM, time(NULL));

		bonjour_jabber_close_conversation(bb->conversation);
		bb->conversation = NULL;
		return -1;
	}

	if (ret < len) {
		/* Don't interfere with the stream starting */
		if (bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start && bconv->tx_handler == 0)
			bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE,
				_send_data_write_cb, pb);
		purple_circ_buffer_append(bconv->tx_buf, message + ret, len - ret);
	}

	return ret;
}
コード例 #9
0
ファイル: irc.c プロジェクト: dylex/pidgin
int irc_send_len(struct irc_conn *irc, const char *buf, int buflen)
{
	int ret;
 	char *tosend = g_strdup(buf);

	purple_signal_emit(_irc_plugin, "irc-sending-text", purple_account_get_connection(irc->account), &tosend);

	if (tosend == NULL)
		return 0;

	if (!purple_strequal(tosend, buf)) {
		buflen = strlen(tosend);
	}

	if (purple_debug_is_verbose()) {
		char *clean = purple_utf8_salvage(tosend);
		clean = g_strstrip(clean);
		purple_debug_misc("irc", "<< %s\n", clean);
		g_free(clean);
	}

	/* If we're not buffering writes, try to send immediately */
	if (!irc->writeh)
		ret = do_send(irc, tosend, buflen);
	else {
		ret = -1;
		errno = EAGAIN;
	}

	/* purple_debug(PURPLE_DEBUG_MISC, "irc", "sent%s: %s",
		irc->gsc ? " (ssl)" : "", tosend); */
	if (ret <= 0 && errno != EAGAIN) {
		PurpleConnection *gc = purple_account_get_connection(irc->account);
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
			g_strerror(errno));
		purple_connection_error_reason (gc,
			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
		g_free(tmp);
	} else if (ret < buflen) {
		if (ret < 0)
			ret = 0;
		if (!irc->writeh)
			irc->writeh = purple_input_add(
				irc->gsc ? irc->gsc->fd : irc->fd,
				PURPLE_INPUT_WRITE, irc_send_cb, irc);
		purple_circ_buffer_append(irc->outbuf, tosend + ret,
			buflen - ret);
	}
	g_free(tosend);
	return ret;
}
コード例 #10
0
ファイル: peer.c プロジェクト: Tasssadar/libpurple
/**
 * This should be called by OFT/ODC code to send a standard OFT or ODC
 * frame across the peer connection along with some payload data.  Or
 * maybe a file.  Anything, really.
 */
void
peer_connection_send(PeerConnection *conn, ByteStream *bs)
{
	/* Add everything to our outgoing buffer */
	purple_circ_buffer_append(conn->buffer_outgoing, bs->data, bs->len);

	/* If we haven't already started writing stuff, then start the cycle */
	if ((conn->watcher_outgoing == 0) && (conn->fd >= 0))
	{
		conn->watcher_outgoing = purple_input_add(conn->fd,
				PURPLE_INPUT_WRITE, send_cb, conn);
		send_cb(conn, conn->fd, 0);
	}
}
コード例 #11
0
ファイル: f_portrait.c プロジェクト: cxcxcxcx/fetion
void UploadPortrait(gpointer data, gint source, const gchar * error_message)
{
	struct fetion_account_data *sip = data;
	PurpleStoredImage *img = sip->icon;
	gchar *head;
	gchar *buf;
	gint head_len;
	gint ret, lenth, writed;
	gconstpointer img_data = purple_imgstore_get_data(img);
	size_t size = purple_imgstore_get_size(img);

	head = g_strdup_printf("POST /%s/setportrait.aspx HTTP/1.1\r\n"
			       "User-Agent: IIC2.0/PC 3.3.0370\r\n"
			       "Content-Type: image/jpeg\r\n"
			       "Host: %s\r\n"
			       "Cookie: ssic=%s\r\n"
			       "Content-Length: %d\r\n\r\n",
			       sip->UploadPrefix,
			       sip->UploadServer, sip->ssic, size);
	purple_debug_info("fetion:", "UploadPortrait:head[%s][%d]\n", head,
			  size);
	head_len = strlen(head);
	buf = g_malloc(head_len + size);
	memcpy(buf, head, head_len);
	memcpy(buf + head_len, img_data, size);
	lenth = size + strlen(head);
	writed = 0;
	ret = write(source, buf, lenth);
	if (ret < 0 && errno == EAGAIN)
		ret = 0;
	g_return_if_fail(ret >= 0);
	if (ret < lenth) {
		purple_circ_buffer_append(sip->icon_buf, buf + ret,
					  lenth - ret);
		sip->icon_handler =
		    purple_input_add(source, PURPLE_INPUT_WRITE,
				     (PurpleInputFunction) UploadPortrait_cb,
				     sip);

	}
	g_free(head);
	sip->icon = NULL;
	purple_imgstore_unref(img);
}
コード例 #12
0
ファイル: yahoo_packet.c プロジェクト: Draghtnod/pidgin
int yahoo_packet_send(struct yahoo_packet *pkt, YahooData *yd)
{
	size_t len;
	gssize ret;
	guchar *data;

	if (yd->fd < 0)
		return -1;

	len = yahoo_packet_build(pkt, 0, yd->wm, yd->jp, &data);

	yahoo_packet_dump(data, len);
	if (yd->txhandler == 0)
		ret = write(yd->fd, data, len);
	else {
		ret = -1;
		errno = EAGAIN;
	}

	if (ret < 0 && errno == EAGAIN)
		ret = 0;
	else if (ret <= 0) {
		purple_debug_warning("yahoo", "Only wrote %" G_GSSIZE_FORMAT
				" of %" G_GSIZE_FORMAT " bytes!\n", ret, len);
		g_free(data);
		return ret;
	}

	if ((gsize)ret < len) {
		if (yd->txhandler == 0)
			yd->txhandler = purple_input_add(yd->fd, PURPLE_INPUT_WRITE,
				yahoo_packet_send_can_write, yd);
		purple_circ_buffer_append(yd->txbuf, data + ret, len - ret);
	}

	g_free(data);

	return ret;
}
コード例 #13
0
ファイル: irc.c プロジェクト: arminius2/apolloim
int irc_send(struct irc_conn *irc, const char *buf)
{
	int ret, buflen;
 	char *tosend= g_strdup(buf);

	purple_signal_emit(_irc_plugin, "irc-sending-text", purple_account_get_connection(irc->account), &tosend);
	if (tosend == NULL)
		return 0;

	buflen = strlen(tosend);


	/* If we're not buffering writes, try to send immediately */
	if (!irc->writeh)
		ret = do_send(irc, tosend, buflen);
	else {
		ret = -1;
		errno = EAGAIN;
	}

	/* purple_debug(PURPLE_DEBUG_MISC, "irc", "sent%s: %s",
		irc->gsc ? " (ssl)" : "", tosend); */
	if (ret <= 0 && errno != EAGAIN) {
		purple_connection_error(purple_account_get_connection(irc->account),
				      _("Server has disconnected"));
	} else if (ret < buflen) {
		if (ret < 0)
			ret = 0;
		if (!irc->writeh)
			irc->writeh = purple_input_add(
				irc->gsc ? irc->gsc->fd : irc->fd,
				PURPLE_INPUT_WRITE, irc_send_cb, irc);
		purple_circ_buffer_append(irc->outbuf, tosend + ret,
			buflen - ret);
	}
	g_free(tosend);
	return ret;
}
コード例 #14
0
ファイル: bosh.c プロジェクト: Lilitana/Pidgin
static void
jabber_bosh_connection_send(PurpleBOSHConnection *conn,
                            const PurpleBOSHPacketType type, const char *data)
{
	PurpleHTTPConnection *chosen;
	GString *packet = NULL;

	if (type != PACKET_FLUSH && type != PACKET_TERMINATE) {
		/*
		 * Unless this is a flush (or session terminate, which needs to be
		 * sent immediately), queue up the data and start a timer to flush
		 * the buffer.
		 */
		if (data) {
			int len = data ? strlen(data) : 0;
			purple_circ_buffer_append(conn->pending, data, len);
		}

		if (purple_debug_is_verbose())
			purple_debug_misc("jabber", "bosh: %p has %" G_GSIZE_FORMAT " bytes in "
			                  "the buffer.\n", conn, conn->pending->bufused);
		if (conn->send_timer == 0)
			conn->send_timer = purple_timeout_add_seconds(BUFFER_SEND_IN_SECS,
					send_timer_cb, conn);
		return;
	}

	chosen = find_available_http_connection(conn);

	if (!chosen) {
		if (type == PACKET_FLUSH)
			return;
		/*
		 * For non-ordinary traffic, we can't 'buffer' it, so use the
		 * first connection.
		 */
		chosen = conn->connections[0];

		if (chosen->state != HTTP_CONN_CONNECTED) {
			purple_debug_warning("jabber", "Unable to find a ready BOSH "
					"connection. Ignoring send of type 0x%02x.\n", type);
			return;
		}
	}

	/* We're flushing the send buffer, so remove the send timer */
	if (conn->send_timer != 0) {
		purple_timeout_remove(conn->send_timer);
		conn->send_timer = 0;
	}

	packet = g_string_new(NULL);

	g_string_printf(packet, "<body "
	                "rid='%" G_GUINT64_FORMAT "' "
	                "sid='%s' "
	                "to='%s' "
	                "xml:lang='en' "
	                "xmlns='" NS_BOSH "' "
	                "xmlns:xmpp='" NS_XMPP_BOSH "'",
	                ++conn->rid,
	                conn->sid,
	                conn->js->user->domain);

	if (conn->js->reinit) {
		packet = g_string_append(packet, " xmpp:restart='true'/>");
		/* TODO: Do we need to wait for a response? */
		conn->js->reinit = FALSE;
	} else {
		gsize read_amt;
		if (type == PACKET_TERMINATE)
			packet = g_string_append(packet, " type='terminate'");

		packet = g_string_append_c(packet, '>');

		while ((read_amt = purple_circ_buffer_get_max_read(conn->pending)) > 0) {
			packet = g_string_append_len(packet, conn->pending->outptr, read_amt);
			purple_circ_buffer_mark_read(conn->pending, read_amt);
		}

		if (data)
			packet = g_string_append(packet, data);
		packet = g_string_append(packet, "</body>");
	}

	http_connection_send_request(chosen, packet);
}