Blame src/vfs-create.c

Packit Service 672cf4
/* vfs-create.c - vfs create support in GPGME
Packit Service 6c01f9
   Copyright (C) 2009 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, write to the Free Software
Packit Service 6c01f9
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
Packit Service 6c01f9
   02111-1307, USA.  */
Packit Service 672cf4
Packit Service 672cf4
#if HAVE_CONFIG_H
Packit Service 672cf4
#include <config.h>
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
#include <stdlib.h>
Packit Service 672cf4
#include <string.h>
Packit Service 672cf4
Packit Service 672cf4
#include "gpgme.h"
Packit Service 672cf4
#include "debug.h"
Packit Service 672cf4
#include "context.h"
Packit Service 672cf4
#include "ops.h"
Packit Service 672cf4
#include "util.h"
Packit Service 672cf4
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
vfs_start (gpgme_ctx_t ctx, int synchronous,
Packit Service 672cf4
	   const char *command,
Packit Service 672cf4
	   gpgme_assuan_data_cb_t data_cb,
Packit Service 672cf4
	   void *data_cb_value,
Packit Service 672cf4
	   gpgme_assuan_inquire_cb_t inq_cb,
Packit Service 672cf4
	   void *inq_cb_value,
Packit Service 672cf4
	   gpgme_assuan_status_cb_t status_cb,
Packit Service 672cf4
	   void *status_cb_value)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 672cf4
  if (!command || !*command)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  /* The flag value 256 is used to suppress an engine reset.  This is
Packit Service 672cf4
     required to keep the connection running.  */
Packit Service 672cf4
  err = _gpgme_op_reset (ctx, ((synchronous & 255) | 256));
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  return _gpgme_engine_op_assuan_transact (ctx->engine, command,
Packit Service 672cf4
					   data_cb, data_cb_value,
Packit Service 672cf4
					   inq_cb, inq_cb_value,
Packit Service 672cf4
					   status_cb, status_cb_value);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
#if 0
Packit Service 672cf4
/* XXXX.  This is the asynchronous variant. */
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
gpgme_op_vfs_transact_start (gpgme_ctx_t ctx,
Packit Service 672cf4
			     const char *command,
Packit Service 672cf4
			     gpgme_assuan_data_cb_t data_cb,
Packit Service 672cf4
			     void *data_cb_value,
Packit Service 672cf4
			     gpgme_assuan_inquire_cb_t inq_cb,
Packit Service 672cf4
			     void *inq_cb_value,
Packit Service 672cf4
			     gpgme_assuan_status_cb_t status_cb,
Packit Service 672cf4
			     void *status_cb_value)
Packit Service 672cf4
{
Packit Service 672cf4
  return vfs_start (ctx, 0, command, data_cb, data_cb_value,
Packit Service 672cf4
		    inq_cb, inq_cb_value, status_cb, status_cb_value);
Packit Service 672cf4
}
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
/* XXXX.  This is the synchronous variant. */
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
gpgme_op_vfs_transact (gpgme_ctx_t ctx,
Packit Service 672cf4
		       const char *command,
Packit Service 672cf4
		       gpgme_assuan_data_cb_t data_cb,
Packit Service 672cf4
		       void *data_cb_value,
Packit Service 672cf4
		       gpgme_assuan_inquire_cb_t inq_cb,
Packit Service 672cf4
		       void *inq_cb_value,
Packit Service 672cf4
		       gpgme_assuan_status_cb_t status_cb,
Packit Service 672cf4
		       void *status_cb_value,
Packit Service 672cf4
		       gpgme_error_t *op_err)
Packit Service 672cf4
{
Packit Service 672cf4
  gpgme_error_t err;
Packit Service 672cf4
Packit Service 672cf4
  if (!ctx)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  err = vfs_start (ctx, 1, command, data_cb, data_cb_value,
Packit Service 672cf4
		   inq_cb, inq_cb_value, status_cb, status_cb_value);
Packit Service 672cf4
  if (!err)
Packit Service 672cf4
    err = _gpgme_wait_one_ext (ctx, op_err);
Packit Service 672cf4
  return err;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4

Packit Service 672cf4
/* The actual exported interface follows.  */
Packit Service 672cf4
Packit Service 672cf4
/* The container is automatically uncreateed when the context is reset
Packit Service 672cf4
   or destroyed.  This is a synchronous convenience interface, which
Packit Service 672cf4
   automatically returns an operation error if there is no
Packit Service 672cf4
   transmission error.  */
Packit Service 672cf4
static gpgme_error_t
Packit Service 672cf4
_gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
Packit Service 672cf4
		      const char *container_file, unsigned int flags,
Packit Service 672cf4
		      gpgme_error_t *op_err)
