[telepathy-mission-control/master] McdClientProxy: new subclass of TpProxy to use for Client proxies
Simon McVittie
simon.mcvittie at collabora.co.uk
Fri May 22 07:13:43 PDT 2009
Also, syntax-check Client bus names.
---
src/Makefile.am | 2 +
src/mcd-client-priv.h | 82 +++++++++++++++++++++++++++++
src/mcd-client.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++
src/mcd-dispatcher.c | 53 ++++++++-----------
4 files changed, 244 insertions(+), 31 deletions(-)
create mode 100644 src/mcd-client-priv.h
create mode 100644 src/mcd-client.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 4d374eb..12828cd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -116,6 +116,8 @@ libmissioncontrol_server_la_SOURCES = \
mcd-account-manager-priv.h \
mcd-account-manager-query.c \
mcd-account-priv.h \
+ mcd-client.c \
+ mcd-client-priv.h \
mcd-dbusprop.c \
mcd-dbusprop.h \
mcd-debug.c \
diff --git a/src/mcd-client-priv.h b/src/mcd-client-priv.h
new file mode 100644
index 0000000..b63cc00
--- /dev/null
+++ b/src/mcd-client-priv.h
@@ -0,0 +1,82 @@
+/* vi: set et sw=4 ts=8 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Mission Control client proxy.
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef MCD_CLIENT_PRIV_H
+#define MCD_CLIENT_PRIV_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <telepathy-glib/proxy.h>
+
+G_BEGIN_DECLS
+
+typedef struct _McdClientProxy McdClientProxy;
+typedef struct _McdClientProxyClass McdClientProxyClass;
+typedef struct _McdClientProxyPrivate McdClientProxyPrivate;
+
+struct _McdClientProxy
+{
+ TpProxy parent;
+ McdClientProxyPrivate *priv;
+};
+
+struct _McdClientProxyClass
+{
+ TpProxyClass parent_class;
+};
+
+G_GNUC_INTERNAL GType _mcd_client_proxy_get_type (void);
+
+#define MCD_TYPE_CLIENT_PROXY \
+ (_mcd_client_proxy_get_type ())
+#define MCD_CLIENT_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MCD_TYPE_CLIENT_PROXY, \
+ McdClientProxy))
+#define MCD_CLIENT_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MCD_TYPE_CLIENT_PROXY, \
+ McdClientProxyClass))
+#define MCD_IS_CLIENT_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MCD_TYPE_CLIENT_PROXY))
+#define MCD_IS_CLIENT_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MCD_TYPE_CLIENT_PROXY))
+#define MCD_CLIENT_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MCD_TYPE_CLIENT_PROXY, \
+ McdClientProxyClass))
+
+G_GNUC_INTERNAL McdClientProxy *_mcd_client_proxy_new (
+ TpDBusDaemon *dbus_daemon, const gchar *name_suffix);
+
+G_GNUC_INTERNAL gboolean _mcd_client_check_valid_name (
+ const gchar *name_suffix, GError **error);
+
+/* Analogous to TP_CM_*_BASE */
+#define MC_CLIENT_BUS_NAME_BASE MC_IFACE_CLIENT "."
+#define MC_CLIENT_OBJECT_PATH_BASE "/org/freedesktop/Telepathy/Client/"
+#define MC_CLIENT_BUS_NAME_BASE_LEN (sizeof (MC_CLIENT_BUS_NAME_BASE) - 1)
+
+G_END_DECLS
+
+#endif
diff --git a/src/mcd-client.c b/src/mcd-client.c
new file mode 100644
index 0000000..d5615db
--- /dev/null
+++ b/src/mcd-client.c
@@ -0,0 +1,138 @@
+/* vi: set et sw=4 ts=8 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Mission Control client proxy.
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "mcd-client-priv.h"
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/errors.h>
+#include <telepathy-glib/proxy-subclass.h>
+
+#include "_gen/interfaces.h"
+
+G_DEFINE_TYPE (McdClientProxy, _mcd_client_proxy, TP_TYPE_PROXY);
+
+struct _McdClientProxyPrivate
+{
+ guint dummy:1;
+};
+
+static void
+_mcd_client_proxy_init (McdClientProxy *self)
+{
+}
+
+static void
+_mcd_client_proxy_class_init (McdClientProxyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (McdClientProxyPrivate));
+}
+
+gboolean
+_mcd_client_check_valid_name (const gchar *name_suffix,
+ GError **error)
+{
+ guint i;
+
+ if (!g_ascii_isalpha (*name_suffix))
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Client names must start with a letter");
+ return FALSE;
+ }
+
+ for (i = 1; name_suffix[i] != '\0'; i++)
+ {
+ if (i > (255 - MC_CLIENT_BUS_NAME_BASE_LEN))
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Client name too long");
+ }
+
+ if (name_suffix[i] == '_' || g_ascii_isalpha (name_suffix[i]))
+ {
+ continue;
+ }
+
+ if (name_suffix[i] == '.' || g_ascii_isdigit (name_suffix[i]))
+ {
+ if (name_suffix[i-1] == '.')
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Client names must not have a digit or dot "
+ "following a dot");
+ return FALSE;
+ }
+ }
+ else
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Client names must not contain '%c'", name_suffix[i]);
+ return FALSE;
+ }
+ }
+
+ if (name_suffix[i-1] == '.')
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Client names must not end with a dot");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+McdClientProxy *
+_mcd_client_proxy_new (TpDBusDaemon *dbus_daemon,
+ const gchar *name_suffix)
+{
+ McdClientProxy *self;
+ gchar *bus_name, *object_path;
+
+ g_return_val_if_fail (_mcd_client_check_valid_name (name_suffix, NULL),
+ NULL);
+
+ bus_name = g_strconcat (MC_CLIENT_BUS_NAME_BASE, name_suffix, NULL);
+ object_path = g_strconcat (MC_CLIENT_OBJECT_PATH_BASE, name_suffix, NULL);
+ g_strdelimit (object_path, ".", '/');
+
+ g_assert (tp_dbus_check_valid_bus_name (bus_name,
+ TP_DBUS_NAME_TYPE_WELL_KNOWN,
+ NULL));
+ g_assert (tp_dbus_check_valid_object_path (object_path, NULL));
+
+ self = g_object_new (MCD_TYPE_CLIENT_PROXY,
+ "dbus-daemon", dbus_daemon,
+ "object-path", object_path,
+ "bus-name", bus_name,
+ NULL);
+
+ g_free (object_path);
+ g_free (bus_name);
+
+ return self;
+}
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 05dce93..b90b0f1 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -45,6 +45,7 @@
#include "mcd-signals-marshal.h"
#include "mcd-account-priv.h"
+#include "mcd-client-priv.h"
#include "mcd-connection.h"
#include "mcd-connection-priv.h"
#include "mcd-channel.h"
@@ -145,7 +146,7 @@ typedef enum
typedef struct _McdClient
{
- TpProxy *proxy;
+ McdClientProxy *proxy;
gchar *name;
McdClientInterface interfaces;
gchar **handled_channels;
@@ -179,10 +180,6 @@ typedef struct _McdClient
GList *observer_filters;
} McdClient;
-/* Analogous to TP_CM_*_BASE */
-#define MC_CLIENT_BUS_NAME_BASE MC_IFACE_CLIENT "."
-#define MC_CLIENT_OBJECT_PATH_BASE "/org/freedesktop/Telepathy/Client/"
-
struct _McdDispatcherPrivate
{
/* Dispatching contexts */
@@ -244,7 +241,7 @@ typedef struct
typedef struct
{
- TpProxy *handler;
+ McdClientProxy *handler;
gchar *request_path;
} McdRemoveRequestData;
@@ -1982,17 +1979,19 @@ finally:
static void
client_add_interface_by_id (McdClient *client)
{
- tp_proxy_add_interface_by_id (client->proxy, MC_IFACE_QUARK_CLIENT);
+ TpProxy *proxy = (TpProxy *) client->proxy;
+
+ tp_proxy_add_interface_by_id (proxy, MC_IFACE_QUARK_CLIENT);
if (client->interfaces & MCD_CLIENT_APPROVER)
- tp_proxy_add_interface_by_id (client->proxy,
+ tp_proxy_add_interface_by_id (proxy,
MC_IFACE_QUARK_CLIENT_APPROVER);
if (client->interfaces & MCD_CLIENT_HANDLER)
- tp_proxy_add_interface_by_id (client->proxy,
+ tp_proxy_add_interface_by_id (proxy,
MC_IFACE_QUARK_CLIENT_HANDLER);
if (client->interfaces & MCD_CLIENT_INTERFACE_REQUESTS)
- tp_proxy_add_interface_by_id (client->proxy, MC_IFACE_QUARK_CLIENT_INTERFACE_REQUESTS);
+ tp_proxy_add_interface_by_id (proxy, MC_IFACE_QUARK_CLIENT_INTERFACE_REQUESTS);
if (client->interfaces & MCD_CLIENT_OBSERVER)
- tp_proxy_add_interface_by_id (client->proxy,
+ tp_proxy_add_interface_by_id (proxy,
MC_IFACE_QUARK_CLIENT_OBSERVER);
}
@@ -2092,24 +2091,6 @@ finally:
}
static void
-create_client_proxy (McdDispatcher *self, McdClient *client)
-{
- McdDispatcherPrivate *priv = MCD_DISPATCHER_PRIV (self);
- gchar *bus_name, *object_path;
-
- bus_name = g_strconcat (MC_CLIENT_BUS_NAME_BASE, client->name, NULL);
- object_path = g_strconcat (MC_CLIENT_OBJECT_PATH_BASE, client->name, NULL);
- g_strdelimit (object_path, ".", '/');
- client->proxy = g_object_new (TP_TYPE_PROXY,
- "dbus-daemon", priv->dbus_daemon,
- "object-path", object_path,
- "bus-name", bus_name,
- NULL);
- g_free (object_path);
- g_free (bus_name);
-}
-
-static void
parse_client_file (McdClient *client, GKeyFile *file)
{
gchar **iface_names, **groups;
@@ -2234,7 +2215,7 @@ create_mcd_client (McdDispatcher *self,
g_assert (g_str_has_prefix (name, MC_CLIENT_BUS_NAME_BASE));
client = g_slice_new0 (McdClient);
- client->name = g_strdup (name + sizeof (MC_CLIENT_BUS_NAME_BASE) - 1);
+ client->name = g_strdup (name + MC_CLIENT_BUS_NAME_BASE_LEN);
client->activatable = activatable;
if (!activatable)
client->active = TRUE;
@@ -2267,7 +2248,8 @@ create_mcd_client (McdDispatcher *self,
g_free (filename);
}
- create_client_proxy (self, client);
+ client->proxy = _mcd_client_proxy_new (self->priv->dbus_daemon,
+ client->name);
if (!file_found)
{
@@ -2309,6 +2291,15 @@ new_names_cb (McdDispatcher *self,
continue;
}
+ if (!_mcd_client_check_valid_name (name + MC_CLIENT_BUS_NAME_BASE_LEN,
+ NULL))
+ {
+ /* This is probably meant to be a Telepathy Client, but it's not */
+ DEBUG ("Ignoring invalid Client name: %s",
+ name + MC_CLIENT_BUS_NAME_BASE_LEN);
+ continue;
+ }
+
client = g_hash_table_lookup (priv->clients, name);
if (client)
{
--
1.5.6.5
More information about the telepathy-commits
mailing list