Beautify source code.
[gpgme.git] / gpgme / rungpg.c
index 05d0718..698d0ca 100644 (file)
@@ -1,6 +1,6 @@
 /* rungpg.c - Gpg Engine.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003 g10 Code GmbH
  
    This file is part of GPGME.
  
@@ -40,6 +40,7 @@
 #include "context.h"  /*temp hack until we have GpmeData methods to do I/O */
 #include "io.h"
 #include "sema.h"
+#include "debug.h"
 
 #include "status-table.h"
 #include "engine-backend.h"
@@ -50,7 +51,7 @@
 struct arg_and_data_s
 {
   struct arg_and_data_s *next;
-  GpgmeData data;  /* If this is not NULL, use arg below.  */
+  gpgme_data_t data;  /* If this is not NULL, use arg below.  */
   int inbound;     /* True if this is used for reading from gpg.  */
   int dup_to;
   int print_fd;    /* Print the fd number and not the special form of it.  */
@@ -60,7 +61,7 @@ struct arg_and_data_s
 
 struct fd_data_map_s
 {
-  GpgmeData data;
+  gpgme_data_t data;
   int inbound;  /* true if this is used for reading from gpg */
   int dup_to;
   int fd;       /* the fd to use */
@@ -82,7 +83,7 @@ struct gpg_object_s
     char *buffer;
     size_t readpos;
     int eof;
-    GpgmeStatusHandler fnc;
+    EngineStatusHandler fnc;
     void *fnc_value;
     void *tag;
   } status;
@@ -95,7 +96,7 @@ struct gpg_object_s
     char *buffer;
     size_t readpos;
     int eof;
-    GpgmeColonLineHandler fnc;  /* this indicate use of this structrue */
+    EngineColonLineHandler fnc;  /* this indicate use of this structrue */
     void *fnc_value;
     void *tag;
   } colon;
@@ -109,23 +110,25 @@ struct gpg_object_s
     int used;
     int fd;
     int idx;           /* Index in fd_data_map */
-    GpgmeData cb_data;   /* hack to get init the above idx later */
-    GpgmeStatusCode code;  /* last code */
+    gpgme_data_t cb_data;   /* hack to get init the above idx later */
+    gpgme_status_code_t code;  /* last code */
     char *keyword;       /* what has been requested (malloced) */
-    GpgmeCommandHandler fnc; 
+    EngineCommandHandler fnc; 
     void *fnc_value;
     /* The kludges never end.  This is used to couple command handlers
        with output data in edit key mode.  */
-    GpgmeData linked_data;
+    gpgme_data_t linked_data;
     int linked_idx;
   } cmd;
 
-  struct GpgmeIOCbs io_cbs;
+  struct gpgme_io_cbs io_cbs;
 };
 
+typedef struct gpg_object_s *GpgObject;
 
+\f
 static void
-gpg_io_event (void *engine, GpgmeEventIO type, void *type_data)
+gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
 {
   GpgObject gpg = engine;
 
@@ -138,17 +141,12 @@ static void
 close_notify_handler (int fd, void *opaque)
 {
   GpgObject gpg = opaque;
-  int possibly_done = 0;
-  int not_done = 0;
   assert (fd != -1);
 
   if (gpg->status.fd[0] == fd)
     {
       if (gpg->status.tag)
-       {
-         (*gpg->io_cbs.remove) (gpg->status.tag);
-         possibly_done = 1;
-       }
+       (*gpg->io_cbs.remove) (gpg->status.tag);
       gpg->status.fd[0] = -1;
     }
   else if (gpg->status.fd[1] == fd)
@@ -156,10 +154,7 @@ close_notify_handler (int fd, void *opaque)
   else if (gpg->colon.fd[0] == fd)
     {
       if (gpg->colon.tag)
-       {
-         (*gpg->io_cbs.remove) (gpg->colon.tag);
-         possibly_done = 1;
-       }
+       (*gpg->io_cbs.remove) (gpg->colon.tag);
       gpg->colon.fd[0] = -1;
     }
   else if (gpg->colon.fd[1] == fd)
@@ -173,10 +168,7 @@ close_notify_handler (int fd, void *opaque)
          if (gpg->fd_data_map[i].fd == fd)
            {
              if (gpg->fd_data_map[i].tag)
-               {
-                 (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
-                 possibly_done = 1;
-               }
+               (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
              gpg->fd_data_map[i].fd = -1;
              break;
             }
@@ -187,28 +179,9 @@ close_notify_handler (int fd, void *opaque)
             }
         }
     }
-  if (!possibly_done)
-    not_done = 1;
-  else if (gpg->status.fd[0] != -1)
-    not_done = 1;
-  else if (gpg->colon.fd[0] != -1)
-    not_done = 1;
-  else if (gpg->fd_data_map)
-    {
-      int i;
-
-      for (i = 0; gpg->fd_data_map[i].data; i++)
-       if (gpg->fd_data_map[i].fd != -1)
-         {
-           not_done = 1;
-           break;
-         }
-    }
-  if (!not_done)
-    gpg_io_event (gpg, GPGME_EVENT_DONE, NULL);
 }
 
