cscvs to tla changeset 77
[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  * $Id: sixdegrees.c,v 1.4 2003/06/04 20:57:12 noodles Exp $
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include "hash.h"
15 #include "keydb.h"
16 #include "keystructs.h"
17 #include "ll.h"
18 #include "onak-conf.h"
19 #include "stats.h"
20
21 unsigned long countdegree(struct stats_key *have, bool sigs, int maxdegree)
22 {
23         unsigned long     count = 0, curdegree = 0;
24         struct ll        *curll, *nextll, *sigll, *tmp;
25         struct stats_key *key = NULL;
26
27         ++curdegree;
28
29         nextll = NULL;
30         curll = lladd(NULL, have);
31
32         while (curll != NULL && curdegree <= maxdegree) {
33                 if (sigs) {
34                         sigll = cached_getkeysigs(((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         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 = 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();
130         initdb();
131         inithash();
132         sixdegrees(getfullkeyid(keyid));
133         destroyhash();
134         cleanupdb();
135         cleanupconfig();
136
137         return 0;
138 }