Beautify source code.
[gpgme.git] / gpgme / engine.c
1 /* engine.c - GPGME engine support.
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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "gpgme.h"
28 #include "util.h"
29 #include "sema.h"
30 #include "ops.h"
31
32 #include "engine.h"
33 #include "engine-backend.h"
34
35
36 struct engine_object_s
37 {
38   struct engine_ops *ops;
39   void *engine;
40 };
41
42
43 static struct engine_ops *engine_ops[] =
44   {
45     &_gpgme_engine_ops_gpg,             /* OpenPGP.  */
46 #ifdef ENABLE_GPGSM
47     &_gpgme_engine_ops_gpgsm            /* CMS.  */
48 #else
49     NULL
50 #endif
51   };
52
53 \f
54 /* Get the file name of the engine for PROTOCOL.  */
55 static const char *
56 engine_get_file_name (gpgme_protocol_t proto)
57 {
58   if (proto > DIM (engine_ops))
59     return NULL;
60
61   if (engine_ops[proto] && engine_ops[proto]->get_file_name)
62     return (*engine_ops[proto]->get_file_name) ();
63   else
64     return NULL;
65 }
66
67
68 /* Get the version number of the engine for PROTOCOL.  */
69 static const char *
70 engine_get_version (gpgme_protocol_t proto)
71 {
72   if (proto > DIM (engine_ops))
73     return NULL;
74
75   if (engine_ops[proto] && engine_ops[proto]->get_version)
76     return (*engine_ops[proto]->get_version) ();
77   else
78     return NULL;
79 }
80
81
82 /* Get the required version number of the engine for PROTOCOL.  */
83 static const char *
84 engine_get_req_version (gpgme_protocol_t proto)
85 {
86   if (proto > DIM (engine_ops))
87     return NULL;
88
89   if (engine_ops[proto] && engine_ops[proto]->get_req_version)
90     return (*engine_ops[proto]->get_req_version) ();
91   else
92     return NULL;
93 }
94
95
96 /* Verify the version requirement for the engine for PROTOCOL.  */
97 gpgme_error_t
98 gpgme_engine_check_version (gpgme_protocol_t proto)
99 {
100   return _gpgme_compare_versions (engine_get_version (proto),
101                                   engine_get_req_version (proto))
102     ? 0 : GPGME_Invalid_Engine;
103 }
104
105
106 /* Get the information about the configured and installed engines.  A
107    pointer to the first engine in the statically allocated linked list
108    is returned in *INFO.  If an error occurs, it is returned.  */
109 gpgme_error_t
110 gpgme_get_engine_info (gpgme_engine_info_t *info)
111 {
112   static gpgme_engine_info_t engine_info;
113   DEFINE_STATIC_LOCK (engine_info_lock);
114
115   LOCK (engine_info_lock);
116   if (!engine_info)
117     {
118       gpgme_engine_info_t *lastp = &engine_info;
119       gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
120                                      GPGME_PROTOCOL_CMS };
121       int proto;
122
123       for (proto = 0; proto < DIM (proto_list); proto++)
124         {
125           const char *file_name = engine_get_file_name (proto_list[proto]);
126
127           if (!file_name)
128             continue;
129
130           *lastp = malloc (sizeof (*engine_info));
131           if (!*lastp)
132             {
133               while (engine_info)
134                 {
135                   gpgme_engine_info_t next_info = engine_info->next;
136                   free (engine_info);
137                   engine_info = next_info;
138                 }
139               UNLOCK (engine_info_lock);
140               return GPGME_Out_Of_Core;
141             }
142
143           (*lastp)->protocol = proto_list[proto];
144           (*lastp)->file_name = file_name;
145           (*lastp)->version = engine_get_version (proto_list[proto]);
146           (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
147           lastp = &(*lastp)->next;
148         }
149     }
150   UNLOCK (engine_info_lock);
151   *info = engine_info;
152   return 0;
153 }
154
155 \f
156 gpgme_error_t
157 _gpgme_engine_new (gpgme_protocol_t proto, EngineObject *r_engine)
158 {
159   EngineObject engine;
160
161   const char *file_name;
162   const char *version;
163
164   if (proto > DIM (engine_ops))
165     return GPGME_Invalid_Value;
166
167   if (!engine_ops[proto])
168     return GPGME_Invalid_Engine;
169
170   file_name = engine_get_file_name (proto);
171   version = engine_get_version (proto);
172   if (!file_name || !version)
173     return GPGME_Invalid_Engine;
174
175   engine = calloc (1, sizeof *engine);
176   if (!engine)
177     return GPGME_Out_Of_Core;
178
179   engine->ops = engine_ops[proto];
180   if (engine_ops[proto]->new)
181     {
182       gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine);
183       if (err)
184         {
185           free (engine);
186           return err;
187         }
188     }
189   else
190     engine->engine = NULL;
191
192   *r_engine = engine;
193   return 0;
194 }
195
196
197 void
198 _gpgme_engine_release (EngineObject engine)
199 {
200   if (!engine)
201     return;
202
203   if (engine->ops->release)
204     (*engine->ops->release) (engine->engine);
205   free (engine);
206 }
207
208
209 void
210 _gpgme_engine_set_status_handler (EngineObject engine,
211                                   EngineStatusHandler fnc, void *fnc_value)
212 {
213   if (!engine)
214     return;
215
216   if (engine->ops->set_status_handler)
217     (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
218 }
219
220
221 gpgme_error_t
222 _gpgme_engine_set_command_handler (EngineObject engine,
223                                    EngineCommandHandler fnc, void *fnc_value,
224                                    gpgme_data_t linked_data)
225 {
226   if (!engine)
227     return GPGME_Invalid_Value;
228
229   if (!engine->ops->set_command_handler)
230     return GPGME_Not_Implemented;
231
232   return (*engine->ops->set_command_handler) (engine->engine,
233                                               fnc, fnc_value, linked_data);
234 }
235
236 gpgme_error_t _gpgme_engine_set_colon_line_handler (EngineObject engine,
237                                                  EngineColonLineHandler fnc,
238                                                  void *fnc_value)
239 {
240   if (!engine)
241     return GPGME_Invalid_Value;
242
243   if (!engine->ops->set_colon_line_handler)
244     return GPGME_Not_Implemented;
245
246   return (*engine->ops->set_colon_line_handler) (engine->engine,
247                                                  fnc, fnc_value);
248 }
249
250 gpgme_error_t
251 _gpgme_engine_op_decrypt (EngineObject engine, gpgme_data_t ciph,
252                           gpgme_data_t plain)
253 {
254   if (!engine)
255     return GPGME_Invalid_Value;
256
257   if (!engine->ops->decrypt)
258     return GPGME_Not_Implemented;
259
260   return (*engine->ops->decrypt) (engine->engine, ciph, plain);
261 }
262
263 gpgme_error_t
264 _gpgme_engine_op_delete (EngineObject engine, gpgme_key_t key,
265                          int allow_secret)
266 {
267   if (!engine)
268     return GPGME_Invalid_Value;
269
270   if (!engine->ops->delete)
271     return GPGME_Not_Implemented;
272
273   return (*engine->ops->delete) (engine->engine, key, allow_secret);
274 }
275
276
277 gpgme_error_t
278 _gpgme_engine_op_edit (EngineObject engine, gpgme_key_t key, gpgme_data_t out,
279                        gpgme_ctx_t ctx /* FIXME */)
280 {
281   if (!engine)
282     return GPGME_Invalid_Value;
283
284   if (!engine->ops->edit)
285     return GPGME_Not_Implemented;
286
287   return (*engine->ops->edit) (engine->engine, key, out, ctx);
288 }
289
290
291 gpgme_error_t
292 _gpgme_engine_op_encrypt (EngineObject engine, gpgme_recipients_t recp,
293                           gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
294 {
295   if (!engine)
296     return GPGME_Invalid_Value;
297
298   if (!engine->ops->encrypt)
299     return GPGME_Not_Implemented;
300
301   return (*engine->ops->encrypt) (engine->engine, recp, plain, ciph,
302                                   use_armor);
303 }
304
305
306 gpgme_error_t
307 _gpgme_engine_op_encrypt_sign (EngineObject engine, gpgme_recipients_t recp,
308                                gpgme_data_t plain, gpgme_data_t ciph,
309                                int use_armor, gpgme_ctx_t ctx /* FIXME */)
310 {
311   if (!engine)
312     return GPGME_Invalid_Value;
313
314   if (!engine->ops->encrypt_sign)
315     return GPGME_Not_Implemented;
316
317   return (*engine->ops->encrypt_sign) (engine->engine, recp, plain, ciph,
318                                        use_armor, ctx);
319 }
320
321
322 gpgme_error_t
323 _gpgme_engine_op_export (EngineObject engine, gpgme_recipients_t recp,
324                          gpgme_data_t keydata, int use_armor)
325 {
326   if (!engine)
327     return GPGME_Invalid_Value;
328
329   if (!engine->ops->export)
330     return GPGME_Not_Implemented;
331
332   return (*engine->ops->export) (engine->engine, recp, keydata,
333                                  use_armor);
334 }
335
336
337 gpgme_error_t
338 _gpgme_engine_op_genkey (EngineObject engine, gpgme_data_t help_data,
339                          int use_armor, gpgme_data_t pubkey,
340                          gpgme_data_t seckey)
341 {
342   if (!engine)
343     return GPGME_Invalid_Value;
344
345   if (!engine->ops->genkey)
346     return GPGME_Not_Implemented;
347
348   return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
349                                  pubkey, seckey);
350 }
351
352
353 gpgme_error_t
354 _gpgme_engine_op_import (EngineObject engine, gpgme_data_t keydata)
355 {
356   if (!engine)
357     return GPGME_Invalid_Value;
358
359   if (!engine->ops->import)
360     return GPGME_Not_Implemented;
361
362   return (*engine->ops->import) (engine->engine, keydata);
363 }
364
365
366 gpgme_error_t
367 _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
368                           int secret_only, int keylist_mode)
369 {
370   if (!engine)
371     return GPGME_Invalid_Value;
372
373   if (!engine->ops->keylist)
374     return GPGME_Not_Implemented;
375
376   return (*engine->ops->keylist) (engine->engine, pattern, secret_only,
377                                   keylist_mode);
378 }
379
380
381 gpgme_error_t
382 _gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[],
383                               int secret_only, int reserved, int keylist_mode)
384 {
385   if (!engine)
386     return GPGME_Invalid_Value;
387
388   if (!engine->ops->keylist_ext)
389     return GPGME_Not_Implemented;
390
391   return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
392                                       reserved, keylist_mode);
393 }
394
395
396 gpgme_error_t
397 _gpgme_engine_op_sign (EngineObject engine, gpgme_data_t in, gpgme_data_t out,
398                        gpgme_sig_mode_t mode, int use_armor,
399                        int use_textmode, int include_certs,
400                        gpgme_ctx_t ctx /* FIXME */)
401 {
402   if (!engine)
403     return GPGME_Invalid_Value;
404
405   if (!engine->ops->sign)
406     return GPGME_Not_Implemented;
407
408   return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
409                                use_textmode, include_certs, ctx);
410 }
411
412
413 gpgme_error_t
414 _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern)
415 {
416   if (!engine)
417     return GPGME_Invalid_Value;
418
419   if (!engine->ops->trustlist)
420     return GPGME_Not_Implemented;
421
422   return (*engine->ops->trustlist) (engine->engine, pattern);
423 }
424
425
426 gpgme_error_t
427 _gpgme_engine_op_verify (EngineObject engine, gpgme_data_t sig,
428                          gpgme_data_t signed_text, gpgme_data_t plaintext)
429 {
430   if (!engine)
431     return GPGME_Invalid_Value;
432
433   if (!engine->ops->verify)
434     return GPGME_Not_Implemented;
435
436   return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
437 }
438
439
440 void
441 _gpgme_engine_set_io_cbs (EngineObject engine, gpgme_io_cbs_t io_cbs)
442 {
443   if (!engine)
444     return;
445
446   (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
447 }
448
449
450 void
451 _gpgme_engine_io_event (EngineObject engine,
452                         gpgme_event_io_t type, void *type_data)
453 {
454   if (!engine)
455     return;
456
457   (*engine->ops->io_event) (engine->engine, type, type_data);
458 }