static void infinoted_plugin_document_stream_deinitialize(gpointer plugin_info) { InfinotedPluginDocumentStream* plugin; plugin = (InfinotedPluginDocumentStream*)plugin_info; while(plugin->streams != NULL) { infinoted_plugin_document_stream_close_stream( (InfinotedPluginDocumentStreamStream*)plugin->streams->data ); } inf_signal_handlers_disconnect_by_func( G_OBJECT(infinoted_plugin_manager_get_directory(plugin->manager)), G_CALLBACK(infinoted_plugin_document_stream_node_removed_cb), plugin ); if(plugin->watch != NULL) { inf_io_remove_watch( infinoted_plugin_manager_get_io(plugin->manager), plugin->watch ); } if(plugin->socket != -1) { close(plugin->socket); } }
static void infinoted_plugin_document_stream_close_stream( InfinotedPluginDocumentStreamStream* stream) { stream->plugin->streams = g_slist_remove(stream->plugin->streams, stream); if(stream->proxy != NULL || stream->subscribe_request != NULL) infinoted_plugin_document_stream_stop(stream, FALSE); if(stream->navigate_handle != NULL) { infinoted_plugin_util_navigate_cancel(stream->navigate_handle); stream->navigate_handle = NULL; } infinoted_plugin_document_stream_queue_finalize(&stream->send_queue); infinoted_plugin_document_stream_queue_finalize(&stream->recv_queue); inf_io_remove_watch( infinoted_plugin_manager_get_io(stream->plugin->manager), stream->watch ); g_free(stream->username); stream->username = NULL; close(stream->socket); stream->socket = -1; if(stream->status == INFINOTED_PLUGIN_DOCUMENT_STREAM_NORMAL) g_slice_free(InfinotedPluginDocumentStreamStream, stream); else if(stream->status == INFINOTED_PLUGIN_DOCUMENT_STREAM_RECEIVING) stream->status = INFINOTED_PLUGIN_DOCUMENT_STREAM_CLOSED; }
static void infinoted_plugin_document_stream_add_stream( InfinotedPluginDocumentStream* plugin, InfNativeSocket new_socket) { InfinotedPluginDocumentStreamStream* stream; stream = g_slice_new(InfinotedPluginDocumentStreamStream); stream->plugin = plugin; stream->socket = new_socket; stream->watch = inf_io_add_watch( infinoted_plugin_manager_get_io(plugin->manager), &stream->socket, INF_IO_INCOMING, infinoted_plugin_document_stream_io_func, stream, NULL ); stream->username = NULL; stream->status = INFINOTED_PLUGIN_DOCUMENT_STREAM_NORMAL; infinoted_plugin_document_stream_queue_initialize(&stream->send_queue); infinoted_plugin_document_stream_queue_initialize(&stream->recv_queue); stream->navigate_handle = NULL; stream->subscribe_request = NULL; stream->user_request = NULL; stream->proxy = NULL; stream->user = NULL; stream->buffer = NULL; plugin->streams = g_slist_prepend(plugin->streams, stream); }
static gboolean infinoted_plugin_document_stream_io_out( InfinotedPluginDocumentStreamStream* stream, GError** error) { GError* local_error; gsize sent; g_assert(stream->status == INFINOTED_PLUGIN_DOCUMENT_STREAM_NORMAL); g_assert(stream->send_queue.len > 0); local_error = NULL; sent = infinoted_plugin_document_stream_send_direct( stream, stream->send_queue.data + stream->send_queue.pos, stream->send_queue.len, &local_error ); if(local_error != NULL) { g_propagate_error(error, local_error); infinoted_plugin_document_stream_close_stream(stream); return FALSE; } else if(sent == 0) { infinoted_plugin_document_stream_close_stream(stream); return TRUE; } else { infinoted_plugin_document_stream_queue_consume(&stream->send_queue, sent); if(stream->send_queue.len == 0) { inf_io_update_watch( infinoted_plugin_manager_get_io(stream->plugin->manager), stream->watch, INF_IO_INCOMING ); } return TRUE; } }
static void infinoted_plugin_dbus_method_call_func(GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { /* Dispatch to the main thread */ InfinotedPluginDbus* plugin; InfinotedPluginDbusInvocation* thread_invocation; InfIo* io; plugin = (InfinotedPluginDbus*)user_data; thread_invocation = g_slice_new(InfinotedPluginDbusInvocation); thread_invocation->plugin = plugin; thread_invocation->ref_count = 1; thread_invocation->method_name = g_strdup(method_name); thread_invocation->parameters = g_variant_ref(parameters); thread_invocation->invocation = g_object_ref(invocation); thread_invocation->navigate = NULL; thread_invocation->request = NULL; thread_invocation->request_func = NULL; io = infinoted_plugin_manager_get_io(plugin->manager); inf_io_add_dispatch( io, infinoted_plugin_dbus_main_invocation, thread_invocation, infinoted_plugin_dbus_invocation_unref ); }
static gboolean infinoted_plugin_document_stream_send( InfinotedPluginDocumentStreamStream* stream, const void* data, gsize len) { GError* error; gsize sent; if(stream->send_queue.len > 0) { infinoted_plugin_document_stream_queue_append( &stream->send_queue, data, len ); return TRUE; } else { error = NULL; sent = infinoted_plugin_document_stream_send_direct( stream, data, len, &error ); if(error != NULL) { infinoted_log_warning( infinoted_plugin_manager_get_log(stream->plugin->manager), "Document stream error: %s", error->message ); g_error_free(error); return FALSE; } else { if(sent < len) { infinoted_plugin_document_stream_queue_append( &stream->send_queue, (const gchar*)data + sent, len - sent ); inf_io_update_watch( infinoted_plugin_manager_get_io(stream->plugin->manager), stream->watch, INF_IO_INCOMING | INF_IO_OUTGOING ); } return TRUE; } } }
static gboolean infinoted_plugin_document_stream_initialize(InfinotedPluginManager* manager, gpointer plugin_info, GError** error) { static const char ADDRESS_NAME[] = "org.infinote.infinoted"; struct sockaddr_un addr; InfinotedPluginDocumentStream* plugin; plugin = (InfinotedPluginDocumentStream*)plugin_info; plugin->manager = manager; plugin->socket = socket(AF_UNIX, SOCK_STREAM, 0); if(plugin->socket == -1) { infinoted_plugin_document_stream_make_system_error(errno, error); return FALSE; } /* TODO: Make the address configurable -- note that abstract paths * are a Linux extension. */ addr.sun_family = AF_UNIX; addr.sun_path[0] = '\0'; memcpy(&addr.sun_path[1], ADDRESS_NAME, sizeof(ADDRESS_NAME) - 1); memset( &addr.sun_path[1] + sizeof(ADDRESS_NAME) - 1, '\0', sizeof(addr.sun_path) - 1 - (sizeof(ADDRESS_NAME) - 1) ); if(!infinoted_plugin_document_stream_set_nonblock(plugin->socket, error)) return FALSE; if(bind(plugin->socket, (struct sockaddr*)&addr, sizeof(addr)) == -1) { infinoted_plugin_document_stream_make_system_error(errno, error); return FALSE; } if(listen(plugin->socket, 5) == -1) { infinoted_plugin_document_stream_make_system_error(errno, error); return FALSE; } plugin->watch = inf_io_add_watch( infinoted_plugin_manager_get_io(plugin->manager), &plugin->socket, INF_IO_INCOMING, infinoted_plugin_manager_socket_accept_func, plugin, NULL ); g_signal_connect( G_OBJECT(infinoted_plugin_manager_get_directory(plugin->manager)), "node-removed", G_CALLBACK(infinoted_plugin_document_stream_node_removed_cb), plugin ); return TRUE; }