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