Blame gio/tests/gdbus-example-peer.c

Packit 84794d
/*
Packit 84794d
Packit 84794d
Usage examples (modulo addresses / credentials).
Packit 84794d
Packit 84794d
UNIX domain socket transport:
Packit 84794d
Packit 84794d
 Server:
Packit 84794d
   $ ./gdbus-example-peer --server --address unix:abstract=myaddr
Packit 84794d
   Server is listening at: unix:abstract=myaddr
Packit 84794d
   Client connected.
Packit 84794d
   Peer credentials: GCredentials:unix-user=500,unix-group=500,unix-process=13378
Packit 84794d
   Negotiated capabilities: unix-fd-passing=1
Packit 84794d
   Client said: Hey, it's 1273093080 already!
Packit 84794d
Packit 84794d
 Client:
Packit 84794d
   $ ./gdbus-example-peer --address unix:abstract=myaddr
Packit 84794d
   Connected.
Packit 84794d
   Negotiated capabilities: unix-fd-passing=1
Packit 84794d
   Server said: You said 'Hey, it's 1273093080 already!'. KTHXBYE!
Packit 84794d
Packit 84794d
Nonce-secured TCP transport on the same host:
Packit 84794d
Packit 84794d
 Server:
Packit 84794d
   $ ./gdbus-example-peer --server --address nonce-tcp:
Packit 84794d
   Server is listening at: nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
Packit 84794d
   Client connected.
Packit 84794d
   Peer credentials: (no credentials received)
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Client said: Hey, it's 1273093206 already!
Packit 84794d
Packit 84794d
 Client:
Packit 84794d
   $ ./gdbus-example-peer -address nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
Packit 84794d
   Connected.
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Server said: You said 'Hey, it's 1273093206 already!'. KTHXBYE!
Packit 84794d
Packit 84794d
TCP transport on two different hosts with a shared home directory:
Packit 84794d
Packit 84794d
 Server:
Packit 84794d
   host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0
Packit 84794d
   Server is listening at: tcp:host=0.0.0.0,port=46314
Packit 84794d
   Client connected.
Packit 84794d
   Peer credentials: (no credentials received)
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Client said: Hey, it's 1273093337 already!
Packit 84794d
Packit 84794d
 Client:
Packit 84794d
   host2 $ ./gdbus-example-peer -a tcp:host=host1,port=46314
Packit 84794d
   Connected.
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Server said: You said 'Hey, it's 1273093337 already!'. KTHXBYE!
Packit 84794d
Packit 84794d
TCP transport on two different hosts without authentication:
Packit 84794d
Packit 84794d
 Server:
Packit 84794d
   host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0 --allow-anonymous
Packit 84794d
   Server is listening at: tcp:host=0.0.0.0,port=59556
Packit 84794d
   Client connected.
Packit 84794d
   Peer credentials: (no credentials received)
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Client said: Hey, it's 1273093652 already!
Packit 84794d
Packit 84794d
 Client:
Packit 84794d
   host2 $ ./gdbus-example-peer -a tcp:host=host1,port=59556
Packit 84794d
   Connected.
Packit 84794d
   Negotiated capabilities: unix-fd-passing=0
Packit 84794d
   Server said: You said 'Hey, it's 1273093652 already!'. KTHXBYE!
Packit 84794d
Packit 84794d
 */
Packit 84794d
Packit 84794d
#include <gio/gio.h>
Packit 84794d
#include <stdlib.h>
Packit 84794d
Packit 84794d
/* ---------------------------------------------------------------------------------------------------- */
Packit 84794d
Packit 84794d
static GDBusNodeInfo *introspection_data = NULL;
Packit 84794d
Packit 84794d
/* Introspection data for the service we are exporting */
Packit 84794d
static const gchar introspection_xml[] =
Packit 84794d
  "<node>"
Packit 84794d
  "  <interface name='org.gtk.GDBus.TestPeerInterface'>"
Packit 84794d
  "    <method name='HelloWorld'>"
Packit 84794d
  "      <arg type='s' name='greeting' direction='in'/>"
Packit 84794d
  "      <arg type='s' name='response' direction='out'/>"
Packit 84794d
  "    </method>"
Packit 84794d
  "  </interface>"
Packit 84794d
  "</node>";
Packit 84794d
Packit 84794d
/* ---------------------------------------------------------------------------------------------------- */
Packit 84794d
Packit 84794d
static void
Packit 84794d
handle_method_call (GDBusConnection       *connection,
Packit 84794d
                    const gchar           *sender,
Packit 84794d
                    const gchar           *object_path,
Packit 84794d
                    const gchar           *interface_name,
Packit 84794d
                    const gchar           *method_name,
Packit 84794d
                    GVariant              *parameters,
Packit 84794d
                    GDBusMethodInvocation *invocation,
Packit 84794d
                    gpointer               user_data)
