09d71fc898227d6536b6ed416a98c96006c98d9f
[onak.git] / keymerge.c
1 /*
2  * keymerge.c - Takes a key on stdin, merges it and outputs the difference.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  * 
6  * Copyright 2002 Project Purple
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "armor.h"
13 #include "keydb.h"
14 #include "keyid.h"
15 #include "keystructs.h"
16 #include "mem.h"
17 #include "merge.h"
18 #include "parsekey.h"
19
20 int stdin_getchar(void *ctx, unsigned char *c)
21 {
22         int ic;
23         ic = getchar();
24         *c = ic;
25         return (ic == EOF);
26 }
27
28 int stdout_putchar(void *ctx, unsigned char c)
29 {
30         return (putchar(c));
31 }
32
33
34 int main(int argc, char *argv[])
35 {
36         struct openpgp_packet_list      *packets = NULL;
37         struct openpgp_packet_list      *list_end = NULL;
38         struct openpgp_publickey        *keys = NULL;
39         struct openpgp_publickey        *prev = NULL;
40         struct openpgp_publickey        *curkey = NULL;
41         struct openpgp_publickey        *oldkey = NULL;
42         int                              newkeys = 0;
43         int                              rc = EXIT_SUCCESS;
44
45         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
46         parse_keys(packets, &keys);
47         free_packet_list(packets);
48         packets = NULL;
49
50         initdb();
51         for (curkey = keys; curkey != NULL; curkey = curkey->next) {
52                 fprintf(stderr, "Dealing with key.\n");
53                 fprintf(stderr, "fetch_key: %d\n",
54                                 fetch_key(get_keyid(curkey), &oldkey));
55
56                 /*
57                  * If we already have the key stored in the DB then merge it
58                  * with the new one that's been supplied. Otherwise the key
59                  * we've just got is the one that goes in the DB and also the
60                  * one that we send out.
61                  */
62                 if (oldkey != NULL) {
63                         fprintf(stderr, "merge_keys: %d\n",
64                                         merge_keys(oldkey, curkey));
65                         if (curkey->revocations == NULL &&
66                                         curkey->uids == NULL &&
67                                         curkey->subkeys == NULL) {
68                                 fprintf(stderr, "No new info.\n");
69                                 if (prev == NULL) {
70                                         keys = curkey->next;
71                                 } else {
72                                         prev->next = curkey->next;
73                                         prev = curkey->next;
74                                 }
75                         } else {
76                                 prev = curkey;
77                         }
78                         /* TODO: store_key(oldkey); */
79                         free_publickey(oldkey);
80                         oldkey = NULL;
81                 } else {
82                         store_key(curkey);
83                         newkeys++;
84                 }
85         }
86         cleanupdb();
87
88         if (keys != NULL) {
89                 flatten_publickey(keys, &packets, &list_end);
90                 free_publickey(keys);
91                 keys = NULL;
92
93                 armor_openpgp_stream(stdout_putchar, NULL, packets);
94                 free_packet_list(packets);
95                 packets = NULL;
96         } else {
97                 rc = 1;
98         }
99
100         return rc;
101 }