diff options
Diffstat (limited to 'pk/gkr-pk-index.c')
-rw-r--r-- | pk/gkr-pk-index.c | 1216 |
1 files changed, 0 insertions, 1216 deletions
diff --git a/pk/gkr-pk-index.c b/pk/gkr-pk-index.c deleted file mode 100644 index 838f4855..00000000 --- a/pk/gkr-pk-index.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pk-index.c - indexes to store values related to pk objects - - Copyright (C) 2007 Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#include "config.h" - -#include "gkr-pk-index.h" -#include "gkr-pk-places.h" - -#include "common/gkr-async.h" -#include "common/gkr-cleanup.h" -#include "common/gkr-crypto.h" -#include "common/gkr-location.h" - -#include <sys/file.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> - -#define MAX_LOCK_TRIES 16 - -#define GKR_TYPE_PK_INDEX (gkr_pk_index_get_type()) -#define GKR_PK_INDEX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GKR_TYPE_PK_INDEX, GkrPkIndex)) -#define GKR_IS_PK_INDEX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GKR_TYPE_PK_INDEX)) - -typedef struct _GkrPkIndex GkrPkIndex; -typedef struct _GkrPkIndexClass GkrPkIndexClass; - -struct _GkrPkIndex { - GObject parent; - GHashTable *path_by_location; - GHashTable *mtime_by_location; - GHashTable *file_by_location; - GHashTable *defaults_by_parent; -}; - -struct _GkrPkIndexClass { - GObjectClass parent_class; -}; - -static GType gkr_pk_index_get_type (void); -G_DEFINE_TYPE (GkrPkIndex, gkr_pk_index, G_TYPE_OBJECT); - -static GkrPkIndex *index_singleton = NULL; -static GQuark no_location = 0; - -typedef gboolean (*ReadValueFunc) (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gpointer user_data); - -typedef gboolean (*WriteValueFunc) (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gpointer user_data); - -/* ----------------------------------------------------------------------------- - * HELPERS - */ - -#ifndef HAVE_FLOCK -#define LOCK_SH 1 -#define LOCK_EX 2 -#define LOCK_NB 4 -#define LOCK_UN 8 - -static int flock(int fd, int operation) -{ - struct flock flock; - - switch (operation & ~LOCK_NB) { - case LOCK_SH: - flock.l_type = F_RDLCK; - break; - case LOCK_EX: - flock.l_type = F_WRLCK; - break; - case LOCK_UN: - flock.l_type = F_UNLCK; - break; - default: - errno = EINVAL; - return -1; - } - - flock.l_whence = 0; - flock.l_start = 0; - flock.l_len = 0; - - return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock); -} -#endif //NOT_HAVE_FLOCK - -static void -free_mtime (gpointer v) -{ - g_slice_free (time_t, v); -} - -static GQuark* -quarks_from_strings (const gchar **strv, gsize *n_quarks) -{ - GArray *arr; - GQuark quark; - - arr = g_array_new (TRUE, TRUE, sizeof (GQuark)); - while (*strv) { - quark = g_quark_from_string (*strv); - g_array_append_val (arr, quark); - ++strv; - } - - if (n_quarks) - *n_quarks = arr->len; - - return (GQuark*)g_array_free (arr, FALSE); -} - -static gchar** -quarks_to_strings (const GQuark* quarks, gsize *n_strings) -{ - const gchar *value; - GArray *arr; - - arr = g_array_new (TRUE, TRUE, sizeof (const gchar*)); - while (*quarks) { - value = g_quark_to_string (*quarks); - g_array_append_val (arr, value); - ++quarks; - } - - if (n_strings) - *n_strings = arr->len; - return (gchar**)g_array_free (arr, FALSE); -} - -static gboolean -strings_are_equal (const gchar **one, const gchar **two) -{ - while (*one && *two) { - if (!g_str_equal (*one, *two)) - return FALSE; - ++one; - ++two; - } - - return *one == *two; -} - -static gpointer -location_to_key (GQuark loc) -{ - return GUINT_TO_POINTER (loc ? loc : no_location); -} - -static GQuark -location_from_key (gpointer key) -{ - GQuark ret = GPOINTER_TO_UINT (key); - return ret == no_location ? 0 : ret; -} - -static const gchar* -index_path_for_location (GkrPkIndex *index, GQuark loc) -{ - gchar *locpath; - gchar *path; - - if (!loc) - return NULL; - - path = g_hash_table_lookup (index->path_by_location, location_to_key (loc)); - if (!path) { - locpath = gkr_location_to_path (loc); - if (!locpath) { - g_message ("The disk or drive this file is located on is not present: %s", - g_quark_to_string (loc)); - return NULL; - } - - /* Our index files have a .keystore extension */ - path = g_strconcat (locpath, ".keystore", NULL); - g_free (locpath); - - g_hash_table_replace (index->path_by_location, location_to_key (loc), path); - } - - return path; -} - -static gboolean -check_index_mtime (GkrPkIndex *index, GQuark loc, time_t mtime) -{ - gpointer k; - gboolean ret = FALSE; - time_t *last; - - k = location_to_key (loc); - - /* Check on last mtime */ - last = (time_t*)g_hash_table_lookup (index->mtime_by_location, k); - ret = !last || (*last != mtime); - - /* Setup new mtime */ - if (ret) { - last = g_slice_new (time_t); - *last = mtime; - g_hash_table_replace (index->mtime_by_location, k, last); - } - - return ret; -} - -static gchar* -digest_to_group (gkrconstid digest) -{ - const guchar *digdata; - gsize n_group, n_digdata; - gboolean r; - gchar *group; - - g_return_val_if_fail (digest, NULL); - - digdata = gkr_id_get_raw (digest, &n_digdata); - g_assert (digdata); - n_group = (n_digdata * 2) + 1; - group = g_malloc0 (n_group); - - r = gkr_crypto_hex_encode (digdata, n_digdata, group, &n_group); - g_assert (r == TRUE); - - return group; -} - -static gboolean -read_exists_any_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gboolean *value) -{ - g_assert (value); - *value = g_key_file_has_group (file, group); - return TRUE; -} - -static gboolean -read_exists_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gboolean *value) -{ - g_assert (value); - g_assert (field); - *value = g_key_file_has_key (file, group, field, err); - return *err == NULL; -} - -static gboolean -read_boolean_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gboolean *value) -{ - g_assert (value); - g_assert (field); - *value = g_key_file_get_boolean (file, group, field, err); - return *err == NULL; -} - -static gboolean -read_int_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gint *value) -{ - g_assert (value); - g_assert (field); - *value = g_key_file_get_integer (file, group, field, err); - return *err == NULL; -} - -static gboolean -read_string_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gchar **value) -{ - g_assert (value); - g_assert (field); - *value = g_key_file_get_string (file, group, field, err); - return *value != NULL; -} - -static gboolean -read_quarks_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, GQuark **value) -{ - gchar **vals; - - g_assert (value); - g_assert (field); - - vals = g_key_file_get_string_list (file, group, field, NULL, err); - if (vals != NULL) { - g_assert (*err == NULL); - *value = quarks_from_strings ((const gchar**)vals, NULL); - g_strfreev (vals); - return TRUE; - } - - return FALSE; -} - -static gint -get_keyfile_value (GKeyFile *key_file, const gchar *group, - const gchar *field, ReadValueFunc func, gpointer data) -{ - GError *err = NULL; - - g_assert (key_file); - g_assert (group); - g_assert (func); - - if ((func) (key_file, group, field, &err, data)) - return 1; - - if (err != NULL) { - if (err->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND && - err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { - g_warning ("couldn't read field '%s' from index: %s", - field, err->message ? err->message : ""); - g_error_free (err); - return -1; - } - - g_error_free (err); - } - - return 0; -} - -static gboolean -write_clear (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gpointer user_data) -{ - if (!g_key_file_has_group (file, group)) - return FALSE; - g_key_file_remove_group (file, group, err); - return TRUE; -} - -static gboolean -write_delete (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gpointer user_data) -{ - g_assert (field); - - if (g_key_file_has_key (file, group, field, err)) { - g_key_file_remove_key (file, group, field, err); - return TRUE; - } - - return FALSE; -} - -static gboolean -write_boolean_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gboolean *value) -{ - g_assert (value); - g_assert (field); - - if (g_key_file_get_boolean (file, group, field, err) != *value || err != NULL) { - g_clear_error (err); - g_key_file_set_boolean (file, group, field, *value); - return TRUE; - } - - return FALSE; -} - -static gboolean -write_int_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, gint *value) -{ - g_assert (value); - g_assert (field); - - if (g_key_file_get_integer (file, group, field, err) != *value || err != NULL) { - g_clear_error (err); - g_key_file_set_integer (file, group, field, *value); - return TRUE; - } - - return FALSE; -} - -static gboolean -write_string_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, const gchar **value) -{ - gboolean ret = FALSE; - gchar *o; - - g_assert (value); - g_assert (*value); - g_assert (field); - - o = g_key_file_get_value (file, group, field, NULL); - - if (!o || !g_str_equal (o, *value)) { - g_key_file_set_string (file, group, field, *value); - ret = TRUE; - } - - g_free (o); - return ret; -} - -static gboolean -write_quarks_value (GKeyFile *file, const gchar *group, const gchar *field, - GError **err, GQuark **value) -{ - GQuark *quarks; - gsize n_strings; - gchar **strings, **o; - gboolean ret = FALSE; - - g_assert (value); - g_assert (*value); - g_assert (field); - - quarks = *value; - strings = quarks_to_strings (quarks, &n_strings); - o = g_key_file_get_string_list (file, group, field, NULL, NULL); - - if (!o || !strings_are_equal ((const gchar**)strings, (const gchar**)o)) { - g_key_file_set_string_list (file, group, field, (const gchar**)strings, n_strings); - ret = TRUE; - } - - g_strfreev (o); - g_free (strings); - return ret; -} - -static void -set_keyfile_value (GKeyFile *key_file, gkrconstid digest, - const gchar *field, WriteValueFunc func, - gpointer data, gboolean *updated) -{ - GError *err = NULL; - gchar *group; - - g_assert (key_file); - g_assert (digest); - g_assert (func); - g_assert (updated); - - /* TODO: Cache this somehow? */ - group = digest_to_group (digest); - g_return_if_fail (group); - - *updated = (func) (key_file, group, field, &err, data); - - if (err) { - g_warning ("couldn't write field '%s' to index: %s", - field, err->message ? err->message : ""); - g_error_free (err); - } - - g_free (group); -} - -static GKeyFile* -read_key_file (int fd, GError **err) -{ - GKeyFile *key_file = NULL; - gchar *contents; - gboolean res; - struct stat sb; - - g_assert (fd != -1); - - if (fstat (fd, &sb) == -1) { - g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), - "failed to get index file size: %s", g_strerror (errno)); - return NULL; - } - - /* Empty file, empty key file */ - if (sb.st_size == 0 || sb.st_size > G_MAXSIZE) - return g_key_file_new (); - - contents = (gchar*)mmap (NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (!contents) { - g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), - "failed to read (map) index file: %s", g_strerror (errno)); - return NULL; - } - - key_file = g_key_file_new (); - res = g_key_file_load_from_data (key_file, contents, sb.st_size, G_KEY_FILE_KEEP_COMMENTS, err); - munmap (contents, sb.st_size); - - if (!res) { - g_key_file_free (key_file); - key_file = NULL; - } - - return key_file; -} - -static GKeyFile* -load_index_key_file (GkrPkIndex *index, GQuark loc, int fd, gboolean force) -{ - GKeyFile *key_file = NULL; - const gchar *path; - gboolean closefd = FALSE; - GError *err = NULL; - - /* If we've never seen it then we should try to read it */ - if (loc && !force && - !g_hash_table_lookup (index->file_by_location, location_to_key (loc))) - force = TRUE; - - /* Read it when necessary and possible */ - if (force) { - path = index_path_for_location (index, loc); - if (path) { - fd = open (path, O_RDONLY); - if (fd == -1) { - if (errno != ENOTDIR && errno != ENOENT) { - g_message ("couldn't open index file: %s: %s", - path, g_strerror (errno)); - return NULL; - } - } - - closefd = TRUE; - } - - /* No file on disk, no index */ - if (fd == -1) { - g_hash_table_remove (index->file_by_location, - location_to_key (loc)); - - /* Read in the open file */ - } else { - key_file = read_key_file (fd, &err); - if (closefd) - close (fd); - - if (!key_file) { - g_message ("couldn't read index file: %s: %s", path ? path : "", - err && err->message ? err->message : ""); - return NULL; - } - - g_hash_table_replace (index->file_by_location, - location_to_key (loc), key_file); - } - } - - key_file = g_hash_table_lookup (index->file_by_location, - location_to_key (loc)); - - /* Automatically create an in memory key file for 'no location' */ - if (!key_file && !loc) { - key_file = g_key_file_new (); - g_hash_table_replace (index->file_by_location, - location_to_key (loc), key_file); - } - - /* No index is available for this location */ - if (!key_file) - return NULL; - - return key_file; -} - -static const gchar* -find_parent_defaults (GQuark parent) -{ - const GkrPkPlace *place; - const gchar *defaults = NULL; - GSList *volumes, *l; - GQuark loc; - guint i; - - for (i = 0; i < G_N_ELEMENTS (gkr_pk_places); ++i) { - place = &(gkr_pk_places[i]); - - /* With a specific volume */ - if (place->volume) { - loc = gkr_location_from_string (place->volume); - loc = gkr_location_from_child (loc, place->directory); - if (loc == parent) - defaults = place->defaults; - - /* With any volume */ - } else { - volumes = gkr_location_manager_get_volumes (NULL); - for (l = volumes; l; l = g_slist_next (l)) { - loc = gkr_location_from_child (GPOINTER_TO_UINT (l->data), - place->directory); - if (loc == parent) { - defaults = place->defaults; - break; - } - } - g_slist_free (volumes); - } - - /* Found something? */ - if (defaults) - return defaults; - } - - return NULL; -} - -static GKeyFile* -load_parent_key_file (GkrPkIndex *index, GQuark loc) -{ - GKeyFile *file; - GQuark parent; - const gchar *defaults; - - if (!loc) - return NULL; - - parent = gkr_location_to_parent (loc); - if (!parent) - return NULL; - - file = g_hash_table_lookup (index->defaults_by_parent, GUINT_TO_POINTER (parent)); - if (!file) { - file = g_key_file_new (); - g_hash_table_insert (index->defaults_by_parent, GUINT_TO_POINTER (parent), file); - - /* - * Look in the places list and load any default index data - * from there. - */ - defaults = find_parent_defaults (parent); - if (defaults) { - if (!g_key_file_load_from_data (file, defaults, strlen (defaults), - G_KEY_FILE_NONE, NULL)) - g_warning ("couldn't parse builtin parent defaults"); - } - } - - return file; -} - -static gboolean -read_pk_index_value (GkrPkIndex *index, GQuark loc, gkrconstid digest, - const gchar *field, GkrPkObject *object, - ReadValueFunc func, gpointer data) -{ - const gchar *path = NULL; - struct stat sb; - gboolean force = FALSE; - GKeyFile *key_file = NULL; - gchar *group; - gint ret = 0; - - g_return_val_if_fail (digest, FALSE); - - if (loc) { - path = index_path_for_location (index, loc); - if (!path) - return FALSE; - - /* TODO: Any way to do this less often? */ - force = (stat (path, &sb) < 0 || check_index_mtime (index, loc, sb.st_mtime)); - } - - key_file = load_index_key_file (index, loc, -1, force); - - /* Try the actual item first */ - if (key_file) { - group = digest_to_group (digest); - g_return_val_if_fail (group, FALSE); - - ret = get_keyfile_value (key_file, group, field, func, data); - g_free (group); - - /* If not found, look in the default section */ - if (ret == 0) - ret = get_keyfile_value (key_file, "default", field, func, data); - } - - /* Look in the parent directory defaults */ - if (ret == 0) { - key_file = load_parent_key_file (index, loc); - if (key_file) - ret = get_keyfile_value (key_file, "default", field, func, data); - } - - /* - * If we saw that the file was changed, then tell the object - * to flush all of its caches and etc... - */ - if (force && object) - gkr_pk_object_flush (object); - - return ret == 1; -} - -static gboolean -update_pk_index_value (GkrPkIndex *index, GQuark loc, gkrconstid digest, - const gchar *field, GkrPkObject *object, - WriteValueFunc func, gpointer data) -{ - const gchar *path = NULL; - gchar *contents = NULL; - gboolean ret = FALSE; - gboolean force = FALSE; - gboolean updated = FALSE; - GError *err = NULL; - GKeyFile *key_file = NULL; - gsize n_contents; - struct stat sb; - int tries = 0; - int fd = -1; - - g_return_val_if_fail (digest, FALSE); - - if (loc) { - path = index_path_for_location (index, loc); - if (!path) - return FALSE; - - /* File lock retry loop */ - for (;;) { - if (tries > MAX_LOCK_TRIES) { - g_message ("couldn't write index '%s' value to file: %s: file is locked", - field, path); - goto done; - } - - fd = open (path, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR); - if (fd == -1) { - g_message ("couldn't create index file: %s: %s", path, g_strerror (errno)); - goto done; - } - - if (flock (fd, LOCK_EX | LOCK_NB) < 0) { - if (errno == EWOULDBLOCK) { - close (fd); - fd = -1; - ++tries; - gkr_async_usleep (200000); - continue; - } - g_message ("couldn't lock index file: %s: %s", path, g_strerror (errno)); - goto done; - } - - /* Successfully opened file */; - break; - } - - - /* See if file needs updating */ - force = (fstat (fd, &sb) < 0 || check_index_mtime (index, loc, sb.st_mtime)); - } - - key_file = load_index_key_file (index, loc, -1, force); - if (!key_file) - goto done; - - set_keyfile_value (key_file, digest, field, func, data, &updated); - if (updated && loc) { - - /* Serialize the key file into memory */ - contents = g_key_file_to_data (key_file, &n_contents, &err); - if (!contents) { - g_warning ("couldn't serialize index file: %s", - err && err->message ? err->message : ""); - g_error_free (err); - goto done; - } - - g_assert (path); - - /* And write that memory to disk atomically */ - if (!g_file_set_contents (path, contents, n_contents, &err)) { - g_message ("couldn't write index file to disk: %s: %s", - path, err && err->message ? err->message : ""); - g_error_free (err); - goto done; - } - } - - /* - * If the file was updated then tell the object to flush all of - * its caches and other optimizations... - */ - if ((force || updated) && object) - gkr_pk_object_flush (object); - - ret = TRUE; - -done: - if (fd != -1) - close (fd); - g_free (contents); - - return ret; -} - -static void -cleanup_index_singleton (void *unused) -{ - g_assert (index_singleton); - g_object_unref (index_singleton); - index_singleton = NULL; -} - -static GkrPkIndex* -get_index_singleton (void) -{ - if (!index_singleton) { - index_singleton = g_object_new (GKR_TYPE_PK_INDEX, NULL); - gkr_cleanup_register (cleanup_index_singleton, NULL); - } - - return index_singleton; -} - -static gboolean -remove_descendent_locations (gpointer key, gpointer value, gpointer user_data) -{ - GQuark loc = location_from_key (key); - GQuark volume = GPOINTER_TO_UINT (user_data); - return loc && gkr_location_is_descendant (volume, loc); -} - -static void -flush_caches (GkrLocationManager *locmgr, GQuark volume, GkrPkIndex *index) -{ - /* - * Called when the location manager adds or removes a prefix - * possibly invalidating our cached paths. - */ - - g_hash_table_foreach_remove (index->path_by_location, remove_descendent_locations, - GUINT_TO_POINTER (volume)); - g_hash_table_foreach_remove (index->file_by_location, remove_descendent_locations, - GUINT_TO_POINTER (volume)); - g_hash_table_foreach_remove (index->mtime_by_location, remove_descendent_locations, - GUINT_TO_POINTER (volume)); - g_hash_table_foreach_remove (index->defaults_by_parent, remove_descendent_locations, - GUINT_TO_POINTER (volume)); -} - -/* ----------------------------------------------------------------------------- - * OBJECT - */ - -static void -gkr_pk_index_init (GkrPkIndex *index) -{ - GkrLocationManager *locmgr; - - index->path_by_location = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - index->mtime_by_location = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_mtime); - index->file_by_location = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify)g_key_file_free); - index->defaults_by_parent = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify)g_key_file_free); - - locmgr = gkr_location_manager_get (); - g_signal_connect (locmgr, "volume-removed", G_CALLBACK (flush_caches), index); -} - -static void -gkr_pk_index_finalize (GObject *obj) -{ - GkrPkIndex *index = GKR_PK_INDEX (obj); - GkrLocationManager *locmgr; - - locmgr = gkr_location_manager_get (); - g_signal_handlers_disconnect_by_func (locmgr, flush_caches, index); - - g_hash_table_destroy (index->path_by_location); - g_hash_table_destroy (index->mtime_by_location); - g_hash_table_destroy (index->file_by_location); - g_hash_table_destroy (index->defaults_by_parent); - index->path_by_location = index->mtime_by_location = NULL; - index->file_by_location = index->defaults_by_parent = NULL; - - G_OBJECT_CLASS (gkr_pk_index_parent_class)->finalize (obj); -} - -static void -gkr_pk_index_class_init (GkrPkIndexClass *klass) -{ - GObjectClass *gobject_class; - - gkr_pk_index_parent_class = g_type_class_peek_parent (klass); - - gobject_class = (GObjectClass*)klass; - gobject_class->finalize = gkr_pk_index_finalize; - - /* A special quark that denotes stored in memory */ - no_location = g_quark_from_static_string ("MEMORY"); -} - -/* ----------------------------------------------------------------------------- - * PUBLIC - */ - -gboolean -gkr_pk_index_get_boolean (GkrPkObject *obj, const gchar *field, gboolean defvalue) -{ - gboolean ret = defvalue; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), ret); - g_return_val_if_fail (field != NULL, ret); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (ReadValueFunc)read_boolean_value, &ret)) - ret = defvalue; - - return ret; -} - -gboolean -gkr_pk_index_get_boolean_full (GQuark location, gkrconstid digest, - const gchar *field, gboolean defvalue) -{ - gboolean ret = defvalue; - - g_return_val_if_fail (digest, ret); - g_return_val_if_fail (field != NULL, ret); - - if (!read_pk_index_value (get_index_singleton (), location, digest, field, - NULL, (ReadValueFunc)read_boolean_value, &ret)) - ret = defvalue; - - return ret; -} - -gint -gkr_pk_index_get_int (GkrPkObject *obj, const gchar *field, gint defvalue) -{ - gint ret = defvalue; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), ret); - g_return_val_if_fail (field != NULL, ret); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (ReadValueFunc)read_int_value, &ret)) - ret = defvalue; - - return ret; -} - -gchar* -gkr_pk_index_get_string (GkrPkObject *obj, const gchar *field) -{ - gchar *ret = NULL; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), NULL); - g_return_val_if_fail (field != NULL, NULL); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (ReadValueFunc)read_string_value, &ret)) - ret = NULL; - - return ret; -} - -gchar* -gkr_pk_index_get_string_full (GQuark location, gkrconstid digest, - const gchar *field) -{ - gchar *ret = NULL; - - g_return_val_if_fail (digest, NULL); - g_return_val_if_fail (field != NULL, NULL); - - if (!read_pk_index_value (get_index_singleton (), location, digest, field, - NULL, (ReadValueFunc)read_string_value, &ret)) - ret = NULL; - - return ret; -} - -guchar* -gkr_pk_index_get_binary (GkrPkObject *obj, const gchar *field, gsize *n_data) -{ - guchar *data; - gchar *str; - gsize n_str; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), NULL); - g_return_val_if_fail (field != NULL, NULL); - g_return_val_if_fail (n_data != NULL, NULL); - - str = gkr_pk_index_get_string (obj, field); - if (!str) - return NULL; - - n_str = strlen (str); - *n_data = (n_str / 2) + 1; - data = g_malloc0 (*n_data); - if (!gkr_crypto_hex_decode (str, n_str, data, n_data)) { - g_message ("invalid binary data in index under field '%s'", field); - g_free (data); - data = NULL; - } - - g_free (str); - return data; -} - -GQuark* -gkr_pk_index_get_quarks (GkrPkObject *obj, const gchar *field) -{ - GQuark *ret = NULL; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), NULL); - g_return_val_if_fail (field != NULL, NULL); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (ReadValueFunc)read_quarks_value, &ret)) - ret = NULL; - - return ret; -} - -gboolean -gkr_pk_index_has_value (GkrPkObject *obj, const gchar *field) -{ - gboolean ret; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (ReadValueFunc)read_exists_value, &ret)) - ret = FALSE; - - return ret; -} - -gboolean -gkr_pk_index_have (GkrPkObject *obj) -{ - gboolean ret; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - - if (!read_pk_index_value (get_index_singleton (), obj->location, obj->digest, - NULL, obj, (ReadValueFunc)read_exists_any_value, &ret)) - ret = FALSE; - - return ret; -} - -gboolean -gkr_pk_index_have_full (GQuark location, gkrconstid digest) -{ - gboolean ret; - - g_return_val_if_fail (digest, FALSE); - - if (!read_pk_index_value (get_index_singleton (), location, digest, NULL, - NULL, (ReadValueFunc)read_exists_any_value, &ret)) - ret = FALSE; - - return ret; -} - -gboolean -gkr_pk_index_set_boolean (GkrPkObject *obj, const gchar *field, gboolean val) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (WriteValueFunc)write_boolean_value, &val); -} - -gboolean -gkr_pk_index_set_int (GkrPkObject *obj, const gchar *field, gint val) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (WriteValueFunc)write_int_value, &val); -} - -gboolean -gkr_pk_index_set_string (GkrPkObject *obj, const gchar *field, const gchar *val) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - g_return_val_if_fail (val, FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (WriteValueFunc)write_string_value, &val); -} - -gboolean -gkr_pk_index_set_string_full (GQuark location, gkrconstid digest, const gchar *field, - const gchar *val) -{ - g_return_val_if_fail (digest, FALSE); - g_return_val_if_fail (field != NULL, FALSE); - g_return_val_if_fail (val, FALSE); - - return update_pk_index_value (get_index_singleton (), location, digest, field, - NULL, (WriteValueFunc)write_string_value, &val); -} - -gboolean -gkr_pk_index_set_binary (GkrPkObject *obj, const gchar *field, - const guchar *data, gsize n_data) -{ - gboolean ret, r; - gchar *str; - gsize n_str; - - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - - n_str = (n_data * 2) + 1; - str = g_malloc0 (n_str); - - r = gkr_crypto_hex_encode (data, n_data, str, &n_str); - g_assert (r == TRUE); - - ret = gkr_pk_index_set_string (obj, field, str); - g_free (str); - - return ret; -} - -gboolean -gkr_pk_index_set_quarks (GkrPkObject *obj, const gchar *field, GQuark *quarks) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (WriteValueFunc)write_quarks_value, &quarks); -} - -gboolean -gkr_pk_index_delete (GkrPkObject *obj, const gchar *field) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - g_return_val_if_fail (field != NULL, FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - field, obj, (WriteValueFunc)write_delete, NULL); - -} - -gboolean -gkr_pk_index_clear (GkrPkObject *obj) -{ - g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), FALSE); - - return update_pk_index_value (get_index_singleton (), obj->location, obj->digest, - NULL, obj, (WriteValueFunc)write_clear, NULL); - -} - -gboolean -gkr_pk_index_quarks_has (GQuark *quarks, GQuark check) -{ - while (*quarks) { - if (*quarks == check) - return TRUE; - ++quarks; - } - - return FALSE; -} - -GQuark* -gkr_pk_index_quarks_dup (GQuark *quarks) -{ - GQuark *last = quarks; - - /* Figure out how many there are */ - while (*last) - ++last; - - /* Include the null termination */ - ++last; - return g_memdup (quarks, (last - quarks) * sizeof (GQuark)); -} - -void -gkr_pk_index_quarks_free (GQuark *quarks) -{ - g_free (quarks); -} |