2 * wotsap.c - Output a set of wotsap files from an onak keyring
6 * http://www.lysator.liu.se/~jc/wotsap/wotfileformat.txt
8 * for more details of the format.
10 * Copyright 2013 Jonathan McDowell <noodles@earth.li>
12 * This program is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; version 2 of the License.
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 51
23 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 #include <arpa/inet.h>
34 #include "onak-conf.h"
38 static struct ll *sortkeyll(struct ll *keys)
40 struct ll *newll, *tmp, **curobj;
41 struct stats_key *curkey, *toadd;
45 toadd = (struct stats_key *) keys->object;
48 curkey = (struct stats_key *) (*curobj)->object;
49 if (curkey->keyid >= toadd->keyid) {
52 curobj = &((*curobj)->next);
56 if (*curobj == NULL || curkey->keyid != toadd->keyid) {
65 static void output_key(struct onak_dbctx *dbctx,
66 FILE *names, FILE *keys, uint64_t keyid)
68 fprintf(names, "%s\n", dbctx->keyid2uid(dbctx, keyid));
69 fprintf(keys, "%c%c%c%c", (int) (keyid >> 24) & 0xFF,
70 (int) (keyid >> 16) & 0xFF,
71 (int) (keyid >> 8) & 0xFF,
72 (int) (keyid ) & 0xFF);
75 static void wotsap(struct onak_dbctx *dbctx, uint64_t keyid, char *dir)
77 struct ll *pending, *sigll, *sigsave;
79 struct stats_key *curkey, *addkey;
81 FILE *names, *keys, *sigs, *file;
83 uint32_t sigcount, sigentry;
85 /* Length of dir + "/" + "signatures" + NUL */
86 tmppath = malloc(strlen(dir) + 12);
88 sprintf(tmppath, "%s/WOTVERSION", dir);
89 file = fopen(tmppath, "w");
91 fprintf(stderr, "Couldn't open %s\n", tmppath);
94 fprintf(file, "0.2\n");
97 sprintf(tmppath, "%s/README", dir);
98 file = fopen(tmppath, "w");
100 fprintf(stderr, "Couldn't open %s\n", tmppath);
103 fprintf(file, "This is a Web of Trust archive.\n");
104 fprintf(file, "The file format is documented at:\n");
105 fprintf(file, " http://www.lysator.liu.se/~jc/wotsap/wotfileformat.txt\n\n");
106 fprintf(file, "This file was generated by onak " ONAK_VERSION " \n");
109 sprintf(tmppath, "%s/names", dir);
110 names = fopen(tmppath, "w");
112 fprintf(stderr, "Couldn't open %s\n", tmppath);
115 sprintf(tmppath, "%s/keys", dir);
116 keys = fopen(tmppath, "wb");
118 fprintf(stderr, "Couldn't open %s\n", tmppath);
121 sprintf(tmppath, "%s/signatures", dir);
122 sigs = fopen(tmppath, "wb");
124 fprintf(stderr, "Couldn't open %s\n", tmppath);
129 dbctx->cached_getkeysigs(dbctx, keyid);
130 curkey = findinhash(keyid);
131 curkey->colour = ++curidx;
132 pending = lladd(NULL, curkey);
134 output_key(dbctx, names, keys, curkey->keyid);
136 while (pending != NULL) {
137 curkey = (struct stats_key *) pending->object;
138 sigll = dbctx->cached_getkeysigs(dbctx, curkey->keyid);
139 sigsave = sigll = sortkeyll(sigll);
141 while (sigll != NULL) {
142 addkey = (struct stats_key *) sigll->object;
143 if (addkey->colour == 0 && !addkey->revoked) {
144 uid = dbctx->keyid2uid(dbctx, addkey->keyid);
146 /* Force it to be loaded so we know if it's revoked */
147 dbctx->cached_getkeysigs(dbctx,
149 if (!addkey->revoked) {
150 addkey->colour = ++curidx;
151 pending = lladdend(pending, addkey);
152 output_key(dbctx, names, keys,
157 if (addkey->colour != 0) {
162 /* Now output the signatures */
163 sigcount = htonl(sigcount);
164 fwrite(&sigcount, sizeof (sigcount), 1, sigs);
166 while (sigll != NULL) {
167 addkey = (struct stats_key *) sigll->object;
168 if (addkey->colour != 0) {
169 sigentry = addkey->colour - 1;
170 /* Pretend it's on the primary UID for now */
171 sigentry |= 0x40000000;
172 sigentry = htonl(sigentry);
173 fwrite(&sigentry, sizeof (sigentry), 1, sigs);
177 pending = pending->next;
185 int main(int argc, char *argv[])
188 char *configfile = NULL, *dir = NULL;
189 uint64_t keyid = 0x2DA8B985;
190 struct onak_dbctx *dbctx;
192 while ((optchar = getopt(argc, argv, "c:")) != -1 ) {
195 configfile = strdup(optarg);
204 readconfig(configfile);
205 initlogthing("wotsap", config.logfile);
206 dbctx = config.dbinit(true);
209 wotsap(dbctx, dbctx->getfullkeyid(dbctx, keyid),
212 dbctx->cleanupdb(dbctx);
214 fprintf(stderr, "Couldn't initialize key database.\n");