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