Add gpgme_set/get_status_cb().
[gpgme.git] / src / gpgme.c
1 /* gpgme.c - GnuPG Made Easy.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
4                  2014 g10 Code GmbH
5
6    This file is part of GPGME.
7
8    GPGME is free software; you can redistribute it and/or modify it
9    under the terms of the GNU Lesser General Public License as
10    published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    GPGME is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #ifdef HAVE_LOCALE_H
31 #include <locale.h>
32 #endif
33
34 #include "util.h"
35 #include "context.h"
36 #include "ops.h"
37 #include "wait.h"
38 #include "debug.h"
39 #include "priv-io.h"
40 #include "sys-util.h"
41
42 \f
43 /* The default locale.  */
44 DEFINE_STATIC_LOCK (def_lc_lock);
45 static char *def_lc_ctype;
46 static char *def_lc_messages;
47
48 \f
49 gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
50
51 /* Protects all reference counters in result structures.  All other
52    accesses to a result structure are read only.  */
53 DEFINE_STATIC_LOCK (result_ref_lock);
54
55 \f
56 /* Set the global flag NAME to VALUE.  Return 0 on success.  Note that
57    this function does not use gpgme_error and thus a non-zero return
58    value merely means "error".  Certain flags may be set before
59    gpgme_check_version is called.  See the manual for a description of
60    supported flags.  The caller must assure that this function is
61    called only by one thread at a time.  */
62 int
63 gpgme_set_global_flag (const char *name, const char *value)
64 {
65   if (!name || !value)
66     return -1;
67   else if (!strcmp (name, "debug"))
68     return _gpgme_debug_set_debug_envvar (value);
69   else if (!strcmp (name, "disable-gpgconf"))
70     {
71       _gpgme_dirinfo_disable_gpgconf ();
72       return 0;
73     }
74   else if (!strcmp (name, "gpgconf-name"))
75     return _gpgme_set_default_gpgconf_name (value);
76   else if (!strcmp (name, "gpg-name"))
77     return _gpgme_set_default_gpg_name (value);
78   else
79     return -1;
80 }
81
82
83 \f
84 /* Create a new context as an environment for GPGME crypto
85    operations.  */
86 gpgme_error_t
87 gpgme_new (gpgme_ctx_t *r_ctx)
88 {
89   gpgme_error_t err;
90   gpgme_ctx_t ctx;
91   TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
92
93   if (_gpgme_selftest)
94     return TRACE_ERR (gpgme_error (_gpgme_selftest));
95
96   if (!r_ctx)
97     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
98
99   ctx = calloc (1, sizeof *ctx);
100   if (!ctx)
101     return TRACE_ERR (gpg_error_from_syserror ());
102
103   INIT_LOCK (ctx->lock);
104
105   err = _gpgme_engine_info_copy (&ctx->engine_info);
106   if (!err && !ctx->engine_info)
107     err = gpg_error (GPG_ERR_NO_ENGINE);
108   if (err)
109     {
110       free (ctx);
111       return TRACE_ERR (err);
112     }
113
114   ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
115   ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
116   ctx->protocol = GPGME_PROTOCOL_OpenPGP;
117   ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
118   _gpgme_fd_table_init (&ctx->fdt);
119
120   LOCK (def_lc_lock);
121   if (def_lc_ctype)
122     {
123       ctx->lc_ctype = strdup (def_lc_ctype);
124       if (!ctx->lc_ctype)
125         {
126           int saved_err = gpg_error_from_syserror ();
127           UNLOCK (def_lc_lock);
128           _gpgme_engine_info_release (ctx->engine_info);
129           free (ctx);
130           return TRACE_ERR (saved_err);
131         }
132     }
133   else
134     def_lc_ctype = NULL;
135
136   if (def_lc_messages)
137     {
138       ctx->lc_messages = strdup (def_lc_messages);
139       if (!ctx->lc_messages)
140         {
141           int saved_err = gpg_error_from_syserror ();
142           UNLOCK (def_lc_lock);
143           if (ctx->lc_ctype)
144             free (ctx->lc_ctype);
145           _gpgme_engine_info_release (ctx->engine_info);
146           free (ctx);
147           return TRACE_ERR (saved_err);
148         }
149     }
150   else
151     def_lc_messages = NULL;
152   UNLOCK (def_lc_lock);
153
154   *r_ctx = ctx;
155
156   return TRACE_SUC1 ("ctx=%p", ctx);
157 }
158
159
160 gpgme_error_t
161 _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
162                         gpg_error_t op_err)
163 {
164   gpgme_error_t err;
165   struct gpgme_io_event_done_data data;
166
167   TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
168               ctx_err, op_err);
169
170   if (ctx_err)
171     {
172       err = _gpgme_engine_cancel (ctx->engine);
173       if (err)
174         return TRACE_ERR (err);
175     }
176   else
177     {
178       err = _gpgme_engine_cancel_op (ctx->engine);
179       if (err)
180         return TRACE_ERR (err);
181     }
182
183   data.err = ctx_err;
184   data.op_err = op_err;
185
186   _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
187
188   return TRACE_ERR (0);
189 }
190
191
192 /* Cancel a pending asynchronous operation.  */
193 gpgme_error_t
194 gpgme_cancel (gpgme_ctx_t ctx)
195 {
196   gpg_error_t err;
197
198   TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);
199
200   if (!ctx)
201     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
202
203   err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);
204
205   return TRACE_ERR (err);
206 }
207
208
209 /* Cancel a pending operation asynchronously.  */
210 gpgme_error_t
211 gpgme_cancel_async (gpgme_ctx_t ctx)
212 {
213   TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
214
215   if (!ctx)
216     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
217
218   LOCK (ctx->lock);
219   ctx->canceled = 1;
220   UNLOCK (ctx->lock);
221
222   return TRACE_ERR (0);
223 }
224
225
226 /* Release all resources associated with the given context.  */
227 void
228 gpgme_release (gpgme_ctx_t ctx)
229 {
230   TRACE (DEBUG_CTX, "gpgme_release", ctx);
231
232   if (!ctx)
233     return;
234
235   _gpgme_engine_release (ctx->engine);
236   ctx->engine = NULL;
237   _gpgme_fd_table_deinit (&ctx->fdt);
238   _gpgme_release_result (ctx);
239   _gpgme_signers_clear (ctx);
240   _gpgme_sig_notation_clear (ctx);
241   if (ctx->signers)
242     free (ctx->signers);
243   if (ctx->lc_ctype)
244     free (ctx->lc_ctype);
245   if (ctx->lc_messages)
246     free (ctx->lc_messages);
247   _gpgme_engine_info_release (ctx->engine_info);
248   ctx->engine_info = NULL;
249   DESTROY_LOCK (ctx->lock);
250   free (ctx);
251 }
252
253
254 void
255 gpgme_result_ref (void *result)
256 {
257   struct ctx_op_data *data;
258
259   if (! result)
260     return;
261
262   data = (void*)((char*)result - sizeof (struct ctx_op_data));
263
264   assert (data->magic == CTX_OP_DATA_MAGIC);
265
266   LOCK (result_ref_lock);
267   data->references++;
268   UNLOCK (result_ref_lock);
269 }
270
271
272 void
273 gpgme_result_unref (void *result)
274 {
275   struct ctx_op_data *data;
276
277   if (! result)
278     return;
279
280   data = (void*)((char*)result - sizeof (struct ctx_op_data));
281
282   assert (data->magic == CTX_OP_DATA_MAGIC);
283
284   LOCK (result_ref_lock);
285   if (--data->references)
286     {
287       UNLOCK (result_ref_lock);
288       return;
289     }
290   UNLOCK (result_ref_lock);
291
292   if (data->cleanup)
293     (*data->cleanup) (data->hook);
294   free (data);
295 }
296
297
298 void
299 _gpgme_release_result (gpgme_ctx_t ctx)
300 {
301   struct ctx_op_data *data = ctx->op_data;
302
303   while (data)
304     {
305       struct ctx_op_data *next_data = data->next;
306       data->next = NULL;
307       gpgme_result_unref (data->hook);
308       data = next_data;
309     }
310   ctx->op_data = NULL;
311 }
312
313
314 gpgme_error_t
315 gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
316 {
317   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
318               protocol, gpgme_get_protocol_name (protocol)
319               ? gpgme_get_protocol_name (protocol) : "invalid");
320
321   if (protocol != GPGME_PROTOCOL_OpenPGP
322       && protocol != GPGME_PROTOCOL_CMS
323       && protocol != GPGME_PROTOCOL_GPGCONF
324       && protocol != GPGME_PROTOCOL_ASSUAN
325       && protocol != GPGME_PROTOCOL_G13
326       && protocol != GPGME_PROTOCOL_UISERVER
327       && protocol != GPGME_PROTOCOL_SPAWN)
328     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
329
330   if (!ctx)
331     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
332
333   if (ctx->protocol != protocol)
334     {
335       /* Shut down the engine when switching protocols.  */
336       if (ctx->engine)
337         {
338           TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
339           _gpgme_engine_release (ctx->engine);
340           ctx->engine = NULL;
341         }
342
343       ctx->protocol = protocol;
344     }
345   return TRACE_ERR (0);
346 }
347
348
349 gpgme_protocol_t
350 gpgme_get_protocol (gpgme_ctx_t ctx)
351 {
352   TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
353           "ctx->protocol=%i (%s)", ctx->protocol,
354           gpgme_get_protocol_name (ctx->protocol)
355           ? gpgme_get_protocol_name (ctx->protocol) : "invalid");
356
357   return ctx->protocol;
358 }
359
360
361 gpgme_error_t
362 gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
363 {
364   TRACE2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
365           protocol, gpgme_get_protocol_name (protocol)
366           ? gpgme_get_protocol_name (protocol) : "invalid");
367
368   if (!ctx)
369     return gpg_error (GPG_ERR_INV_VALUE);
370
371   ctx->sub_protocol = protocol;
372   return 0;
373 }
374
375
376 gpgme_protocol_t
377 gpgme_get_sub_protocol (gpgme_ctx_t ctx)
378 {
379   TRACE2 (DEBUG_CTX, "gpgme_get_sub_protocol", ctx,
380           "ctx->sub_protocol=%i (%s)", ctx->sub_protocol,
381           gpgme_get_protocol_name (ctx->sub_protocol)
382           ? gpgme_get_protocol_name (ctx->sub_protocol) : "invalid");
383
384   return ctx->sub_protocol;
385 }
386
387
388 const char *
389 gpgme_get_protocol_name (gpgme_protocol_t protocol)
390 {
391   switch (protocol)
392     {
393     case GPGME_PROTOCOL_OpenPGP:
394       return "OpenPGP";
395
396     case GPGME_PROTOCOL_CMS:
397       return "CMS";
398
399     case GPGME_PROTOCOL_GPGCONF:
400       return "GPGCONF";
401
402     case GPGME_PROTOCOL_ASSUAN:
403       return "Assuan";
404
405     case GPGME_PROTOCOL_G13:
406       return "G13";
407
408     case GPGME_PROTOCOL_UISERVER:
409       return "UIServer";
410
411     case GPGME_PROTOCOL_SPAWN:
412       return "Spawn";
413
414     case GPGME_PROTOCOL_DEFAULT:
415       return "default";
416
417     case GPGME_PROTOCOL_UNKNOWN:
418       return "unknown";
419
420     default:
421       return NULL;
422     }
423 }
424
425 /* Enable or disable the use of an ascii armor for all output.  */
426 void
427 gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
428 {
429   TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
430           use_armor, use_armor ? "yes" : "no");
431
432   if (!ctx)
433     return;
434
435   ctx->use_armor = use_armor;
436 }
437
438
439 /* Return the state of the armor flag.  */
440 int
441 gpgme_get_armor (gpgme_ctx_t ctx)
442 {
443   TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
444           ctx->use_armor, ctx->use_armor ? "yes" : "no");
445   return ctx->use_armor;
446 }
447
448
449 /* Enable or disable the use of the special textmode.  Textmode is for
450   example used for the RFC2015 signatures; note that the updated RFC
451   3156 mandates that the MUA does some preparations so that textmode
452   is not needed anymore.  */
453 void
454 gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
455 {
456   TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
457           use_textmode, use_textmode ? "yes" : "no");
458
459   if (!ctx)
460     return;
461
462   ctx->use_textmode = use_textmode;
463 }
464
465 /* Return the state of the textmode flag.  */
466 int
467 gpgme_get_textmode (gpgme_ctx_t ctx)
468 {
469   TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
470           ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
471   return ctx->use_textmode;
472 }
473
474
475 /* Enable offline mode for this context. In offline mode dirmngr
476   will be disabled. */
477 void
478 gpgme_set_offline (gpgme_ctx_t ctx, int offline)
479 {
480   TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
481           offline, offline ? "yes" : "no");
482
483   if (!ctx)
484     return;
485
486   ctx->offline = offline;
487 }
488
489 /* Return the state of the offline flag.  */
490 int
491 gpgme_get_offline (gpgme_ctx_t ctx)
492 {
493   TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
494           ctx->offline, ctx->offline ? "yes" : "no");
495   return ctx->offline;
496 }
497
498
499 /* Set the number of certifications to include in an S/MIME message.
500    The default is GPGME_INCLUDE_CERTS_DEFAULT.  -1 means all certs,
501    and -2 means all certs except the root cert.  */
502 void
503 gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
504 {
505   if (!ctx)
506     return;
507
508   if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
509     ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
510   else if (nr_of_certs < -2)
511     ctx->include_certs = -2;
512   else
513     ctx->include_certs = nr_of_certs;
514
515   TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
516           nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
517 }
518
519
520 /* Get the number of certifications to include in an S/MIME
521    message.  */
522 int
523 gpgme_get_include_certs (gpgme_ctx_t ctx)
524 {
525   TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
526           ctx->include_certs);
527   return ctx->include_certs;
528 }
529
530
531 /* This function changes the default behaviour of the keylisting
532    functions.  MODE is a bitwise-OR of the GPGME_KEYLIST_* flags.  The
533    default mode is GPGME_KEYLIST_MODE_LOCAL.  */
534 gpgme_error_t
535 gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
536 {
537   TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
538           mode);
539
540   if (!ctx)
541     return gpg_error (GPG_ERR_INV_VALUE);
542
543   ctx->keylist_mode = mode;
544   return 0;
545 }
546
547 /* This function returns the default behaviour of the keylisting
548    functions.  */
549 gpgme_keylist_mode_t
550 gpgme_get_keylist_mode (gpgme_ctx_t ctx)
551 {
552   TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
553           "ctx->keylist_mode=0x%x", ctx->keylist_mode);
554   return ctx->keylist_mode;
555 }
556
557
558 /* Set the pinentry mode for CTX to MODE. */
559 gpgme_error_t
560 gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_pinentry_mode_t mode)
561 {
562   TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
563           (unsigned int)mode);
564
565   if (!ctx)
566     return gpg_error (GPG_ERR_INV_VALUE);
567
568   switch (mode)
569     {
570     case GPGME_PINENTRY_MODE_DEFAULT:
571     case GPGME_PINENTRY_MODE_ASK:
572     case GPGME_PINENTRY_MODE_CANCEL:
573     case GPGME_PINENTRY_MODE_ERROR:
574     case GPGME_PINENTRY_MODE_LOOPBACK:
575       break;
576     default:
577       return gpg_error (GPG_ERR_INV_VALUE);
578     }
579
580   ctx->pinentry_mode = mode;
581   return 0;
582 }
583
584
585 /* Get the pinentry mode of CTX.  */
586 gpgme_pinentry_mode_t
587 gpgme_get_pinentry_mode (gpgme_ctx_t ctx)
588 {
589   TRACE1 (DEBUG_CTX, "gpgme_get_pinentry_mode", ctx,
590           "ctx->pinentry_mode=%u", (unsigned int)ctx->pinentry_mode);
591   return ctx->pinentry_mode;
592 }
593
594
595 /* This function sets a callback function to be used to pass a
596    passphrase to gpg.  */
597 void
598 gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
599                          void *cb_value)
600 {
601   TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
602           "passphrase_cb=%p/%p", cb, cb_value);
603
604   if (!ctx)
605     return;
606
607   ctx->passphrase_cb = cb;
608   ctx->passphrase_cb_value = cb_value;
609 }
610
611
612 /* This function returns the callback function to be used to pass a
613    passphrase to the crypto engine.  */
614 void
615 gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
616                          void **r_cb_value)
617 {
618   TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
619           "ctx->passphrase_cb=%p/%p",
620           ctx->passphrase_cb, ctx->passphrase_cb_value);
621   if (r_cb)
622     *r_cb = ctx->passphrase_cb;
623   if (r_cb_value)
624     *r_cb_value = ctx->passphrase_cb_value;
625 }
626
627
628 /* This function sets a callback function to be used as a progress
629    indicator.  */
630 void
631 gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
632 {
633   TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
634           cb, cb_value);
635
636   if (!ctx)
637     return;
638
639   ctx->progress_cb = cb;
640   ctx->progress_cb_value = cb_value;
641 }
642
643
644 /* This function returns the callback function to be used as a
645    progress indicator.  */
646 void
647 gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
648                        void **r_cb_value)
649 {
650   TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
651           ctx->progress_cb, ctx->progress_cb_value);
652   if (r_cb)
653     *r_cb = ctx->progress_cb;
654   if (r_cb_value)
655     *r_cb_value = ctx->progress_cb_value;
656 }
657
658
659 /* This function sets a callback function to be used as a status
660    message forwarder.  */
661 void
662 gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
663 {
664   TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
665           cb, cb_value);
666
667   if (!ctx)
668     return;
669
670   ctx->status_cb = cb;
671   ctx->status_cb_value = cb_value;
672 }
673
674
675 /* This function returns the callback function to be used as a
676    status message forwarder.  */
677 void
678 gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
679                        void **r_cb_value)
680 {
681   TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
682           ctx->status_cb, ctx->status_cb_value);
683   if (r_cb)
684     *r_cb = ctx->status_cb;
685   if (r_cb_value)
686     *r_cb_value = ctx->status_cb_value;
687 }
688
689
690 /* Set the I/O callback functions for CTX to IO_CBS.  */
691 void
692 gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
693 {
694   if (!ctx)
695     return;
696
697   if (io_cbs)
698     {
699       TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
700               "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
701               io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
702               io_cbs->event, io_cbs->event_priv);
703       ctx->io_cbs = *io_cbs;
704     }
705   else
706     {
707       TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
708               "io_cbs=%p (default)", io_cbs);
709       ctx->io_cbs.add = NULL;
710       ctx->io_cbs.add_priv = NULL;
711       ctx->io_cbs.remove = NULL;
712       ctx->io_cbs.event = NULL;
713       ctx->io_cbs.event_priv = NULL;
714     }
715 }
716
717
718 /* This function provides access to the internal read function; it is
719    normally not used.  */
720 gpgme_ssize_t
721 gpgme_io_read (int fd, void *buffer, size_t count)
722 {
723   int ret;
724   TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
725               "buffer=%p, count=%u", buffer, count);
726
727   ret = _gpgme_io_read (fd, buffer, count);
728
729   return TRACE_SYSRES (ret);
730 }
731
732
733 /* This function provides access to the internal write function.  It
734    is to be used by user callbacks to return data to gpgme.  See
735    gpgme_passphrase_cb_t and gpgme_edit_cb_t.  */
736 gpgme_ssize_t
737 gpgme_io_write (int fd, const void *buffer, size_t count)
738 {
739   int ret;
740   TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
741               "buffer=%p, count=%u", buffer, count);
742
743   ret = _gpgme_io_write (fd, buffer, count);
744
745   return TRACE_SYSRES (ret);
746 }
747
748 /* This function provides access to the internal write function.  It
749    is to be used by user callbacks to return data to gpgme.  See
750    gpgme_passphrase_cb_t and gpgme_edit_cb_t.  Note that this is a
751    variant of gpgme_io_write which guarantees that all COUNT bytes are
752    written or an error is return.  Returns: 0 on success or -1 on
753    error and the sets errno. */
754 int
755 gpgme_io_writen (int fd, const void *buffer_arg, size_t count)
756 {
757   const char *buffer = buffer_arg;
758   int ret = 0;
759   TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_writen", fd,
760               "buffer=%p, count=%u", buffer, count);
761   while (count)
762     {
763       ret = _gpgme_io_write (fd, buffer, count);
764       if (ret < 0)
765         break;
766       buffer += ret;
767       count -= ret;
768       ret = 0;
769     }
770   return TRACE_SYSRES (ret);
771 }
772
773
774 /* This function returns the callback function for I/O.  */
775 void
776 gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
777 {
778   TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
779           "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
780           io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
781           io_cbs->event, io_cbs->event_priv);
782
783   *io_cbs = ctx->io_cbs;
784 }
785
786 \f
787 /* This function sets the locale for the context CTX, or the default
788    locale if CTX is a null pointer.  */
789 gpgme_error_t
790 gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
791 {
792   int failed = 0;
793   char *new_lc_ctype = NULL;
794   char *new_lc_messages = NULL;
795
796   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
797                "category=%i, value=%s", category, value ? value : "(null)");
798
799 #define PREPARE_ONE_LOCALE(lcat, ucat)                          \
800   if (!failed && value                                          \
801       && (category == LC_ALL || category == LC_ ## ucat))       \
802     {                                                           \
803       new_lc_ ## lcat = strdup (value);                         \
804       if (!new_lc_ ## lcat)                                     \
805         failed = 1;                                             \
806     }
807
808 #ifdef LC_CTYPE
809   PREPARE_ONE_LOCALE (ctype, CTYPE);
810 #endif
811 #ifdef LC_MESSAGES
812   PREPARE_ONE_LOCALE (messages, MESSAGES);
813 #endif
814
815   if (failed)
816     {
817       int saved_err = gpg_error_from_syserror ();
818
819       if (new_lc_ctype)
820         free (new_lc_ctype);
821       if (new_lc_messages)
822         free (new_lc_messages);
823
824       return TRACE_ERR (saved_err);
825     }
826
827 #define SET_ONE_LOCALE(lcat, ucat)                      \
828   if (category == LC_ALL || category == LC_ ## ucat)    \
829     {                                                   \
830       if (ctx)                                          \
831         {                                               \
832           if (ctx->lc_ ## lcat)                         \
833             free (ctx->lc_ ## lcat);                    \
834           ctx->lc_ ## lcat = new_lc_ ## lcat;           \
835         }                                               \
836       else                                              \
837         {                                               \
838           if (def_lc_ ## lcat)                          \
839             free (def_lc_ ## lcat);                     \
840           def_lc_ ## lcat = new_lc_ ## lcat;            \
841         }                                               \
842     }
843
844   if (!ctx)
845     LOCK (def_lc_lock);
846 #ifdef LC_CTYPE
847   SET_ONE_LOCALE (ctype, CTYPE);
848 #endif
849 #ifdef LC_MESSAGES
850   SET_ONE_LOCALE (messages, MESSAGES);
851 #endif
852   if (!ctx)
853     UNLOCK (def_lc_lock);
854
855   return TRACE_ERR (0);
856 }
857
858 \f
859 /* Get the information about the configured engines.  A pointer to the
860    first engine in the statically allocated linked list is returned.
861    The returned data is valid until the next gpgme_ctx_set_engine_info.  */
862 gpgme_engine_info_t
863 gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
864 {
865   TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
866           "ctx->engine_info=%p", ctx->engine_info);
867   return ctx->engine_info;
868 }
869
870
871 /* Set the engine info for the context CTX, protocol PROTO, to the
872    file name FILE_NAME and the home directory HOME_DIR.  */
873 gpgme_error_t
874 gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
875                            const char *file_name, const char *home_dir)
876 {
877   gpgme_error_t err;
878   TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
879               "protocol=%i (%s), file_name=%s, home_dir=%s",
880               proto, gpgme_get_protocol_name (proto)
881               ? gpgme_get_protocol_name (proto) : "unknown",
882               file_name ? file_name : "(default)",
883               home_dir ? home_dir : "(default)");
884
885   if (!ctx)
886     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
887
888   /* Shut down the engine when changing engine info.  */
889   if (ctx->engine)
890     {
891       TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
892       _gpgme_engine_release (ctx->engine);
893       ctx->engine = NULL;
894     }
895   err = _gpgme_set_engine_info (ctx->engine_info, proto,
896                                 file_name, home_dir);
897   return TRACE_ERR (err);
898 }
899
900 \f
901 /* Clear all notation data from the context.  */
902 void
903 _gpgme_sig_notation_clear (gpgme_ctx_t ctx)
904 {
905   gpgme_sig_notation_t notation;
906
907   if (!ctx)
908     return;
909
910   notation = ctx->sig_notations;
911   while (notation)
912     {
913       gpgme_sig_notation_t next_notation = notation->next;
914       _gpgme_sig_notation_free (notation);
915       notation = next_notation;
916     }
917   ctx->sig_notations = NULL;
918 }
919
920 void
921 gpgme_sig_notation_clear (gpgme_ctx_t ctx)
922 {
923   TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
924
925   if (!ctx)
926     return;
927
928   _gpgme_sig_notation_clear (ctx);
929 }
930
931
932 /* Add the human-readable notation data with name NAME and value VALUE
933    to the context CTX, using the flags FLAGS.  If NAME is NULL, then
934    VALUE should be a policy URL.  The flag
935    GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
936    data, and false for policy URLs.  */
937 gpgme_error_t
938 gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
939                         const char *value, gpgme_sig_notation_flags_t flags)
940 {
941   gpgme_error_t err;
942   gpgme_sig_notation_t notation;
943   gpgme_sig_notation_t *lastp;
944
945   TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
946               "name=%s, value=%s, flags=0x%x",
947               name ? name : "(null)", value ? value : "(null)",
948               flags);
949
950   if (!ctx)
951     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
952
953   if (name)
954     flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
955   else
956     flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
957
958   err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
959                                     value, value ? strlen (value) : 0, flags);
960   if (err)
961     return TRACE_ERR (err);
962
963   lastp = &ctx->sig_notations;
964   while (*lastp)
965     lastp = &(*lastp)->next;
966
967   *lastp = notation;
968   return TRACE_ERR (0);
969 }
970
971
972 /* Get the sig notations for this context.  */
973 gpgme_sig_notation_t
974 gpgme_sig_notation_get (gpgme_ctx_t ctx)
975 {
976   if (!ctx)
977     {
978       TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
979       return NULL;
980     }
981   TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
982           "ctx->sig_notations=%p", ctx->sig_notations);
983
984   return ctx->sig_notations;
985 }
986
987 \f
988 const char *
989 gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
990 {
991   switch (algo)
992     {
993     case GPGME_PK_RSA:
994       return "RSA";
995
996     case GPGME_PK_RSA_E:
997       return "RSA-E";
998
999     case GPGME_PK_RSA_S:
1000       return "RSA-S";
1001
1002     case GPGME_PK_ELG_E:
1003       return "ELG-E";
1004
1005     case GPGME_PK_DSA:
1006       return "DSA";
1007
1008     case GPGME_PK_ECC:
1009       return "ECC";
1010
1011     case GPGME_PK_ELG:
1012       return "ELG";
1013
1014     case GPGME_PK_ECDSA:
1015       return "ECDSA";
1016
1017     case GPGME_PK_ECDH:
1018       return "ECDH";
1019
1020     default:
1021       return NULL;
1022     }
1023 }
1024
1025
1026 const char *
1027 gpgme_hash_algo_name (gpgme_hash_algo_t algo)
1028 {
1029   switch (algo)
1030     {
1031     case GPGME_MD_MD5:
1032       return "MD5";
1033
1034     case GPGME_MD_SHA1:
1035       return "SHA1";
1036
1037     case GPGME_MD_RMD160:
1038       return "RIPEMD160";
1039
1040     case GPGME_MD_MD2:
1041       return "MD2";
1042
1043     case GPGME_MD_TIGER:
1044       return "TIGER192";
1045
1046     case GPGME_MD_HAVAL:
1047       return "HAVAL";
1048
1049     case GPGME_MD_SHA256:
1050       return "SHA256";
1051
1052     case GPGME_MD_SHA384:
1053       return "SHA384";
1054
1055     case GPGME_MD_SHA512:
1056       return "SHA512";
1057
1058     case GPGME_MD_SHA224:
1059       return "SHA224";
1060
1061     case GPGME_MD_MD4:
1062       return "MD4";
1063
1064     case GPGME_MD_CRC32:
1065       return "CRC32";
1066
1067     case GPGME_MD_CRC32_RFC1510:
1068       return "CRC32RFC1510";
1069
1070     case GPGME_MD_CRC24_RFC2440:
1071       return "CRC24RFC2440";
1072
1073     default:
1074       return NULL;
1075     }
1076 }