Packit 84794d
{
Packit 84794d
  if (g_strcmp0 (method_name, "HelloWorld") == 0)
Packit 84794d
    {
Packit 84794d
      const gchar *greeting;
Packit 84794d
      gchar *response;
Packit 84794d
Packit 84794d
      g_variant_get (parameters, "(&s)", &greeting);
Packit 84794d
      response = g_strdup_printf ("You said '%s'. KTHXBYE!", greeting);
Packit 84794d
      g_dbus_method_invocation_return_value (invocation,
Packit 84794d
                                             g_variant_new ("(s)", response));
Packit 84794d
      g_free (response);
Packit 84794d
      g_print ("Client said: %s\n", greeting);
Packit 84794d
    }
Packit 84794d
}
Packit 84794d
Packit 84794d
static const GDBusInterfaceVTable interface_vtable =
Packit 84794d
{
Packit 84794d
  handle_method_call,
Packit 84794d
  NULL,
Packit 84794d
  NULL,
Packit 84794d
};
Packit 84794d
Packit 84794d
/* ---------------------------------------------------------------------------------------------------- */
Packit 84794d
Packit 84794d
static gboolean
Packit 84794d
on_new_connection (GDBusServer *server,
Packit 84794d
                   GDBusConnection *connection,
Packit 84794d
                   gpointer user_data)
