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 void inf_tcp_connection_connected(InfTcpConnection* connection) { InfTcpConnectionPrivate* priv; priv = INF_TCP_CONNECTION_PRIVATE(connection); priv->status = INF_TCP_CONNECTION_CONNECTED; priv->front_pos = 0; priv->back_pos = 0; priv->events = INF_IO_INCOMING | INF_IO_ERROR; if(priv->watch == NULL) { priv->watch = inf_io_add_watch( priv->io, &priv->socket, priv->events, inf_tcp_connection_io, connection, NULL ); } else { inf_io_update_watch(priv->io, priv->watch, priv->events); } g_object_freeze_notify(G_OBJECT(connection)); /* Update adresses from resolver */ if(priv->resolver != NULL) { if(priv->remote_address != NULL) inf_ip_address_free(priv->remote_address); priv->remote_address = inf_ip_address_copy( inf_name_resolver_get_address(priv->resolver, priv->resolver_index) ); priv->remote_port = inf_name_resolver_get_port(priv->resolver, priv->resolver_index); g_object_notify(G_OBJECT(connection), "remote-address"); g_object_notify(G_OBJECT(connection), "remote-port"); priv->resolver_index = 0; } g_object_notify(G_OBJECT(connection), "status"); g_object_notify(G_OBJECT(connection), "local-address"); g_object_notify(G_OBJECT(connection), "local-port"); g_object_thaw_notify(G_OBJECT(connection)); }
/** * infinoted_signal_register: * @run: A #InfinotedRun. * * Registers signal handlers for SIGINT and SIGTERM that terminate the given * infinote server. When you don't need the signal handlers anymore, you * must unregister them again using infinoted_signal_unregister(). * * Returns: A #InfinotedSignal to unregister the signal handlers again later. */ InfinotedSignal* infinoted_signal_register(InfinotedRun* run) { InfinotedSignal* sig; sig = g_slice_new(InfinotedSignal); #ifdef LIBINFINITY_HAVE_LIBDAEMON sig->run = run; /* TODO: Should we report when this fails? Should ideally happen before * actually forking then - are signal connections kept in fork()'s child? */ if(daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) == 0) { sig->signal_fd = daemon_signal_fd(); sig->watch = inf_io_add_watch( INF_IO(run->io), &sig->signal_fd, INF_IO_INCOMING | INF_IO_ERROR, infinoted_signal_sig_func, sig, NULL ); } #else sig->previous_sigint_handler = signal(SIGINT, &infinoted_signal_sigint_handler); sig->previous_sigterm_handler = signal(SIGTERM, &infinoted_signal_sigterm_handler); sig->previous_sigquit_handler = #ifndef G_OS_WIN32 signal(SIGQUIT, &infinoted_signal_sigquit_handler); sig->previous_sighup_handler = signal(SIGHUP, &infinoted_signal_sighup_handler); #endif /* !G_OS_WIN32 */ _infinoted_signal_server = run; #endif /* !LIBINFINITY_HAVE_LIBDAEMON */ #ifdef G_OS_WIN32 SetConsoleCtrlHandler(infinoted_signal_console_handler, TRUE); #endif return sig; }
static void inf_test_chat_userjoin_finished_cb(InfcRequest* request, InfUser* user, gpointer user_data) { InfTestChat* test; test = (InfTestChat*)user_data; printf("User join complete. Start chatting!\n"); #ifndef G_OS_WIN32 inf_io_add_watch( INF_IO(test->io), &test->input_fd, INF_IO_INCOMING | INF_IO_ERROR, inf_test_chat_input_cb, test, NULL ); #endif test->self = user; }
static void inf_test_browser_notify_status_cb(GObject* object, GParamSpec* pspec, gpointer user_data) { InfTestBrowser* test; InfBrowserStatus status; test = (InfTestBrowser*)user_data; g_object_get(G_OBJECT(test->browser), "status", &status, NULL); if(status == INF_BROWSER_OPEN) { printf("Connection established\n"); #ifndef G_OS_WIN32 inf_io_add_watch( INF_IO(test->io), &test->input_fd, INF_IO_INCOMING | INF_IO_ERROR, inf_test_browser_input_cb, test, NULL ); #endif /* Explore root node */ inf_browser_get_root(test->browser, &test->cwd); inf_browser_explore(test->browser, &test->cwd, NULL, NULL); } if(status == INF_BROWSER_CLOSED) { if(inf_standalone_io_loop_running(test->io)) inf_standalone_io_loop_quit(test->io); } }
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; }
static gboolean inf_tcp_connection_open_real(InfTcpConnection* connection, const InfIpAddress* address, guint port, GError** error) { InfTcpConnectionPrivate* priv; union { struct sockaddr_in in; struct sockaddr_in6 in6; } native_address; struct sockaddr* addr; socklen_t addrlen; int result; int errcode; const InfKeepalive* keepalive; GError* local_error; priv = INF_TCP_CONNECTION_PRIVATE(connection); g_assert(priv->status == INF_TCP_CONNECTION_CLOSED || priv->status == INF_TCP_CONNECTION_CONNECTING); /* Close previous socket */ if(priv->socket != INVALID_SOCKET) closesocket(priv->socket); switch(inf_ip_address_get_family(address)) { case INF_IP_ADDRESS_IPV4: priv->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); addr = (struct sockaddr*)&native_address.in; addrlen = sizeof(struct sockaddr_in); memcpy( &native_address.in.sin_addr, inf_ip_address_get_raw(address), sizeof(struct in_addr) ); native_address.in.sin_family = AF_INET; native_address.in.sin_port = htons(port); break; case INF_IP_ADDRESS_IPV6: priv->socket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); addr = (struct sockaddr*)&native_address.in6; addrlen = sizeof(struct sockaddr_in6); memcpy( &native_address.in6.sin6_addr, inf_ip_address_get_raw(address), sizeof(struct in6_addr) ); native_address.in6.sin6_family = AF_INET6; native_address.in6.sin6_port = htons(port); native_address.in6.sin6_flowinfo = 0; native_address.in6.sin6_scope_id = priv->device_index; break; default: g_assert_not_reached(); break; } if(priv->socket == INVALID_SOCKET) { inf_native_socket_make_error(INF_NATIVE_SOCKET_LAST_ERROR, error); return FALSE; } /* Set socket non-blocking and keepalive */ keepalive = &priv->keepalive; if(!inf_tcp_connection_configure_socket(priv->socket, keepalive, error)) { closesocket(priv->socket); priv->socket = INVALID_SOCKET; return FALSE; } /* Connect */ do { result = connect(priv->socket, addr, addrlen); errcode = INF_NATIVE_SOCKET_LAST_ERROR; if(result == -1 && errcode != INF_NATIVE_SOCKET_EINTR && errcode != INF_NATIVE_SOCKET_EINPROGRESS) { local_error = NULL; inf_native_socket_make_error(errcode, &local_error); if(inf_tcp_connection_connection_error(connection, local_error) == TRUE) { /* In this case, we could recover from the error by connecting to a * different address. */ g_error_free(local_error); return TRUE; } g_propagate_error(error, local_error); return FALSE; } } while(result == -1 && errcode != INF_NATIVE_SOCKET_EINPROGRESS); if(result == 0) { /* Connection fully established */ inf_tcp_connection_connected(connection); } else { g_assert(priv->watch == NULL); /* Connection establishment in progress */ priv->events = INF_IO_OUTGOING | INF_IO_ERROR; priv->watch = inf_io_add_watch( priv->io, &priv->socket, priv->events, inf_tcp_connection_io, connection, NULL ); if(priv->status != INF_TCP_CONNECTION_CONNECTING) { priv->status = INF_TCP_CONNECTION_CONNECTING; g_object_notify(G_OBJECT(connection), "status"); } } return TRUE; }