]> git.sommitrealweird.co.uk Git - onak.git/blob - sixdegrees.c
0.3.1 release.
[onak.git] / sixdegrees.c
1 /*
2  * sixdegrees.c - List the size of the six degrees of trust away from a key.
3  * 
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2001-2002 Project Purple.
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "hash.h"
13 #include "keydb.h"
14 #include "keystructs.h"
15 #include "ll.h"
16 #include "log.h"
17 #include "onak-conf.h"
18 #include "stats.h"
19
20 unsigned long countdegree(struct stats_key *have, bool sigs, int maxdegree)
21 {
22         unsigned long     count = 0, curdegree = 0;
23         struct ll        *curll, *nextll, *sigll, *tmp;
24         struct stats_key *key = NULL;
25
26         ++curdegree;
27
28         nextll = NULL;
29         curll = lladd(NULL, have);
30
31         while (curll != NULL && curdegree <= maxdegree) {
32                 if (sigs) {
33                         sigll = cached_getkeysigs(((struct stats_key *)
34                                 curll->object)->keyid);
35                 } else {
36                         sigll = NULL;
37                         key = findinhash(((struct stats_key *)
38                                 curll->object)->keyid);
39                         if (key != NULL) {
40                                 sigll = key->signs;
41                         }
42                 }
43                 while (sigll != NULL) {
44                         if (((struct stats_key *) sigll->object)->colour==0) {
45                                 /* We've never seen it. Count it, mark it and
46                                         explore its subtree */
47                                 count++;
48                                 ((struct stats_key *)sigll->object)->colour = 
49                                         curdegree;
50                                 ((struct stats_key *)sigll->object)->parent = 
51                                         ((struct stats_key *)
52                                          curll->object)->keyid;
53                                 nextll=lladd(nextll, sigll->object);
54                         }
55                         sigll = sigll->next;
56                 }
57                 tmp = curll->next;
58                 free(curll);
59                 curll = tmp;
60                 if (curll == NULL) {
61                         curll = nextll;
62                         nextll = NULL;
63                         ++curdegree;
64                 };
65         }
66         if (curll != NULL) {
67                 llfree(curll, NULL);
68                 curll = NULL;
69         }
70         if (nextll != NULL) {
71                 llfree(nextll, NULL);
72                 nextll = NULL;
73         }
74
75         return count;
76 }
77
78 void sixdegrees(uint64_t keyid)
79 {
80         struct stats_key *keyinfo;
81         int loop;
82         long degree;
83         char *uid;
84
85         cached_getkeysigs(keyid);
86
87         if ((keyinfo = findinhash(keyid)) == NULL) {
88                 printf("Couldn't find key 0x%llX.\n", keyid);
89                 return;
90         }
91
92         uid = keyid2uid(keyinfo->keyid);
93         printf("Six degrees for 0x%llX (%s):\n", keyinfo->keyid, uid);
94         free(uid);
95         uid = NULL;
96
97         /*
98          * Cheat. This prefills the ->sign part of all the keys we want to
99          * look at so that we can output that info at the same time as the
100          * signers. However we're assuming that the signers and signees are
101          * reasonably closely related otherwise the info is wildly off - the
102          * only way to get 100% accurate results is to examine every key to see
103          * if it's signed by the key we're looking at.
104          */
105         initcolour(false);
106         degree = countdegree(keyinfo, true, 7);
107
108         puts("\t\tSigned by\t\tSigns");
109         for (loop = 1; loop < 7; loop++) {
110                 initcolour(false);
111                 degree = countdegree(keyinfo, true, loop);
112                 printf("Degree %d:\t%8ld", loop, degree);
113
114                 initcolour(false);
115                 degree = countdegree(keyinfo, false, loop);
116                 printf("\t\t%8ld\n", degree);
117         }
118 }
119
120 int main(int argc, char *argv[])
121 {
122         uint64_t keyid = 0x5B430367;
123
124         if (argc == 2) {
125                 keyid = strtoll(argv[1], NULL, 16);
126         }
127
128         readconfig(NULL);
129         initlogthing("sixdegrees", config.logfile);
130         initdb(true);
131         inithash();
132         sixdegrees(getfullkeyid(keyid));
133         destroyhash();
134         cleanupdb();
135         cleanuplogthing();
136         cleanupconfig();
137
138         return 0;
139 }