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