Packit 84794d
{
Packit 84794d
  guint registration_id;
Packit 84794d
  GCredentials *credentials;
Packit 84794d
  gchar *s;
Packit 84794d
Packit 84794d
  credentials = g_dbus_connection_get_peer_credentials (connection);
Packit 84794d
  if (credentials == NULL)
Packit 84794d
    s = g_strdup ("(no credentials received)");
Packit 84794d
  else
Packit 84794d
    s = g_credentials_to_string (credentials);
Packit 84794d
Packit 84794d
Packit 84794d
  g_print ("Client connected.\n"
Packit 84794d
           "Peer credentials: %s\n"
Packit 84794d
           "Negotiated capabilities: unix-fd-passing=%d\n",
Packit 84794d
           s,
Packit 84794d
           g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
Packit 84794d
Packit 84794d
  g_object_ref (connection);
Packit 84794d
  registration_id = g_dbus_connection_register_object (connection,
Packit 84794d
                                                       "/org/gtk/GDBus/TestObject",
Packit 84794d
                                                       introspection_data->interfaces[0],
Packit 84794d
                                                       &interface_vtable,
Packit 84794d
                                                       NULL,  /* user_data */
Packit 84794d
                                                       NULL,  /* user_data_free_func */
Packit 84794d
                                                       NULL); /* GError** */
Packit 84794d
  g_assert (registration_id > 0);
Packit 84794d
Packit 84794d
  return TRUE;
Packit 84794d
}
Packit 84794d
Packit 84794d
/* ---------------------------------------------------------------------------------------------------- */
Packit 84794d
Packit 84794d
int
Packit 84794d
main (int argc, char *argv[])
Packit 84794d
{
Packit 84794d
  gint ret;
Packit 84794d
  gboolean opt_server;
Packit 84794d
  gchar *opt_address;
Packit 84794d
  GOptionContext *opt_context;
Packit 84794d
  gboolean opt_allow_anonymous;
Packit 84794d
  GError *error;
Packit 84794d
  GOptionEntry opt_entries[] =
Packit 84794d
    {
Packit 84794d
      { "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL },
Packit 84794d
      { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL },
Packit 84794d
      { "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL },
Packit 84794d
      { NULL}
Packit 84794d
    };
Packit 84794d
Packit 84794d
  ret = 1;
Packit 84794d
Packit 84794d
  opt_address = NULL;
Packit 84794d
  opt_server = FALSE;
Packit 84794d
  opt_allow_anonymous = FALSE;
Packit 84794d
Packit 84794d
  opt_context = g_option_context_new ("peer-to-peer example");
Packit 84794d
  error = NULL;
Packit 84794d
  g_option_context_add_main_entries (opt_context, opt_entries, NULL);
Packit 84794d
  if (!g_option_context_parse (opt_context, &argc, &argv, &error))
Packit 84794d
    {
Packit 84794d
      g_printerr ("Error parsing options: %s\n", error->message);
Packit 84794d
      g_error_free (error);
Packit 84794d
      goto out;
Packit 84794d
    }
Packit 84794d
  if (opt_address == NULL)
Packit 84794d
    {
Packit 84794d
      g_printerr ("Incorrect usage, try --help.\n");
Packit 84794d
      goto out;
Packit 84794d
    }
Packit 84794d
  if (!opt_server && opt_allow_anonymous)
Packit 84794d
    {
Packit 84794d
      g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n");
Packit 84794d
      goto out;
Packit 84794d
    }
Packit 84794d
Packit 84794d
  /* We are lazy here - we don't want to manually provide
Packit 84794d
   * the introspection data structures - so we just build
Packit 84794d
   * them from XML.
Packit 84794d
   */
Packit 84794d
  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
Packit 84794d
  g_assert (introspection_data != NULL);
Packit 84794d
Packit 84794d
  if (opt_server)
Packit 84794d
    {
Packit 84794d
      GDBusServer *server;
Packit 84794d
      gchar *guid;
Packit 84794d
      GMainLoop *loop;
Packit 84794d
      GDBusServerFlags server_flags;
Packit 84794d
Packit 84794d
      guid = g_dbus_generate_guid ();
Packit 84794d
Packit 84794d
      server_flags = G_DBUS_SERVER_FLAGS_NONE;
Packit 84794d
      if (opt_allow_anonymous)
Packit 84794d
        server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
Packit 84794d
Packit 84794d
      error = NULL;
Packit 84794d
      server = g_dbus_server_new_sync (opt_address,
Packit 84794d
                                       server_flags,
Packit 84794d
                                       guid,
Packit 84794d
                                       NULL, /* GDBusAuthObserver */
Packit 84794d
                                       NULL, /* GCancellable */
Packit 84794d
                                       &error);
Packit 84794d
      g_dbus_server_start (server);
Packit 84794d
      g_free (guid);
Packit 84794d
Packit 84794d
      if (server == NULL)
Packit 84794d
        {
Packit 84794d
          g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message);
Packit 84794d
          g_error_free (error);
Packit 84794d
          goto out;
Packit 84794d
        }
Packit 84794d
      g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server));
Packit 84794d
      g_signal_connect (server,
Packit 84794d
                        "new-connection",
Packit 84794d
                        G_CALLBACK (on_new_connection),
Packit 84794d
                        NULL);
Packit 84794d
Packit 84794d
      loop = g_main_loop_new (NULL, FALSE);
Packit 84794d
      g_main_loop_run (loop);
Packit 84794d
Packit 84794d
      g_object_unref (server);
Packit 84794d
      g_main_loop_unref (loop);
Packit 84794d
    }
Packit 84794d
  else
Packit 84794d
    {
Packit 84794d
      GDBusConnection *connection;
Packit 84794d
      const gchar *greeting_response;
Packit 84794d
      GVariant *value;
Packit 84794d
      gchar *greeting;
Packit 84794d
Packit 84794d
      error = NULL;
Packit 84794d
      connection = g_dbus_connection_new_for_address_sync (opt_address,
Packit 84794d
                                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
Packit 84794d
                                                           NULL, /* GDBusAuthObserver */
Packit 84794d
                                                           NULL, /* GCancellable */
Packit 84794d
                                                           &error);
Packit 84794d
      if (connection == NULL)
Packit 84794d
        {
Packit 84794d
          g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message);
Packit 84794d
          g_error_free (error);
Packit 84794d
          goto out;
Packit 84794d
        }
Packit 84794d
Packit 84794d
      g_print ("Connected.\n"
Packit 84794d
               "Negotiated capabilities: unix-fd-passing=%d\n",
Packit 84794d
               g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
Packit 84794d
Packit 84794d
      greeting = g_strdup_printf ("Hey, it's %" G_GUINT64_FORMAT " already!", (guint64) time (NULL));
Packit 84794d
      value = g_dbus_connection_call_sync (connection,
Packit 84794d
                                           NULL, /* bus_name */
Packit 84794d
                                           "/org/gtk/GDBus/TestObject",
Packit 84794d
                                           "org.gtk.GDBus.TestPeerInterface",
Packit 84794d
                                           "HelloWorld",
Packit 84794d
                                           g_variant_new ("(s)", greeting),
Packit 84794d
                                           G_VARIANT_TYPE ("(s)"),
Packit 84794d
                                           G_DBUS_CALL_FLAGS_NONE,
Packit 84794d
                                           -1,
Packit 84794d
                                           NULL,
Packit 84794d
                                           &error);
Packit 84794d
      if (value == NULL)
Packit 84794d
        {
Packit 84794d
          g_printerr ("Error invoking HelloWorld(): %s\n", error->message);
Packit 84794d
          g_error_free (error);
Packit 84794d
          goto out;
Packit 84794d
        }
Packit 84794d
      g_variant_get (value, "(&s)", &greeting_response);
Packit 84794d
      g_print ("Server said: %s\n", greeting_response);
Packit 84794d
      g_variant_unref (value);
Packit 84794d
Packit 84794d
      g_object_unref (connection);
Packit 84794d
    }
Packit 84794d
  g_dbus_node_info_unref (introspection_data);
Packit 84794d
Packit 84794d
  ret = 0;
Packit 84794d
Packit 84794d
 out:
Packit 84794d
  return ret;
Packit 84794d
}