Blame src/gpgme.c

Packit Service 672cf4
/* gpgme.c - GnuPG Made Easy.
Packit Service 6c01f9
   Copyright (C) 2000 Werner Koch (dd9jn)
Packit Service 6c01f9
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
Packit Service 6c01f9
                 2014, 2015 g10 Code GmbH
Packit Service 6c01f9
Packit Service 6c01f9
   This file is part of GPGME.
Packit Service 6c01f9
Packit Service 6c01f9
   GPGME is free software; you can redistribute it and/or modify it
Packit Service 6c01f9
   under the terms of the GNU Lesser General Public License as
Packit Service 6c01f9
   published by the Free Software Foundation; either version 2.1 of
Packit Service 6c01f9
   the License, or (at your option) any later version.
Packit Service 6c01f9
Packit Service 6c01f9
   GPGME is distributed in the hope that it will be useful, but
Packit Service 6c01f9
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 6c01f9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 6c01f9
   Lesser General Public License for more details.
Packit Service 6c01f9
Packit Service 6c01f9
   You should have received a copy of the GNU Lesser General Public
Packit Service 6c01f9
   License along with this program; if not, see <https://www.gnu.org/licenses/>.
Packit Service 672cf4
 */
Packit Service 672cf4
Packit Service 672cf4
#if HAVE_CONFIG_H
Packit Service 672cf4
#include <config.h>
Packit Service 672cf4
#endif
Packit Service 672cf4
#include <stdio.h>
Packit Service 672cf4
#include <stdlib.h>
Packit Service 672cf4
#include <string.h>
Packit Service 672cf4
#include <assert.h>
Packit Service 672cf4
#include <errno.h>
Packit Service 672cf4
#ifdef HAVE_LOCALE_H
Packit Service 672cf4
#include <locale.h>
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
#include "util.h"
Packit Service 672cf4
#include "context.h"
Packit Service 672cf4
#include "ops.h"
Packit Service 672cf4
#include "wait.h"
Packit Service 672cf4
#include "debug.h"
Packit Service 672cf4
#include "priv-io.h"
Packit Service 672cf4
#include "sys-util.h"
Packit Service 672cf4
#include "mbox-util.h"
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* The default locale.  */
Packit Service 672cf4
DEFINE_STATIC_LOCK (def_lc_lock);
Packit Service 672cf4
static char *def_lc_ctype;
Packit Service 672cf4
static char *def_lc_messages;
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
Packit Service 672cf4
Packit Service 672cf4
/* Protects all reference counters in result structures.  All other
Packit Service 672cf4
   accesses to a result structure are read only.  */
Packit Service 672cf4
DEFINE_STATIC_LOCK (result_ref_lock);
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Set the global flag NAME to VALUE.  Return 0 on success.  Note that
Packit Service 672cf4
   this function does not use gpgme_error and thus a non-zero return
Packit Service 672cf4
   value merely means "error".  Certain flags may be set before
Packit Service 672cf4
   gpgme_check_version is called.  See the manual for a description of
Packit Service 672cf4
   supported flags.  The caller must assure that this function is
Packit Service 672cf4
   called only by one thread at a time.  */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_set_global_flag (const char *name, const char *value)
Packit Service 672cf4
{
Packit Service 672cf4
  if (!name || !value)
Packit Service 672cf4
    return -1;
Packit Service 672cf4
  else if (!strcmp (name, "debug"))
Packit Service 672cf4
    return _gpgme_debug_set_debug_envvar (value);
Packit Service 672cf4
  else if (!strcmp (name, "disable-gpgconf"))
Packit Service 672cf4
    {
Packit Service 672cf4
      _gpgme_dirinfo_disable_gpgconf ();
Packit Service 672cf4
      return 0;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "require-gnupg"))
Packit Service 672cf4
    return _gpgme_set_engine_minimal_version (value);
Packit Service 672cf4
  else if (!strcmp (name, "gpgconf-name"))
Packit Service 672cf4
    return _gpgme_set_default_gpgconf_name (value);
Packit Service 672cf4
  else if (!strcmp (name, "gpg-name"))
Packit Service 672cf4
    return _gpgme_set_default_gpg_name (value);
Packit Service 672cf4
  else if (!strcmp (name, "w32-inst-dir"))
Packit Service 672cf4
    return _gpgme_set_override_inst_dir (value);
Packit Service 672cf4
  else
Packit Service 672cf4
    return -1;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Create a new context as an environment for GPGME crypto
