static gboolean on_new_connection (GDBusServer *server, GDBusConnection *connection, gpointer user_data) { guint registration_id; GCredentials *credentials; gchar *s; credentials = g_dbus_connection_get_peer_credentials (connection); if (credentials == NULL) s = g_strdup ("(no credentials received)"); else s = g_credentials_to_string (credentials); g_print ("Client connected.\n" "Peer credentials: %s\n" "Negotiated capabilities: unix-fd-passing=%d\n", s, g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); g_object_ref (connection); registration_id = g_dbus_connection_register_object (connection, "/org/gtk/GDBus/TestObject", introspection_data->interfaces[0], &interface_vtable, NULL, /* user_data */ NULL, /* user_data_free_func */ NULL); /* GError** */ g_assert (registration_id > 0); return TRUE; }
static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { if (g_strcmp0 (method_name, "HelloWorld") == 0) { const gchar *greeting; g_variant_get (parameters, "(&s)", &greeting); if (g_strcmp0 (greeting, "Return Unregistered") == 0) { g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED, "As requested, here's a GError not registered (G_IO_ERROR_FAILED_HANDLED)"); } else if (g_strcmp0 (greeting, "Return Registered") == 0) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, "As requested, here's a GError that is registered (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)"); } else if (g_strcmp0 (greeting, "Return Raw") == 0) { g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.SomeErrorName", "As requested, here's a raw D-Bus error"); } else { gchar *response; response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", response)); g_free (response); } } else if (g_strcmp0 (method_name, "EmitSignal") == 0) { GError *local_error; gdouble speed_in_mph; gchar *speed_as_string; g_variant_get (parameters, "(d)", &speed_in_mph); speed_as_string = g_strdup_printf ("%g mph!", speed_in_mph); local_error = NULL; g_dbus_connection_emit_signal (connection, NULL, object_path, interface_name, "VelocityChanged", g_variant_new ("(ds)", speed_in_mph, speed_as_string), &local_error); g_assert_no_error (local_error); g_free (speed_as_string); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "GimmeStdout") == 0) { #ifdef G_OS_UNIX if (g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { GDBusMessage *reply; GUnixFDList *fd_list; GError *error; fd_list = g_unix_fd_list_new (); error = NULL; g_unix_fd_list_append (fd_list, STDOUT_FILENO, &error); g_assert_no_error (error); reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); g_dbus_message_set_unix_fd_list (reply, fd_list); error = NULL; g_dbus_connection_send_message (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, /* out_serial */ &error); g_assert_no_error (error); g_object_unref (invocation); g_object_unref (fd_list); g_object_unref (reply); } else { g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.Failed", "Your message bus daemon does not support file descriptor passing (need D-Bus >= 1.3.0)"); } #else g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.NotOnUnix", "Your OS does not support file descriptor passing"); #endif } }
int main (int argc, char *argv[]) { gint ret; gboolean opt_server; gchar *opt_address; GOptionContext *opt_context; gboolean opt_allow_anonymous; GError *error; GOptionEntry opt_entries[] = { { "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL }, { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL }, { "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL }, { NULL} }; ret = 1; g_type_init (); opt_address = NULL; opt_server = FALSE; opt_allow_anonymous = FALSE; opt_context = g_option_context_new ("peer-to-peer example"); error = NULL; g_option_context_add_main_entries (opt_context, opt_entries, NULL); if (!g_option_context_parse (opt_context, &argc, &argv, &error)) { g_printerr ("Error parsing options: %s\n", error->message); g_error_free (error); goto out; } if (opt_address == NULL) { g_printerr ("Incorrect usage, try --help.\n"); goto out; } if (!opt_server && opt_allow_anonymous) { g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n"); goto out; } /* We are lazy here - we don't want to manually provide * the introspection data structures - so we just build * them from XML. */ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); g_assert (introspection_data != NULL); if (opt_server) { GDBusServer *server; gchar *guid; GMainLoop *loop; GDBusServerFlags server_flags; guid = g_dbus_generate_guid (); server_flags = G_DBUS_SERVER_FLAGS_NONE; if (opt_allow_anonymous) server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; error = NULL; server = g_dbus_server_new_sync (opt_address, server_flags, guid, NULL, /* GDBusAuthObserver */ NULL, /* GCancellable */ &error); g_dbus_server_start (server); g_free (guid); if (server == NULL) { g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message); g_error_free (error); goto out; } g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server)); g_signal_connect (server, "new-connection", G_CALLBACK (on_new_connection), NULL); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_object_unref (server); g_main_loop_unref (loop); } else { GDBusConnection *connection; const gchar *greeting_response; GVariant *value; gchar *greeting; error = NULL; connection = g_dbus_connection_new_for_address_sync (opt_address, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, /* GDBusAuthObserver */ NULL, /* GCancellable */ &error); if (connection == NULL) { g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message); g_error_free (error); goto out; } g_print ("Connected.\n" "Negotiated capabilities: unix-fd-passing=%d\n", g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); greeting = g_strdup_printf ("Hey, it's %" G_GUINT64_FORMAT " already!", (guint64) time (NULL)); value = g_dbus_connection_call_sync (connection, NULL, /* bus_name */ "/org/gtk/GDBus/TestObject", "org.gtk.GDBus.TestPeerInterface", "HelloWorld", g_variant_new ("(s)", greeting), G_VARIANT_TYPE ("(s)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (value == NULL) { g_printerr ("Error invoking HelloWorld(): %s\n", error->message); g_error_free (error); goto out; } g_variant_get (value, "(&s)", &greeting_response); g_print ("Server said: %s\n", greeting_response); g_variant_unref (value); g_object_unref (connection); } g_dbus_node_info_unref (introspection_data); ret = 0; out: return ret; }