Example #1
0
static void
send_close (FilechooserPortalData *data)
{
  GDBusMessage *message;
  GError *error = NULL;

  message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop",
                                            "/org/freedesktop/portal/desktop",
                                            "org.freedesktop.portal.FileChooser",
                                            "Close");
  g_dbus_message_set_body (message,
                           g_variant_new ("(o)", data->portal_handle));

  if (!g_dbus_connection_send_message (data->connection,
                                       message,
                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                       NULL, &error))
    {
      g_warning ("unable to send FileChooser Close message: %s", error->message);
      g_error_free (error);
    }

  g_object_unref (message);
}
static void
writeback_cancel_remote_operation (GCancellable      *cancellable,
                                   WritebackFileData *data)
{
	TrackerWritebackDispatcherPrivate *priv;
	GDBusMessage *message;
        gchar *uris[2];

	priv = TRACKER_WRITEBACK_DISPATCHER_GET_PRIVATE (data->self);

	uris[0] = g_file_get_uri (data->file);
	uris[1] = NULL;

	message = g_dbus_message_new_method_call (TRACKER_WRITEBACK_SERVICE,
	                                          TRACKER_WRITEBACK_PATH,
	                                          TRACKER_WRITEBACK_INTERFACE,
	                                          "CancelTasks");

	g_dbus_message_set_body (message, g_variant_new ("(^as)", uris));
	g_dbus_connection_send_message (priv->d_connection, message,
	                                G_DBUS_SEND_MESSAGE_FLAGS_NONE,
	                                NULL, NULL);
	g_free (uris[0]);
}
/**
 * g_dbus_method_invocation_return_value:
 * @invocation: A #GDBusMethodInvocation.
 * @parameters: A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
 *
 * Finishes handling a D-Bus method call by returning @parameters.
 * If the @parameters GVariant is floating, it is consumed.
 *
 * It is an error if @parameters is not of the right format.
 *
 * This method will free @invocation, you cannot use it afterwards.
 *
 * Since: 2.26
 */
