Blame src/engine.c

Packit d7e8d0
/* engine.c - GPGME engine support.
Packit d7e8d0
   Copyright (C) 2000 Werner Koch (dd9jn)
Packit d7e8d0
   Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009, 2010 g10 Code GmbH
Packit d7e8d0
Packit d7e8d0
   This file is part of GPGME.
Packit d7e8d0
Packit d7e8d0
   GPGME is free software; you can redistribute it and/or modify it
Packit d7e8d0
   under the terms of the GNU Lesser General Public License as
Packit d7e8d0
   published by the Free Software Foundation; either version 2.1 of
Packit d7e8d0
   the License, or (at your option) any later version.
Packit d7e8d0
Packit d7e8d0
   GPGME is distributed in the hope that it will be useful, but
Packit d7e8d0
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit d7e8d0
   Lesser General Public License for more details.
Packit d7e8d0
Packit d7e8d0
   You should have received a copy of the GNU Lesser General Public
Packit d7e8d0
   License along with this program; if not, see <https://www.gnu.org/licenses/>.
Packit d7e8d0
*/
Packit d7e8d0
Packit d7e8d0
#ifdef HAVE_CONFIG_H
Packit d7e8d0
#include <config.h>
Packit d7e8d0
#endif
Packit d7e8d0
#include <stdlib.h>
Packit d7e8d0
#include <string.h>
Packit d7e8d0
#include <errno.h>
Packit d7e8d0
#include <assert.h>
Packit d7e8d0
Packit d7e8d0
#include "gpgme.h"
Packit d7e8d0
#include "util.h"
Packit d7e8d0
#include "sema.h"
Packit d7e8d0
#include "ops.h"
Packit d7e8d0
#include "debug.h"
Packit d7e8d0
Packit d7e8d0
#include "engine.h"
Packit d7e8d0
#include "engine-backend.h"
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
struct engine
Packit d7e8d0
{
Packit d7e8d0
  struct engine_ops *ops;
Packit d7e8d0
  void *engine;
Packit d7e8d0
};
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
static struct engine_ops *engine_ops[] =
Packit d7e8d0
  {
Packit d7e8d0
    &_gpgme_engine_ops_gpg,		/* OpenPGP.  */
Packit d7e8d0
    &_gpgme_engine_ops_gpgsm,		/* CMS.  */
Packit d7e8d0
    &_gpgme_engine_ops_gpgconf,		/* gpg-conf.  */
Packit d7e8d0
    &_gpgme_engine_ops_assuan,		/* Low-Level Assuan.  */
Packit d7e8d0
    &_gpgme_engine_ops_g13,		/* Crypto VFS.  */
Packit d7e8d0
#ifdef ENABLE_UISERVER
Packit d7e8d0
    &_gpgme_engine_ops_uiserver,	/* UI-Server.  */
Packit d7e8d0
#else
Packit d7e8d0
    NULL,
Packit d7e8d0
#endif
Packit d7e8d0
    &_gpgme_engine_ops_spawn
Packit d7e8d0
  };
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* The engine info.  */
Packit d7e8d0
static gpgme_engine_info_t engine_info;
Packit d7e8d0
DEFINE_STATIC_LOCK (engine_info_lock);
Packit d7e8d0
Packit d7e8d0
/* If non-NULL, the minimal version required for all engines.  */
Packit d7e8d0
static char *engine_minimal_version;
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0

