示例#1
0
文件: ycht.c 项目: Distrotech/pidgin
static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	YchtConn *ycht = data;
	int ret, writelen;
	const gchar *output = NULL;

	writelen = purple_circular_buffer_get_max_read(ycht->txbuf);

	if (writelen == 0) {
		purple_input_remove(ycht->tx_handler);
		ycht->tx_handler = 0;
		return;
	}

	output = purple_circular_buffer_get_output(ycht->txbuf);

	ret = write(ycht->fd, output, writelen);

	if (ret < 0 && errno == EAGAIN)
		return;
	else if (ret <= 0) {
		/* TODO: error handling */
/*
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
				g_strerror(errno));
		purple_connection_error(purple_account_get_connection(irc->account),
			      PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
		g_free(tmp);
*/
		return;
	}

	purple_circular_buffer_mark_read(ycht->txbuf, ret);

}
示例#2
0
static void
purple_circular_buffer_get_property(GObject *obj, guint param_id,
                                    GValue *value, GParamSpec *pspec)
{
	PurpleCircularBuffer *buffer = PURPLE_CIRCULAR_BUFFER(obj);

	switch(param_id) {
		case PROP_GROW_SIZE:
			g_value_set_ulong(value,
			                  purple_circular_buffer_get_grow_size(buffer));
			break;
		case PROP_BUFFER_USED:
			g_value_set_ulong(value,
			                  purple_circular_buffer_get_used(buffer));
			break;
		case PROP_INPUT:
			g_value_set_pointer(value,
			                    (void*) purple_circular_buffer_get_input(buffer));
			break;
		case PROP_OUTPUT:
			g_value_set_pointer(value,
			                    (void*) purple_circular_buffer_get_output(buffer));
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
			break;
	}
}
/**
 * @param source When this function is called as a callback source is
 *        set to the fd that triggered the callback.  But this function
 *        is also called directly from flap_connection_send_byte_stream(),
 *        in which case source will be -1.  So don't use source--use
 *        conn->gsc or conn->fd instead.
 */
static void
send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	FlapConnection *conn;
	int writelen, ret;
	const gchar *output = NULL;

	conn = data;
	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
	output = purple_circular_buffer_get_output(conn->buffer_outgoing);

	if (writelen == 0)
	{
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		return;
	}

	if (conn->gsc)
		ret = purple_ssl_write(conn->gsc, output, writelen);
	else
		ret = send(conn->fd, output, writelen, 0);
	if (ret <= 0)
	{
		if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
			/* No worries */
			return;

		/* Error! */
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		if (conn->gsc) {
			purple_ssl_close(conn->gsc);
			conn->gsc = NULL;
		} else {
			close(conn->fd);
			conn->fd = -1;
		}
		flap_connection_schedule_destroy(conn,
				OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno));
		return;
	}

	purple_circular_buffer_mark_read(conn->buffer_outgoing, ret);
}
示例#4
0
文件: peer.c 项目: Distrotech/pidgin
static void
send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	PeerConnection *conn;
	gsize writelen;
	gssize wrotelen;
	const gchar *output = NULL;

	conn = data;
	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);

	if (writelen == 0)
	{
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		/*
		 * The buffer is currently empty, so reset the current input
		 * and output positions to the start of the buffer.  We do
		 * this so that the next chunk of data that we put into the
		 * buffer can be read back out of the buffer in one fell swoop.
		 * Otherwise it gets fragmented and we have to read from the
		 * second half of the buffer than go back and read the rest of
		 * the chunk from the first half.
		 *
		 * We're using TCP, which is a stream based protocol, so this
		 * isn't supposed to matter.  However, experience has shown
		 * that at least the proxy file transfer code in AIM 6.1.41.2
		 * requires that the entire OFT frame arrive all at once.  If
		 * the frame is fragmented then AIM freaks out and aborts the
		 * file transfer.  Somebody should teach those guys how to
		 * write good TCP code.
		 */
		purple_circular_buffer_reset(conn->buffer_outgoing);
		return;
	}

	output = purple_circular_buffer_get_output(conn->buffer_outgoing);

	wrotelen = send(conn->fd, output, writelen, 0);
	if (wrotelen <= 0)
	{
		if (wrotelen < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
			/* No worries */
			return;

		if (conn->ready)
		{
			purple_input_remove(conn->watcher_outgoing);
			conn->watcher_outgoing = 0;
			close(conn->fd);
			conn->fd = -1;
			peer_connection_schedule_destroy(conn,
					OSCAR_DISCONNECT_LOST_CONNECTION, NULL);
		}
		else
		{
			/*
			 * This could happen when unable to send a negotiation
			 * frame to a peer proxy server.
			 */
			peer_connection_trynext(conn);
		}
		return;
	}

	purple_circular_buffer_mark_read(conn->buffer_outgoing, wrotelen);
	conn->lastactivity = time(NULL);
}