From 7181fbafe840fe3ab1c46cceb6fff8968e0dc2f5 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 29 Oct 2013 13:46:48 +0000 Subject: [PATCH 06/12] Add an account-store backend for files containing a stringified GVariant --- tests/Makefile.am | 5 +- tests/account-store-variant-file.c | 189 +++++++++++++++++++++++++++++++++++++ tests/account-store-variant-file.h | 37 ++++++++ tests/account-store.c | 14 +++ 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 tests/account-store-variant-file.c create mode 100644 tests/account-store-variant-file.h diff --git a/tests/Makefile.am b/tests/Makefile.am index d349d7d..bc55887 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -38,7 +38,10 @@ account_store_LDADD = $(GLIB_LIBS) account_store_SOURCES = \ account-store.c \ account-store-keyfile.c \ - account-store-keyfile.h + account-store-keyfile.h \ + account-store-variant-file.c \ + account-store-variant-file.h \ + $(NULL) if ENABLE_LIBACCOUNTS_SSO account_store_SOURCES += account-store-libaccounts.c account-store-libaccounts.h diff --git a/tests/account-store-variant-file.c b/tests/account-store-variant-file.c new file mode 100644 index 0000000..0a44f2a --- /dev/null +++ b/tests/account-store-variant-file.c @@ -0,0 +1,189 @@ +/* + * MC account storage inspector: MC 5.14 GVariant-file backend + * + * Copyright © 2010 Nokia Corporation + * Copyright © 2010-2012 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 "account-store-variant-file.h" + +#include + +#include +#include + +static gchar * +get_path (const gchar *account) +{ + gchar *ret; + gchar *basename; + + basename = g_strdup_printf ("%s.account", account); + g_strdelimit (basename, "/", '-'); + + ret = g_build_filename (g_get_user_data_dir (), "telepathy", + "mission-control", basename, NULL); + g_free (basename); + return ret; +} + +static GVariant * +load (const gchar *account) +{ + GError *error = NULL; + gchar *contents = NULL; + gsize len; + GVariant *ret = NULL; + gchar *path = NULL; + + path = get_path (account); + + if (!g_file_get_contents (path, &contents, &len, &error)) + goto finally; + + ret = g_variant_parse (G_VARIANT_TYPE_VARDICT, contents, contents + len, + NULL, &error); + +finally: + if (error != NULL) + g_warning ("variant file '%s' error: %s", path, error->message); + + g_free (path); + g_clear_error (&error); + g_free (contents); + return ret; +} + +gchar * +variant_get (const gchar *account, + const gchar *key) +{ + GVariant *asv = load (account); + GVariant *v = NULL; + GString *ret = NULL; + + if (asv == NULL) + return NULL; + + if (g_str_has_prefix (key, "param-")) + { + GVariant *intermediate = g_variant_lookup_value (asv, + "Parameters", NULL); + + if (intermediate != NULL) + { + g_assert (g_variant_is_of_type (intermediate, + G_VARIANT_TYPE ("a{sv}"))); + v = g_variant_lookup_value (intermediate, key + 6, NULL); + } + + intermediate = g_variant_lookup_value (asv, + "KeyFileParameters", NULL); + + if (v == NULL && intermediate != NULL) + { + g_assert (g_variant_is_of_type (intermediate, + G_VARIANT_TYPE ("a{ss}"))); + v = g_variant_lookup_value (intermediate, key + 6, + G_VARIANT_TYPE_STRING); + + if (v != NULL) + ret = g_string_new ("keyfile-escaped "); + } + } + else + { + v = g_variant_lookup_value (asv, key, NULL); + } + + if (v != NULL) + { + ret = g_variant_print_string (v, ret, TRUE); + g_variant_unref (v); + } + + g_variant_unref (asv); + + if (ret == NULL) + return NULL; + + return g_string_free (ret, FALSE); +} + +gboolean +variant_delete (const gchar *account) +{ + gchar *path = get_path (account); + + if (g_unlink (path) != 0) + { + g_warning ("%s", g_strerror (errno)); + g_free (path); + return FALSE; + } + + g_free (path); + return TRUE; +} + +gboolean +variant_exists (const gchar *account) +{ + gchar *path = get_path (account); + gboolean ret = g_file_test (path, G_FILE_TEST_EXISTS); + + g_free (path); + return ret; +} + +GStrv +variant_list (void) +{ + GPtrArray *ret = g_ptr_array_new (); + gchar *dir_path = g_build_filename (g_get_user_data_dir (), "telepathy", + "mission-control", NULL); + GDir *dir = g_dir_open (dir_path, 0, NULL); + + if (dir != NULL) + { + const gchar *name; + + for (name = g_dir_read_name (dir); + name != NULL; + name = g_dir_read_name (dir)) + { + gchar *dup; + + if (!g_str_has_suffix (name, ".account")) + continue; + + /* this is not production code so we're ignoring the possibility + * of invalid account names here */ + dup = g_strdup (name); + g_strdelimit (dup, "-", '/'); + g_strdelimit (dup, ".", '\0'); + g_ptr_array_add (ret, dup); + } + + g_dir_close (dir); + } + + g_free (dir_path); + g_ptr_array_add (ret, NULL); + return (GStrv) g_ptr_array_free (ret, FALSE); +} diff --git a/tests/account-store-variant-file.h b/tests/account-store-variant-file.h new file mode 100644 index 0000000..dad07bf --- /dev/null +++ b/tests/account-store-variant-file.h @@ -0,0 +1,37 @@ +/* + * MC account storage inspector: MC 5.14 GVariant-file backend + * + * Copyright © 2010 Nokia Corporation + * Copyright © 2010-2012 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 _ACCOUNT_STORE_VARIANT_FILE_H_ +#define _ACCOUNT_STORE_VARIANT_FILE_H_ + +#include +#include + +gchar *variant_get (const gchar *account, + const gchar *key); + +gboolean variant_delete (const gchar *account); + +gboolean variant_exists (const gchar *account); + +GStrv variant_list (void); + +#endif diff --git a/tests/account-store.c b/tests/account-store.c index 15e43ea..fd5cc4a 100644 --- a/tests/account-store.c +++ b/tests/account-store.c @@ -28,6 +28,7 @@ #include #include "account-store-keyfile.h" +#include "account-store-variant-file.h" #define DOCSTRING_A \ "%s OP BACKEND ACCOUNT [KEY [VALUE]]\n\n" \ @@ -70,6 +71,13 @@ const Backend backends[] = { keyfile_exists, keyfile_list }, + { "variant-file", + variant_get, + NULL, + variant_delete, + variant_exists, + variant_list }, + #if ENABLE_LIBACCOUNTS_SSO { "libaccounts", libaccounts_get, @@ -182,6 +190,12 @@ int main (int argc, char **argv) break; case OP_SET: + if (store->set == NULL) + { + g_printerr ("Listing is unimplemented for this backend"); + break; + } + success = store->set (account, setting, value); output = g_strdup_printf ("%s.%s set to '%s' in %s", account, setting, value, store->name); -- 1.8.4.rc3