[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