static gboolean lookup_internal (const gchar *name, GSocketConnectable **connectable) { const gchar *env; g_assert (name != NULL); g_assert (connectable != NULL); if (g_str_equal (name, "ssh-agent")) { *connectable = NULL; env = g_getenv ("SSH_AUTH_SOCK"); if (env != NULL && env[0] != '\0') *connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (env)); else *connectable = NULL; return TRUE; } if (internal_addresses) { return g_hash_table_lookup_extended (internal_addresses, name, NULL, (gpointer *)connectable); } return FALSE; }
static gboolean lookup_internal (const gchar *name, GSocketConnectable **connectable) { const gchar *env; gboolean ret = FALSE; GSocketAddress *address; g_assert (name != NULL); g_assert (connectable != NULL); if (internal_addresses) { ret = g_hash_table_lookup_extended (internal_addresses, name, NULL, (gpointer *)connectable); } if (!ret && g_str_equal (name, "ssh-agent")) { *connectable = NULL; env = g_getenv ("SSH_AUTH_SOCK"); if (env != NULL && env[0] != '\0') { address = g_unix_socket_address_new (env); *connectable = G_SOCKET_CONNECTABLE (address); cockpit_channel_internal_address ("ssh-agent", address); } ret = TRUE; } return ret; }
/** * soup_socket_connect_async: * @sock: a client #SoupSocket (which must not already be connected) * @cancellable: a #GCancellable, or %NULL * @callback: (scope async): callback to call after connecting * @user_data: data to pass to @callback * * Begins asynchronously connecting to @sock's remote address. The * socket will call @callback when it succeeds or fails (but not * before returning from this function). * * If @cancellable is non-%NULL, it can be used to cancel the * connection. @callback will still be invoked in this case, with a * status of %SOUP_STATUS_CANCELLED. **/ void soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable, SoupSocketCallback callback, gpointer user_data) { SoupSocketPrivate *priv; SoupSocketAsyncConnectData *sacd; GSocketClient *client; g_return_if_fail (SOUP_IS_SOCKET (sock)); priv = SOUP_SOCKET_GET_PRIVATE (sock); g_return_if_fail (priv->remote_addr != NULL); sacd = g_slice_new0 (SoupSocketAsyncConnectData); sacd->sock = g_object_ref (sock); sacd->callback = callback; sacd->user_data = user_data; priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new (); if (priv->async_context && !priv->use_thread_context) g_main_context_push_thread_default (priv->async_context); client = new_socket_client (sock); g_socket_client_connect_async (client, G_SOCKET_CONNECTABLE (priv->remote_addr), priv->connect_cancel, async_connected, sacd); g_object_unref (client); }
/** * soup_socket_connect_sync: * @sock: a client #SoupSocket (which must not already be connected) * @cancellable: a #GCancellable, or %NULL * * Attempt to synchronously connect @sock to its remote address. * * If @cancellable is non-%NULL, it can be used to cancel the * connection, in which case soup_socket_connect_sync() will return * %SOUP_STATUS_CANCELLED. * * Return value: a success or failure code. **/ guint soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable) { SoupSocketPrivate *priv; GSocketClient *client; GSocketConnection *conn; GError *error = NULL; g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED); priv = SOUP_SOCKET_GET_PRIVATE (sock); g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED); g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED); g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED); if (cancellable) g_object_ref (cancellable); else cancellable = g_cancellable_new (); priv->connect_cancel = cancellable; client = new_socket_client (sock); conn = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (priv->remote_addr), priv->connect_cancel, &error); g_object_unref (client); return socket_connected (sock, conn, error); }
/* TODO: could use dbus, but for portability maybe not..... */ static void do_connect(SpiceVDAgent *agent) { GError *error = NULL; GSocketAddressEnumerator *enumerator; GSocketAddress *address; #ifdef G_OS_UNIX agent->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error); agent->connectable = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(vdagentd_socket)); #endif enumerator = g_socket_connectable_enumerate (agent->connectable); while (TRUE) { address = g_socket_address_enumerator_next (enumerator, agent->cancellable, NULL); if (!address) { g_error("can't connect to socket"); exit(1); } if (g_socket_connect(agent->socket, address, agent->cancellable, &error)) break; g_debug("Connection failed, trying next"); g_clear_error (&error); g_object_unref (address); } g_object_unref(enumerator); agent->connection = G_IO_STREAM(g_socket_connection_factory_create_connection(agent->socket)); g_debug("Connected to %s %p", vdagentd_socket, agent->connection); send_xorg_config(agent); }
static void do_connectable (const char *arg, gboolean synchronous) { char **parts; GSocketConnectable *connectable; GSocketAddressEnumerator *enumerator; if (strchr (arg, '/')) { /* service/protocol/domain */ parts = g_strsplit (arg, "/", 3); if (!parts || !parts[2]) usage (); connectable = g_network_service_new (parts[0], parts[1], parts[2]); } else { guint16 port; parts = g_strsplit (arg, ":", 2); if (parts && parts[1]) { arg = parts[0]; port = strtoul (parts[1], NULL, 10); } else port = 0; if (g_hostname_is_ip_address (arg)) { GInetAddress *addr = g_inet_address_new_from_string (arg); GSocketAddress *sockaddr = g_inet_socket_address_new (addr, port); g_object_unref (addr); connectable = G_SOCKET_CONNECTABLE (sockaddr); } else connectable = g_network_address_new (arg, port); } enumerator = g_socket_connectable_enumerate (connectable); g_object_unref (connectable); if (synchronous) do_sync_connectable (enumerator); else do_async_connectable (enumerator); }
gboolean g_vfs_ftp_connection_open_data_connection (GVfsFtpConnection *conn, GSocketAddress * addr, GCancellable * cancellable, GError ** error) { g_return_val_if_fail (conn != NULL, FALSE); g_return_val_if_fail (conn->data == NULL, FALSE); g_vfs_ftp_connection_stop_listening (conn); conn->data = G_IO_STREAM (g_socket_client_connect (conn->client, G_SOCKET_CONNECTABLE (addr), cancellable, error)); return conn->data != NULL; }
static void _j4status_io_stream_connect(J4statusIOStream *self) { if ( self->connection != NULL ) { g_object_unref(self->in); g_object_unref(self->out); g_object_unref(self->connection); self->connection = NULL; self->out = NULL; self->in = NULL; } GSocketClient *client; client = g_socket_client_new(); g_socket_client_connect_async(client, G_SOCKET_CONNECTABLE(self->address), NULL, _j4status_io_stream_connect_callback, self); g_object_unref(client); }
static void use_inet_address (gboolean synchronous) { GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; GInetAddress *addr = NULL; guint port = 0; gchar **ip_and_port; ip_and_port = g_strsplit (info, ":", 2); if (ip_and_port[0]) { addr = g_inet_address_new_from_string (ip_and_port[0]); if (ip_and_port [1]) port = strtoul (ip_and_port [1], NULL, 10); } g_strfreev (ip_and_port); if (addr == NULL || port <= 0 || port >= 65535) { fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info); if (addr) g_object_unref (addr); return_value = 1; return; } sockaddr = g_inet_socket_address_new (addr, port); g_object_unref (addr); enumerator = g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); g_object_unref (sockaddr); printf ("Proxies for ip and port '%s' are:\n", info); run_with_enumerator (synchronous, enumerator); g_object_unref (enumerator); }
static void use_unix_address (gboolean synchronous) { GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); if (sockaddr == NULL) { fprintf (stderr, "Failed to create unix socket with name '%s'\n", info); return_value = 1; return; } enumerator = g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); g_object_unref (sockaddr); printf ("Proxies for path '%s' are:\n", info); run_with_enumerator (synchronous, enumerator); g_object_unref (enumerator); }
/* TODO: Declare an extension point called GDBusTransport (or similar) * and move code below to extensions implementing said extension * point. That way we can implement a D-Bus transport over X11 without * making libgio link to libX11... */ static GIOStream * g_dbus_address_connect (const gchar *address_entry, const gchar *transport_name, GHashTable *key_value_pairs, GCancellable *cancellable, GError **error) { GIOStream *ret; GSocketConnectable *connectable; const gchar *nonce_file; connectable = NULL; ret = NULL; nonce_file = NULL; if (FALSE) { } #ifdef G_OS_UNIX else if (g_strcmp0 (transport_name, "unix") == 0) { const gchar *path; const gchar *abstract; path = g_hash_table_lookup (key_value_pairs, "path"); abstract = g_hash_table_lookup (key_value_pairs, "abstract"); if ((path == NULL && abstract == NULL) || (path != NULL && abstract != NULL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address '%s' - the unix transport requires exactly one of the " "keys 'path' or 'abstract' to be set"), address_entry); } else if (path != NULL) { connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (path)); } else if (abstract != NULL) { connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new_with_type (abstract, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT)); } else { g_assert_not_reached (); } } #endif else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0) { const gchar *s; const gchar *host; glong port; gchar *endp; gboolean is_nonce; is_nonce = (g_strcmp0 (transport_name, "nonce-tcp") == 0); host = g_hash_table_lookup (key_value_pairs, "host"); if (host == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address '%s' - the host attribute is missing or malformed"), address_entry); goto out; } s = g_hash_table_lookup (key_value_pairs, "port"); if (s == NULL) s = "0"; port = strtol (s, &endp, 10); if ((*s == '\0' || *endp != '\0') || port < 0 || port >= 65536) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address '%s' - the port attribute is missing or malformed"), address_entry); goto out; } if (is_nonce) { nonce_file = g_hash_table_lookup (key_value_pairs, "noncefile"); if (nonce_file == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address '%s' - the noncefile attribute is missing or malformed"), address_entry); goto out; } } /* TODO: deal with family key/value-pair */ connectable = g_network_address_new (host, port); } else if (g_strcmp0 (address_entry, "autolaunch:") == 0) { gchar *autolaunch_address; autolaunch_address = get_session_address_platform_specific (error); if (autolaunch_address != NULL) { ret = g_dbus_address_try_connect_one (autolaunch_address, NULL, cancellable, error); g_free (autolaunch_address); goto out; } else { g_prefix_error (error, _("Error auto-launching: ")); } } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Unknown or unsupported transport '%s' for address '%s'"), transport_name, address_entry); } if (connectable != NULL) { GSocketClient *client; GSocketConnection *connection; g_assert (ret == NULL); client = g_socket_client_new (); connection = g_socket_client_connect (client, connectable, cancellable, error); g_object_unref (connectable); g_object_unref (client); if (connection == NULL) goto out; ret = G_IO_STREAM (connection); if (nonce_file != NULL) { gchar nonce_contents[16 + 1]; size_t num_bytes_read; FILE *f; /* be careful to read only 16 bytes - we also check that the file is only 16 bytes long */ f = fopen (nonce_file, "rb"); if (f == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error opening nonce file '%s': %s"), nonce_file, g_strerror (errno)); g_object_unref (ret); ret = NULL; goto out; } num_bytes_read = fread (nonce_contents, sizeof (gchar), 16 + 1, f); if (num_bytes_read != 16) { if (num_bytes_read == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error reading from nonce file '%s': %s"), nonce_file, g_strerror (errno)); } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error reading from nonce file '%s', expected 16 bytes, got %d"), nonce_file, (gint) num_bytes_read); } g_object_unref (ret); ret = NULL; fclose (f); goto out; } fclose (f); if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret), nonce_contents, 16, NULL, cancellable, error)) { g_prefix_error (error, _("Error writing contents of nonce file '%s' to stream:"), nonce_file); g_object_unref (ret); ret = NULL; goto out; } } } out: return ret; }
/* TODO: Declare an extension point called GDBusTransport (or similar) * and move code below to extensions implementing said extension * point. That way we can implement a D-Bus transport over X11 without * making libgio link to libX11... */ static GIOStream * g_dbus_address_connect (const gchar *address_entry, const gchar *transport_name, GHashTable *key_value_pairs, GCancellable *cancellable, GError **error) { GIOStream *ret; GSocketConnectable *connectable; const gchar *nonce_file; connectable = NULL; ret = NULL; nonce_file = NULL; if (FALSE) { } #ifdef G_OS_UNIX else if (g_strcmp0 (transport_name, "unix") == 0) { const gchar *path; const gchar *abstract; path = g_hash_table_lookup (key_value_pairs, "path"); abstract = g_hash_table_lookup (key_value_pairs, "abstract"); if ((path == NULL && abstract == NULL) || (path != NULL && abstract != NULL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address `%s' - the unix transport requires exactly one of the " "keys `path' or `abstract' to be set"), address_entry); } else if (path != NULL) { connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (path)); } else if (abstract != NULL) { connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new_with_type (abstract, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT)); } else { g_assert_not_reached (); } } #endif else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0) { const gchar *s; const gchar *host; guint port; gchar *endp; gboolean is_nonce; is_nonce = (g_strcmp0 (transport_name, "nonce-tcp") == 0); host = g_hash_table_lookup (key_value_pairs, "host"); if (host == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address `%s' - the host attribute is missing or malformed"), address_entry); goto out; } s = g_hash_table_lookup (key_value_pairs, "port"); if (s == NULL) s = "0"; port = strtol (s, &endp, 10); if ((*s == '\0' || *endp != '\0') || port < 0 || port >= 65536) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address `%s' - the port attribute is missing or malformed"), address_entry); goto out; } if (is_nonce) { nonce_file = g_hash_table_lookup (key_value_pairs, "noncefile"); if (nonce_file == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error in address `%s' - the noncefile attribute is missing or malformed"), address_entry); goto out; } } /* TODO: deal with family */ connectable = g_network_address_new (host, port); } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Unknown or unsupported transport `%s' for address `%s'"), transport_name, address_entry); } if (connectable != NULL) { GSocketClient *client; GSocketConnection *connection; g_assert (ret == NULL); client = g_socket_client_new (); connection = g_socket_client_connect (client, connectable, cancellable, error); g_object_unref (connectable); g_object_unref (client); if (connection == NULL) goto out; ret = G_IO_STREAM (connection); if (nonce_file != NULL) { gchar *nonce_contents; gsize nonce_length; /* TODO: too dangerous to read the entire file? (think denial-of-service etc.) */ if (!g_file_get_contents (nonce_file, &nonce_contents, &nonce_length, error)) { g_prefix_error (error, _("Error reading nonce file `%s':"), nonce_file); g_object_unref (ret); ret = NULL; goto out; } if (nonce_length != 16) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("The nonce-file `%s' was %" G_GSIZE_FORMAT " bytes. Expected 16 bytes."), nonce_file, nonce_length); g_free (nonce_contents); g_object_unref (ret); ret = NULL; goto out; } if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret), nonce_contents, nonce_length, NULL, cancellable, error)) { g_prefix_error (error, _("Error write contents of nonce file `%s' to stream:"), nonce_file); g_object_unref (ret); ret = NULL; g_free (nonce_contents); goto out; } g_free (nonce_contents); } } out: return ret; }
static gboolean make_connection (const char *argument, GTlsCertificate *certificate, GCancellable *cancellable, GSocket **socket, GSocketAddress **address, GIOStream **connection, GInputStream **istream, GOutputStream **ostream, GError **error) { GSocketType socket_type; GSocketFamily socket_family; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; GSocketAddress *src_address; GTlsInteraction *interaction; GError *err = NULL; if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; *socket = g_socket_new (socket_family, socket_type, 0, error); if (*socket == NULL) return FALSE; if (read_timeout) g_socket_set_timeout (*socket, read_timeout); if (unix_socket) { GSocketAddress *addr; addr = socket_address_from_string (argument); if (addr == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not parse '%s' as unix socket name", argument); return FALSE; } connectable = G_SOCKET_CONNECTABLE (addr); } else { connectable = g_network_address_parse (argument, 7777, error); if (connectable == NULL) return FALSE; } enumerator = g_socket_connectable_enumerate (connectable); while (TRUE) { *address = g_socket_address_enumerator_next (enumerator, cancellable, error); if (*address == NULL) { if (error != NULL && *error == NULL) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No more addresses to try"); return FALSE; } if (g_socket_connect (*socket, *address, cancellable, &err)) break; g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message); g_clear_error (&err); g_object_unref (*address); } g_object_unref (enumerator); g_print ("Connected to %s\n", socket_address_to_string (*address)); src_address = g_socket_get_local_address (*socket, error); if (!src_address) { g_prefix_error (error, "Error getting local address: "); return FALSE; } g_print ("local address: %s\n", socket_address_to_string (src_address)); g_object_unref (src_address); if (use_udp) { *connection = NULL; *istream = NULL; *ostream = NULL; } else *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket)); if (tls) { GIOStream *tls_conn; tls_conn = g_tls_client_connection_new (*connection, connectable, error); if (!tls_conn) { g_prefix_error (error, "Could not create TLS connection: "); return FALSE; } g_signal_connect (tls_conn, "accept-certificate", G_CALLBACK (accept_certificate), NULL); interaction = g_tls_console_interaction_new (); g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction); g_object_unref (interaction); if (certificate) g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate); g_object_unref (*connection); *connection = G_IO_STREAM (tls_conn); if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn), cancellable, error)) { g_prefix_error (error, "Error during TLS handshake: "); return FALSE; } } g_object_unref (connectable); if (*connection) { *istream = g_io_stream_get_input_stream (*connection); *ostream = g_io_stream_get_output_stream (*connection); } return TRUE; }
static void use_proxy_address (gboolean synchronous) { GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; GInetAddress *addr; guint port = 0; gchar *protocol; gchar *dest_host; guint dest_port; gchar *username = NULL; gchar *password = NULL; gchar **split_info; split_info = g_strsplit (info, ":", 7); if (!split_info[0] || !split_info[1] || !split_info[2] || !split_info[3] || !split_info[4]) { fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info); return_value = 1; return; } addr = g_inet_address_new_from_string (split_info[0]); port = strtoul (split_info [1], NULL, 10); protocol = g_strdup (split_info[2]); dest_host = g_strdup (split_info[3]); dest_port = strtoul (split_info[4], NULL, 10); if (split_info[5]) { username = g_strdup (split_info[5]); if (split_info[6]) password = g_strdup (split_info[6]); } g_strfreev (split_info); sockaddr = g_proxy_address_new (addr, port, protocol, dest_host, dest_port, username, password); g_object_unref (addr); g_free (protocol); g_free (dest_host); g_free (username); g_free (password); enumerator = g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); g_object_unref (sockaddr); printf ("Proxies for ip and port '%s' are:\n", info); run_with_enumerator (synchronous, enumerator); g_object_unref (enumerator); }
ControllerLIRC::ControllerLIRC( TPContext * context , const char * uds , guint _repeat ) : connection( 0 ), controller( 0 ), timer( 0 ), repeat( gdouble( _repeat ) / 1000.0 ) { g_assert( context ); g_assert( uds ); //......................................................................... // Get the address of the Unix Domain Socket GSocketAddress * socket_address = g_unix_socket_address_new( uds ); if ( ! socket_address ) { tpwarn( "FAILED TO CREATE SOCKET ADDRESS WITH '%d'" , uds ); return; } //......................................................................... // Create a socket client and attempt to connect to the address GSocketClient * client = g_socket_client_new(); connection = g_socket_client_connect( client , G_SOCKET_CONNECTABLE( socket_address ) , NULL , NULL ); g_object_unref( socket_address ); g_object_unref( client ); if ( ! connection ) { tplog( "FAILED TO CONNECT TO LIRC SOCKET" ); return; } //......................................................................... // Now, get the socket's input stream, create a data input stream from it // and start reading lines. GDataInputStream * input_stream = g_data_input_stream_new( g_io_stream_get_input_stream( G_IO_STREAM( connection ) ) ); g_assert( input_stream ); g_data_input_stream_read_line_async( input_stream , 0 , NULL , line_read , this ); g_object_unref( input_stream ); //......................................................................... // Add the controller TPControllerSpec controller_spec; memset( & controller_spec , 0 , sizeof( controller_spec ) ); controller_spec.capabilities = TP_CONTROLLER_HAS_KEYS; controller = tp_context_add_controller( context , "Remote" , & controller_spec , 0 ); g_assert( controller ); //......................................................................... // Populate the key map key_map[ "0" ] = TP_KEY_0; key_map[ "1" ] = TP_KEY_1; key_map[ "2" ] = TP_KEY_2; key_map[ "3" ] = TP_KEY_3; key_map[ "4" ] = TP_KEY_4; key_map[ "5" ] = TP_KEY_5; key_map[ "6" ] = TP_KEY_6; key_map[ "7" ] = TP_KEY_7; key_map[ "8" ] = TP_KEY_8; key_map[ "9" ] = TP_KEY_9; key_map[ "MUTE" ] = TP_KEY_MUTE; key_map[ "CH_UP" ] = TP_KEY_CHAN_UP; key_map[ "VOL_UP" ] = TP_KEY_VOL_UP; key_map[ "CH_DOWN" ] = TP_KEY_CHAN_DOWN; key_map[ "VOL_DOWN" ] = TP_KEY_VOL_DOWN; key_map[ "UP" ] = TP_KEY_UP; key_map[ "LEFT" ] = TP_KEY_LEFT; key_map[ "OK" ] = TP_KEY_OK; key_map[ "RIGHT" ] = TP_KEY_RIGHT; key_map[ "DOWN" ] = TP_KEY_DOWN; key_map[ "MENU" ] = TP_KEY_MENU; key_map[ "EXIT" ] = TP_KEY_EXIT; key_map[ "PLAY" ] = TP_KEY_PLAY; key_map[ "PAUSE" ] = TP_KEY_PAUSE; key_map[ "STOP" ] = TP_KEY_STOP; key_map[ "|<<" ] = TP_KEY_PREV; key_map[ ">>|" ] = TP_KEY_NEXT; key_map[ "RECORD" ] = TP_KEY_REC; key_map[ "<<" ] = TP_KEY_REW; key_map[ ">>" ] = TP_KEY_FFWD; key_map[ "RED" ] = TP_KEY_RED; key_map[ "GREEN" ] = TP_KEY_GREEN; key_map[ "YELLOW" ] = TP_KEY_YELLOW; key_map[ "BLUE" ] = TP_KEY_BLUE; key_map[ "BACK" ] = TP_KEY_BACK; timer = g_timer_new(); tplog( "READY" ); }
int main (int argc, char *argv[]) { GSocket *socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GSocketFamily socket_family; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; g_thread_init (NULL); g_type_init (); context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (argc != 2) { g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name"); return 1; } if (cancel_timeout) { cancellable = g_cancellable_new (); g_thread_create (cancel_thread, cancellable, FALSE, NULL); } else { cancellable = NULL; } loop = g_main_loop_new (NULL, FALSE); if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; socket = g_socket_new (socket_family, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (read_timeout) g_socket_set_timeout (socket, read_timeout); if (unix_socket) { GSocketAddress *addr; addr = socket_address_from_string (argv[1]); if (addr == NULL) { g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]); return 1; } connectable = G_SOCKET_CONNECTABLE (addr); } else { connectable = g_network_address_parse (argv[1], 7777, &error); if (connectable == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } } enumerator = g_socket_connectable_enumerate (connectable); while (TRUE) { address = g_socket_address_enumerator_next (enumerator, cancellable, &error); if (address == NULL) { if (error == NULL) g_printerr ("%s: No more addresses to try\n", argv[0]); else g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (g_socket_connect (socket, address, cancellable, &error)) break; g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message); g_error_free (error); error = NULL; g_object_unref (address); } g_object_unref (enumerator); g_object_unref (connectable); g_print ("Connected to %s\n", socket_address_to_string (address)); /* TODO: Test non-blocking connect */ if (non_blocking) g_socket_set_blocking (socket, FALSE); src_address = g_socket_get_local_address (socket, &error); if (!src_address) { g_printerr ("Error getting local address: %s\n", error->message); return 1; } g_print ("local address: %s\n", socket_address_to_string (src_address)); g_object_unref (src_address); while (TRUE) { gchar buffer[4096]; gssize size; gsize to_send; if (fgets (buffer, sizeof buffer, stdin) == NULL) break; to_send = strlen (buffer); while (to_send > 0) { ensure_condition (socket, "send", cancellable, G_IO_OUT); if (use_udp) size = g_socket_send_to (socket, address, buffer, to_send, cancellable, &error); else size = g_socket_send (socket, buffer, to_send, cancellable, &error); if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } ensure_condition (socket, "receive", cancellable, G_IO_IN); if (use_udp) size = g_socket_receive_from (socket, &src_address, buffer, sizeof buffer, cancellable, &error); else size = g_socket_receive (socket, buffer, sizeof buffer, cancellable, &error); if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (src_address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s" "-------------------------\n", (int)size, buffer); } g_print ("closing socket\n"); if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (socket)); g_object_unref (G_OBJECT (address)); return 0; }
GSocketConnectable * cockpit_channel_parse_connectable (CockpitChannel *self, gchar **possible_name) { const gchar *problem = "protocol-error"; GSocketConnectable *connectable = NULL; const gchar *unix_path; const gchar *internal; JsonObject *options; GError *error = NULL; const gchar *host; gint64 port; options = self->priv->open_options; if (!cockpit_json_get_string (options, "unix", NULL, &unix_path)) { g_warning ("invalid \"unix\" option in channel"); goto out; } if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port)) { g_warning ("invalid \"port\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "internal", NULL, &internal)) { g_warning ("invalid \"internal\" option in channel"); goto out; } if (port != G_MAXINT64 && unix_path) { g_warning ("cannot specify both \"port\" and \"unix\" options"); goto out; } else if (port != G_MAXINT64) { if (port <= 0 || port > 65535) { g_warning ("received invalid \"port\" option"); goto out; } if (cockpit_bridge_local_address) { connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error); host = cockpit_bridge_local_address; } else { connectable = cockpit_loopback_new (port); host = "localhost"; } if (error != NULL) { g_warning ("couldn't parse local address: %s: %s", host, error->message); problem = "internal-error"; goto out; } else { if (possible_name) *possible_name = g_strdup_printf ("%s:%d", host, (gint)port); } } else if (unix_path) { if (possible_name) *possible_name = g_strdup (unix_path); connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path)); } else if (internal) { gboolean reg = FALSE; if (internal_addresses) { reg = g_hash_table_lookup_extended(internal_addresses, internal, NULL, (gpointer *)&connectable); } if (!connectable) { if (!reg) g_warning ("couldn't find internal address: %s", internal); problem = "not-found"; goto out; } if (possible_name) *possible_name = g_strdup (internal); connectable = g_object_ref (connectable); } else { g_warning ("no \"port\" or \"unix\" or other address option for channel"); goto out; } problem = NULL; out: g_clear_error (&error); if (problem) { cockpit_channel_close (self, problem); if (connectable) g_object_unref (connectable); connectable = NULL; } return connectable; }
static void dasom_im_init (DasomIM *im) { g_debug (G_STRLOC ": %s", G_STRFUNC); GSocketClient *client; GSocketAddress *address; GSocket *socket; GError *error = NULL; address = g_unix_socket_address_new_with_type (DASOM_ADDRESS, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); client = g_socket_client_new (); im->connection = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (address), NULL, &error); g_object_unref (address); g_object_unref (client); if (im->connection == NULL) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message); g_clear_error (&error); return; } socket = g_socket_connection_get_socket (im->connection); if (!socket) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, "Can't get socket"); return; } DasomMessage *message; DasomConnectionType type = DASOM_CONNECTION_DASOM_IM; dasom_send_message (socket, DASOM_MESSAGE_CONNECT, &type, sizeof (DasomConnectionType), NULL); g_socket_condition_wait (socket, G_IO_IN, NULL, NULL); message = dasom_recv_message (socket); if (G_UNLIKELY (message == NULL || message->header->type != DASOM_MESSAGE_CONNECT_REPLY)) { dasom_message_unref (message); g_error ("Couldn't connect to dasom daemon"); } dasom_message_unref (message); im->result = g_slice_new0 (DasomResult); im->preedit_string = g_strdup (""); GMutex mutex; g_mutex_init (&mutex); g_mutex_lock (&mutex); if (G_UNLIKELY (dasom_im_sockets_context == NULL)) { dasom_im_sockets_context = g_main_context_new (); dasom_im_sockets_context_ref_count++; } else { dasom_im_sockets_context = g_main_context_ref (dasom_im_sockets_context); dasom_im_sockets_context_ref_count++; } g_mutex_unlock (&mutex); /* when g_main_context_iteration(), iterate only sockets */ im->sockets_context_source = g_socket_create_source (socket, G_IO_IN, NULL); g_source_set_can_recurse (im->sockets_context_source, TRUE); g_source_attach (im->sockets_context_source, dasom_im_sockets_context); g_source_set_callback (im->sockets_context_source, (GSourceFunc) on_incoming_message, im, NULL); im->default_context_source = g_socket_create_source (socket, G_IO_IN, NULL); g_source_set_can_recurse (im->default_context_source, TRUE); g_source_set_callback (im->default_context_source, (GSourceFunc) on_incoming_message, im, NULL); g_source_attach (im->default_context_source, NULL); }
static GSocketConnectable * parse_address (CockpitChannel *self, gchar **possible_name, gboolean *local_address) { GSocketConnectable *connectable = NULL; const gchar *unix_path; const gchar *internal; const gchar *address; JsonObject *options; gboolean local = FALSE; GError *error = NULL; const gchar *host; gint64 port; gchar *name = NULL; gboolean open = FALSE; options = self->priv->open_options; if (!cockpit_json_get_string (options, "unix", NULL, &unix_path)) { cockpit_channel_fail (self, "protocol-error", "invalid \"unix\" option in channel"); goto out; } if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port)) { cockpit_channel_fail (self, "protocol-error", "invalid \"port\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "internal", NULL, &internal)) { cockpit_channel_fail (self, "protocol-error", "invalid \"internal\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "address", NULL, &address)) { cockpit_channel_fail (self, "protocol-error", "invalid \"address\" option in channel"); goto out; } if (port != G_MAXINT64 && unix_path) { cockpit_channel_fail (self, "protocol-error", "cannot specify both \"port\" and \"unix\" options"); goto out; } else if (port != G_MAXINT64) { if (port <= 0 || port > 65535) { cockpit_channel_fail (self, "protocol-error", "received invalid \"port\" option"); goto out; } if (address) { connectable = g_network_address_new (address, port); host = address; /* This isn't perfect, but matches the use case. Specify address => non-local */ local = FALSE; } else if (cockpit_bridge_local_address) { connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error); host = cockpit_bridge_local_address; local = TRUE; } else { connectable = cockpit_loopback_new (port); host = "localhost"; local = TRUE; } if (error != NULL) { cockpit_channel_fail (self, "internal-error", "couldn't parse local address: %s: %s", host, error->message); goto out; } else { name = g_strdup_printf ("%s:%d", host, (gint)port); } } else if (unix_path) { name = g_strdup (unix_path); connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path)); local = FALSE; } else if (internal) { gboolean reg = lookup_internal (internal, &connectable); if (!connectable) { if (reg) cockpit_channel_close (self, "not-found"); else cockpit_channel_fail (self, "not-found", "couldn't find internal address: %s", internal); goto out; } name = g_strdup (internal); connectable = g_object_ref (connectable); local = FALSE; } else { cockpit_channel_fail (self, "protocol-error", "no \"port\" or \"unix\" or other address option for channel"); goto out; } open = TRUE; out: g_clear_error (&error); if (open) { if (possible_name) *possible_name = g_strdup (name); if (local_address) *local_address = local; } else { if (connectable) g_object_unref (connectable); connectable = NULL; } g_free (name); return connectable; }