Line data Source code
1 : /* trustlist.c - Trust item listing.
2 : Copyright (C) 2000 Werner Koch (dd9jn)
3 : Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
4 :
5 : This file is part of GPGME.
6 :
7 : GPGME is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU Lesser General Public License as
9 : published by the Free Software Foundation; either version 2.1 of
10 : the License, or (at your option) any later version.
11 :
12 : GPGME is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public
18 : License along with this program; if not, write to the Free Software
19 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 : 02111-1307, USA. */
21 :
22 : #if HAVE_CONFIG_H
23 : #include <config.h>
24 : #endif
25 : #include <stdlib.h>
26 : #include <string.h>
27 : #include <assert.h>
28 : #include <errno.h>
29 :
30 : #include "gpgme.h"
31 : #include "debug.h"
32 : #include "util.h"
33 : #include "context.h"
34 : #include "ops.h"
35 :
36 :
37 : struct trust_queue_item_s
38 : {
39 : struct trust_queue_item_s *next;
40 : gpgme_trust_item_t item;
41 : };
42 :
43 : typedef struct
44 : {
45 : /* Something new is available. */
46 : int trust_cond;
47 : struct trust_queue_item_s *trust_queue;
48 : } *op_data_t;
49 :
50 :
51 :
52 : static gpgme_error_t
53 0 : trustlist_status_handler (void *priv, gpgme_status_code_t code, char *args)
54 : {
55 : (void)priv;
56 : (void)code;
57 : (void)args;
58 0 : return 0;
59 : }
60 :
61 :
62 : /* This handler is used to parse the output of --list-trust-path:
63 : Format:
64 : level:keyid:type:recno:ot:val:mc:cc:name:
65 : With TYPE = U for a user ID
66 : K for a key
67 : The RECNO is either the one of the dir record or the one of the uid
68 : record. OT is the the usual trust letter and only availabel on K
69 : lines. VAL is the calcualted validity MC is the marginal trust
70 : counter and only available on U lines CC is the same for the
71 : complete count NAME ist the username and only printed on U
72 : lines. */
73 : static gpgme_error_t
74 0 : trustlist_colon_handler (void *priv, char *line)
75 : {
76 0 : gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
77 : gpgme_error_t err;
78 : char *p, *pend;
79 0 : int field = 0;
80 0 : gpgme_trust_item_t item = NULL;
81 :
82 0 : if (!line)
83 0 : return 0; /* EOF */
84 :
85 0 : for (p = line; p; p = pend)
86 : {
87 0 : field++;
88 0 : pend = strchr (p, ':');
89 0 : if (pend)
90 0 : *pend++ = 0;
91 :
92 0 : switch (field)
93 : {
94 : case 1: /* level */
95 0 : err = _gpgme_trust_item_new (&item);
96 0 : if (err)
97 0 : return err;
98 0 : item->level = atoi (p);
99 0 : break;
100 : case 2: /* long keyid */
101 0 : if (strlen (p) == DIM(item->keyid) - 1)
102 0 : strcpy (item->keyid, p);
103 0 : break;
104 : case 3: /* type */
105 0 : item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
106 0 : break;
107 : case 5: /* owner trust */
108 0 : item->_owner_trust[0] = *p;
109 0 : break;
110 : case 6: /* validity */
111 0 : item->_validity[0] = *p;
112 0 : break;
113 : case 9: /* user ID */
114 0 : item->name = strdup (p);
115 0 : if (!item->name)
116 : {
117 0 : int saved_err = gpg_error_from_syserror ();
118 0 : gpgme_trust_item_unref (item);
119 0 : return saved_err;
120 : }
121 0 : break;
122 : }
123 : }
124 :
125 0 : if (item)
126 0 : _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item);
127 0 : return 0;
128 : }
129 :
130 :
131 : void
132 0 : _gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
133 : void *type_data)
134 : {
135 0 : gpgme_ctx_t ctx = (gpgme_ctx_t) data;
136 : gpgme_error_t err;
137 : void *hook;
138 : op_data_t opd;
139 0 : gpgme_trust_item_t item = (gpgme_trust_item_t) type_data;
140 : struct trust_queue_item_s *q, *q2;
141 :
142 0 : assert (type == GPGME_EVENT_NEXT_TRUSTITEM);
143 :
144 0 : err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL);
145 0 : opd = hook;
146 0 : if (err)
147 0 : return;
148 :
149 0 : q = malloc (sizeof *q);
150 0 : if (!q)
151 : {
152 0 : gpgme_trust_item_unref (item);
153 : /* FIXME: GPGME_Out_Of_Core; */
154 0 : return;
155 : }
156 0 : q->item = item;
157 0 : q->next = NULL;
158 : /* FIXME: Use a tail pointer */
159 0 : q2 = opd->trust_queue;
160 0 : if (!q2)
161 0 : opd->trust_queue = q;
162 : else
163 : {
164 0 : while (q2->next)
165 0 : q2 = q2->next;
166 0 : q2->next = q;
167 : }
168 : /* FIXME: unlock queue */
169 0 : opd->trust_cond = 1;
170 : }
171 :
172 :
173 : gpgme_error_t
174 0 : gpgme_op_trustlist_start (gpgme_ctx_t ctx, const char *pattern, int max_level)
175 : {
176 0 : gpgme_error_t err = 0;
177 : void *hook;
178 : op_data_t opd;
179 :
180 0 : TRACE_BEG2 (DEBUG_CTX, "gpgme_op_trustlist_start", ctx,
181 : "pattern=%s, max_level=%i", pattern, max_level);
182 :
183 0 : if (!ctx || !pattern || !*pattern)
184 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
185 :
186 0 : err = _gpgme_op_reset (ctx, 2);
187 0 : if (err)
188 0 : return TRACE_ERR (err);
189 :
190 0 : err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook,
191 : sizeof (*opd), NULL);
192 0 : opd = hook;
193 0 : if (err)
194 0 : return TRACE_ERR (err);
195 :
196 0 : _gpgme_engine_set_status_handler (ctx->engine,
197 : trustlist_status_handler, ctx);
198 0 : err = _gpgme_engine_set_colon_line_handler (ctx->engine,
199 : trustlist_colon_handler, ctx);
200 0 : if (err)
201 0 : return TRACE_ERR (err);
202 :
203 0 : err = _gpgme_engine_op_trustlist (ctx->engine, pattern);
204 0 : return TRACE_ERR (err);
205 : }
206 :
207 :
208 : gpgme_error_t
209 0 : gpgme_op_trustlist_next (gpgme_ctx_t ctx, gpgme_trust_item_t *r_item)
210 : {
211 : gpgme_error_t err;
212 : void *hook;
213 : op_data_t opd;
214 : struct trust_queue_item_s *q;
215 :
216 0 : TRACE_BEG (DEBUG_CTX, "gpgme_op_trustlist_next", ctx);
217 :
218 0 : if (!ctx || !r_item)
219 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
220 0 : *r_item = NULL;
221 0 : if (!ctx)
222 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
223 :
224 0 : err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL);
225 0 : opd = hook;
226 0 : if (err)
227 0 : return TRACE_ERR (err);
228 0 : if (opd == NULL)
229 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
230 :
231 0 : if (!opd->trust_queue)
232 : {
233 0 : err = _gpgme_wait_on_condition (ctx, &opd->trust_cond, NULL);
234 0 : if (err)
235 0 : return TRACE_ERR (err);
236 0 : if (!opd->trust_cond)
237 0 : return TRACE_ERR (gpg_error (GPG_ERR_EOF));
238 0 : opd->trust_cond = 0;
239 0 : assert (opd->trust_queue);
240 : }
241 0 : q = opd->trust_queue;
242 0 : opd->trust_queue = q->next;
243 :
244 0 : *r_item = q->item;
245 0 : free (q);
246 0 : if ((*r_item)->type == 1)
247 : {
248 0 : TRACE_SUC5 ("trust_item=%p: %s: owner trust %s with level %i "
249 : "and validity 0x%x", *r_item, (*r_item)->keyid,
250 : (*r_item)->owner_trust, (*r_item)->level,
251 : (*r_item)->validity);
252 : }
253 0 : else if ((*r_item)->type == 2)
254 : {
255 0 : TRACE_SUC5 ("trust_item=%p: %s: UID %s with level %i "
256 : "and validity 0x%x", *r_item, (*r_item)->keyid,
257 : (*r_item)->name, (*r_item)->level, (*r_item)->validity);
258 : }
259 : else
260 : {
261 0 : TRACE_SUC5 ("trust_item=%p: %s: unknown type %i with level %i "
262 : "and validity 0x%x", *r_item, (*r_item)->keyid,
263 : (*r_item)->type, (*r_item)->level, (*r_item)->validity);
264 : }
265 0 : return 0;
266 : }
267 :
268 :
269 : /* Terminate a pending trustlist operation within CTX. */
270 : gpgme_error_t
271 0 : gpgme_op_trustlist_end (gpgme_ctx_t ctx)
272 : {
273 0 : TRACE (DEBUG_CTX, "gpgme_op_trustlist_end", ctx);
274 :
275 0 : if (!ctx)
276 0 : return gpg_error (GPG_ERR_INV_VALUE);
277 :
278 0 : return 0;
279 : }
|