Packit Service 672cf4
   operations.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_new (gpgme_ctx_t *r_ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  gpgme_ctx_t ctx;
Packit Service 6c01f9
  TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
Packit Service 672cf4
Packit Service 672cf4
  if (_gpgme_selftest)
Packit Service 672cf4
    return TRACE_ERR (_gpgme_selftest);
Packit Service 672cf4
Packit Service 672cf4
  if (!r_ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  ctx = calloc (1, sizeof *ctx);
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error_from_syserror ());
Packit Service 672cf4
Packit Service 672cf4
  INIT_LOCK (ctx->lock);
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_engine_info_copy (&ctx->engine_info);
Packit Service 672cf4
  if (!err && !ctx->engine_info)
Packit Service 672cf4
    err = gpg_error (GPG_ERR_NO_ENGINE);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    {
Packit Service 672cf4
      free (ctx);
Packit Service 672cf4
      return TRACE_ERR (err);
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
Packit Service 672cf4
  ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
Packit Service 672cf4
  ctx->protocol = GPGME_PROTOCOL_OpenPGP;
Packit Service 672cf4
  ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
Packit Service 672cf4
  _gpgme_fd_table_init (&ctx->fdt);
Packit Service 672cf4
Packit Service 672cf4
  LOCK (def_lc_lock);
Packit Service 672cf4
  if (def_lc_ctype)
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->lc_ctype = strdup (def_lc_ctype);
Packit Service 672cf4
      if (!ctx->lc_ctype)
Packit Service 672cf4
	{
Packit Service 672cf4
          int saved_err = gpg_error_from_syserror ();
Packit Service 672cf4
	  UNLOCK (def_lc_lock);
Packit Service 672cf4
	  _gpgme_engine_info_release (ctx->engine_info);
Packit Service 672cf4
	  free (ctx);
Packit Service 672cf4
	  return TRACE_ERR (saved_err);
Packit Service 672cf4
	}
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    def_lc_ctype = NULL;
Packit Service 672cf4
Packit Service 672cf4
  if (def_lc_messages)
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->lc_messages = strdup (def_lc_messages);
Packit Service 672cf4
      if (!ctx->lc_messages)
Packit Service 672cf4
	{
Packit Service 672cf4
          int saved_err = gpg_error_from_syserror ();
Packit Service 672cf4
	  UNLOCK (def_lc_lock);
Packit Service 672cf4
	  if (ctx->lc_ctype)
Packit Service 672cf4
	    free (ctx->lc_ctype);
Packit Service 672cf4
	  _gpgme_engine_info_release (ctx->engine_info);
Packit Service 672cf4
	  free (ctx);
Packit Service 672cf4
	  return TRACE_ERR (saved_err);
Packit Service 672cf4
	}
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    def_lc_messages = NULL;
Packit Service 672cf4
  UNLOCK (def_lc_lock);
Packit Service 672cf4
Packit Service 672cf4
  *r_ctx = ctx;
Packit Service 672cf4
Packit Service 6c01f9
  return TRACE_SUC1 ("ctx=%p", ctx);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
_gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
Packit Service 672cf4
			gpg_error_t op_err)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  struct gpgme_io_event_done_data data;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
Packit Service 672cf4
	      ctx_err, op_err);
Packit Service 672cf4
Packit Service 672cf4
  if (ctx_err)
