summaryrefslogtreecommitdiff
path: root/tests/twisted/mcp-account-diversion.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/twisted/mcp-account-diversion.c')
-rw-r--r--tests/twisted/mcp-account-diversion.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c
new file mode 100644
index 0000000..0994e25
--- /dev/null
+++ b/tests/twisted/mcp-account-diversion.c
@@ -0,0 +1,286 @@
+/*
+ * A demonstration plugin that diverts account storage to an alternate location.
+ *
+ * Copyright © 2010 Nokia Corporation
+ * Copyright © 2010 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 <mission-control-plugins/mission-control-plugins.h>
+
+#define DONT_DIVERT "fakecm/fakeprotocol/dontdivert"
+#define CONFFILE "mcp-test-diverted-account-plugin.conf"
+
+#define PLUGIN_NAME "diverted-keyfile"
+#define PLUGIN_PRIORITY MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL
+#define PLUGIN_DESCRIPTION \
+ "Test plugin that grabs all accounts it receives (except '" \
+ DONT_DIVERT "*') and diverts them to '" CONFFILE \
+ "' in g_get_user_cache_dir () instead of the usual location."
+
+#define DEBUG g_debug
+
+typedef struct {
+ GObject parent;
+ GKeyFile *keyfile;
+ gboolean save;
+ gboolean loaded;
+} AccountDiversionPlugin;
+
+typedef struct {
+ GObjectClass parent_class;
+} AccountDiversionPluginClass;
+
+GType account_diversion_plugin_get_type (void) G_GNUC_CONST;
+static void account_storage_iface_init (McpAccountStorageIface *,
+ gpointer);
+
+
+#define ACCOUNT_DIVERSION_PLUGIN(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), account_diversion_plugin_get_type (), \
+ AccountDiversionPlugin))
+
+G_DEFINE_TYPE_WITH_CODE (AccountDiversionPlugin, account_diversion_plugin,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_STORAGE,
+ account_storage_iface_init));
+
+static void
+account_diversion_plugin_init (AccountDiversionPlugin *self)
+{
+ DEBUG ("account_diversion_plugin_init");
+ self->keyfile = g_key_file_new ();
+ self->save = FALSE;
+ self->loaded = FALSE;
+}
+
+static void
+account_diversion_plugin_class_init (AccountDiversionPluginClass *cls)
+{
+ DEBUG ("account_diversion_plugin_class_init");
+}
+
+static gchar *
+_conf_filename (void)
+{
+ static gchar *file = NULL;
+
+ if (file == NULL)
+ {
+ const gchar *dir = g_get_user_cache_dir ();
+
+ file = g_build_path (G_DIR_SEPARATOR_S, dir, CONFFILE, NULL);
+ }
+
+ return file;
+}
+
+static gboolean
+_have_config (void)
+{
+ const gchar *file = _conf_filename ();
+
+ DEBUG ("checking for %s", file);
+ return g_file_test (file, G_FILE_TEST_EXISTS);
+}
+
+static void
+_create_config (void)
+{
+ gchar *file = _conf_filename ();
+ gchar *dir = g_path_get_dirname (file);
+
+ g_mkdir_with_parents (dir, 0700);
+ g_free (dir);
+
+ g_file_set_contents (file, "# diverted accounts\n", -1, NULL);
+ DEBUG ("created %s", file);
+}
+
+static gboolean
+_set (const McpAccountStorage *self,
+ const McpAccountManager *am,
+ const gchar *account,
+ const gchar *key,
+ const gchar *val)
+{
+ AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self);
+
+ if (g_str_has_prefix (account, DONT_DIVERT))
+ return FALSE;
+
+ adp->save = TRUE;
+ g_key_file_set_value (adp->keyfile, account, key, val);
+
+ return TRUE;
+}
+
+static gboolean
+_get (const McpAccountStorage *self,
+ const McpAccountManager *am,
+ const gchar *account,
+ const gchar *key)
+{
+ AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self);
+
+ if (key != NULL)
+ {
+ gchar *v = g_key_file_get_value (adp->keyfile, account, key, NULL);
+
+ if (v == NULL)
+ return FALSE;
+
+ mcp_account_manager_set_value (am, account, key, v);
+ g_free (v);
+ }
+ else
+ {
+ gsize i;
+ gsize n;
+ GStrv keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL);
+
+ if (keys == NULL)
+ n = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ gchar *v = g_key_file_get_value (adp->keyfile, account, keys[i], NULL);
+
+ if (v != NULL)
+ mcp_account_manager_set_value (am, account, keys[i], v);
+
+ g_free (v);
+ }
+
+ g_strfreev (keys);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+_delete (const McpAccountStorage *self,
+ const McpAccountManager *am,
+ const gchar *account,
+ const gchar *key)
+{
+ AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self);
+
+ if (key == NULL)
+ {
+ if (g_key_file_remove_group (adp->keyfile, account, NULL))
+ adp->save = TRUE;
+ }
+ else
+ {
+ gsize n;
+ GStrv keys;
+
+ if (g_key_file_remove_key (adp->keyfile, account, key, NULL))
+ adp->save = TRUE;
+
+ keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL);
+
+ if (keys == NULL || n == 0)
+ g_key_file_remove_group (adp->keyfile, account, NULL);
+
+ g_strfreev (keys);
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+_commit (const McpAccountStorage *self,
+ const McpAccountManager *am)
+{
+ gsize n;
+ gchar *data;
+ AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self);
+ gboolean rval = FALSE;
+
+ if (!adp->save)
+ return TRUE;
+
+ if (!_have_config ())
+ _create_config ();
+
+ data = g_key_file_to_data (adp->keyfile, &n, NULL);
+ rval = g_file_set_contents (_conf_filename (), data, n, NULL);
+ adp->save = !rval;
+ g_free (data);
+
+ return rval;
+}
+
+static GList *
+_list (const McpAccountStorage *self,
+ const McpAccountManager *am)
+{
+ gsize i;
+ gsize n;
+ GStrv accounts;
+ GList *rval = NULL;
+ AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self);
+
+ if (!_have_config ())
+ _create_config ();
+
+ if (!adp->loaded)
+ adp->loaded = g_key_file_load_from_file (adp->keyfile, _conf_filename (),
+ G_KEY_FILE_KEEP_COMMENTS, NULL);
+
+ accounts = g_key_file_get_groups (adp->keyfile, &n);
+
+ for (i = 0; i < n; i++)
+ rval = g_list_prepend (rval, g_strdup (accounts[i]));
+
+ g_strfreev (accounts);
+
+ return rval;
+}
+
+static void
+account_storage_iface_init (McpAccountStorageIface *iface,
+ gpointer unused G_GNUC_UNUSED)
+{
+ mcp_account_storage_iface_set_name (iface, PLUGIN_NAME);
+ mcp_account_storage_iface_set_desc (iface, PLUGIN_DESCRIPTION);
+ mcp_account_storage_iface_set_priority (iface, PLUGIN_PRIORITY);
+
+ mcp_account_storage_iface_implement_get (iface, _get);
+ mcp_account_storage_iface_implement_set (iface, _set);
+ mcp_account_storage_iface_implement_delete (iface, _delete);
+ mcp_account_storage_iface_implement_commit (iface, _commit);
+ mcp_account_storage_iface_implement_list (iface, _list);
+}
+
+
+GObject *
+mcp_plugin_ref_nth_object (guint n)
+{
+ DEBUG ("Initializing mcp-account-diversion-plugin (n=%u)", n);
+
+ switch (n)
+ {
+ case 0:
+ return g_object_new (account_diversion_plugin_get_type (), NULL);
+
+ default:
+ return NULL;
+ }
+}