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