Packit Service 672cf4
    {
Packit Service 672cf4
      err = _gpgme_engine_cancel (ctx->engine);
Packit Service 672cf4
      if (err)
Packit Service 672cf4
	return TRACE_ERR (err);
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    {
Packit Service 672cf4
      err = _gpgme_engine_cancel_op (ctx->engine);
Packit Service 672cf4
      if (err)
Packit Service 672cf4
	return TRACE_ERR (err);
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  data.err = ctx_err;
Packit Service 672cf4
  data.op_err = op_err;
Packit Service 672cf4
Packit Service 672cf4
  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Cancel a pending asynchronous operation.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_cancel (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  gpg_error_t err;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_ERR (err);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Cancel a pending operation asynchronously.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_cancel_async (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  LOCK (ctx->lock);
Packit Service 672cf4
  ctx->canceled = 1;
Packit Service 672cf4
  UNLOCK (ctx->lock);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Release all resources associated with the given context.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_release (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE (DEBUG_CTX, "gpgme_release", ctx);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  _gpgme_engine_release (ctx->engine);
Packit Service 672cf4
  ctx->engine = NULL;
Packit Service 672cf4
  _gpgme_fd_table_deinit (&ctx->fdt);
Packit Service 672cf4
  _gpgme_release_result (ctx);
Packit Service 672cf4
  _gpgme_signers_clear (ctx);
Packit Service 672cf4
  _gpgme_sig_notation_clear (ctx);
Packit Service 672cf4
  free (ctx->sender);
Packit Service 672cf4
  free (ctx->signers);
Packit Service 672cf4
  free (ctx->lc_ctype);
Packit Service 672cf4
  free (ctx->lc_messages);
Packit Service 672cf4
  free (ctx->override_session_key);
Packit Service 672cf4
  _gpgme_engine_info_release (ctx->engine_info);
Packit Service 672cf4
  ctx->engine_info = NULL;
Packit Service 672cf4
  DESTROY_LOCK (ctx->lock);
Packit Service 672cf4
  free (ctx);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_result_ref (void *result)
Packit Service 672cf4
{
Packit Service 672cf4
  struct ctx_op_data *data;
Packit Service 672cf4
Packit Service 672cf4
  if (! result)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  data = (void*)((char*)result - sizeof (struct ctx_op_data));
Packit Service 672cf4
Packit Service 672cf4
  assert (data->magic == CTX_OP_DATA_MAGIC);
Packit Service 672cf4
Packit Service 672cf4
  LOCK (result_ref_lock);
Packit Service 672cf4
  data->references++;
Packit Service 672cf4
  UNLOCK (result_ref_lock);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_result_unref (void *result)
Packit Service 672cf4
{
Packit Service 672cf4
  struct ctx_op_data *data;
Packit Service 672cf4
Packit Service 672cf4
  if (! result)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  data = (void*)((char*)result - sizeof (struct ctx_op_data));
Packit Service 672cf4
Packit Service 672cf4
  assert (data->magic == CTX_OP_DATA_MAGIC);
Packit Service 672cf4
Packit Service 672cf4
  LOCK (result_ref_lock);
Packit Service 672cf4
  if (--data->references)
Packit Service 672cf4
    {
Packit Service 672cf4
      UNLOCK (result_ref_lock);
Packit Service 672cf4
      return;
Packit Service 672cf4
    }
Packit Service 672cf4
  UNLOCK (result_ref_lock);
Packit Service 672cf4
Packit Service 672cf4
  if (data->cleanup)
Packit Service 672cf4
    (*data->cleanup) (data->hook);
Packit Service 672cf4
  free (data);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
void
Packit Service 672cf4
_gpgme_release_result (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  struct ctx_op_data *data = ctx->op_data;
Packit Service 672cf4
Packit Service 672cf4
  while (data)
Packit Service 672cf4
    {
Packit Service 672cf4
      struct ctx_op_data *next_data = data->next;
Packit Service 672cf4
      data->next = NULL;
Packit Service 672cf4
      gpgme_result_unref (data->hook);
Packit Service 672cf4
      data = next_data;
Packit Service 672cf4
    }
Packit Service 672cf4
  ctx->op_data = NULL;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
Packit Service 672cf4
	      protocol, gpgme_get_protocol_name (protocol)
Packit Service 672cf4
	      ? gpgme_get_protocol_name (protocol) : "invalid");
Packit Service 672cf4
Packit Service 672cf4
  if (protocol != GPGME_PROTOCOL_OpenPGP
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_CMS
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_GPGCONF
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_ASSUAN
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_G13
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_UISERVER
Packit Service 672cf4
      && protocol != GPGME_PROTOCOL_SPAWN)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  if (ctx->protocol != protocol)
Packit Service 672cf4
    {
Packit Service 672cf4
      /* Shut down the engine when switching protocols.  */
Packit Service 672cf4
      if (ctx->engine)
Packit Service 672cf4
	{
Packit Service 6c01f9
	  TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
Packit Service 672cf4
	  _gpgme_engine_release (ctx->engine);
Packit Service 672cf4
	  ctx->engine = NULL;
Packit Service 672cf4
	}
Packit Service 672cf4
Packit Service 672cf4
      ctx->protocol = protocol;
Packit Service 672cf4
    }
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_protocol_t
Packit Service 672cf4
gpgme_get_protocol (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
Packit Service 672cf4
	  "ctx->protocol=%i (%s)", ctx->protocol,
Packit Service 672cf4
	  gpgme_get_protocol_name (ctx->protocol)
Packit Service 672cf4
	  ? gpgme_get_protocol_name (ctx->protocol) : "invalid");
Packit Service 672cf4
Packit Service 672cf4
  return ctx->protocol;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
Packit Service 672cf4
	  protocol, gpgme_get_protocol_name (protocol)
Packit Service 672cf4
	  ? gpgme_get_protocol_name (protocol) : "invalid");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  ctx->sub_protocol = protocol;
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_protocol_t
Packit Service 672cf4
gpgme_get_sub_protocol (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_sub_protocol", ctx,
Packit Service 672cf4
	  "ctx->sub_protocol=%i (%s)", ctx->sub_protocol,
Packit Service 672cf4
	  gpgme_get_protocol_name (ctx->sub_protocol)
Packit Service 672cf4
	  ? gpgme_get_protocol_name (ctx->sub_protocol) : "invalid");
Packit Service 672cf4
Packit Service 672cf4
  return ctx->sub_protocol;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
const char *
Packit Service 672cf4
gpgme_get_protocol_name (gpgme_protocol_t protocol)
Packit Service 672cf4
{
Packit Service 672cf4
  switch (protocol)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_PROTOCOL_OpenPGP:
Packit Service 672cf4
      return "OpenPGP";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_CMS:
Packit Service 672cf4
      return "CMS";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_GPGCONF:
Packit Service 672cf4
      return "GPGCONF";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_ASSUAN:
Packit Service 672cf4
      return "Assuan";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_G13:
Packit Service 672cf4
      return "G13";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_UISERVER:
Packit Service 672cf4
      return "UIServer";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_SPAWN:
Packit Service 672cf4
      return "Spawn";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_DEFAULT:
Packit Service 672cf4
      return "default";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_PROTOCOL_UNKNOWN:
Packit Service 672cf4
      return "unknown";
Packit Service 672cf4
Packit Service 672cf4
    default:
Packit Service 672cf4
      return NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Store the sender's address in the context.  ADDRESS is addr-spec of
Packit Service 672cf4
 * mailbox but my also be a complete mailbox, in which case this
Packit Service 672cf4
 * function extracts the addr-spec from it.  Returns 0 on success or
Packit Service 672cf4
 * an error code if no valid addr-spec could be extracted from
Packit Service 672cf4
 * ADDRESS.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_sender (gpgme_ctx_t ctx, const char *address)
Packit Service 672cf4
{
Packit Service 672cf4
  char *p = NULL;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG1 (DEBUG_CTX, "gpgme_set_sender", ctx, "sender='%s'",
Packit Service 672cf4
              address?address:"(null)");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx || (address && !(p = _gpgme_mailbox_from_userid (address))))
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  free (ctx->sender);
Packit Service 672cf4
  ctx->sender = p;
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Return the sender's address (addr-spec part) from the context or
Packit Service 672cf4
 * NULL if none was set.  The returned value is valid as long as the
Packit Service 672cf4
 * CTX is valid and gpgme_set_sender has not been used.  */
Packit Service 672cf4
const char *
Packit Service 672cf4
gpgme_get_sender (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_get_sender", ctx, "sender='%s'",
Packit Service 672cf4
          ctx?ctx->sender:"");
Packit Service 672cf4
Packit Service 672cf4
  return ctx->sender;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Enable or disable the use of an ascii armor for all output.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
Packit Service 672cf4
	  use_armor, use_armor ? "yes" : "no");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->use_armor = !!use_armor;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Return the state of the armor flag.  */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_get_armor (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
Packit Service 672cf4
	  ctx->use_armor, ctx->use_armor ? "yes" : "no");
Packit Service 672cf4
  return ctx->use_armor;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 6c01f9
/* Set the flag NAME for CTX to VALUE.  The supported flags are:
Packit Service 6c01f9
 *
Packit Service 6c01f9
 * - full-status :: With a value of "1" the status callback set by
Packit Service 6c01f9
 *                  gpgme_set_status_cb returns all status lines
Packit Service 6c01f9
 *                  except for PROGRESS lines.  With the default of
Packit Service 6c01f9
 *                  "0" the status callback is only called in certain
Packit Service 6c01f9
 *                  situations.
Packit Service 672cf4
 */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err = 0;
Packit Service 672cf4
  int abool;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_ctx_flag", ctx,
Packit Service 672cf4
          "name='%s' value='%s'",
Packit Service 672cf4
	  name? name:"(null)", value?value:"(null)");
Packit Service 672cf4
Packit Service 672cf4
  abool = (value && *value)? !!atoi (value) : 0;
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx || !name || !value)
Packit Service 672cf4
    err = gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
  else if (!strcmp (name, "redraw"))
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->redraw_suggested = abool;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "full-status"))
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->full_status = abool;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "raw-description"))
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->raw_description = abool;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "export-session-key"))
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->export_session_keys = abool;
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "override-session-key"))
Packit Service 672cf4
    {
Packit Service 672cf4
      free (ctx->override_session_key);
Packit Service 672cf4
      ctx->override_session_key = strdup (value);
Packit Service 672cf4
      if (!ctx->override_session_key)
Packit Service 672cf4
        err = gpg_error_from_syserror ();
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "auto-key-retrieve"))
Packit Service 672cf4
    {
Packit Service 672cf4
      ctx->auto_key_retrieve = abool;
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    err = gpg_error (GPG_ERR_UNKNOWN_NAME);
Packit Service 672cf4
Packit Service 672cf4
  return err;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Get the context flag named NAME.  See gpgme_set_ctx_flag for a list
Packit Service 672cf4
 * of valid names.  If the NAME is unknown NULL is returned.  For a
Packit Service 672cf4
 * boolean flag an empty string is returned for False and the string
Packit Service 672cf4
 * "1" for True; thus either atoi or a simple string test can be
Packit Service 672cf4
 * used.  */
Packit Service 672cf4
const char *
Packit Service 672cf4
gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
Packit Service 672cf4
{
Packit Service 672cf4
  if (!ctx || !name)
Packit Service 672cf4
    return NULL;
Packit Service 672cf4
  else if (!strcmp (name, "redraw"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->redraw_suggested? "1":"";
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "full-status"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->full_status? "1":"";
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "raw-description"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->raw_description? "1":"";
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "export-session-key"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->export_session_keys? "1":"";
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "override-session-key"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->override_session_key? ctx->override_session_key : "";
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (!strcmp (name, "auto-key-retrieve"))
Packit Service 672cf4
    {
Packit Service 672cf4
      return ctx->auto_key_retrieve? "1":"";
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    return NULL;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Enable or disable the use of the special textmode.  Textmode is for
Packit Service 672cf4
  example used for the RFC2015 signatures; note that the updated RFC
Packit Service 672cf4
  3156 mandates that the MUA does some preparations so that textmode
Packit Service 672cf4
  is not needed anymore.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
Packit Service 672cf4
	  use_textmode, use_textmode ? "yes" : "no");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->use_textmode = !!use_textmode;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
/* Return the state of the textmode flag.  */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_get_textmode (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
Packit Service 672cf4
	  ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
Packit Service 672cf4
  return ctx->use_textmode;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Enable offline mode for this context. In offline mode dirmngr
Packit Service 672cf4
  will be disabled. */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_offline (gpgme_ctx_t ctx, int offline)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
Packit Service 672cf4
          offline, offline ? "yes" : "no");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->offline = !!offline;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
/* Return the state of the offline flag.  */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_get_offline (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
Packit Service 672cf4
          ctx->offline, ctx->offline ? "yes" : "no");
Packit Service 672cf4
  return ctx->offline;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Set the number of certifications to include in an S/MIME message.
Packit Service 672cf4
   The default is GPGME_INCLUDE_CERTS_DEFAULT.  -1 means all certs,
Packit Service 672cf4
   and -2 means all certs except the root cert.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
Packit Service 672cf4
{
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
Packit Service 672cf4
    ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
Packit Service 672cf4
  else if (nr_of_certs < -2)
Packit Service 672cf4
    ctx->include_certs = -2;
Packit Service 672cf4
  else
Packit Service 672cf4
    ctx->include_certs = nr_of_certs;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
Packit Service 672cf4
	  nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Get the number of certifications to include in an S/MIME
Packit Service 672cf4
   message.  */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_get_include_certs (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
Packit Service 672cf4
	  ctx->include_certs);
Packit Service 672cf4
  return ctx->include_certs;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function changes the default behaviour of the keylisting
Packit Service 672cf4
   functions.  MODE is a bitwise-OR of the GPGME_KEYLIST_* flags.  The
Packit Service 672cf4
   default mode is GPGME_KEYLIST_MODE_LOCAL.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
Packit Service 672cf4
	  mode);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  ctx->keylist_mode = mode;
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
/* This function returns the default behaviour of the keylisting
Packit Service 672cf4
   functions.  */
Packit Service 672cf4
gpgme_keylist_mode_t
Packit Service 672cf4
gpgme_get_keylist_mode (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
Packit Service 672cf4
	  "ctx->keylist_mode=0x%x", ctx->keylist_mode);
Packit Service 672cf4
  return ctx->keylist_mode;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Set the pinentry mode for CTX to MODE. */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_pinentry_mode_t mode)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
Packit Service 672cf4
	  (unsigned int)mode);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  switch (mode)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_PINENTRY_MODE_DEFAULT:
Packit Service 672cf4
    case GPGME_PINENTRY_MODE_ASK:
Packit Service 672cf4
    case GPGME_PINENTRY_MODE_CANCEL:
Packit Service 672cf4
    case GPGME_PINENTRY_MODE_ERROR:
Packit Service 672cf4
    case GPGME_PINENTRY_MODE_LOOPBACK:
Packit Service 672cf4
      break;
Packit Service 672cf4
    default:
Packit Service 672cf4
      return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  ctx->pinentry_mode = mode;
Packit Service 672cf4
  return 0;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Get the pinentry mode of CTX.  */
Packit Service 672cf4
gpgme_pinentry_mode_t
Packit Service 672cf4
gpgme_get_pinentry_mode (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_get_pinentry_mode", ctx,
Packit Service 672cf4
	  "ctx->pinentry_mode=%u", (unsigned int)ctx->pinentry_mode);
Packit Service 672cf4
  return ctx->pinentry_mode;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function sets a callback function to be used to pass a
Packit Service 672cf4
   passphrase to gpg.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
Packit Service 672cf4
			 void *cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
Packit Service 672cf4
	  "passphrase_cb=%p/%p", cb, cb_value);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->passphrase_cb = cb;
Packit Service 672cf4
  ctx->passphrase_cb_value = cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function returns the callback function to be used to pass a
Packit Service 672cf4
   passphrase to the crypto engine.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
Packit Service 672cf4
			 void **r_cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
Packit Service 672cf4
	  "ctx->passphrase_cb=%p/%p",
Packit Service 672cf4
	  ctx->passphrase_cb, ctx->passphrase_cb_value);