Packit Service 672cf4
{
Packit Service 672cf4
  gpg_error_t err;
Packit Service 672cf4
  char *cmd;
Packit Service 672cf4
  char *container_file_esc = NULL;
Packit Service 672cf4
  int i;
Packit Service 672cf4
Packit Service 672cf4
  (void)flags;
Packit Service 672cf4
Packit Service 672cf4
  /* We want to encourage people to check error values, so not getting
Packit Service 672cf4
     them is discouraged here.  Also makes our code easier.  */
Packit Service 672cf4
  if (! op_err)
Packit Service 672cf4
    return gpg_error (GPG_ERR_INV_VALUE);
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0);
Packit Service 672cf4
  if (err)
Packit Service 672cf4
    return err;
Packit Service 672cf4
Packit Service 672cf4
  i = 0;
Packit Service 672cf4
  while (!err && recp[i])
Packit Service 672cf4
    {
Packit Service 672cf4
      if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
Packit Service 672cf4
	{
Packit Service 672cf4
	  free (container_file_esc);
Packit Service 672cf4
	  return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
Packit Service 672cf4
	}
Packit Service 672cf4
Packit Service 672cf4
      if (gpgrt_asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
Packit Service 672cf4
	{
Packit Service 672cf4
	  err = gpg_error_from_syserror ();
Packit Service 672cf4
	  free (container_file_esc);
Packit Service 672cf4
	  return err;
Packit Service 672cf4
	}
Packit Service 672cf4
Packit Service 672cf4
      err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
Packit Service 672cf4
				   NULL, NULL, op_err);
Packit Service 672cf4
      gpgrt_free (cmd);
Packit Service 672cf4
      if (err || *op_err)
Packit Service 672cf4
	{
Packit Service 672cf4
	  free (container_file_esc);
Packit Service 672cf4
	  return err;
Packit Service 672cf4
	}
Packit Service 672cf4
      recp++;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  if (gpgrt_asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
Packit Service 672cf4
    {
Packit Service 672cf4
      err = gpg_error_from_syserror ();
Packit Service 672cf4
      free (container_file_esc);
Packit Service 672cf4
      return err;
Packit Service 672cf4
    }
Packit Service 672cf4
  free (container_file_esc);
Packit Service 672cf4
Packit Service 672cf4
  err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
Packit Service 672cf4
			       NULL, NULL, op_err);
Packit Service 672cf4
  gpgrt_free (cmd);
Packit Service 672cf4
Packit Service 672cf4
  return err;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
gpgme_error_t
Packit Service 672cf4
gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
Packit Service 672cf4
		      const char *container_file, unsigned int flags,
Packit Service 672cf4
		      gpgme_error_t *op_err)
Packit Service 672cf4
{
Packit Service 672cf4
  gpg_error_t err;
Packit Service 672cf4
Packit Service 6c01f9
  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_vfs_create", ctx,
Packit Service 672cf4
	      "container_file=%s, flags=0x%x, op_err=%p",
Packit Service 672cf4
	      container_file, flags, op_err);
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 (_gpgme_debug_trace () && recp)
Packit Service 672cf4
    {
Packit Service 672cf4
      int i = 0;
Packit Service 672cf4
Packit Service 672cf4
      while (recp[i])
Packit Service 672cf4
	{
Packit Service 6c01f9
	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
Packit Service 672cf4
		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
Packit Service 672cf4
		      recp[i]->subkeys->fpr : "invalid");
Packit Service 672cf4
	  i++;
Packit Service 672cf4
	}
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
  err = _gpgme_op_vfs_create (ctx, recp, container_file, flags, op_err);
Packit Service 672cf4
  return TRACE_ERR (err);
Packit Service 672cf4
}
Packit Service 672cf4