Packit d7e8d0
/* Get the file name of the engine for PROTOCOL.  */
Packit d7e8d0
static const char *
Packit d7e8d0
engine_get_file_name (gpgme_protocol_t proto)
Packit d7e8d0
{
Packit d7e8d0
  if (proto > DIM (engine_ops))
Packit d7e8d0
    return NULL;
Packit d7e8d0
Packit d7e8d0
  if (engine_ops[proto] && engine_ops[proto]->get_file_name)
Packit d7e8d0
    return (*engine_ops[proto]->get_file_name) ();
Packit d7e8d0
  else
Packit d7e8d0
    return NULL;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Get the standard home dir of the engine for PROTOCOL.  */
Packit d7e8d0
static const char *
Packit d7e8d0
engine_get_home_dir (gpgme_protocol_t proto)
Packit d7e8d0
{
Packit d7e8d0
  if (proto > DIM (engine_ops))
Packit d7e8d0
    return NULL;
Packit d7e8d0
Packit d7e8d0
  if (engine_ops[proto] && engine_ops[proto]->get_home_dir)
Packit d7e8d0
    return (*engine_ops[proto]->get_home_dir) ();
Packit d7e8d0
  else
Packit d7e8d0
    return NULL;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Get a malloced string containing the version number of the engine
Packit d7e8d0
 * for PROTOCOL.  If this function returns NULL for a valid protocol,
Packit d7e8d0
 * it should be assumed that the engine is a pseudo engine. */
Packit d7e8d0
static char *
Packit d7e8d0
engine_get_version (gpgme_protocol_t proto, const char *file_name)
Packit d7e8d0
{
Packit d7e8d0
  if (proto > DIM (engine_ops))
Packit d7e8d0
    return NULL;
Packit d7e8d0
Packit d7e8d0
  if (engine_ops[proto] && engine_ops[proto]->get_version)
Packit d7e8d0
    return (*engine_ops[proto]->get_version) (file_name);
Packit d7e8d0
  else
Packit d7e8d0
    return NULL;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Get the required version number of the engine for PROTOCOL.  This
Packit d7e8d0
 * may be NULL. */
Packit d7e8d0
static const char *
Packit d7e8d0
engine_get_req_version (gpgme_protocol_t proto)
Packit d7e8d0
{
Packit d7e8d0
  if (proto > DIM (engine_ops))
Packit d7e8d0
    return NULL;
Packit d7e8d0
Packit d7e8d0
  if (engine_ops[proto] && engine_ops[proto]->get_req_version)
Packit d7e8d0
    return (*engine_ops[proto]->get_req_version) ();
Packit d7e8d0
  else
Packit d7e8d0
    return NULL;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Verify the version requirement for the engine for PROTOCOL.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
gpgme_engine_check_version (gpgme_protocol_t proto)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_error_t err;
Packit d7e8d0
  gpgme_engine_info_t info;
Packit d7e8d0
  int result;
Packit d7e8d0
Packit d7e8d0
  LOCK (engine_info_lock);
Packit d7e8d0
  info = engine_info;
Packit d7e8d0
  if (!info)
Packit d7e8d0
    {
Packit d7e8d0
      /* Make sure it is initialized.  */
Packit d7e8d0
      UNLOCK (engine_info_lock);
Packit d7e8d0
      err = gpgme_get_engine_info (&info;;
Packit d7e8d0
      if (err)
Packit d7e8d0
	return err;
Packit d7e8d0
Packit d7e8d0
      LOCK (engine_info_lock);
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  while (info && info->protocol != proto)
Packit d7e8d0
    info = info->next;
Packit d7e8d0
Packit d7e8d0
  if (!info)
Packit d7e8d0
    result = 0;
Packit d7e8d0
  else
Packit d7e8d0
    result = _gpgme_compare_versions (info->version,
Packit d7e8d0
				      info->req_version);
Packit d7e8d0
Packit d7e8d0
  UNLOCK (engine_info_lock);
Packit d7e8d0
  return result ? 0 : trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Release the engine info INFO.  */
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_info_release (gpgme_engine_info_t info)
Packit d7e8d0
{
Packit d7e8d0
  while (info)
Packit d7e8d0
    {
Packit d7e8d0
      gpgme_engine_info_t next_info = info->next;
Packit d7e8d0
Packit d7e8d0
      if (info->file_name)
Packit d7e8d0
        free (info->file_name);
Packit d7e8d0
      if (info->home_dir)
Packit d7e8d0
	free (info->home_dir);
Packit d7e8d0
      if (info->version)
Packit d7e8d0
	free (info->version);
Packit d7e8d0
      free (info);
Packit d7e8d0
      info = next_info;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* This is an internal function to set a mimimal required version.
Packit d7e8d0
 * This function must only be called by gpgme_set_global_flag.
Packit d7e8d0
 * Returns 0 on success.  */
Packit d7e8d0
int
Packit d7e8d0
_gpgme_set_engine_minimal_version (const char *value)
Packit d7e8d0
{
Packit d7e8d0
  free (engine_minimal_version);
Packit d7e8d0
  if (value)
Packit d7e8d0
    {
Packit d7e8d0
      engine_minimal_version = strdup (value);
Packit d7e8d0
      return !engine_minimal_version;
Packit d7e8d0
    }
Packit d7e8d0
  else
Packit d7e8d0
    {
Packit d7e8d0
      engine_minimal_version = NULL;
Packit d7e8d0
      return 0;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Get the information about the configured and installed engines.  A
Packit d7e8d0
   pointer to the first engine in the statically allocated linked list
Packit d7e8d0
   is returned in *INFO.  If an error occurs, it is returned.  The
Packit d7e8d0
   returned data is valid until the next gpgme_set_engine_info.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
gpgme_get_engine_info (gpgme_engine_info_t *info)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_error_t err;
Packit d7e8d0
Packit d7e8d0
  LOCK (engine_info_lock);
Packit d7e8d0
  if (!engine_info)
Packit d7e8d0
    {
Packit d7e8d0
      gpgme_engine_info_t *lastp = &engine_info;
Packit d7e8d0
      gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
Packit d7e8d0
					GPGME_PROTOCOL_CMS,
Packit d7e8d0
					GPGME_PROTOCOL_GPGCONF,
Packit d7e8d0
					GPGME_PROTOCOL_ASSUAN,
Packit d7e8d0
					GPGME_PROTOCOL_G13,
Packit d7e8d0
					GPGME_PROTOCOL_UISERVER,
Packit d7e8d0
                                        GPGME_PROTOCOL_SPAWN    };
Packit d7e8d0
      unsigned int proto;
Packit d7e8d0
Packit d7e8d0
      err = 0;
Packit d7e8d0
      for (proto = 0; proto < DIM (proto_list); proto++)
Packit d7e8d0
	{
Packit d7e8d0
	  const char *ofile_name = engine_get_file_name (proto_list[proto]);
Packit d7e8d0
	  const char *ohome_dir  = engine_get_home_dir (proto_list[proto]);
Packit d7e8d0
          char *version = engine_get_version (proto_list[proto], NULL);
Packit d7e8d0
	  char *file_name;
Packit d7e8d0
	  char *home_dir;
Packit d7e8d0
Packit d7e8d0
	  if (!ofile_name)
Packit d7e8d0
	    continue;
Packit d7e8d0
Packit d7e8d0
	  file_name = strdup (ofile_name);
Packit d7e8d0
          if (!file_name)
Packit d7e8d0
            err = gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
          if (ohome_dir)
Packit d7e8d0
            {
Packit d7e8d0
              home_dir = strdup (ohome_dir);
Packit d7e8d0
              if (!home_dir && !err)
Packit d7e8d0
                err = gpg_error_from_syserror ();
Packit d7e8d0
            }
Packit d7e8d0
          else
Packit d7e8d0
            home_dir = NULL;
Packit d7e8d0
Packit d7e8d0
	  *lastp = calloc (1, sizeof (*engine_info));
Packit d7e8d0
          if (!*lastp && !err)
Packit d7e8d0
            err = gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
          /* Check against the optional minimal engine version.  */
Packit d7e8d0
          if (!err && version && engine_minimal_version
Packit d7e8d0
              && !_gpgme_compare_versions (version, engine_minimal_version))
Packit d7e8d0
            {
Packit d7e8d0
#if GPG_ERROR_VERSION_NUMBER < 0x011900 /* 1.25 */
Packit d7e8d0
              err = gpg_error (GPG_ERR_NO_ENGINE);
Packit d7e8d0
#else
Packit d7e8d0
              err = gpg_error (GPG_ERR_ENGINE_TOO_OLD);
Packit d7e8d0
#endif
Packit d7e8d0
            }
Packit d7e8d0
Packit d7e8d0
          /* Now set the dummy version for pseudo engines.  */
Packit d7e8d0
          if (!err && !version)
Packit d7e8d0
            {
Packit d7e8d0
              version = strdup ("1.0.0");
Packit d7e8d0
              if (!version)
Packit d7e8d0
                err = gpg_error_from_syserror ();
Packit d7e8d0
            }
Packit d7e8d0
Packit d7e8d0
	  if (err)
Packit d7e8d0
	    {
Packit d7e8d0
	      _gpgme_engine_info_release (engine_info);
Packit d7e8d0
	      engine_info = NULL;
Packit d7e8d0
Packit d7e8d0
	      if (file_name)
Packit d7e8d0
		free (file_name);
Packit d7e8d0
	      if (home_dir)
Packit d7e8d0
		free (home_dir);
Packit d7e8d0
	      if (version)
Packit d7e8d0
		free (version);
Packit d7e8d0
Packit d7e8d0
	      UNLOCK (engine_info_lock);
Packit d7e8d0
	      return err;
Packit d7e8d0
	    }
Packit d7e8d0
Packit d7e8d0
	  (*lastp)->protocol = proto_list[proto];
Packit d7e8d0
	  (*lastp)->file_name = file_name;
Packit d7e8d0
	  (*lastp)->home_dir = home_dir;
Packit d7e8d0
	  (*lastp)->version = version;
Packit d7e8d0
	  (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
Packit d7e8d0
	  if (!(*lastp)->req_version)
Packit d7e8d0
            (*lastp)->req_version = "1.0.0"; /* Dummy for pseudo engines. */
Packit d7e8d0
	  (*lastp)->next = NULL;
Packit d7e8d0
	  lastp = &(*lastp)->next;
Packit d7e8d0
	}
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  *info = engine_info;
Packit d7e8d0
  UNLOCK (engine_info_lock);
Packit d7e8d0
  return 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Get a deep copy of the engine info and return it in INFO.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_error_t err = 0;
Packit d7e8d0
  gpgme_engine_info_t info;
Packit d7e8d0
  gpgme_engine_info_t new_info;
Packit d7e8d0
  gpgme_engine_info_t *lastp;
Packit d7e8d0
Packit d7e8d0
  LOCK (engine_info_lock);
Packit d7e8d0
  info = engine_info;
Packit d7e8d0
  if (!info)
Packit d7e8d0
    {
Packit d7e8d0
      /* Make sure it is initialized.  */
Packit d7e8d0
      UNLOCK (engine_info_lock);
Packit d7e8d0
      err = gpgme_get_engine_info (&info;;
Packit d7e8d0
      if (err)
Packit d7e8d0
	return err;
Packit d7e8d0
Packit d7e8d0
      LOCK (engine_info_lock);
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  new_info = NULL;
Packit d7e8d0
  lastp = &new_info;
Packit d7e8d0
Packit d7e8d0
  while (info)
Packit d7e8d0
    {
Packit d7e8d0
      char *file_name;
Packit d7e8d0
      char *home_dir;
Packit d7e8d0
      char *version;
Packit d7e8d0
Packit d7e8d0
      assert (info->file_name);
Packit d7e8d0
      file_name = strdup (info->file_name);
Packit d7e8d0
      if (!file_name)
Packit d7e8d0
        err = gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
      if (info->home_dir)
Packit d7e8d0
	{
Packit d7e8d0
	  home_dir = strdup (info->home_dir);
Packit d7e8d0
	  if (!home_dir && !err)
Packit d7e8d0
	    err = gpg_error_from_syserror ();
Packit d7e8d0
	}
Packit d7e8d0
      else
Packit d7e8d0
	home_dir = NULL;
Packit d7e8d0
Packit d7e8d0
      if (info->version)
Packit d7e8d0
	{
Packit d7e8d0
	  version = strdup (info->version);
Packit d7e8d0
	  if (!version && !err)
Packit d7e8d0
	    err = gpg_error_from_syserror ();
Packit d7e8d0
	}
Packit d7e8d0
      else
Packit d7e8d0
	version = NULL;
Packit d7e8d0
Packit d7e8d0
      *lastp = malloc (sizeof (*engine_info));
Packit d7e8d0
      if (!*lastp && !err)
Packit d7e8d0
        err = gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
      if (err)
Packit d7e8d0
	{
Packit d7e8d0
	  _gpgme_engine_info_release (new_info);
Packit d7e8d0
	  if (file_name)
Packit d7e8d0
	    free (file_name);
Packit d7e8d0
	  if (home_dir)
Packit d7e8d0
	    free (home_dir);
Packit d7e8d0
	  if (version)
Packit d7e8d0
	    free (version);
Packit d7e8d0
Packit d7e8d0
	  UNLOCK (engine_info_lock);
Packit d7e8d0
	  return err;
Packit d7e8d0
	}
Packit d7e8d0
Packit d7e8d0
      (*lastp)->protocol = info->protocol;
Packit d7e8d0
      (*lastp)->file_name = file_name;
Packit d7e8d0
      (*lastp)->home_dir = home_dir;
Packit d7e8d0
      (*lastp)->version = version;
Packit d7e8d0
      (*lastp)->req_version = info->req_version;
Packit d7e8d0
      (*lastp)->next = NULL;
Packit d7e8d0
      lastp = &(*lastp)->next;
Packit d7e8d0
Packit d7e8d0
      info = info->next;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  *r_info = new_info;
Packit d7e8d0
  UNLOCK (engine_info_lock);
Packit d7e8d0
  return 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Set the engine info for the info list INFO, protocol PROTO, to the
Packit d7e8d0
   file name FILE_NAME and the home directory HOME_DIR.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
Packit d7e8d0
			const char *file_name, const char *home_dir)
Packit d7e8d0
{
Packit d7e8d0
  char *new_file_name;
Packit d7e8d0
  char *new_home_dir;
Packit d7e8d0
  char *new_version;
Packit d7e8d0
Packit d7e8d0
  /* FIXME: Use some PROTO_MAX definition.  */
Packit d7e8d0
  if (proto > DIM (engine_ops))
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  while (info && info->protocol != proto)
Packit d7e8d0
    info = info->next;
Packit d7e8d0
Packit d7e8d0
  if (!info)
Packit d7e8d0
    return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit d7e8d0
Packit d7e8d0
  /* Prepare new members.  */
Packit d7e8d0
  if (file_name)
Packit d7e8d0
    new_file_name = strdup (file_name);
Packit d7e8d0
  else
Packit d7e8d0
    {
Packit d7e8d0
      const char *ofile_name = engine_get_file_name (proto);
Packit d7e8d0
      assert (ofile_name);
Packit d7e8d0
      new_file_name = strdup (ofile_name);
Packit d7e8d0
    }
Packit d7e8d0
  if (!new_file_name)
Packit d7e8d0
    return gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
  if (home_dir)
Packit d7e8d0
    {
Packit d7e8d0
      new_home_dir = strdup (home_dir);
Packit d7e8d0
      if (!new_home_dir)
Packit d7e8d0
	{
Packit d7e8d0
	  free (new_file_name);
Packit d7e8d0
	  return gpg_error_from_syserror ();
Packit d7e8d0
	}
Packit d7e8d0
    }
Packit d7e8d0
  else
Packit d7e8d0
    {
Packit d7e8d0
      const char *ohome_dir = engine_get_home_dir (proto);
Packit d7e8d0
      if (ohome_dir)
Packit d7e8d0
        {
Packit d7e8d0
          new_home_dir = strdup (ohome_dir);
Packit d7e8d0
          if (!new_home_dir)
Packit d7e8d0
            {
Packit d7e8d0
              free (new_file_name);
Packit d7e8d0
              return gpg_error_from_syserror ();
Packit d7e8d0
            }
Packit d7e8d0
        }
Packit d7e8d0
      else
Packit d7e8d0
        new_home_dir = NULL;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  new_version = engine_get_version (proto, new_file_name);
Packit d7e8d0
  if (!new_version)
Packit d7e8d0
    {
Packit d7e8d0
      new_version = strdup ("1.0.0"); /* Fake one for dummy entries.  */
Packit d7e8d0
      if (!new_version)
Packit d7e8d0
        {
Packit d7e8d0
          free (new_file_name);
Packit d7e8d0
          free (new_home_dir);
Packit d7e8d0
        }
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  /* Remove the old members.  */
Packit d7e8d0
  assert (info->file_name);
Packit d7e8d0
  free (info->file_name);
Packit d7e8d0
  if (info->home_dir)
Packit d7e8d0
    free (info->home_dir);
Packit d7e8d0
  if (info->version)
Packit d7e8d0
    free (info->version);
Packit d7e8d0
Packit d7e8d0
  /* Install the new members.  */
Packit d7e8d0
  info->file_name = new_file_name;
Packit d7e8d0
  info->home_dir = new_home_dir;
Packit d7e8d0
  info->version = new_version;
Packit d7e8d0
Packit d7e8d0
  return 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Set the default engine info for the protocol PROTO to the file name
Packit d7e8d0
   FILE_NAME and the home directory HOME_DIR.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
gpgme_set_engine_info (gpgme_protocol_t proto,
Packit d7e8d0
		       const char *file_name, const char *home_dir)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_error_t err;
Packit d7e8d0
  gpgme_engine_info_t info;
Packit d7e8d0
Packit d7e8d0
  LOCK (engine_info_lock);
Packit d7e8d0
  info = engine_info;
Packit d7e8d0
  if (!info)
Packit d7e8d0
    {
Packit d7e8d0
      /* Make sure it is initialized.  */
Packit d7e8d0
      UNLOCK (engine_info_lock);
Packit d7e8d0
      err = gpgme_get_engine_info (&info;;
Packit d7e8d0
      if (err)
Packit d7e8d0
	return err;
Packit d7e8d0
Packit d7e8d0
      LOCK (engine_info_lock);
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
Packit d7e8d0
  UNLOCK (engine_info_lock);
Packit d7e8d0
  return err;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0

Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
Packit d7e8d0
{
Packit d7e8d0
  engine_t engine;
Packit d7e8d0
Packit d7e8d0
  if (!info->file_name || !info->version)
Packit d7e8d0
    return trace_gpg_error (GPG_ERR_INV_ENGINE);
Packit d7e8d0
Packit d7e8d0
  engine = calloc (1, sizeof *engine);
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error_from_syserror ();
Packit d7e8d0
Packit d7e8d0
  engine->ops = engine_ops[info->protocol];
Packit d7e8d0
  if (engine->ops->new)
Packit d7e8d0
    {
Packit d7e8d0
      gpgme_error_t err;
Packit d7e8d0
      err = (*engine->ops->new) (&engine->engine,
Packit d7e8d0
				 info->file_name, info->home_dir,
Packit d7e8d0
                                 info->version);
Packit d7e8d0
      if (err)
Packit d7e8d0
	{
Packit d7e8d0
	  free (engine);
Packit d7e8d0
	  return err;
Packit d7e8d0
	}
Packit d7e8d0
    }
Packit d7e8d0
  else
Packit d7e8d0
    engine->engine = NULL;
Packit d7e8d0
Packit d7e8d0
  *r_engine = engine;
Packit d7e8d0
  return 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_reset (engine_t engine)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->reset)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->reset) (engine->engine);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_release (engine_t engine)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return;
Packit d7e8d0
Packit d7e8d0
  if (engine->ops->release)
Packit d7e8d0
    (*engine->ops->release) (engine->engine);
Packit d7e8d0
  free (engine);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Set a status callback which is used to monitor the status values
Packit d7e8d0
 * before they are passed to a handler set with
Packit d7e8d0
 * _gpgme_engine_set_status_handler.  */
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_set_status_cb (engine_t engine,
Packit d7e8d0
                             gpgme_status_cb_t cb, void *cb_value)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return;
Packit d7e8d0
Packit d7e8d0
  if (engine->ops->set_status_cb)
Packit d7e8d0
    (*engine->ops->set_status_cb) (engine->engine, cb, cb_value);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_set_status_handler (engine_t engine,
Packit d7e8d0
				  engine_status_handler_t fnc, void *fnc_value)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return;
Packit d7e8d0
Packit d7e8d0
  if (engine->ops->set_status_handler)
Packit d7e8d0
    (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_set_command_handler (engine_t engine,
Packit d7e8d0
				   engine_command_handler_t fnc,
Packit d7e8d0
				   void *fnc_value,
Packit d7e8d0
				   gpgme_data_t linked_data)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->set_command_handler)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->set_command_handler) (engine->engine,
Packit d7e8d0
					      fnc, fnc_value, linked_data);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_set_colon_line_handler (engine_t engine,
Packit d7e8d0
				      engine_colon_line_handler_t fnc,
Packit d7e8d0
				      void *fnc_value)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->set_colon_line_handler)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->set_colon_line_handler) (engine->engine,
Packit d7e8d0
						 fnc, fnc_value);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_set_locale (engine_t engine, int category,
Packit d7e8d0
			  const char *value)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->set_locale)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->set_locale) (engine->engine, category, value);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->set_protocol)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->set_protocol) (engine->engine, protocol);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_decrypt (engine_t engine,
Packit d7e8d0
                          gpgme_decrypt_flags_t flags,
Packit d7e8d0
                          gpgme_data_t ciph,
Packit d7e8d0
			  gpgme_data_t plain, int export_session_key,
Packit d7e8d0
                          const char *override_session_key,
Packit d7e8d0
                          int auto_key_retrieve)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->decrypt)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->decrypt) (engine->engine, flags, ciph, plain,
Packit d7e8d0
                                  export_session_key, override_session_key,
Packit d7e8d0
                                  auto_key_retrieve);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
Packit d7e8d0
			 unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->delete)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->delete) (engine->engine, key, flags);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
Packit d7e8d0
		       gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->edit)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
Packit d7e8d0
			  gpgme_encrypt_flags_t flags,
Packit d7e8d0
			  gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->encrypt)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
Packit d7e8d0
				  use_armor);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
Packit d7e8d0
			       gpgme_encrypt_flags_t flags,
Packit d7e8d0
			       gpgme_data_t plain, gpgme_data_t ciph,
Packit d7e8d0
			       int use_armor, gpgme_ctx_t ctx /* FIXME */)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->encrypt_sign)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
Packit d7e8d0
				       plain, ciph, use_armor, ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_export (engine_t engine, const char *pattern,
Packit d7e8d0
			 gpgme_export_mode_t mode, gpgme_data_t keydata,
Packit d7e8d0
			 int use_armor)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->export)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->export) (engine->engine, pattern, mode,
Packit d7e8d0
				 keydata, use_armor);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
