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