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