Packit Service 672cf4
  if (r_cb)
Packit Service 672cf4
    *r_cb = ctx->passphrase_cb;
Packit Service 672cf4
  if (r_cb_value)
Packit Service 672cf4
    *r_cb_value = ctx->passphrase_cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function sets a callback function to be used as a progress
Packit Service 672cf4
   indicator.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
Packit Service 672cf4
	  cb, cb_value);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->progress_cb = cb;
Packit Service 672cf4
  ctx->progress_cb_value = cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function returns the callback function to be used as a
Packit Service 672cf4
   progress indicator.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
Packit Service 672cf4
		       void **r_cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
Packit Service 672cf4
	  ctx->progress_cb, ctx->progress_cb_value);
Packit Service 672cf4
  if (r_cb)
Packit Service 672cf4
    *r_cb = ctx->progress_cb;
Packit Service 672cf4
  if (r_cb_value)
Packit Service 672cf4
    *r_cb_value = ctx->progress_cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function sets a callback function to be used as a status
Packit Service 672cf4
   message forwarder.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
Packit Service 672cf4
	  cb, cb_value);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  ctx->status_cb = cb;
Packit Service 672cf4
  ctx->status_cb_value = cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function returns the callback function to be used as a
Packit Service 672cf4
   status message forwarder.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
