cscvs to tla changeset 138
[onak.git] / cleankey.c
diff --git a/cleankey.c b/cleankey.c
new file mode 100644 (file)
index 0000000..b236fa3
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * cleankey.c - Routines to look for common key problems and clean them up.
+ *
+ * Jonathan McDowell <noodles@earth.li>
+ *
+ * Copyright 2004 Project Purple
+ *
+ * $Id: cleankey.c,v 1.1 2004/05/31 14:16:49 noodles Exp $
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cleankey.h"
+#include "keystructs.h"
+#include "mem.h"
+#include "merge.h"
+#include "log.h"
+
+/**
+ *     dedupuids - Merge duplicate uids on a key.
+ *     @key: The key to de-dup uids on.
+ *
+ *     This function attempts to merge duplicate IDs on a key. It returns 0
+ *     if the key is unchanged, otherwise the number of dups merged.
+ */
+int dedupuids(struct openpgp_publickey *key)
+{
+       struct openpgp_signedpacket_list *curuid = NULL;
+       struct openpgp_signedpacket_list *dup = NULL;
+       struct openpgp_signedpacket_list *tmp = NULL;
+       int                               merged = 0;
+
+       assert(key != NULL);
+       curuid = key->uids;
+       while (curuid != NULL) {
+               dup = find_signed_packet(curuid->next, curuid->packet);
+               while (dup != NULL) {
+                       logthing(LOGTHING_INFO, "Found duplicate uid: %.*s",
+                                       curuid->packet->length,
+                                       curuid->packet->data);
+                       merged++;
+                       merge_packet_sigs(curuid, dup);
+                       /*
+                        * Remove the duplicate uid.
+                        */
+                       tmp = curuid;
+                       while (tmp != NULL && tmp->next != dup) {
+                               tmp = tmp->next;
+                       }
+                       assert(tmp != NULL);
+                       tmp->next = dup->next;
+                       dup->next = NULL;
+                       free_signedpacket_list(dup);
+
+                       dup = find_signed_packet(curuid->next, curuid->packet);
+               }
+               curuid = curuid->next;
+       }
+
+       return merged;
+}
+
+/**
+ *     cleankeys - Apply all available cleaning options on a list of keys.
+ *     @keys: The list of keys to clean.
+ *
+ *     Applies all the cleaning options we can (eg duplicate key ids) to a
+ *     list of keys. Returns 0 if no changes were made, otherwise the number
+ *     of keys cleaned.
+ */
+int cleankeys(struct openpgp_publickey *keys)
+{
+       int changed = 0;
+
+       while (keys != NULL) {
+               if (dedupuids(keys) > 0) {
+                       changed++;
+               }
+               keys = keys->next;
+       }
+
+       return changed;
+}