Packit d7e8d0
			     unsigned int reserved, gpgme_data_t keydata,
Packit d7e8d0
			     int use_armor)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->export_ext)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
Packit d7e8d0
				     keydata, use_armor);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_genkey (engine_t engine,
Packit d7e8d0
                         const char *userid, const char *algo,
Packit d7e8d0
                         unsigned long reserved, unsigned long expires,
Packit d7e8d0
                         gpgme_key_t key, unsigned int flags,
Packit d7e8d0
                         gpgme_data_t help_data,
Packit d7e8d0
			 unsigned int extraflags,
Packit d7e8d0
                         gpgme_data_t pubkey, gpgme_data_t seckey)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->genkey)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->genkey) (engine->engine,
Packit d7e8d0
                                 userid, algo, reserved, expires, key, flags,
Packit d7e8d0
                                 help_data, extraflags,
Packit d7e8d0
				 pubkey, seckey);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_keysign (engine_t engine, gpgme_key_t key, const char *userid,
Packit d7e8d0
                          unsigned long expires, unsigned int flags,
Packit d7e8d0
                          gpgme_ctx_t ctx)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->keysign)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->keysign) (engine->engine,
Packit d7e8d0
                                  key, userid, expires, flags, ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_tofu_policy (engine_t engine,
Packit d7e8d0
                              gpgme_key_t key,  gpgme_tofu_policy_t policy)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->tofu_policy)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->tofu_policy) (engine->engine, key, policy);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