Packit Service 672cf4
		       void **r_cb_value)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
Packit Service 672cf4
	  ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL);
Packit Service 672cf4
Packit Service 672cf4
  if (r_cb)
Packit Service 672cf4
    *r_cb = NULL;
Packit Service 672cf4
Packit Service 672cf4
  if (r_cb_value)
Packit Service 672cf4
    *r_cb_value = NULL;
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx || !ctx->status_cb)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  if (r_cb)
Packit Service 672cf4
    *r_cb = ctx->status_cb;
Packit Service 672cf4
  if (r_cb_value)
Packit Service 672cf4
    *r_cb_value = ctx->status_cb_value;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Set the I/O callback functions for CTX to IO_CBS.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
Packit Service 672cf4
{
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  if (io_cbs)
Packit Service 672cf4
    {
Packit Service 6c01f9
      TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
Packit Service 672cf4
	      "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
Packit Service 672cf4
	      io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
Packit Service 672cf4
	      io_cbs->event, io_cbs->event_priv);
Packit Service 672cf4
      ctx->io_cbs = *io_cbs;
Packit Service 672cf4
    }
Packit Service 672cf4
  else
Packit Service 672cf4
    {
Packit Service 6c01f9
      TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
Packit Service 672cf4
	      "io_cbs=%p (default)", io_cbs);