-static GpgmeError
+static gpgme_error_t
 add_arg (GpgObject gpg, const char *arg)
 {
   struct arg_and_data_s *a;
@@ -220,7 +193,7 @@ add_arg (GpgObject gpg, const char *arg)
   if (!a)
     {
       gpg->arg_error = 1;
-      return mk_error(Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
   a->next = NULL;
   a->data = NULL;
@@ -231,8 +204,8 @@ add_arg (GpgObject gpg, const char *arg)
   return 0;
 }
 
-static GpgmeError
-add_data (GpgObject gpg, GpgmeData data, int dup_to, int inbound)
+static gpgme_error_t
+add_data (GpgObject gpg, gpgme_data_t data, int dup_to, int inbound)
 {
   struct arg_and_data_s *a;
 
@@ -243,7 +216,7 @@ add_data (GpgObject gpg, GpgmeData data, int dup_to, int inbound)
   if (!a)
     {
       gpg->arg_error = 1;
-      return mk_error(Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
   a->next = NULL;
   a->data = data;
@@ -278,11 +251,10 @@ gpg_get_version (void)
 }
 
 
-static GpgmeError
-gpg_check_version (void)
+static const char *
+gpg_get_req_version (void)
 {
-  return _gpgme_compare_versions (gpg_get_version (), NEED_GPG_VERSION)
-    ? 0 : mk_error (Invalid_Engine);
+  return NEED_GPG_VERSION;
 }
 
 
@@ -355,7 +327,7 @@ gpg_release (void *engine)
 }
 
 
-static GpgmeError
+static gpgme_error_t
 gpg_new (void **engine)
 {
   GpgObject gpg;
@@ -364,7 +336,7 @@ gpg_new (void **engine)
   gpg = calloc (1, sizeof *gpg);
   if (!gpg)
     {
-      rc = mk_error (Out_Of_Core);
+      rc = GPGME_Out_Of_Core;
       goto leave;
     }
   gpg->argtail = &gpg->arglist;
@@ -384,14 +356,14 @@ gpg_new (void **engine)
   gpg->status.buffer = malloc (gpg->status.bufsize);
   if (!gpg->status.buffer)
     {
-      rc = mk_error (Out_Of_Core);
+      rc = GPGME_Out_Of_Core;
       goto leave;
     }
   /* In any case we need a status pipe - create it right here and
-     don't handle it with our generic GpgmeData mechanism.  */
+     don't handle it with our generic gpgme_data_t mechanism.  */
   if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
     {
-      rc = mk_error (Pipe_Error);
+      rc = GPGME_Pipe_Error;
       goto leave;
     }
   if (_gpgme_io_set_close_notify (gpg->status.fd[0],
@@ -399,7 +371,7 @@ gpg_new (void **engine)
       || _gpgme_io_set_close_notify (gpg->status.fd[1],
                                     close_notify_handler, gpg))
     {
-      rc = mk_error (General_Error);
+      rc = GPGME_General_Error;
       goto leave;
     }
   gpg->status.eof = 0;
@@ -422,21 +394,10 @@ gpg_new (void **engine)
 }
 
 
-static GpgmeError
-gpg_set_verbosity (void *engine, int verbosity)
-{
-  GpgObject gpg = engine;
-
-  GpgmeError err = 0;
-  while (!err && verbosity-- > 0)
-    err = add_arg (gpg, "--verbose");
-  return err;
-}
-
 /* Note, that the status_handler is allowed to modifiy the args
    value.  */
 static void
-gpg_set_status_handler (void *engine, GpgmeStatusHandler fnc, void *fnc_value)
+gpg_set_status_handler (void *engine, EngineStatusHandler fnc, void *fnc_value)
 {
   GpgObject gpg = engine;
 
@@ -445,8 +406,8 @@ gpg_set_status_handler (void *engine, GpgmeStatusHandler fnc, void *fnc_value)
 }
 
 /* Kludge to process --with-colon output.  */
-static GpgmeError
-gpg_set_colon_line_handler (void *engine, GpgmeColonLineHandler fnc,
+static gpgme_error_t
+gpg_set_colon_line_handler (void *engine, EngineColonLineHandler fnc,
                            void *fnc_value)
 {
   GpgObject gpg = engine;
@@ -455,18 +416,18 @@ gpg_set_colon_line_handler (void *engine, GpgmeColonLineHandler fnc,
   gpg->colon.readpos = 0;
   gpg->colon.buffer = malloc (gpg->colon.bufsize);
   if (!gpg->colon.buffer)
-    return mk_error (Out_Of_Core);
+    return GPGME_Out_Of_Core;
 
   if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1) 
     {
       free (gpg->colon.buffer);
       gpg->colon.buffer = NULL;
-      return mk_error (Pipe_Error);
+      return GPGME_Pipe_Error;
     }
   if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg)
       || _gpgme_io_set_close_notify (gpg->colon.fd[1],
                                     close_notify_handler, gpg))
-    return mk_error (General_Error);
+    return GPGME_General_Error;
   gpg->colon.eof = 0;
   gpg->colon.fnc = fnc;
   gpg->colon.fnc_value = fnc_value;
@@ -476,9 +437,10 @@ gpg_set_colon_line_handler (void *engine, GpgmeColonLineHandler fnc,
 
 /* Here we handle --command-fd.  This works closely together with the
    status handler.  */
-static int
+static gpgme_error_t
 command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
 {
+  gpgme_error_t err;
   GpgObject gpg = opaque;
   const char *value;
   int value_len;
@@ -500,12 +462,16 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
       return -1;
     }
 
-  value = gpg->cmd.fnc (gpg->cmd.fnc_value, 
-                       gpg->cmd.code, gpg->cmd.keyword);
+  /* FIXME catch error */
+  err = gpg->cmd.fnc (gpg->cmd.fnc_value, 
+                     gpg->cmd.code, gpg->cmd.keyword, &value);
+  if (err)
+    return err;
+
   if (!value)
     {
       DEBUG0 ("command_cb: no data from user cb\n");
-      gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
+      gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
       return -1;
     }
 
@@ -513,7 +479,7 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
   if (value_len + 1 > length)
     {
       DEBUG0 ("command_cb: too much data from user cb\n");
-      gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
+      gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
       return -1;
     }
 
@@ -522,7 +488,7 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
     buffer[value_len++] = '\n';
   *nread = value_len;
     
-  gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
+  gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value, &value);
   gpg->cmd.code = 0;
   /* And sleep again until read_status will wake us up again.  */
   /* XXX We must check if there are any more fds active after removing
@@ -540,13 +506,13 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
    resources associated with the returned value from another call.  To
    match such a second call to a first call, the returned value from
    the first call is passed as keyword.  */
-static GpgmeError
-gpg_set_command_handler (void *engine, GpgmeCommandHandler fnc,
-                        void *fnc_value, GpgmeData linked_data)
+static gpgme_error_t
+gpg_set_command_handler (void *engine, EngineCommandHandler fnc,
+                        void *fnc_value, gpgme_data_t linked_data)
 {
   GpgObject gpg = engine;
-  GpgmeData tmp;
-  GpgmeError err;
+  gpgme_data_t tmp;
+  gpgme_error_t err;
 
   err = gpgme_data_new_with_read_cb (&tmp, command_cb, gpg);
   if (err)
@@ -563,7 +529,7 @@ gpg_set_command_handler (void *engine, GpgmeCommandHandler fnc,
 }
 
 
-static GpgmeError
+static gpgme_error_t
 build_argv (GpgObject gpg)
 {
   struct arg_and_data_s *a;
@@ -617,12 +583,12 @@ build_argv (GpgObject gpg)
 
   argv = calloc (argc + 1, sizeof *argv);
   if (!argv)
-    return mk_error (Out_Of_Core);
+    return GPGME_Out_Of_Core;
   fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
   if (!fd_data_map)
     {
       free_argv (argv);
-      return mk_error (Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
 
   argc = datac = 0;
@@ -631,7 +597,7 @@ build_argv (GpgObject gpg)
     {
       free (fd_data_map);
       free_argv (argv);
-      return mk_error (Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
   argc++;
   if (need_special)
@@ -641,7 +607,7 @@ build_argv (GpgObject gpg)
        {
          free (fd_data_map);
          free_argv (argv);
-         return mk_error (Out_Of_Core);
+         return GPGME_Out_Of_Core;
         }
       argc++;
     }
@@ -652,7 +618,7 @@ build_argv (GpgObject gpg)
        {
          free (fd_data_map);
          free_argv (argv);
-         return mk_error (Out_Of_Core);
+         return GPGME_Out_Of_Core;
         }
       argc++;
     }
@@ -663,7 +629,7 @@ build_argv (GpgObject gpg)
        {
          free (fd_data_map);
          free_argv (argv);
-         return mk_error (Out_Of_Core);
+         return GPGME_Out_Of_Core;
         }
       argc++;
     }
@@ -672,7 +638,7 @@ build_argv (GpgObject gpg)
     {
       free (fd_data_map);
       free_argv (argv);
-      return mk_error (Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
   argc++;
   argv[argc] = strdup ("");
@@ -680,7 +646,7 @@ build_argv (GpgObject gpg)
     {
       free (fd_data_map);
       free_argv (argv);
-      return mk_error (Out_Of_Core);
+      return GPGME_Out_Of_Core;
     }
   argc++;
   for (a = gpg->arglist; a; a = a->next)
@@ -699,7 +665,7 @@ build_argv (GpgObject gpg)
              {
                free (fd_data_map);
                free_argv (argv);
-               return mk_error (Pipe_Error);
+               return GPGME_Pipe_Error;
              }
            if (_gpgme_io_set_close_notify (fds[0],
                                            close_notify_handler, gpg)
@@ -707,7 +673,7 @@ build_argv (GpgObject gpg)
                                               close_notify_handler,
                                               gpg))
              {
-               return mk_error (General_Error);
+               return GPGME_General_Error;
              }
            /* If the data_type is FD, we have to do a dup2 here.  */
            if (fd_data_map[datac].inbound)
@@ -746,7 +712,7 @@ build_argv (GpgObject gpg)
                {
                  free (fd_data_map);
                  free_argv (argv);
-                 return mk_error (Out_Of_Core);
+                 return GPGME_Out_Of_Core;
                 }
              sprintf (argv[argc], 
                       a->print_fd ? "%d" : "-&%d",
@@ -762,7 +728,7 @@ build_argv (GpgObject gpg)
            {
              free (fd_data_map);
              free_argv (argv);
-             return mk_error (Out_Of_Core);
+             return GPGME_Out_Of_Core;
             }
             argc++;
         }
@@ -774,11 +740,11 @@ build_argv (GpgObject gpg)
 }
 
 
-static GpgmeError
-add_io_cb (GpgObject gpg, int fd, int dir, GpgmeIOCb handler, void *data,
+static gpgme_error_t
+add_io_cb (GpgObject gpg, int fd, int dir, gpgme_io_cb_t handler, void *data,
           void **tag)
 {
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
   if (err)
@@ -807,7 +773,7 @@ status_cmp (const void *ap, const void *bp)
    e.g. with a large user ID.  Note: We can optimize this to only cope
    with status line code we know about and skip all other stuff
    without buffering (i.e. without extending the buffer).  */
-static GpgmeError
+static gpgme_error_t
 read_status (GpgObject gpg)
 {
   char *p;
@@ -823,19 +789,24 @@ read_status (GpgObject gpg)
       bufsize += 1024;
       buffer = realloc (buffer, bufsize);
       if (!buffer)
-       return mk_error (Out_Of_Core);
+       return GPGME_Out_Of_Core;
     }
 
   nread = _gpgme_io_read (gpg->status.fd[0],
                          buffer + readpos, bufsize-readpos);
   if (nread == -1)
-    return mk_error(Read_Error);
+    return GPGME_Read_Error;
 
   if (!nread)
     {
       gpg->status.eof = 1;
       if (gpg->status.fnc)
-       gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
+       {
+         gpgme_error_t err;
+         err = gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
+         if (err)
+           return err;
+       }
       return 0;
     }
 
@@ -874,7 +845,7 @@ read_status (GpgObject gpg)
                          free (gpg->cmd.keyword);
                          gpg->cmd.keyword = strdup (rest);
                          if (!gpg->cmd.keyword)
-                           return mk_error (Out_Of_Core);
+                           return GPGME_Out_Of_Core;
                          /* This should be the last thing we have
                             received and the next thing will be that
                             the command handler does its action.  */
@@ -913,8 +884,11 @@ read_status (GpgObject gpg)
                         }
                      else if (gpg->status.fnc)
                        {
-                         gpg->status.fnc (gpg->status.fnc_value, 
-                                          r->code, rest);
+                         gpgme_error_t err;
+                         err = gpg->status.fnc (gpg->status.fnc_value, 
+                                                r->code, rest);
+                         if (err)
+                           return err;
                         }
                     
                      if (r->code == GPGME_STATUS_END_STREAM)
@@ -957,7 +931,7 @@ read_status (GpgObject gpg)
 }
 
 
-static void
+static gpgme_error_t
 status_handler (void *opaque, int fd)
 {
   GpgObject gpg = opaque;
@@ -966,21 +940,14 @@ status_handler (void *opaque, int fd)
   assert (fd == gpg->status.fd[0]);
   err = read_status (gpg);
   if (err)
-    {
-      /* XXX Horrible kludge.  We really must not make use of
-        fnc_value.  */
-      GpgmeCtx ctx = (GpgmeCtx) gpg->status.fnc_value;
-      ctx->error = err;
-      DEBUG1 ("gpg_handler: read_status problem %d\n - stop", err);
-      _gpgme_io_close (fd);
-      return;
-    }
+    return err;
   if (gpg->status.eof)
     _gpgme_io_close (fd);
+  return 0;
 }
 
 
-static GpgmeError
+static gpgme_error_t
 read_colon_line (GpgObject gpg)
 {
   char *p;
@@ -996,12 +963,12 @@ read_colon_line (GpgObject gpg)
       bufsize += 1024;
       buffer = realloc (buffer, bufsize);
       if (!buffer) 
-       return mk_error (Out_Of_Core);
+       return GPGME_Out_Of_Core;
     }
 
   nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
   if (nread == -1)
-    return mk_error (Read_Error);
+    return GPGME_Read_Error;
 
   if (!nread)
     {
@@ -1055,48 +1022,43 @@ read_colon_line (GpgObject gpg)
 
 
 /* This colonline handler thing is not the clean way to do it.  It
-   might be better to enhance the GpgmeData object to act as a wrapper
+   might be better to enhance the gpgme_data_t object to act as a wrapper
    for a callback.  Same goes for the status thing.  For now we use
    this thing here because it is easier to implement.  */
-static void
+static gpgme_error_t
 colon_line_handler (void *opaque, int fd)
 {
   GpgObject gpg = opaque;
-  GpgmeError rc = 0;
+  gpgme_error_t rc = 0;
 
   assert (fd == gpg->colon.fd[0]);
   rc = read_colon_line (gpg);
   if (rc)
-    {
-      DEBUG1 ("gpg_colon_line_handler: "
-             "read problem %d\n - stop", rc);
-      _gpgme_io_close (fd);
-      return;
-    }
+    return rc;
   if (gpg->colon.eof)
     _gpgme_io_close (fd);
+  return 0;
 }
 
 
-static GpgmeError
-gpg_start (void *engine, void *opaque)
+static gpgme_error_t
+start (GpgObject gpg)
 {
-  GpgObject gpg = engine;
-  GpgmeError rc;
+  gpgme_error_t rc;
   int i, n;
   int status;
   struct spawn_fd_item_s *fd_child_list, *fd_parent_list;
 
   if (!gpg)
-    return mk_error (Invalid_Value);
+    return GPGME_Invalid_Value;
 
   if (! _gpgme_get_gpg_path ())
-    return mk_error (Invalid_Engine);
+    return GPGME_Invalid_Engine;
 
   /* Kludge, so that we don't need to check the return code of all the
      add_arg ().  We bail out here instead.  */
   if (gpg->arg_error)
-    return mk_error (Out_Of_Core);
+    return GPGME_Out_Of_Core;
 
   rc = build_argv (gpg);
   if (rc)
@@ -1107,7 +1069,7 @@ gpg_start (void *engine, void *opaque)
     n++;
   fd_child_list = calloc (n + n, sizeof *fd_child_list);
   if (!fd_child_list)
-    return mk_error (Out_Of_Core);
+    return GPGME_Out_Of_Core;
   fd_parent_list = fd_child_list + n;
 
   /* build the fd list for the child */
@@ -1137,21 +1099,18 @@ gpg_start (void *engine, void *opaque)
       fd_parent_list[n].fd = gpg->status.fd[1];
       fd_parent_list[n].dup_to = -1;
       n++;
-      gpg->status.fd[1] = -1;
     }
   if (gpg->colon.fd[1] != -1)
     {
       fd_parent_list[n].fd = gpg->colon.fd[1];
       fd_parent_list[n].dup_to = -1;
       n++;
-      gpg->colon.fd[1] = -1;
     }
   for (i = 0; gpg->fd_data_map[i].data; i++)
     {
       fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd;
       fd_parent_list[n].dup_to = -1;
       n++;
-      gpg->fd_data_map[i].peer_fd = -1;
     }        
   fd_parent_list[n].fd = -1;
   fd_parent_list[n].dup_to = -1;
@@ -1160,7 +1119,7 @@ gpg_start (void *engine, void *opaque)
                            gpg->argv, fd_child_list, fd_parent_list);
   free (fd_child_list);
   if (status == -1)
-    return mk_error (Exec_Error);
+    return GPGME_Exec_Error;
 
   /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
 
@@ -1202,17 +1161,19 @@ gpg_start (void *engine, void *opaque)
            return rc;
        }
     }
+
+  (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_START, NULL);
   
   /* fixme: check what data we can release here */
   return 0;
 }
 
 
-static GpgmeError
-gpg_decrypt (void *engine, GpgmeData ciph, GpgmeData plain)
+static gpgme_error_t
+gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--decrypt");
 
@@ -1226,14 +1187,16 @@ gpg_decrypt (void *engine, GpgmeData ciph, GpgmeData plain)
   if (!err)
     err = add_data (gpg, ciph, 0, 0);
 
+  if (!err)
+    start (gpg);
   return err;
 }
 
-static GpgmeError
-gpg_delete (void *engine, GpgmeKey key, int allow_secret)
+static gpgme_error_t
+gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
                 : "--delete-key");
@@ -1241,28 +1204,28 @@ gpg_delete (void *engine, GpgmeKey key, int allow_secret)
     err = add_arg (gpg, "--");
   if (!err)
     {
-      const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
-      if (!s)
-       err = mk_error (Invalid_Key);
+      if (!key->subkeys || !key->subkeys->fpr)
+       err = GPGME_Invalid_Key;
       else
-       err = add_arg (gpg, s);
+       err = add_arg (gpg, key->subkeys->fpr);
     }
 
+  if (!err)
+    start (gpg);
   return err;
 }
 
 
-static GpgmeError
-append_args_from_signers (GpgObject gpg, GpgmeCtx ctx /* FIXME */)
+static gpgme_error_t
+append_args_from_signers (GpgObject gpg, gpgme_ctx_t ctx /* FIXME */)
 {
-  GpgmeError err = 0;
+  gpgme_error_t err = 0;
   int i;
-  GpgmeKey key;
+  gpgme_key_t key;
 
   for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
     {
-      const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID,
-                                                NULL, 0);
+      const char *s = key->subkeys ? key->subkeys->keyid : NULL;
       if (s)
        {
          if (!err)
@@ -1277,11 +1240,12 @@ append_args_from_signers (GpgObject gpg, GpgmeCtx ctx /* FIXME */)
 }
 
 
-static GpgmeError
-gpg_edit (void *engine, GpgmeKey key, GpgmeData out, GpgmeCtx ctx /* FIXME */)
+static gpgme_error_t
+gpg_edit (void *engine, gpgme_key_t key, gpgme_data_t out,
+         gpgme_ctx_t ctx /* FIXME */)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--with-colons");
   if (!err)
@@ -1294,29 +1258,31 @@ gpg_edit (void *engine, GpgmeKey key, GpgmeData out, GpgmeCtx ctx /* FIXME */)
     err = add_arg (gpg, "--");
   if (!err)
     {
-      const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
+      const char *s = key->subkeys ? key->subkeys->fpr : NULL;
       if (!s)
-       err = mk_error (Invalid_Key);
+       err = GPGME_Invalid_Key;
       else
        err = add_arg (gpg, s);
     }
+  if (!err)
+    err = start (gpg);
 
   return err;
 }
 
 
-static GpgmeError
-append_args_from_recipients (GpgObject gpg, const GpgmeRecipients rset)
+static gpgme_error_t
+append_args_from_recipients (GpgObject gpg, const gpgme_recipients_t rset)
 {
-  GpgmeError err = 0;
-  struct user_id_s *r;
+  gpgme_error_t err = 0;
+  gpgme_user_id_t uid;
 
   assert (rset);
-  for (r = rset->list; r; r = r->next)
+  for (uid = rset->list; uid; uid = uid->next)
     {
       err = add_arg (gpg, "-r");
       if (!err)
-       err = add_arg (gpg, r->name);
+       err = add_arg (gpg, uid->uid);
       if (err)
        break;
     }    
@@ -1324,12 +1290,12 @@ append_args_from_recipients (GpgObject gpg, const GpgmeRecipients rset)
 }
 
 
-static GpgmeError
-gpg_encrypt (void *engine, GpgmeRecipients recp, GpgmeData plain,
-            GpgmeData ciph, int use_armor)
+static gpgme_error_t
+gpg_encrypt (void *engine, gpgme_recipients_t recp, gpgme_data_t plain,
+            gpgme_data_t ciph, int use_armor)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
   int symmetric = !recp;
 
   err = add_arg (gpg, symmetric ? "--symmetric" : "--encrypt");
@@ -1360,15 +1326,20 @@ gpg_encrypt (void *engine, GpgmeRecipients recp, GpgmeData plain,
   if (!err)
     err = add_data (gpg, plain, 0, 0);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
-static GpgmeError
-gpg_encrypt_sign (void *engine, GpgmeRecipients recp, GpgmeData plain,
-                 GpgmeData ciph, int use_armor, GpgmeCtx ctx /* FIXME */)
+
+static gpgme_error_t
+gpg_encrypt_sign (void *engine, gpgme_recipients_t recp, gpgme_data_t plain,
+                 gpgme_data_t ciph, int use_armor,
+                 gpgme_ctx_t ctx /* FIXME */)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--encrypt");
   if (!err)
@@ -1399,15 +1370,19 @@ gpg_encrypt_sign (void *engine, GpgmeRecipients recp, GpgmeData plain,
   if (!err)
     err = add_data (gpg, plain, 0, 0);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
-static GpgmeError
-gpg_export (void *engine, GpgmeRecipients recp, GpgmeData keydata,
+
+static gpgme_error_t
+gpg_export (void *engine, gpgme_recipients_t recp, gpgme_data_t keydata,
            int use_armor)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--export");
   if (!err && use_armor)
@@ -1429,26 +1404,29 @@ gpg_export (void *engine, GpgmeRecipients recp, GpgmeData keydata,
        err = gpgme_recipients_enum_close (recp, &ec);
     }
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
-gpg_genkey (void *engine, GpgmeData help_data, int use_armor,
-           GpgmeData pubkey, GpgmeData seckey)
+static gpgme_error_t
+gpg_genkey (void *engine, gpgme_data_t help_data, int use_armor,
+           gpgme_data_t pubkey, gpgme_data_t seckey)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   if (!gpg)
-    return mk_error (Invalid_Value);
+    return GPGME_Invalid_Value;
 
   /* We need a special mechanism to get the fd of a pipe here, so that
      we can use this for the %pubring and %secring parameters.  We
      don't have this yet, so we implement only the adding to the
      standard keyrings.  */
   if (pubkey || seckey)
-    return err = mk_error (Not_Implemented);
+    return err = GPGME_Not_Implemented;
 
   err = add_arg (gpg, "--gen-key");
   if (!err && use_armor)
@@ -1456,30 +1434,36 @@ gpg_genkey (void *engine, GpgmeData help_data, int use_armor,
   if (!err)
     err = add_data (gpg, help_data, 0, 0);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
-gpg_import (void *engine, GpgmeData keydata)
+static gpgme_error_t
+gpg_import (void *engine, gpgme_data_t keydata)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--import");
   if (!err)
     err = add_data (gpg, keydata, 0, 0);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
+static gpgme_error_t
 gpg_keylist (void *engine, const char *pattern, int secret_only,
             int keylist_mode)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--with-colons");
   if (!err)
@@ -1489,10 +1473,9 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
   if (!err)
     err = add_arg (gpg, "--with-fingerprint");
   if (!err)
-    err = add_arg (gpg, (keylist_mode & GPGME_KEYLIST_MODE_SIGS) ?
-                  "--check-sigs" :
-                  secret_only ? "--list-secret-keys"
-                  : "--list-keys");
+    err = add_arg (gpg, secret_only ? "--list-secret-keys"
+                  : ((keylist_mode & GPGME_KEYLIST_MODE_SIGS)
+                     ? "--check-sigs" : "--list-keys"));
   
   /* Tell the gpg object about the data.  */
   if (!err)
@@ -1500,19 +1483,22 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
   if (!err && pattern && *pattern)
     err = add_arg (gpg, pattern);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
+static gpgme_error_t
 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
                 int reserved, int keylist_mode)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   if (reserved)
-    return mk_error (Invalid_Value);
+    return GPGME_Invalid_Value;
 
   err = add_arg (gpg, "--with-colons");
   if (!err)
@@ -1522,8 +1508,10 @@ gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
   if (!err)
     err = add_arg (gpg, "--with-fingerprint");
   if (!err)
-    err = add_arg (gpg, secret_only ? "--list-secret-keys" : "--list-keys");
-  
+    err = add_arg (gpg, secret_only ? "--list-secret-keys"
+                  : ((keylist_mode & GPGME_KEYLIST_MODE_SIGS)
+                     ? "--check-sigs" : "--list-keys"));
+
   /* Tell the gpg object about the data.  */
   if (!err)
     err = add_arg (gpg, "--");
@@ -1533,17 +1521,20 @@ gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
        err = add_arg (gpg, *(pattern++));
     }
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
-gpg_sign (void *engine, GpgmeData in, GpgmeData out, GpgmeSigMode mode,
-         int use_armor, int use_textmode, int include_certs,
-         GpgmeCtx ctx /* FIXME */)
+static gpgme_error_t
+gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
+         gpgme_sig_mode_t mode, int use_armor, int use_textmode,
+         int include_certs, gpgme_ctx_t ctx /* FIXME */)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   if (mode == GPGME_SIG_MODE_CLEAR)
     err = add_arg (gpg, "--clearsign");
@@ -1567,14 +1558,17 @@ gpg_sign (void *engine, GpgmeData in, GpgmeData out, GpgmeSigMode mode,
   if (!err)
     err = add_data (gpg, out, 1, 1);
 
+  if (!err)
+    start (gpg);
+
   return err;
 }
 
-static GpgmeError
+static gpgme_error_t
 gpg_trustlist (void *engine, const char *pattern)
 {
   GpgObject gpg = engine;
-  GpgmeError err;
+  gpgme_error_t err;
 
   err = add_arg (gpg, "--with-colons");
   if (!err)
@@ -1586,16 +1580,19 @@ gpg_trustlist (void *engine, const char *pattern)
   if (!err)
     err = add_arg (gpg, pattern);
 
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
-static GpgmeError
-gpg_verify (void *engine, GpgmeData sig, GpgmeData signed_text,
-           GpgmeData plaintext)
+static gpgme_error_t
+gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
+           gpgme_data_t plaintext)
 {
   GpgObject gpg = engine;
-  GpgmeError err = 0;
+  gpgme_error_t err = 0;
 
   if (plaintext)
     {
@@ -1626,12 +1623,16 @@ gpg_verify (void *engine, GpgmeData sig, GpgmeData signed_text,
            err = add_data (gpg, signed_text, 0, 0);
        }
     }
+
+  if (!err)
+    err = start (gpg);
+
   return err;
 }
 
 
 static void
-gpg_set_io_cbs (void *engine, struct GpgmeIOCbs *io_cbs)
+gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
 {
   GpgObject gpg = engine;
 
@@ -1644,7 +1645,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
     /* Static functions.  */
     _gpgme_get_gpg_path,
     gpg_get_version,
-    gpg_check_version,
+    gpg_get_req_version,
     gpg_new,
 
     /* Member functions.  */
@@ -1652,7 +1653,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
     gpg_set_status_handler,
     gpg_set_command_handler,
     gpg_set_colon_line_handler,
-    gpg_set_verbosity,
     gpg_decrypt,
     gpg_delete,
     gpg_edit,
@@ -1666,7 +1666,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
     gpg_sign,
     gpg_trustlist,
     gpg_verify,
-    gpg_start,
     gpg_set_io_cbs,
     gpg_io_event
   };