void *_transport)
{
struct irc_transport *transport = _transport;
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
struct irc_line *l;
g_assert(transport);
GIOStatus status;
gboolean ret = TRUE;
- while ((status = irc_recv_line(c, transport->incoming_iconv, &error,
+ while ((status = irc_recv_line(c, backend_data->incoming_iconv, &error,
&l)) == G_IO_STATUS_NORMAL) {
ret &= transport->callbacks->recv(transport, l);
void irc_transport_set_callbacks(struct irc_transport *transport,
const struct irc_transport_callbacks *callbacks, void *userdata)
{
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
transport->userdata = userdata;
transport->callbacks = callbacks;
- transport->incoming_id = g_io_add_watch(
- transport->incoming, G_IO_IN | G_IO_HUP,
+ backend_data->incoming_id = g_io_add_watch(
+ backend_data->incoming, G_IO_IN | G_IO_HUP,
handle_transport_receive, transport);
}
struct irc_transport *irc_transport_new_iochannel(GIOChannel *iochannel)
{
struct irc_transport *ret = g_new0(struct irc_transport, 1);
+ struct irc_transport_data_iochannel *backend_data = g_new0(struct irc_transport_data_iochannel, 1);
- ret->incoming = iochannel;
+ ret->backend_data = backend_data;
+ backend_data->incoming = iochannel;
ret->pending_lines = g_queue_new();
- ret->outgoing_iconv = ret->incoming_iconv = (GIConv)-1;
- g_io_channel_ref(ret->incoming);
+ backend_data->outgoing_iconv = backend_data->incoming_iconv = (GIConv)-1;
+ g_io_channel_ref(backend_data->incoming);
return ret;
}
void irc_transport_disconnect(struct irc_transport *transport)
{
- if (transport->incoming == NULL)
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
+
+ if (backend_data->incoming == NULL)
return; /* We're already disconnected */
- g_io_channel_unref(transport->incoming);
+ g_io_channel_unref(backend_data->incoming);
- g_source_remove(transport->incoming_id);
- if (transport->outgoing_id)
- g_source_remove(transport->outgoing_id);
+ g_source_remove(backend_data->incoming_id);
+ if (backend_data->outgoing_id)
+ g_source_remove(backend_data->outgoing_id);
- transport->incoming = NULL;
+ backend_data->incoming = NULL;
transport->callbacks->disconnect(transport);
}
void free_irc_transport(struct irc_transport *transport)
{
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
/* Should already be disconnected */
- g_assert(transport->incoming == NULL);
+ g_assert(backend_data->incoming == NULL);
g_free(transport->charset);
- if (transport->outgoing_iconv != (GIConv)-1)
- g_iconv_close(transport->outgoing_iconv);
- if (transport->incoming_iconv != (GIConv)-1)
- g_iconv_close(transport->incoming_iconv);
+ if (backend_data->outgoing_iconv != (GIConv)-1)
+ g_iconv_close(backend_data->outgoing_iconv);
+ if (backend_data->incoming_iconv != (GIConv)-1)
+ g_iconv_close(backend_data->incoming_iconv);
g_assert(transport->pending_lines != NULL);
g_queue_foreach(transport->pending_lines, free_pending_line, NULL);
g_queue_free(transport->pending_lines);
+ g_free(backend_data);
g_free(transport);
}
gboolean transport_set_charset(struct irc_transport *transport, const char *name)
{
GIConv tmp;
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
if (name != NULL) {
tmp = g_iconv_open(name, "UTF-8");
tmp = (GIConv)-1;
}
- if (transport->outgoing_iconv != (GIConv)-1)
- g_iconv_close(transport->outgoing_iconv);
+ if (backend_data->outgoing_iconv != (GIConv)-1)
+ g_iconv_close(backend_data->outgoing_iconv);
- transport->outgoing_iconv = tmp;
+ backend_data->outgoing_iconv = tmp;
if (name != NULL) {
tmp = g_iconv_open("UTF-8", name);
tmp = (GIConv)-1;
}
- if (transport->incoming_iconv != (GIConv)-1)
- g_iconv_close(transport->incoming_iconv);
+ if (backend_data->incoming_iconv != (GIConv)-1)
+ g_iconv_close(backend_data->incoming_iconv);
- transport->incoming_iconv = tmp;
+ backend_data->incoming_iconv = tmp;
g_free(transport->charset);
transport->charset = g_strdup(name);
{
gboolean ret = FALSE;
struct irc_transport *transport = _transport;
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
GIOStatus status;
- g_assert(ioc == transport->incoming);
+ g_assert(ioc == backend_data->incoming);
- status = g_io_channel_flush(transport->incoming, NULL);
+ status = g_io_channel_flush(backend_data->incoming, NULL);
if (status == G_IO_STATUS_AGAIN)
ret = TRUE;
GError *error = NULL;
struct irc_line *l = g_queue_pop_head(transport->pending_lines);
- g_assert(transport->incoming != NULL);
- status = irc_send_line(transport->incoming,
- transport->outgoing_iconv, l, &error);
+ g_assert(backend_data->incoming != NULL);
+ status = irc_send_line(backend_data->incoming,
+ backend_data->outgoing_iconv, l, &error);
switch (status) {
case G_IO_STATUS_AGAIN:
g_error_free(error);
break;
case G_IO_STATUS_EOF:
- transport->outgoing_id = 0;
+ backend_data->outgoing_id = 0;
transport->callbacks->hangup(transport);
break;
}
- status = g_io_channel_flush(transport->incoming, &error);
+ status = g_io_channel_flush(backend_data->incoming, &error);
switch (status) {
case G_IO_STATUS_EOF:
g_assert_not_reached();
}
if (!ret)
- transport->outgoing_id = 0;
+ backend_data->outgoing_id = 0;
return ret;
}
gboolean transport_send_line(struct irc_transport *transport,
const struct irc_line *l)
{
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
GError *error = NULL;
GIOStatus status;
- if (transport->incoming == NULL)
+ if (backend_data->incoming == NULL)
return FALSE;
- if (transport->outgoing_id != 0) {
+ if (backend_data->outgoing_id != 0) {
g_queue_push_tail(transport->pending_lines, linedup(l));
return TRUE;
}
- status = irc_send_line(transport->incoming, transport->outgoing_iconv, l, &error);
+ status = irc_send_line(backend_data->incoming, backend_data->outgoing_iconv, l, &error);
switch (status) {
case G_IO_STATUS_AGAIN:
- transport->outgoing_id = g_io_add_watch(transport->incoming, G_IO_OUT,
+ backend_data->outgoing_id = g_io_add_watch(backend_data->incoming, G_IO_OUT,
transport_send_queue, transport);
g_queue_push_tail(transport->pending_lines, linedup(l));
break;
break;
}
- status = g_io_channel_flush(transport->incoming, &error);
+ status = g_io_channel_flush(backend_data->incoming, &error);
switch (status) {
case G_IO_STATUS_EOF:
case G_IO_STATUS_NORMAL:
break;
case G_IO_STATUS_AGAIN:
- transport->outgoing_id = g_io_add_watch(transport->incoming, G_IO_OUT,
+ backend_data->outgoing_id = g_io_add_watch(backend_data->incoming, G_IO_OUT,
transport_send_queue, transport);
break;
case G_IO_STATUS_ERROR:
void transport_parse_buffer(struct irc_transport *transport)
{
- handle_transport_receive(transport->incoming,
- g_io_channel_get_buffer_condition(transport->incoming) & G_IO_IN,
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
+ handle_transport_receive(backend_data->incoming,
+ g_io_channel_get_buffer_condition(backend_data->incoming) & G_IO_IN,
transport);
/* g_assert(g_io_channel_get_buffer_condition(transport->incoming) == 0); */
gboolean transport_blocking_recv(struct irc_transport *transport, struct irc_line **l)
{
- GIOFlags old_flags = g_io_channel_get_flags(transport->incoming);
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
+ GIOFlags old_flags = g_io_channel_get_flags(backend_data->incoming);
GError *error = NULL;
GIOStatus status;
gboolean ret;
- g_io_channel_set_flags(transport->incoming, old_flags & ~G_IO_FLAG_NONBLOCK, &error);
+ g_io_channel_set_flags(backend_data->incoming, old_flags & ~G_IO_FLAG_NONBLOCK, &error);
- status = irc_recv_line(transport->incoming, transport->incoming_iconv, &error, l);
+ status = irc_recv_line(backend_data->incoming, backend_data->incoming_iconv, &error, l);
- g_io_channel_set_flags(transport->incoming, old_flags, &error);
+ g_io_channel_set_flags(backend_data->incoming, old_flags, &error);
ret = handle_recv_status(transport, status, error);
socklen_t len = sizeof(struct sockaddr_storage);
struct sockaddr_storage sa;
char hostname[NI_MAXHOST];
+ struct irc_transport_data_iochannel *backend_data = (struct irc_transport_data_iochannel *)transport->backend_data;
- fd = g_io_channel_unix_get_fd(transport->incoming);
+ fd = g_io_channel_unix_get_fd(backend_data->incoming);
if (getpeername (fd, (struct sockaddr *)&sa, &len) < 0) {
return NULL;