Packit Service 672cf4
      ctx->io_cbs.add = NULL;
Packit Service 672cf4
      ctx->io_cbs.add_priv = NULL;
Packit Service 672cf4
      ctx->io_cbs.remove = NULL;
Packit Service 672cf4
      ctx->io_cbs.event = NULL;
Packit Service 672cf4
      ctx->io_cbs.event_priv = NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function provides access to the internal read function; it is
Packit Service 672cf4
   normally not used.  */
Packit Service 672cf4
gpgme_ssize_t
Packit Service 672cf4
gpgme_io_read (int fd, void *buffer, size_t count)
Packit Service 672cf4
{
Packit Service 672cf4
  int ret;
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
Packit Service 6c01f9
	      "buffer=%p, count=%u", buffer, count);
Packit Service 672cf4
Packit Service 672cf4
  ret = _gpgme_io_read (fd, buffer, count);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_SYSRES (ret);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function provides access to the internal write function.  It
Packit Service 672cf4
   is to be used by user callbacks to return data to gpgme.  See
Packit Service 672cf4
   gpgme_passphrase_cb_t and gpgme_edit_cb_t.  */
Packit Service 672cf4
gpgme_ssize_t
Packit Service 672cf4
gpgme_io_write (int fd, const void *buffer, size_t count)
Packit Service 672cf4
{
Packit Service 672cf4
  int ret;
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
Packit Service 6c01f9
	      "buffer=%p, count=%u", buffer, count);
Packit Service 672cf4
Packit Service 672cf4
  ret = _gpgme_io_write (fd, buffer, count);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_SYSRES (ret);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
/* This function provides access to the internal write function.  It
Packit Service 672cf4
   is to be used by user callbacks to return data to gpgme.  See
Packit Service 672cf4
   gpgme_passphrase_cb_t and gpgme_edit_cb_t.  Note that this is a
Packit Service 672cf4
   variant of gpgme_io_write which guarantees that all COUNT bytes are
Packit Service 672cf4
   written or an error is return.  Returns: 0 on success or -1 on
Packit Service 672cf4
   error and the sets errno. */
Packit Service 672cf4
int
Packit Service 672cf4
gpgme_io_writen (int fd, const void *buffer_arg, size_t count)
Packit Service 672cf4
{
Packit Service 672cf4
  const char *buffer = buffer_arg;
Packit Service 672cf4
  int ret = 0;
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_writen", fd,
Packit Service 6c01f9
	      "buffer=%p, count=%u", buffer, count);
Packit Service 672cf4
  while (count)
Packit Service 672cf4
    {
Packit Service 672cf4
      ret = _gpgme_io_write (fd, buffer, count);
Packit Service 672cf4
      if (ret < 0)
Packit Service 672cf4
        break;
Packit Service 672cf4
      buffer += ret;
Packit Service 672cf4
      count -= ret;
Packit Service 672cf4
      ret = 0;
Packit Service 672cf4
    }
Packit Service 672cf4
  return TRACE_SYSRES (ret);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* This function returns the callback function for I/O.  */
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
Packit Service 672cf4
	  "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
Packit Service 672cf4
	  io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
Packit Service 672cf4
	  io_cbs->event, io_cbs->event_priv);
Packit Service 672cf4
Packit Service 672cf4
  *io_cbs = ctx->io_cbs;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* This function sets the locale for the context CTX, or the default
Packit Service 672cf4
   locale if CTX is a null pointer.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
Packit Service 672cf4
{
Packit Service 672cf4
  int failed = 0;
Packit Service 672cf4
  char *new_lc_ctype = NULL;
Packit Service 672cf4
  char *new_lc_messages = NULL;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
Packit Service 672cf4
	       "category=%i, value=%s", category, value ? value : "(null)");
