Beautify source code.
[gpgme.git] / gpgme / trustlist.c
1 /* trustlist.c - Trust item listing.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003 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 General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (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    General Public License for more details.
16  
17    You should have received a copy of the GNU General Public License
18    along with GPGME; if not, write to the Free Software Foundation,
19    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #if HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "gpgme.h"
29 #include "util.h"
30 #include "context.h"
31 #include "ops.h"
32
33 \f
34 struct trust_queue_item_s
35 {
36   struct trust_queue_item_s *next;
37   gpgme_trust_item_t item;
38 };
39
40 typedef struct
41 {
42   /* Something new is available.  */
43   int trust_cond;
44   struct trust_queue_item_s *trust_queue;
45 } *op_data_t;
46
47
48 \f
49 static gpgme_error_t
50 trustlist_status_handler (void *priv, gpgme_status_code_t code, char *args)
51 {
52   return 0;
53 }
54
55
56 /* This handler is used to parse the output of --list-trust-path:
57    Format:
58    level:keyid:type:recno:ot:val:mc:cc:name:
59    With TYPE = U for a user ID
60                K for a key
61    The RECNO is either the one of the dir record or the one of the uid
62    record.  OT is the the usual trust letter and only availabel on K
63    lines.  VAL is the calcualted validity MC is the marginal trust
64    counter and only available on U lines CC is the same for the
65    complete count NAME ist the username and only printed on U
66    lines.  */
67 static gpgme_error_t
68 trustlist_colon_handler (void *priv, char *line)
69 {
70   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
71   gpgme_error_t err;
72   char *p, *pend;
73   int field = 0;
74   gpgme_trust_item_t item = NULL;
75
76   if (!line)
77     return 0; /* EOF */
78
79   for (p = line; p; p = pend)
80     {
81       field++;
82       pend = strchr (p, ':');
83       if (pend) 
84         *pend++ = 0;
85
86       switch (field)
87         {
88         case 1: /* level */
89           err = _gpgme_trust_item_new (&item);
90           if (err)
91             return err;
92           item->level = atoi (p);
93           break;
94         case 2: /* long keyid */
95           if (strlen (p) == DIM(item->keyid) - 1)
96             strcpy (item->keyid, p);
97           break;
98         case 3: /* type */
99           item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
100           break;
101         case 5: /* owner trust */
102           item->_owner_trust[0] = *p;
103           break;
104         case 6: /* validity */
105           item->_validity[0] = *p;
106           break;
107         case 9: /* user ID */
108           item->name = strdup (p);
109           if (!item->name) {
110             gpgme_trust_item_unref (item);
111             return GPGME_Out_Of_Core;
112           }
113           break;
114         }
115     }
116
117   if (item)
118     _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item);
119   return 0;
120 }
121
122
123 void
124 _gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
125                               void *type_data)
126 {
127   gpgme_ctx_t ctx = (gpgme_ctx_t) data;
128   gpgme_error_t err;
129   op_data_t opd;
130   gpgme_trust_item_t item = (gpgme_trust_item_t) type_data;
131   struct trust_queue_item_s *q, *q2;
132
133   assert (type == GPGME_EVENT_NEXT_TRUSTITEM);
134
135   err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, (void **) &opd,
136                                -1, NULL);
137   if (err)
138     return;
139
140   q = malloc (sizeof *q);
141   if (!q)
142     {
143       gpgme_trust_item_unref (item);
144       /* FIXME: GPGME_Out_Of_Core; */
145       return;
146     }
147   q->item = item;
148   q->next = NULL;
149   /* FIXME: Use a tail pointer */
150   q2 = opd->trust_queue;
151   if (!q2)
152     opd->trust_queue = q;
153   else
154     {
155       while (q2->next)
156         q2 = q2->next;
157       q2->next = q;
158     }
159   /* FIXME: unlock queue */
160   opd->trust_cond = 1;
161 }
162
163
164 gpgme_error_t
165 gpgme_op_trustlist_start (gpgme_ctx_t ctx, const char *pattern, int max_level)
166 {
167   gpgme_error_t err = 0;
168   op_data_t opd;
169
170   if (!pattern || !*pattern)
171     return GPGME_Invalid_Value;
172
173   err = _gpgme_op_reset (ctx, 2);
174   if (err)
175     return err;
176
177   err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, (void **) &opd,
178                                sizeof (*opd), NULL);
179   if (err)
180     return err;
181
182   _gpgme_engine_set_status_handler (ctx->engine,
183                                     trustlist_status_handler, ctx);
184   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
185                                               trustlist_colon_handler, ctx);
186   if (err)
187     return err;
188
189   return _gpgme_engine_op_trustlist (ctx->engine, pattern);
190 }
191
192
193 gpgme_error_t
194 gpgme_op_trustlist_next (gpgme_ctx_t ctx, gpgme_trust_item_t *r_item)
195 {
196   gpgme_error_t err;
197   op_data_t opd;
198   struct trust_queue_item_s *q;
199
200   if (!r_item)
201     return GPGME_Invalid_Value;
202   *r_item = NULL;
203   if (!ctx)
204     return GPGME_Invalid_Value;
205
206   err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, (void **) &opd,
207                                -1, NULL);
208   if (err)
209     return err;
210
211   if (!opd->trust_queue)
212     {
213       err = _gpgme_wait_on_condition (ctx, &opd->trust_cond);
214       if (err)
215         return err;
216       if (!opd->trust_cond)
217         return GPGME_EOF;
218       opd->trust_cond = 0; 
219       assert (opd->trust_queue);
220     }
221   q = opd->trust_queue;
222   opd->trust_queue = q->next;
223
224   *r_item = q->item;
225   free (q);
226   return 0;
227 }
228
229
230 /* Terminate a pending trustlist operation within CTX.  */
231 gpgme_error_t
232 gpgme_op_trustlist_end (gpgme_ctx_t ctx)
233 {
234   if (!ctx)
235     return GPGME_Invalid_Value;
236
237   return 0;
238 }