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