void
g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
                                       GVariant              *parameters)
{
  GDBusMessage *reply;
  GError *error;

  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
  g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));

  if (parameters == NULL)
    parameters = g_variant_new_tuple (NULL, 0);

  /* if we have introspection data, check that the signature of @parameters is correct */
  if (invocation->method_info != NULL)
    {
      GVariantType *type;

      type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);

      if (!g_variant_is_of_type (parameters, type))
        {
          gchar *type_string = g_variant_type_dup_string (type);

          g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"),
                     g_variant_get_type_string (parameters), type_string);
          g_variant_type_free (type);
          g_free (type_string);
          goto out;
        }
      g_variant_type_free (type);
    }

  if (G_UNLIKELY (_g_dbus_debug_return ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("========================================================================\n"
               "GDBus-debug:Return:\n"
               " >>>> METHOD RETURN\n"
               "      in response to %s.%s()\n"
               "      on object %s\n"
               "      to name %s\n"
               "      reply-serial %d\n",
               invocation->interface_name, invocation->method_name,
               invocation->object_path,
               invocation->sender,
               g_dbus_message_get_serial (invocation->message));
      _g_dbus_debug_print_unlock ();
    }

  reply = g_dbus_message_new_method_reply (invocation->message);
  g_dbus_message_set_body (reply, parameters);
  error = NULL;
  if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
    {
      g_warning (_("Error sending message: %s"), error->message);
      g_error_free (error);
    }
  g_object_unref (reply);

 out:
  g_object_unref (invocation);
}
static void
g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation,
                                                GVariant              *parameters,
                                                GUnixFDList           *fd_list)
{
  GDBusMessage *reply;
  GError *error;

  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
  g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));

  if (parameters == NULL)
    parameters = g_variant_new_tuple (NULL, 0);

  /* if we have introspection data, check that the signature of @parameters is correct */
  if (invocation->method_info != NULL)
    {
      GVariantType *type;

      type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);

      if (!g_variant_is_of_type (parameters, type))
        {
          gchar *type_string = g_variant_type_dup_string (type);

          g_warning ("Type of return value is incorrect: expected '%s', got '%s''",
		     type_string, g_variant_get_type_string (parameters));
          g_variant_type_free (type);
          g_free (type_string);
          goto out;
        }
      g_variant_type_free (type);
    }

  /* property_info is only non-NULL if set that way from
   * GDBusConnection, so this must be the case of async property
   * handling on either 'Get', 'Set' or 'GetAll'.
   */
  if (invocation->property_info != NULL)
    {
      if (g_str_equal (invocation->method_name, "Get"))
        {
          GVariant *nested;

          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)")))
            {
              g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }

          /* Go deeper and make sure that the value inside of the
           * variant matches the property type.
           */
          g_variant_get (parameters, "(v)", &nested);
          if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature))
            {
              g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'",
                         invocation->property_info->name, invocation->property_info->signature,
                         g_variant_get_type_string (nested));
              g_variant_unref (nested);
              goto out;
            }
          g_variant_unref (nested);
        }

      else if (g_str_equal (invocation->method_name, "GetAll"))
        {
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
            {
              g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }

          /* Could iterate the list of properties and make sure that all
           * of them are actually on the interface and with the correct
           * types, but let's not do that for now...
           */
        }

      else if (g_str_equal (invocation->method_name, "Set"))
        {
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT))
            {
              g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'",
                         g_variant_get_type_string (parameters));
              goto out;
            }
        }

      else
        g_assert_not_reached ();
    }

  if (G_UNLIKELY (_g_dbus_debug_return ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("========================================================================\n"
               "GDBus-debug:Return:\n"
               " >>>> METHOD RETURN\n"
               "      in response to %s.%s()\n"
               "      on object %s\n"
               "      to name %s\n"
               "      reply-serial %d\n",
               invocation->interface_name, invocation->method_name,
               invocation->object_path,
               invocation->sender,
               g_dbus_message_get_serial (invocation->message));
      _g_dbus_debug_print_unlock ();
    }

  reply = g_dbus_message_new_method_reply (invocation->message);
  g_dbus_message_set_body (reply, parameters);

#ifdef G_OS_UNIX
  if (fd_list != NULL)
    g_dbus_message_set_unix_fd_list (reply, fd_list);
#endif

  error = NULL;
  if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
    {
      g_warning ("Error sending message: %s", error->message);
      g_error_free (error);
    }
  g_object_unref (reply);

 out:
  g_object_unref (invocation);
}
Example #5
0
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
    }
}
Example #6
0
static void
test_once (Fixture       *f,
           gconstpointer  context)
{
  GDBusMessage *message;
  gboolean pipe_res;

  pipe_res = g_unix_open_pipe (f->server_to_client, FD_CLOEXEC, &f->error);
  g_assert (pipe_res);
  pipe_res = g_unix_open_pipe (f->client_to_server, FD_CLOEXEC, &f->error);
  g_assert (pipe_res);

  f->server_iostream = my_io_stream_new_for_fds (f->client_to_server[0],
                                                 f->server_to_client[1]);
  f->iostream = my_io_stream_new_for_fds (f->server_to_client[0],
                                          f->client_to_server[1]);

  g_dbus_connection_new (f->server_iostream,
                         f->guid,
                         (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
                          G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS),
                         NULL /* auth observer */,
                         NULL /* cancellable */,
                         on_new_conn, &f->server_conn);

  g_dbus_connection_new (f->iostream,
                         NULL,
                         G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                         NULL /* auth observer */,
                         NULL /* cancellable */,
                         on_new_conn, &f->connection);

  while (f->server_conn == NULL || f->connection == NULL)
    g_main_context_iteration (NULL, TRUE);

  /*
   * queue a message - it'll sometimes be sent while the close is pending,
   * triggering the bug
   */
  message = g_dbus_message_new_signal ("/", "com.example.Foo", "Bar");
  g_dbus_connection_send_message (f->connection, message, 0, NULL, &f->error);
  g_assert_no_error (f->error);
  g_object_unref (message);

  /* close the connection (deliberately or via last-unref) */
  if (g_strcmp0 (context, "unref") == 0)
    {
      g_clear_object (&f->connection);
    }
  else
    {
      g_dbus_connection_close_sync (f->connection, NULL, &f->error);
      g_assert_no_error (f->error);
    }

  /* either way, wait for the connection to close */
  while (!g_dbus_connection_is_closed (f->server_conn))
    g_main_context_iteration (NULL, TRUE);

  /* clean up before the next run */
  g_clear_object (&f->iostream);
  g_clear_object (&f->server_iostream);
  g_clear_object (&f->connection);
  g_clear_object (&f->server_conn);
  g_clear_error (&f->error);
}
gboolean
eas_gdbus_call_finish (struct eas_gdbus_client *client, GAsyncResult *result,
		       guint cancel_serial, const gchar *out_params,
		       va_list *ap, GError **error)
{
	GDBusMessage *reply;
	gchar *out_params_type = (gchar *) out_params;
	gboolean success = FALSE;
	GVariant *v;

	reply = g_dbus_connection_send_message_with_reply_finish(client->connection,
								 result, error);
	if (cancel_serial) {
		GDBusMessage *message;

		message = g_dbus_message_new_method_call (EAS_SERVICE_NAME,
							  EAS_SERVICE_COMMON_OBJECT_PATH,
							  EAS_SERVICE_COMMON_INTERFACE,
							  "cancel_request");
		g_dbus_message_set_body (message,
					 g_variant_new ("(su)",
							client->account_uid,
							cancel_serial));

		g_dbus_connection_send_message (client->connection,
						message,
						G_DBUS_SEND_MESSAGE_FLAGS_NONE,
						NULL, NULL);

		g_object_unref (message);
	}

	if (!reply)
		return FALSE;

	/* g_variant_is_of_type() will fail to match a DBus return
	   of (sas) with a format string of (s^as), where the ^ is
	   required to make it convert to a strv instead of something
	   more complicated. So we remove all ^ characters from the
	   string that we show to g_variant_is_of_type(). Ick. */
	if (out_params && strchr (out_params, '^')) {
		gchar *x, *y;

		out_params_type = g_strdup (out_params);

		x = y = strchr (out_params_type, '^');
		y++;

		while (*y) {
			if (*y == '^')
				y++;
			else
				*(x++) = *(y++);
		}
		*x = 0;
	}
	switch (g_dbus_message_get_message_type (reply)) {
	case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
		/* An empty (successful) response will give a NULL GVariant here */
		v = g_dbus_message_get_body (reply);
		if (!out_params) {
			if (v)
				goto inval;
			else {
				success = TRUE;
				break;
			}
		}
		if (!g_variant_is_of_type (v, G_VARIANT_TYPE (out_params_type))) {
		inval:
			g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
				     "ActiveSync DBus call returned invalid response type %s",
				     v?g_variant_get_type_string (v):"()");
			goto out;
			g_object_unref (reply);
		}
		g_variant_get_va (v, out_params, NULL, ap);
		success = TRUE;
		break;

	case G_DBUS_MESSAGE_TYPE_ERROR:
		g_dbus_message_to_gerror (reply, error);
		break;

	default:
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
			     "EAS DBus call returned weird message type %d",
			     g_dbus_message_get_message_type (reply));
		break;
	}

 out:
	if (out_params_type != out_params)
		g_free (out_params_type);

	g_object_unref (reply);
	return success;
}
Example #8
0
static void
gdkevent_dispatcher (GdkEvent *event,
                     gpointer  data)
{
	GDBusMessage *message;
	GError *error = NULL;

	message = g_dbus_message_new_method_call(NULL, "/",
	                                         "org.perfkit.Agent.GdkEvent",
	                                         "Event");

	switch (event->type) {
   case GDK_TOUCH_BEGIN:
   case GDK_TOUCH_END:
   case GDK_TOUCH_UPDATE:
   case GDK_TOUCH_CANCEL:
	case GDK_NOTHING:
		break;
	case GDK_DELETE:
		gdkevent_handle_any(event, connection);
		break;
	case GDK_DESTROY:
		gdkevent_handle_destroy(event, connection);
		break;
	case GDK_EXPOSE:
		gdkevent_handle_expose(event, message, connection);
		break;
	case GDK_MOTION_NOTIFY:
		gdkevent_handle_motion_notfiy(event, connection);
		break;
	case GDK_BUTTON_PRESS:
	case GDK_2BUTTON_PRESS:
	case GDK_3BUTTON_PRESS:
	case GDK_BUTTON_RELEASE:
		gdkevent_handle_button(event, connection);
		break;
	case GDK_KEY_PRESS:
	case GDK_KEY_RELEASE:
		gdkevent_handle_key(event, connection);
		break;
	case GDK_ENTER_NOTIFY:
	case GDK_LEAVE_NOTIFY:
		gdkevent_handle_crossing(event, connection);
		break;
	case GDK_FOCUS_CHANGE:
		gdkevent_handle_focus(event, connection);
		break;
	case GDK_CONFIGURE:
		gdkevent_handle_configure(event, connection);
		break;
	case GDK_MAP:
	case GDK_UNMAP:
		gdkevent_handle_any(event, connection);
		break;
	case GDK_PROPERTY_NOTIFY:
	case GDK_SELECTION_CLEAR:
	case GDK_SELECTION_REQUEST:
	case GDK_SELECTION_NOTIFY:
	case GDK_PROXIMITY_IN:
	case GDK_PROXIMITY_OUT:
	case GDK_DRAG_ENTER:
	case GDK_DRAG_LEAVE:
	case GDK_DRAG_MOTION:
	case GDK_DRAG_STATUS:
	case GDK_DROP_START:
	case GDK_DROP_FINISHED:
	case GDK_CLIENT_EVENT:
	case GDK_VISIBILITY_NOTIFY:
#if !GTK_CHECK_VERSION(2, 91, 0)
	case GDK_NO_EXPOSE:
#endif
	case GDK_SCROLL:
	case GDK_WINDOW_STATE:
	case GDK_SETTING:
	case GDK_OWNER_CHANGE:
	case GDK_GRAB_BROKEN:
	case GDK_DAMAGE:
	case GDK_EVENT_LAST:
	default:
		/*
		 * TODO: Handle more of these specificaly.
		 */
		gdkevent_handle_any(event, connection);
		break;
	}

	if (!g_dbus_connection_send_message(connection, message,
	                                    G_DBUS_SEND_MESSAGE_FLAGS_NONE,
	                                    NULL, &error)) {
		CRITICAL(Gdk, "Error sending message: %s", error->message);
		g_error_free(error);
	}

	gtk_main_do_event(event);
}