Packit d7e8d0
                         gpgme_key_t *keyarray)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->import)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->import) (engine->engine, keydata, keyarray);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_keylist (engine_t engine, const char *pattern,
Packit d7e8d0
			  int secret_only, gpgme_keylist_mode_t mode,
Packit d7e8d0
			  int engine_flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->keylist)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
Packit d7e8d0
                                  engine_flags);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
Packit d7e8d0
			      int secret_only, int reserved,
Packit d7e8d0
			      gpgme_keylist_mode_t mode, int engine_flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->keylist_ext)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
Packit d7e8d0
				      reserved, mode, engine_flags);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_keylist_data (engine_t engine, gpgme_data_t data)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->keylist_data)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->keylist_data) (engine->engine, data);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
Packit d7e8d0
		       gpgme_sig_mode_t mode, int use_armor,
Packit d7e8d0
		       int use_textmode, int include_certs,
Packit d7e8d0
		       gpgme_ctx_t ctx /* FIXME */)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->sign)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
Packit d7e8d0
			       use_textmode, include_certs, ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->trustlist)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->trustlist) (engine->engine, pattern);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
Packit d7e8d0
			 gpgme_data_t signed_text, gpgme_data_t plaintext,
Packit d7e8d0
                         gpgme_ctx_t ctx)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->verify)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext,
