Commit 5bf8c029 authored by Stefan Walter's avatar Stefan Walter

Add support for unknown keys and the support for the 'DiscoverKeys' dbus

    * daemon/seahorse-service-keyset.c:
    * daemon/seahorse-service-keyset.xml:
    * daemon/seahorse-service.c:
    * daemon/seahorse-service.h:
    * daemon/seahorse-service.xml:
    * libseahorse/Makefile.am:
    * libseahorse/seahorse-context.c:
    * libseahorse/seahorse-context.h:
    * libseahorse/seahorse-hkp-source.c:
    * libseahorse/seahorse-key-source.c:
    * libseahorse/seahorse-key-source.h:
    * libseahorse/seahorse-key.c:
    * libseahorse/seahorse-key.h:
    * libseahorse/seahorse-ldap-source.c:
    * libseahorse/seahorse-pgp-source.c:
    * libseahorse/seahorse-pgp-source.h:
    * libseahorse/seahorse-server-source.c:
    * libseahorse/seahorse-ssh-key.c:
    * libseahorse/seahorse-ssh-key.h:
    * libseahorse/seahorse-ssh-source.c:
    * libseahorse/seahorse-transfer-operation.c (added):
    * libseahorse/seahorse-transfer-operation.h (added):
    * libseahorse/seahorse-unknown-key.c (added):
    * libseahorse/seahorse-unknown-key.h (added):
    * libseahorse/seahorse-unknown-source.c (added):
    * libseahorse/seahorse-unknown-source.h (added):
    * tests/dbus-discover-test.py (added):
    * tests/dbus-import.py (added):
    * tests/dbus-listen-keyset.py (added):
    * tests/dbus-test.py (added): Add support for unknown keys and
    the support for the 'DiscoverKeys' dbus API.
