2001-11-21 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / engine.c
1 /* engine.c 
2  *      Copyright (C) 2000 Werner Koch (dd9jn)
3  *      Copyright (C) 2001 g10 Code GmbH
4  *
5  * This file is part of GPGME.
6  *
7  * GPGME is free software; you can redistribute it and/or modify
8  * it 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,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gpgme.h"
27 #include "util.h"
28
29 #include "engine.h"
30 #include "rungpg.h"
31 #include "engine-gpgsm.h"
32
33 struct engine_object_s
34   {
35     GpgmeProtocol protocol;
36
37     const char *path;
38     const char *version;
39
40     union
41       {
42         GpgObject gpg;
43         GpgsmObject gpgsm;
44       } engine;
45 };
46
47 /* Get the path of the engine for PROTOCOL.  */
48 const char *
49 _gpgme_engine_get_path (GpgmeProtocol proto)
50 {
51   switch (proto)
52     {
53     case GPGME_PROTOCOL_OpenPGP:
54       return _gpgme_get_gpg_path ();
55     case GPGME_PROTOCOL_CMS:
56       return _gpgme_get_gpgsm_path ();
57     default:
58       return NULL;
59     }
60 }
61
62 /* Get the version number of the engine for PROTOCOL.  */
63 const char *
64 _gpgme_engine_get_version (GpgmeProtocol proto)
65 {
66   switch (proto)
67     {
68     case GPGME_PROTOCOL_OpenPGP:
69       return _gpgme_gpg_get_version ();
70     case GPGME_PROTOCOL_CMS:
71       return _gpgme_gpgsm_get_version ();
72     default:
73       return NULL;
74     }
75 }
76
77 GpgmeError
78 gpgme_engine_check_version (GpgmeProtocol proto)
79 {
80   switch (proto)
81     {
82     case GPGME_PROTOCOL_OpenPGP:
83       return _gpgme_gpg_check_version ();
84     case GPGME_PROTOCOL_CMS:
85       return _gpgme_gpgsm_check_version ();
86     default:
87       return mk_error (Invalid_Value);
88     }
89 }
90
91 GpgmeError
92 _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
93 {
94   EngineObject engine;
95   GpgmeError err = 0;
96
97   engine = xtrycalloc (1, sizeof *engine);
98   if (!engine)
99     {
100       err = mk_error (Out_Of_Core);
101       goto leave;
102     }
103
104   engine->protocol = proto;
105   switch (proto)
106     {
107     case GPGME_PROTOCOL_OpenPGP:
108       err =_gpgme_gpg_new (&engine->engine.gpg);
109       break;
110     case GPGME_PROTOCOL_CMS:
111       err = _gpgme_gpgsm_new (&engine->engine.gpgsm);
112       if (err)
113         goto leave;
114       break;
115     default:
116       err = mk_error (Invalid_Value);
117     }
118   if (err)
119     goto leave;
120
121   engine->path = _gpgme_engine_get_path (proto);
122   engine->version = _gpgme_engine_get_version (proto);
123
124   if (!engine->path || !engine->version)
125     {
126       err = mk_error (Invalid_Engine);
127       goto leave;
128     }
129
130  leave:
131   if (err)
132     _gpgme_engine_release (engine);
133   else
134     *r_engine = engine;
135   
136   return err;
137 }
138
139 void
140 _gpgme_engine_release (EngineObject engine)
141 {
142   if (!engine)
143     return;
144
145   switch (engine->protocol)
146     {
147     case GPGME_PROTOCOL_OpenPGP:
148       _gpgme_gpg_release (engine->engine.gpg);
149       break;
150     case GPGME_PROTOCOL_CMS:
151       _gpgme_gpgsm_release (engine->engine.gpgsm);
152       break;
153     default:
154       break;
155     }
156   xfree (engine);
157 }
158
159 void
160 _gpgme_engine_set_verbosity (EngineObject engine, int verbosity)
161 {
162   if (!engine)
163     return;
164
165   switch (engine->protocol)
166     {
167     case GPGME_PROTOCOL_OpenPGP:
168       while (verbosity-- > 0)
169         _gpgme_gpg_add_arg (engine->engine.gpg, "--verbose");
170       break;
171     case GPGME_PROTOCOL_CMS:
172       /* FIXME */
173       break;
174     default:
175       break;
176     }
177 }
178
179 void
180 _gpgme_engine_set_status_handler (EngineObject engine,
181                                   GpgStatusHandler fnc, void *fnc_value)
182 {
183   if (!engine)
184     return;
185
186   switch (engine->protocol)
187     {
188     case GPGME_PROTOCOL_OpenPGP:
189       _gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value);
190       break;
191     case GPGME_PROTOCOL_CMS:
192       /* FIXME */
193       break;
194     default:
195       break;
196     }
197 }
198
199 GpgmeError
200 _gpgme_engine_set_command_handler (EngineObject engine,
201                                   GpgCommandHandler fnc, void *fnc_value)
202 {
203   if (!engine)
204     return mk_error (Invalid_Value);
205
206   switch (engine->protocol)
207     {
208     case GPGME_PROTOCOL_OpenPGP:
209       return _gpgme_gpg_set_command_handler (engine->engine.gpg, fnc, fnc_value);
210     case GPGME_PROTOCOL_CMS:
211       /* FIXME */
212       break;
213     default:
214       break;
215     }
216   return 0;
217 }
218
219 GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine,
220                                                  GpgColonLineHandler fnc,
221                                                  void *fnc_value)
222 {
223   if (!engine)
224     return mk_error (Invalid_Value);
225
226   switch (engine->protocol)
227     {
228     case GPGME_PROTOCOL_OpenPGP:
229       return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg, fnc,
230                                                 fnc_value);
231     case GPGME_PROTOCOL_CMS:
232       /* FIXME */
233       break;
234     default:
235       break;
236     }
237   return 0;
238 }
239
240 GpgmeError
241 _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain)
242 {
243   if (!engine)
244     return mk_error (Invalid_Value);
245
246   switch (engine->protocol)
247     {
248     case GPGME_PROTOCOL_OpenPGP:
249       return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain);
250     case GPGME_PROTOCOL_CMS:
251       /* FIXME */
252       break;
253     default:
254       break;
255     }
256   return 0;
257 }
258
259 GpgmeError
260 _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
261 {
262   if (!engine)
263     return mk_error (Invalid_Value);
264
265   switch (engine->protocol)
266     {
267     case GPGME_PROTOCOL_OpenPGP:
268       return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret);
269     case GPGME_PROTOCOL_CMS:
270       /* FIXME */
271       break;
272     default:
273       break;
274     }
275   return 0;
276 }
277
278 GpgmeError
279 _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
280                           GpgmeData plain, GpgmeData ciph, int use_armor)
281 {
282   if (!engine)
283     return mk_error (Invalid_Value);
284
285   switch (engine->protocol)
286     {
287     case GPGME_PROTOCOL_OpenPGP:
288       return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph,
289                                     use_armor);
290     case GPGME_PROTOCOL_CMS:
291       /* FIXME */
292       break;
293     default:
294       break;
295     }
296   return 0;
297 }
298
299 GpgmeError
300 _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp,
301                          GpgmeData keydata, int use_armor)
302 {
303   if (!engine)
304     return mk_error (Invalid_Value);
305
306   switch (engine->protocol)
307     {
308     case GPGME_PROTOCOL_OpenPGP:
309       return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata,
310                                    use_armor);
311     case GPGME_PROTOCOL_CMS:
312       /* FIXME */
313       break;
314     default:
315       break;
316     }
317   return 0;
318 }
319
320 GpgmeError
321 _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data, int use_armor)
322 {
323   if (!engine)
324     return mk_error (Invalid_Value);
325
326   switch (engine->protocol)
327     {
328     case GPGME_PROTOCOL_OpenPGP:
329       return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor);
330     case GPGME_PROTOCOL_CMS:
331       /* FIXME */
332       break;
333     default:
334       break;
335     }
336   return 0;
337 }
338
339 GpgmeError
340 _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
341 {
342   if (!engine)
343     return mk_error (Invalid_Value);
344
345   switch (engine->protocol)
346     {
347     case GPGME_PROTOCOL_OpenPGP:
348       return _gpgme_gpg_op_import (engine->engine.gpg, keydata);
349     case GPGME_PROTOCOL_CMS:
350       /* FIXME */
351       break;
352     default:
353       break;
354     }
355   return 0;
356 }
357
358 GpgmeError
359 _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only,
360                           int keylist_mode)
361 {
362   if (!engine)
363     return mk_error (Invalid_Value);
364
365   switch (engine->protocol)
366     {
367     case GPGME_PROTOCOL_OpenPGP:
368       return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only,
369                                     keylist_mode);
370     case GPGME_PROTOCOL_CMS:
371       /* FIXME */
372       break;
373     default:
374       break;
375     }
376   return 0;
377 }
378
379 GpgmeError
380 _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
381                     GpgmeSigMode mode, int use_armor,
382                     int use_textmode, GpgmeCtx ctx /* FIXME */)
383 {
384   if (!engine)
385     return mk_error (Invalid_Value);
386
387   switch (engine->protocol)
388     {
389     case GPGME_PROTOCOL_OpenPGP:
390       return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor,
391                                  use_textmode, ctx);
392     case GPGME_PROTOCOL_CMS:
393       /* FIXME */
394       break;
395     default:
396       break;
397     }
398   return 0;
399 }
400
401 GpgmeError
402 _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern)
403 {
404   if (!engine)
405     return mk_error (Invalid_Value);
406
407   switch (engine->protocol)
408     {
409     case GPGME_PROTOCOL_OpenPGP:
410       return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern);
411     case GPGME_PROTOCOL_CMS:
412       /* FIXME */
413       break;
414     default:
415       break;
416     }
417   return 0;
418 }
419
420 GpgmeError
421 _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text)
422 {
423   if (!engine)
424     return mk_error (Invalid_Value);
425
426   switch (engine->protocol)
427     {
428     case GPGME_PROTOCOL_OpenPGP:
429       return _gpgme_gpg_op_verify (engine->engine.gpg, sig, text);
430     case GPGME_PROTOCOL_CMS:
431       /* FIXME */
432       break;
433     default:
434       break;
435     }
436   return 0;
437 }
438
439 GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque)
440 {
441   if (!engine)
442     return mk_error (Invalid_Value);
443
444   switch (engine->protocol)
445     {
446     case GPGME_PROTOCOL_OpenPGP:
447       return _gpgme_gpg_spawn (engine->engine.gpg, opaque);
448     case GPGME_PROTOCOL_CMS:
449       /* FIXME */
450       break;
451     default:
452       break;
453     }
454   return 0;
455 }