Packit d7e8d0
                                 ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
Packit d7e8d0
                              unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->getauditlog)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->getauditlog) (engine->engine, output, flags);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_assuan_transact (engine_t engine,
Packit d7e8d0
                                  const char *command,
Packit d7e8d0
                                  gpgme_assuan_data_cb_t data_cb,
Packit d7e8d0
                                  void *data_cb_value,
Packit d7e8d0
                                  gpgme_assuan_inquire_cb_t inq_cb,
Packit d7e8d0
                                  void *inq_cb_value,
Packit d7e8d0
                                  gpgme_assuan_status_cb_t status_cb,
Packit d7e8d0
                                  void *status_cb_value)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->opassuan_transact)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->opassuan_transact) (engine->engine,
Packit d7e8d0
                                            command,
Packit d7e8d0
                                            data_cb, data_cb_value,
Packit d7e8d0
                                            inq_cb, inq_cb_value,
Packit d7e8d0
                                            status_cb, status_cb_value);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->conf_load)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->conf_load) (engine->engine, conf_p);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->conf_save)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->conf_save) (engine->engine, conf);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_conf_dir (engine_t engine, const char *what, char **result)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->conf_dir)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->conf_dir) (engine->engine, what, result);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_query_swdb (engine_t engine,
Packit d7e8d0
                             const char *name, const char *iversion,
Packit d7e8d0
                             gpgme_query_swdb_result_t result)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->query_swdb)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->query_swdb) (engine->engine, name, iversion, result);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return;