Packit Service 672cf4
Packit Service 672cf4
#define PREPARE_ONE_LOCALE(lcat, ucat)				\
Packit Service 672cf4
  if (!failed && value						\
Packit Service 672cf4
      && (category == LC_ALL || category == LC_ ## ucat))	\
Packit Service 672cf4
    {								\
Packit Service 672cf4
      new_lc_ ## lcat = strdup (value);				\
Packit Service 672cf4
      if (!new_lc_ ## lcat)					\
Packit Service 672cf4
        failed = 1;						\
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
#ifdef LC_CTYPE
Packit Service 672cf4
  PREPARE_ONE_LOCALE (ctype, CTYPE);
Packit Service 672cf4
#endif
Packit Service 672cf4
#ifdef LC_MESSAGES
Packit Service 672cf4
  PREPARE_ONE_LOCALE (messages, MESSAGES);
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
  if (failed)
Packit Service 672cf4
    {
Packit Service 672cf4
      int saved_err = gpg_error_from_syserror ();
Packit Service 672cf4
Packit Service 672cf4
      if (new_lc_ctype)
Packit Service 672cf4
	free (new_lc_ctype);
Packit Service 672cf4
      if (new_lc_messages)
Packit Service 672cf4
	free (new_lc_messages);
Packit Service 672cf4
Packit Service 672cf4
      return TRACE_ERR (saved_err);
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
#define SET_ONE_LOCALE(lcat, ucat)			\
Packit Service 672cf4
  if (category == LC_ALL || category == LC_ ## ucat)	\
Packit Service 672cf4
    {							\
Packit Service 672cf4
      if (ctx)						\
Packit Service 672cf4
	{						\
Packit Service 672cf4
	  if (ctx->lc_ ## lcat)				\
Packit Service 672cf4
	    free (ctx->lc_ ## lcat);			\
Packit Service 672cf4
	  ctx->lc_ ## lcat = new_lc_ ## lcat;		\
Packit Service 672cf4
	}						\
Packit Service 672cf4
      else						\
Packit Service 672cf4
	{						\
Packit Service 672cf4
	  if (def_lc_ ## lcat)				\
Packit Service 672cf4
	    free (def_lc_ ## lcat);			\
Packit Service 672cf4
	  def_lc_ ## lcat = new_lc_ ## lcat;		\
Packit Service 672cf4
	}						\
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    LOCK (def_lc_lock);
Packit Service 672cf4
#ifdef LC_CTYPE
Packit Service 672cf4
  SET_ONE_LOCALE (ctype, CTYPE);
Packit Service 672cf4
#endif
Packit Service 672cf4
#ifdef LC_MESSAGES
Packit Service 672cf4
  SET_ONE_LOCALE (messages, MESSAGES);
Packit Service 672cf4
#endif
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    UNLOCK (def_lc_lock);
Packit Service 672cf4
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Get the information about the configured engines.  A pointer to the
Packit Service 672cf4
   first engine in the statically allocated linked list is returned.
Packit Service 672cf4
   The returned data is valid until the next gpgme_ctx_set_engine_info.  */
Packit Service 672cf4
gpgme_engine_info_t
Packit Service 672cf4
gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
Packit Service 672cf4
	  "ctx->engine_info=%p", ctx->engine_info);
Packit Service 672cf4
  return ctx->engine_info;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Set the engine info for the context CTX, protocol PROTO, to the
Packit Service 672cf4
   file name FILE_NAME and the home directory HOME_DIR.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
Packit Service 672cf4
			   const char *file_name, const char *home_dir)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 6c01f9
  TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
Packit Service 672cf4
	      "protocol=%i (%s), file_name=%s, home_dir=%s",
Packit Service 672cf4
	      proto, gpgme_get_protocol_name (proto)
Packit Service 672cf4
	      ? gpgme_get_protocol_name (proto) : "unknown",
Packit Service 672cf4
	      file_name ? file_name : "(default)",
Packit Service 672cf4
	      home_dir ? home_dir : "(default)");
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  /* Shut down the engine when changing engine info.  */
Packit Service 672cf4
  if (ctx->engine)
Packit Service 672cf4
    {
Packit Service 6c01f9
      TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
Packit Service 672cf4
      _gpgme_engine_release (ctx->engine);
Packit Service 672cf4
      ctx->engine = NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
  err = _gpgme_set_engine_info (ctx->engine_info, proto,
Packit Service 672cf4
				file_name, home_dir);
Packit Service 672cf4
  return TRACE_ERR (err);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Clear all notation data from the context.  */
Packit Service 672cf4
void
Packit Service 672cf4
_gpgme_sig_notation_clear (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_sig_notation_t notation;
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  notation = ctx->sig_notations;
Packit Service 672cf4
  while (notation)
Packit Service 672cf4
    {
Packit Service 672cf4
      gpgme_sig_notation_t next_notation = notation->next;
Packit Service 672cf4
      _gpgme_sig_notation_free (notation);
Packit Service 672cf4
      notation = next_notation;
Packit Service 672cf4
    }
Packit Service 672cf4
  ctx->sig_notations = NULL;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void
Packit Service 672cf4
gpgme_sig_notation_clear (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 6c01f9
  TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return;
Packit Service 672cf4
Packit Service 672cf4
  _gpgme_sig_notation_clear (ctx);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Add the human-readable notation data with name NAME and value VALUE
Packit Service 672cf4
   to the context CTX, using the flags FLAGS.  If NAME is NULL, then
Packit Service 672cf4
   VALUE should be a policy URL.  The flag
Packit Service 672cf4
   GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
Packit Service 672cf4
   data, and false for policy URLs.  */
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
Packit Service 672cf4
			const char *value, gpgme_sig_notation_flags_t flags)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
  gpgme_sig_notation_t notation;
Packit Service 672cf4
  gpgme_sig_notation_t *lastp;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
Packit Service 672cf4
	      "name=%s, value=%s, flags=0x%x",
Packit Service 672cf4
	      name ? name : "(null)", value ? value : "(null)",
Packit Service 672cf4
	      flags);
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
Packit Service 672cf4
Packit Service 672cf4
  if (name)
Packit Service 672cf4
    flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
Packit Service 672cf4
  else
Packit Service 672cf4
    flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
Packit Service 672cf4
				    value, value ? strlen (value) : 0, flags);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return TRACE_ERR (err);
Packit Service 672cf4
Packit Service 672cf4
  lastp = &ctx->sig_notations;
Packit Service 672cf4
  while (*lastp)
Packit Service 672cf4
    lastp = &(*lastp)->next;
Packit Service 672cf4
Packit Service 672cf4
  *lastp = notation;
Packit Service 672cf4
  return TRACE_ERR (0);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* Get the sig notations for this context.  */
Packit Service 672cf4
gpgme_sig_notation_t
Packit Service 672cf4
gpgme_sig_notation_get (gpgme_ctx_t ctx)
Packit Service 672cf4
{
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    {
Packit Service 6c01f9
      TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
Packit Service 672cf4
      return NULL;
Packit Service 672cf4
    }
Packit Service 6c01f9
  TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
Packit Service 672cf4
	  "ctx->sig_notations=%p", ctx->sig_notations);
Packit Service 672cf4
Packit Service 672cf4
  return ctx->sig_notations;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* Return a public key algorithm string made of the algorithm and size
Packit Service 672cf4
   or the curve name.  May return NULL on error.  Caller must free the
Packit Service 672cf4
   result using gpgme_free.  */
Packit Service 672cf4
char *
Packit Service 672cf4
gpgme_pubkey_algo_string (gpgme_subkey_t subkey)
Packit Service 672cf4
{
Packit Service 672cf4
  const char *prefix = NULL;
Packit Service 672cf4
  char *result;
Packit Service 672cf4
Packit Service 672cf4
  if (!subkey)
Packit Service 672cf4
    {
Packit Service 672cf4
      gpg_err_set_errno (EINVAL);
Packit Service 672cf4
      return NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  switch (subkey->pubkey_algo)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_PK_RSA:
Packit Service 672cf4
    case GPGME_PK_RSA_E:
Packit Service 672cf4
    case GPGME_PK_RSA_S: prefix = "rsa"; break;
Packit Service 672cf4
    case GPGME_PK_ELG_E: prefix = "elg"; break;
Packit Service 672cf4
    case GPGME_PK_DSA:	 prefix = "dsa"; break;
Packit Service 672cf4
    case GPGME_PK_ELG:   prefix = "xxx"; break;
Packit Service 672cf4
    case GPGME_PK_ECC:
Packit Service 672cf4
    case GPGME_PK_ECDH:
Packit Service 672cf4
    case GPGME_PK_ECDSA:
Packit Service 672cf4
    case GPGME_PK_EDDSA: prefix = "";    break;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  if (prefix && *prefix)
Packit Service 672cf4
    {
Packit Service 672cf4
      char buffer[40];
Packit Service 672cf4
      snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length);
Packit Service 672cf4
      result = strdup (buffer);
Packit Service 672cf4
    }
Packit Service 672cf4
  else if (prefix && subkey->curve && *subkey->curve)
Packit Service 672cf4
    result = strdup (subkey->curve);
Packit Service 672cf4
  else if (prefix)
Packit Service 672cf4
    result =  strdup ("E_error");
Packit Service 672cf4
  else
Packit Service 672cf4
    result = strdup  ("unknown");
Packit Service 672cf4
Packit Service 672cf4
  return result;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
const char *
Packit Service 672cf4
gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
Packit Service 672cf4
{
Packit Service 672cf4
  switch (algo)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_PK_RSA:   return "RSA";
Packit Service 672cf4
    case GPGME_PK_RSA_E: return "RSA-E";
Packit Service 672cf4
    case GPGME_PK_RSA_S: return "RSA-S";
Packit Service 672cf4
    case GPGME_PK_ELG_E: return "ELG-E";
Packit Service 672cf4
    case GPGME_PK_DSA:   return "DSA";
Packit Service 672cf4
    case GPGME_PK_ECC:   return "ECC";
Packit Service 672cf4
    case GPGME_PK_ELG:   return "ELG";
Packit Service 672cf4
    case GPGME_PK_ECDSA: return "ECDSA";
Packit Service 672cf4
    case GPGME_PK_ECDH:  return "ECDH";
Packit Service 672cf4
    case GPGME_PK_EDDSA: return "EdDSA";
Packit Service 672cf4
    default:             return NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
const char *
Packit Service 672cf4
gpgme_hash_algo_name (gpgme_hash_algo_t algo)
Packit Service 672cf4
{
Packit Service 672cf4
  switch (algo)
Packit Service 672cf4
    {
Packit Service 672cf4
    case GPGME_MD_MD5:
Packit Service 672cf4
      return "MD5";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_SHA1:
Packit Service 672cf4
      return "SHA1";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_RMD160:
Packit Service 672cf4
      return "RIPEMD160";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_MD2:
Packit Service 672cf4
      return "MD2";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_TIGER:
Packit Service 672cf4
      return "TIGER192";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_HAVAL:
Packit Service 672cf4
      return "HAVAL";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_SHA256:
Packit Service 672cf4
      return "SHA256";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_SHA384:
Packit Service 672cf4
      return "SHA384";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_SHA512:
Packit Service 672cf4
      return "SHA512";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_SHA224:
Packit Service 672cf4
      return "SHA224";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_MD4:
Packit Service 672cf4
      return "MD4";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_CRC32:
Packit Service 672cf4
      return "CRC32";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_CRC32_RFC1510:
Packit Service 672cf4
      return "CRC32RFC1510";
Packit Service 672cf4
Packit Service 672cf4
    case GPGME_MD_CRC24_RFC2440:
Packit Service 672cf4
      return "CRC24RFC2440";
Packit Service 672cf4
Packit Service 672cf4
    default:
Packit Service 672cf4
      return NULL;
Packit Service 672cf4
    }
Packit Service 672cf4
}