parent f0912e8a
2006-04-17 Nate Nielsen <nielsen@memberwebs.com>
* daemon/seahorse-service-keyset.c:
* daemon/seahorse-service-keyset.xml:
* daemon/seahorse-service.c:
* daemon/seahorse-service.h:
* daemon/seahorse-service.xml:
* libseahorse/Makefile.am:
* libseahorse/seahorse-context.c:
* libseahorse/seahorse-context.h:
* libseahorse/seahorse-hkp-source.c:
* libseahorse/seahorse-key-source.c:
* libseahorse/seahorse-key-source.h:
* libseahorse/seahorse-key.c:
* libseahorse/seahorse-key.h:
* libseahorse/seahorse-ldap-source.c:
* libseahorse/seahorse-pgp-source.c:
* libseahorse/seahorse-pgp-source.h:
* libseahorse/seahorse-server-source.c:
* libseahorse/seahorse-ssh-key.c:
* libseahorse/seahorse-ssh-key.h:
* libseahorse/seahorse-ssh-source.c:
* libseahorse/seahorse-transfer-operation.c (added):
* libseahorse/seahorse-transfer-operation.h (added):
* libseahorse/seahorse-unknown-key.c (added):
* libseahorse/seahorse-unknown-key.h (added):
* libseahorse/seahorse-unknown-source.c (added):
* libseahorse/seahorse-unknown-source.h (added):
* tests/dbus-discover-test.py (added):
* tests/dbus-import.py (added):
* tests/dbus-listen-keyset.py (added):
* tests/dbus-test.py (added): Add support for unknown keys and
the support for the 'DiscoverKeys' dbus API.
2006-04-17 Nate Nielsen <nielsen@memberwebs.com> 2006-04-17 Nate Nielsen <nielsen@memberwebs.com>
* libseahorse/seahorse-key-store.c: Fix crasher when * libseahorse/seahorse-key-store.c: Fix crasher when
......
...@@ -31,27 +31,8 @@ enum { ...@@ -31,27 +31,8 @@ enum {
}; };
G_DEFINE_TYPE (SeahorseServiceKeyset, seahorse_service_keyset, SEAHORSE_TYPE_KEYSET); G_DEFINE_TYPE (SeahorseServiceKeyset, seahorse_service_keyset, SEAHORSE_TYPE_KEYSET);
static SeahorseKeysetClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
/* -----------------------------------------------------------------------------
* PUBLIC METHODS
*/
SeahorseKeyset*
seahorse_service_keyset_new (GQuark ktype)
{
SeahorseServiceKeyset *skset;
SeahorseKeyPredicate *pred = g_new0(SeahorseKeyPredicate, 1);
pred->ktype = ktype;
skset = g_object_new (SEAHORSE_TYPE_SERVICE_KEYSET, "predicate", pred, NULL);
g_object_set_data_full (G_OBJECT (skset), "quick-predicate", pred, g_free);
return SEAHORSE_KEYSET (skset);
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* DBUS METHODS * DBUS METHODS
*/ */
...@@ -83,12 +64,124 @@ seahorse_service_keyset_list_keys (SeahorseServiceKeyset *keyset, gchar ***keys, ...@@ -83,12 +64,124 @@ seahorse_service_keyset_list_keys (SeahorseServiceKeyset *keyset, gchar ***keys,
return TRUE; return TRUE;
} }
gboolean
seahorse_service_keyset_discover_keys (SeahorseServiceKeyset *keyset, const gchar **keyids,
gint flags, gchar ***keys, GError **error)
{
GArray *akeys = NULL;
gchar *keyid = NULL;
GSList *todiscover = NULL;
GList *toimport = NULL;
SeahorseKey* skey;
SeahorseKeyLoc loc;
SeahorseOperation *op;
const gchar **k;
gchar *t;
GSList *l;
gboolean ret = FALSE;
akeys = g_array_new (TRUE, TRUE, sizeof (gchar*));
/* Check all the keyids */
for (k = keyids; *k; k++) {
g_free (keyid);
keyid = seahorse_key_source_cannonical_keyid (keyset->ktype, *k);
if (!keyid) {
g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
_("Invalid key id: %s"), *k);
goto finally;
}
/* Do we know about this key? */
skey = seahorse_context_find_key (SCTX_APP (), keyset->ktype,
SKEY_LOC_INVALID, keyid);
/* Add to the return value */
t = seahorse_service_keyid_to_dbus (keyset->ktype, keyid, 0);
g_array_append_val (akeys, t);
/* No such key anywhere, discover it */
if (!skey) {
todiscover = g_slist_prepend (todiscover, keyid);
keyid = NULL;
continue;
}
g_free (keyid);
keyid = NULL;
/* We know about this key, check where it is */
loc = seahorse_key_get_location (skey);
g_assert (loc != SKEY_LOC_INVALID);
/* Do nothing for local keys */
if (loc >= SKEY_LOC_LOCAL)
continue;
/* Remote keys get imported */
else if (loc >= SKEY_LOC_REMOTE)
toimport = g_list_prepend (toimport, skey);
/* Searching keys are ignored */
else if (loc >= SKEY_LOC_SEARCHING)
continue;
/* Not found keys are tried again */
else if (loc >= SKEY_LOC_UNKNOWN) {
todiscover = g_slist_prepend (todiscover, keyid);
keyid = NULL;
}
}
/* Start an import process on all toimport */
if (toimport) {
op = seahorse_context_transfer_keys (SCTX_APP (), toimport, NULL);
/* Running operations ref themselves */
g_object_unref (op);
}
/* Start a discover process on all todiscover */
if (todiscover) {
op = seahorse_context_retrieve_keys (SCTX_APP (), keyset->ktype,
todiscover, NULL);
/* Running operations ref themselves */
g_object_unref (op);
}
ret = TRUE;
finally:
if (todiscover) {
for (l = todiscover; l; l = g_slist_next (l))
g_free (l->data);
g_slist_free (todiscover);
}
if (toimport)
g_list_free (toimport);
if (keyid)
g_free (keyid);
if (ret) {
g_assert (akeys);
*keys = (gchar**)g_array_free (akeys, FALSE);
} else if (akeys) {
g_strfreev ((gchar**)g_array_free (akeys, FALSE));
}
return ret;
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* DBUS SIGNALS * DBUS SIGNALS
*/ */
static void static void
seahorse_service_keyset_added (SeahorseKeyset *skset, SeahorseKey *skey) seahorse_service_keyset_added (SeahorseKeyset *skset, SeahorseKey *skey,
gpointer userdata)
{ {
gchar *id; gchar *id;
guint uids, i; guint uids, i;
...@@ -107,11 +200,11 @@ seahorse_service_keyset_added (SeahorseKeyset *skset, SeahorseKey *skey) ...@@ -107,11 +200,11 @@ seahorse_service_keyset_added (SeahorseKeyset *skset, SeahorseKey *skey)
static void static void
seahorse_service_keyset_removed (SeahorseKeyset *skset, SeahorseKey *skey, seahorse_service_keyset_removed (SeahorseKeyset *skset, SeahorseKey *skey,
gpointer closure) gpointer closure, gpointer userdata)
{ {
gchar *id; gchar *id;
guint uids, i; guint uids, i;
uids = GPOINTER_TO_UINT (closure); uids = GPOINTER_TO_UINT (closure);
uids = (uids == 0) ? 1 : uids; uids = (uids == 0) ? 1 : uids;
...@@ -124,7 +217,8 @@ seahorse_service_keyset_removed (SeahorseKeyset *skset, SeahorseKey *skey, ...@@ -124,7 +217,8 @@ seahorse_service_keyset_removed (SeahorseKeyset *skset, SeahorseKey *skey,
static void static void
seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey, seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey,
SeahorseKeyChange change, gpointer closure) SeahorseKeyChange change, gpointer closure,
gpointer userdata)
{ {
gchar *id; gchar *id;
guint uids, euids, i; guint uids, euids, i;
...@@ -135,8 +229,8 @@ seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey, ...@@ -135,8 +229,8 @@ seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey,
euids = GPOINTER_TO_UINT (closure); euids = GPOINTER_TO_UINT (closure);
if (euids > 0 && euids != uids) { if (euids > 0 && euids != uids) {
seahorse_service_keyset_removed (skset, skey, closure); seahorse_service_keyset_removed (skset, skey, closure, NULL);
seahorse_service_keyset_added (skset, skey); seahorse_service_keyset_added (skset, skey, NULL);
return; return;
} }
...@@ -154,31 +248,47 @@ seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey, ...@@ -154,31 +248,47 @@ seahorse_service_keyset_changed (SeahorseKeyset *skset, SeahorseKey *skey,
static void static void
seahorse_service_keyset_init (SeahorseServiceKeyset *keyset) seahorse_service_keyset_init (SeahorseServiceKeyset *keyset)
{ {
g_signal_connect_after (keyset, "added", G_CALLBACK (seahorse_service_keyset_added), NULL);
g_signal_connect_after (keyset, "removed", G_CALLBACK (seahorse_service_keyset_removed), NULL);
g_signal_connect_after (keyset, "added", G_CALLBACK (seahorse_service_keyset_changed), NULL);
} }
static void static void
seahorse_service_keyset_class_init (SeahorseServiceKeysetClass *klass) seahorse_service_keyset_class_init (SeahorseServiceKeysetClass *klass)
{ {
GObjectClass *gclass; GObjectClass *gclass;
parent_class = g_type_class_peek_parent (klass);
parent_class->added = seahorse_service_keyset_added;
parent_class->removed = seahorse_service_keyset_removed;
parent_class->changed = seahorse_service_keyset_changed;
gclass = G_OBJECT_CLASS (klass); gclass = G_OBJECT_CLASS (klass);
signals[KEY_ADDED] = g_signal_new ("key_added", SEAHORSE_TYPE_SERVICE_KEYSET, signals[KEY_ADDED] = g_signal_new ("key_added", SEAHORSE_TYPE_SERVICE_KEYSET,
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_added), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_added),
NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
signals[KEY_REMOVED] = g_signal_new ("key_removed", SEAHORSE_TYPE_SERVICE_KEYSET, signals[KEY_REMOVED] = g_signal_new ("key_removed", SEAHORSE_TYPE_SERVICE_KEYSET,
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_removed), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_removed),
NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
signals[KEY_CHANGED] = g_signal_new ("key_changed", SEAHORSE_TYPE_SERVICE_KEYSET, signals[KEY_CHANGED] = g_signal_new ("key_changed", SEAHORSE_TYPE_SERVICE_KEYSET,
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_changed), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET (SeahorseServiceKeysetClass, key_changed),
NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
} }
/* -----------------------------------------------------------------------------
* PUBLIC METHODS
*/
SeahorseKeyset*
seahorse_service_keyset_new (GQuark ktype, SeahorseKeyLoc location)
{
SeahorseServiceKeyset *skset;
SeahorseKeyPredicate *pred = g_new0(SeahorseKeyPredicate, 1);
pred->ktype = ktype;
pred->location = location;
skset = g_object_new (SEAHORSE_TYPE_SERVICE_KEYSET, "predicate", pred, NULL);
g_object_set_data_full (G_OBJECT (skset), "quick-predicate", pred, g_free);
skset->ktype = ktype;
return SEAHORSE_KEYSET (skset);
}
...@@ -10,6 +10,14 @@ ...@@ -10,6 +10,14 @@
<arg type="as" name="keys" direction="out"/> <arg type="as" name="keys" direction="out"/>
</method> </method>
<method name="DiscoverKeys">
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="seahorse_service_keyset_discover_keys"/>
<arg type="as" name="keyids" direction="in"/>
<arg type="i" name="flags" direction="in"/>
<arg type="as" name="keys" direction="out"/>
</method>
<signal name="KeyAdded"> <signal name="KeyAdded">
<arg type="s" name="key" direction="out"/> <arg type="s" name="key" direction="out"/>
</signal> </signal>
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "seahorse-util.h" #include "seahorse-util.h"
#define KEYSET_PATH "/org/gnome/seahorse/keys/%s" #define KEYSET_PATH "/org/gnome/seahorse/keys/%s"
#define KEYSET_PATH_LOCAL "/org/gnome/seahorse/keys/%s/local"
/* Special fields */ /* Special fields */
enum { enum {
...@@ -94,18 +95,26 @@ void ...@@ -94,18 +95,26 @@ void
add_key_source (SeahorseService *svc, GQuark ktype) add_key_source (SeahorseService *svc, GQuark ktype)
{ {
const gchar *keytype = g_quark_to_string (ktype); const gchar *keytype = g_quark_to_string (ktype);
SeahorseKeyset *keyset;
gchar *dbus_id; gchar *dbus_id;
/* Check if we have a keyset for this key type, and add if not */ /* Check if we have a keyset for this key type, and add if not */
if (svc->keysets && !g_hash_table_lookup (svc->keysets, keytype)) { if (svc->keysets && !g_hash_table_lookup (svc->keysets, keytype)) {
SeahorseKeyset *keyset = seahorse_service_keyset_new (ktype);
/* Register it with DBUS */ /* Keyset for all keys */
keyset = seahorse_service_keyset_new (ktype, SKEY_LOC_INVALID);
dbus_id = g_strdup_printf (KEYSET_PATH, keytype); dbus_id = g_strdup_printf (KEYSET_PATH, keytype);
dbus_g_connection_register_g_object (seahorse_dbus_server_get_connection (), dbus_g_connection_register_g_object (seahorse_dbus_server_get_connection (),
dbus_id, G_OBJECT (keyset)); dbus_id, G_OBJECT (keyset));
g_free (dbus_id); g_free (dbus_id);
/* Keyset for local keys */
keyset = seahorse_service_keyset_new (ktype, SKEY_LOC_LOCAL);
dbus_id = g_strdup_printf (KEYSET_PATH_LOCAL, keytype);
dbus_g_connection_register_g_object (seahorse_dbus_server_get_connection (),
dbus_id, G_OBJECT (keyset));
g_free (dbus_id);
g_hash_table_replace (svc->keysets, g_strdup (keytype), keyset); g_hash_table_replace (svc->keysets, g_strdup (keytype), keyset);
} }
} }
...@@ -125,8 +134,9 @@ seahorse_service_key_from_dbus (const gchar *key, guint *uid) ...@@ -125,8 +134,9 @@ seahorse_service_key_from_dbus (const gchar *key, guint *uid)
if (!vec[0] || !vec[1]) if (!vec[0] || !vec[1])
return NULL; return NULL;
/* This will always get the most preferred key */
skey = seahorse_context_find_key (SCTX_APP (), g_quark_from_string (vec[0]), skey = seahorse_context_find_key (SCTX_APP (), g_quark_from_string (vec[0]),
SKEY_LOC_UNKNOWN, vec[1]); SKEY_LOC_INVALID, vec[1]);
if (uid) if (uid)
*uid = 0; *uid = 0;
...@@ -421,15 +431,6 @@ seahorse_service_match_save (SeahorseService *svc, gchar *ktype, gint flags, ...@@ -421,15 +431,6 @@ seahorse_service_match_save (SeahorseService *svc, gchar *ktype, gint flags,
return FALSE; return FALSE;
} }
gboolean
seahorse_service_discover_keys (SeahorseService *svc, gchar *ktype, gint flags,
gchar **patterns, gchar **keys, GError **error)
{
/* TODO: Implement discover keys */
g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_NOTIMPLEMENTED, "TODO");
return FALSE;
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* SIGNAL HANDLERS * SIGNAL HANDLERS
*/ */
......
...@@ -94,10 +94,6 @@ gboolean seahorse_service_match_save (SeahorseService *svc, gchar ...@@ -94,10 +94,6 @@ gboolean seahorse_service_match_save (SeahorseService *svc, gchar
gint flags, gchar **patterns, gint flags, gchar **patterns,
gchar **keys, GError **error); gchar **keys, GError **error);
gboolean seahorse_service_discover_keys (SeahorseService *svc, gchar *ktype,
gint flags, gchar **patterns, gchar **keys,
GError **error);
SeahorseKey* seahorse_service_key_from_dbus (const gchar *key, guint *uid); SeahorseKey* seahorse_service_key_from_dbus (const gchar *key, guint *uid);
gchar* seahorse_service_key_to_dbus (SeahorseKey *skey, guint uid); gchar* seahorse_service_key_to_dbus (SeahorseKey *skey, guint uid);
...@@ -120,6 +116,9 @@ typedef struct _SeahorseServiceKeysetClass SeahorseServiceKeysetClass; ...@@ -120,6 +116,9 @@ typedef struct _SeahorseServiceKeysetClass SeahorseServiceKeysetClass;
struct _SeahorseServiceKeyset { struct _SeahorseServiceKeyset {
SeahorseKeyset base; SeahorseKeyset base;
/* <public> */
GQuark ktype;
}; };
struct _SeahorseServiceKeysetClass { struct _SeahorseServiceKeysetClass {
...@@ -139,11 +138,16 @@ struct _SeahorseServiceKeysetClass { ...@@ -139,11 +138,16 @@ struct _SeahorseServiceKeysetClass {
GType seahorse_service_keyset_get_type (void); GType seahorse_service_keyset_get_type (void);
SeahorseKeyset* seahorse_service_keyset_new (GQuark keytype); SeahorseKeyset* seahorse_service_keyset_new (GQuark keytype,
SeahorseKeyLoc location);
gboolean seahorse_service_keyset_list_keys (SeahorseServiceKeyset *keyset, gboolean seahorse_service_keyset_list_keys (SeahorseServiceKeyset *keyset,
gchar ***keys, GError **error); gchar ***keys, GError **error);
gboolean seahorse_service_keyset_discover_keys (SeahorseServiceKeyset *keyset,
const gchar **keyids, gint flags,
gchar ***keys, GError **error);
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* CRYPTO SERVICE * CRYPTO SERVICE
*/ */
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
<arg type="as" name="keys" direction="in"/> <arg type="as" name="keys" direction="in"/>
<arg type="s" name="data" direction="out"/> <arg type="s" name="data" direction="out"/>
</method> </method>
<method name="MatchKeys"> <method name="MatchKeys">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" <annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="seahorse_service_match_keys"/> value="seahorse_service_match_keys"/>
...@@ -80,15 +80,6 @@ ...@@ -80,15 +80,6 @@
<arg type="as" name="keys" direction="in"/> <arg type="as" name="keys" direction="in"/>
</method> </method>
<method name="DiscoverKeys">
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="seahorse_service_discover_keys"/>
<arg type="s" name="keytype" direction="in"/>
<arg type="i" name="flags" direction="in"/>
<arg type="as" name="patterns" direction="in"/>
<arg type="as" name="keys" direction="in"/>
</method>
</interface> </interface>
</node> </node>
...@@ -62,6 +62,8 @@ libseahorse_internal_la_SOURCES = \ ...@@ -62,6 +62,8 @@ libseahorse_internal_la_SOURCES = \
seahorse-pgp-key-op.c seahorse-pgp-key-op.h \ seahorse-pgp-key-op.c seahorse-pgp-key-op.h \
seahorse-pgp-source.c seahorse-pgp-source.h \ seahorse-pgp-source.c seahorse-pgp-source.h \
seahorse-pgp-operation.c seahorse-pgp-operation.h \ seahorse-pgp-operation.c seahorse-pgp-operation.h \
seahorse-unknown-key.c seahorse-unknown-key.h \
seahorse-unknown-source.c seahorse-unknown-source.h \
seahorse-context.c seahorse-context.h \ seahorse-context.c seahorse-context.h \
seahorse-widget.c seahorse-widget.h \ seahorse-widget.c seahorse-widget.h \
seahorse-op.c seahorse-op.h \ seahorse-op.c seahorse-op.h \
...@@ -83,6 +85,7 @@ libseahorse_internal_la_SOURCES = \ ...@@ -83,6 +85,7 @@ libseahorse_internal_la_SOURCES = \
seahorse-gpgmex.h seahorse-gpgmex-op.c seahorse-gpgmex-util.c \ seahorse-gpgmex.h seahorse-gpgmex-op.c seahorse-gpgmex-util.c \
seahorse-prefs.c seahorse-prefs.h \ seahorse-prefs.c seahorse-prefs.h \
seahorse-operation.c seahorse-operation.h \ seahorse-operation.c seahorse-operation.h \
seahorse-transfer-operation.c seahorse-transfer-operation.h \
seahorse-progress.c seahorse-progress.h \ seahorse-progress.c seahorse-progress.h \
seahorse-gconf.c seahorse-gconf.h \ seahorse-gconf.c seahorse-gconf.h \
seahorse-dns-sd.c seahorse-dns-sd.h \ seahorse-dns-sd.c seahorse-dns-sd.h \
...@@ -122,4 +125,4 @@ glade_DATA = \ ...@@ -122,4 +125,4 @@ glade_DATA = \
seahorse-progress.glade seahorse-progress.glade
EXTRA_DIST = $(glade_DATA) \ EXTRA_DIST = $(glade_DATA) \
seahorse-marshal.list seahorse-marshal.list
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include "seahorse-server-source.h" #include "seahorse-server-source.h"
#include "seahorse-pgp-source.h" #include "seahorse-pgp-source.h"
#include "seahorse-dns-sd.h" #include "seahorse-dns-sd.h"
#include "seahorse-transfer-operation.h"
#include "seahorse-unknown-source.h"
#include "seahorse-unknown-key.h"
#ifdef WITH_SSH #ifdef WITH_SSH
#include "seahorse-ssh-key.h" #include "seahorse-ssh-key.h"
...@@ -55,33 +58,43 @@ static guint signals[LAST_SIGNAL] = { 0 }; ...@@ -55,33 +58,43 @@ static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (SeahorseContext, seahorse_context, GTK_TYPE_OBJECT); G_DEFINE_TYPE (SeahorseContext, seahorse_context, GTK_TYPE_OBJECT);
/*
* Two hashtables are used to keep track of the keys:
*
* keys_by_source: This contains a reference to the key and allows us to
* lookup keys by their source. Each key/source combination should be
* unique. Hashkeys are made with hashkey_by_source()
* keys_by_type: Each value contains a GList of keys with the same ktype/keyid
* combination (ie: same key from different key sources). The keys are
* orderred in by preferred usage. Hashkeys are made with hashkey_by_type().
*/
struct _SeahorseContextPrivate { struct _SeahorseContextPrivate {
GSList *sources; /* Key sources which add keys to this context */ GSList *sources; /* Key sources which add keys to this context */
GHashTable *keys; /* A list of all keys in the context */
GHashTable *auto_sources; /* Automatically added key sources (keyservers) */ GHashTable *auto_sources; /* Automatically added key sources (keyservers) */
GHashTable *keys_by_source; /* See explanation above */
GHashTable *keys_by_type; /* See explanation above */
guint notify_id; /* Notify for GConf watch */ guint notify_id; /* Notify for GConf watch */
SeahorseServiceDiscovery *discovery; /* Adds key sources from DNS-SD */ SeahorseServiceDiscovery *discovery; /* Adds key sources from DNS-SD */
}; };
static void seahorse_context_dispose (GObject *gobject); static void seahorse_context_dispose (GObject *gobject);
static void seahorse_context_finalize (GObject *gobject); static void seahorse_context_finalize (GObject *gobject);
/* Forward declarations */ /* Forward declarations */
static void refresh_keyservers (GConfClient *client, guint id, static void refresh_keyservers (GConfClient *client, guint id,
GConfEntry *entry, SeahorseContext *sctx); GConfEntry *entry, SeahorseContext *sctx);
static GtkObjectClass *parent_class = NULL;
static void static void
seahorse_context_class_init (SeahorseContextClass *klass) seahorse_context_class_init (SeahorseContextClass *klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
parent_class = g_type_class_peek_parent (klass); seahorse_context_parent_class = g_type_class_peek_parent (klass);
gobject_class = G_OBJECT_CLASS (klass); gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = seahorse_context_dispose; gobject_class->dispose = seahorse_context_dispose;
gobject_class->finalize = seahorse_context_finalize; gobject_class->finalize = seahorse_context_finalize;
signals[ADDED] = g_signal_new ("added", SEAHORSE_TYPE_CONTEXT, signals[ADDED] = g_signal_new ("added", SEAHORSE_TYPE_CONTEXT,
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseContextClass, added), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SeahorseContextClass, added),
...@@ -98,15 +111,18 @@ seahorse_context_class_init (SeahorseContextClass *klass) ...@@ -98,15 +111,18 @@ seahorse_context_class_init (SeahorseContextClass *klass)
static void static void
seahorse_context_init (SeahorseContext *sctx) seahorse_context_init (SeahorseContext *sctx)
{ {
/* init private vars */ /* init private vars */
sctx->pv = g_new0 (SeahorseContextPrivate, 1); sctx->pv = g_new0 (SeahorseContextPrivate, 1);
/* A list of sources */ /* A list of sources */
sctx->pv->sources = NULL; sctx->pv->sources = NULL;
/* A table of keys */ /* A table of keys */
sctx->pv->keys = g_hash_table_new_full (g_direct_hash, g_direct_equal, sctx->pv->keys_by_source = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref); NULL, g_object_unref);
sctx->pv->keys_by_type = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, NULL);
/* The context is explicitly destroyed */ /* The context is explicitly destroyed */
g_object_ref (sctx); g_object_ref (sctx);
...@@ -129,7 +145,8 @@ seahorse_context_dispose (GObject *gobject) ...@@ -129,7 +145,8 @@ seahorse_context_dispose (GObject *gobject)
sctx = SEAHORSE_CONTEXT (gobject); sctx = SEAHORSE_CONTEXT (gobject);
/* All the keys */ /* All the keys */
g_hash_table_foreach_remove (sctx->pv->keys, remove_each, NULL); g_hash_table_foreach_remove (sctx->pv->keys_by_source, remove_each, NULL);
g_hash_table_foreach_remove (sctx->pv->keys_by_type, remove_each, NULL);
/* Gconf notification */ /* Gconf notification */
if (sctx->pv->notify_id) if (sctx->pv->notify_id)
...@@ -154,28 +171,28 @@ seahorse_context_dispose (GObject *gobject) ...@@ -154,28 +171,28 @@ seahorse_context_dispose (GObject *gobject)
g_slist_free (sctx->pv->sources); g_slist_free (sctx->pv->sources);
sctx->pv->sources = NULL; sctx->pv->sources = NULL;
G_OBJECT_CLASS (parent_class)->dispose (gobject); G_OBJECT_CLASS (seahorse_context_parent_class)->dispose (gobject);
} }
/* destroy all keys, free private vars */ /* destroy all keys, free private vars */
static void static void
seahorse_context_finalize (GObject *gobject) seahorse_context_finalize (GObject *gobject)
{ {
SeahorseContext *sctx; SeahorseContext *sctx = SEAHORSE_CONTEXT (gobject);
sctx = SEAHORSE_CONTEXT (gobject);
/* Destroy the hash table */ /* Destroy the hash table */
if (sctx->pv->keys) if (sctx->pv->keys_by_source)
g_hash_table_destroy (sctx->pv->keys); g_hash_table_destroy (sctx->pv->keys_by_source);
if (sctx->pv->keys_by_type)
g_hash_table_destroy (sctx->pv->keys_by_type);
/* Other stuff already done in dispose */ /* Other stuff already done in dispose */
g_assert (sctx->pv->sources == NULL);