Packit d7e8d0
Packit d7e8d0
  (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
_gpgme_engine_io_event (engine_t engine,
Packit d7e8d0
			gpgme_event_io_t type, void *type_data)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return;
Packit d7e8d0
Packit d7e8d0
  (*engine->ops->io_event) (engine->engine, type, type_data);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Cancel the session and the pending operation if any.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_cancel (engine_t engine)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->cancel)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->cancel) (engine->engine);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Cancel the pending operation, but not the complete session.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_cancel_op (engine_t engine)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->cancel_op)
Packit d7e8d0
    return 0;
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->cancel_op) (engine->engine);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Change the passphrase for KEY.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
Packit d7e8d0
                         unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->passwd)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->passwd) (engine->engine, key, flags);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
/* Set the pinentry mode for ENGINE to MODE.  */
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->set_pinentry_mode)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
gpgme_error_t
Packit d7e8d0
_gpgme_engine_op_spawn (engine_t engine,
Packit d7e8d0
                        const char *file, const char *argv[],
Packit d7e8d0
                        gpgme_data_t datain,
Packit d7e8d0
                        gpgme_data_t dataout, gpgme_data_t dataerr,
Packit d7e8d0
                        unsigned int flags)
Packit d7e8d0
{
Packit d7e8d0
  if (!engine)
Packit d7e8d0
    return gpg_error (GPG_ERR_INV_VALUE);
Packit d7e8d0
Packit d7e8d0
  if (!engine->ops->opspawn)
Packit d7e8d0
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
Packit d7e8d0
Packit d7e8d0
  return (*engine->ops->opspawn) (engine->engine, file, argv,
Packit d7e8d0
                                  datain, dataout, dataerr, flags);
Packit d7e8d0
}