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