2010-05-07 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / src / engine-g13.c
index f957691..8b2af4d 100644 (file)
@@ -28,7 +28,9 @@
 #include <sys/types.h>
 #include <assert.h>
 #include <unistd.h>
+#ifdef HAVE_LOCALE_H
 #include <locale.h>
+#endif
 #include <fcntl.h> /* FIXME */
 #include <errno.h>
 
@@ -69,10 +71,6 @@ struct engine_g13
 
   struct gpgme_io_cbs io_cbs;
 
-  /* Internal callbacks.  */
-  engine_assuan_result_cb_t result_cb;
-  void *result_cb_value; 
-
   /* User provided callbacks.  */
   struct {
     gpgme_assuan_data_cb_t data_cb;
@@ -180,6 +178,21 @@ g13_cancel (void *engine)
 }
 
 
+static gpgme_error_t
+g13_cancel_op (void *engine)
+{
+  engine_g13_t g13 = engine;
+
+  if (!g13)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (g13->status_cb.fd != -1)
+    _gpgme_io_close (g13->status_cb.fd);
+
+  return 0;
+}
+
+
 static void
 g13_release (void *engine)
 {
@@ -200,7 +213,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
   gpgme_error_t err = 0;
   engine_g13_t g13;
   int argc;
-  char *argv[5];
+  const char *argv[5];
   char *dft_display = NULL;
   char dft_ttyname[64];
   char *dft_ttytype = NULL;
@@ -215,10 +228,6 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
   g13->status_cb.tag = 0;
   g13->status_cb.data = g13;
 
-  err = assuan_new (&g13->assuan_ctx);
-  if (err)
-    goto leave;
-
   argc = 0;
   argv[argc++] = "g13";
   if (home_dir)
@@ -237,13 +246,13 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
   assuan_ctx_set_system_hooks (g13->assuan_ctx, &_gpgme_assuan_system_hooks);
 
 #if USE_DESCRIPTOR_PASSING
-  err = assuan_pipe_connect_ext
+  err = assuan_pipe_connect
     (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (),
-     argv, NULL, NULL, NULL, 1);
+     argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
 #else
   err = assuan_pipe_connect
     (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (),
-     argv, NULL);
+     argv, NULL, NULL, NULL, 0);
 #endif
   if (err)
     goto leave;
@@ -347,7 +356,10 @@ g13_set_locale (void *engine, int category, const char *value)
   /* FIXME: If value is NULL, we need to reset the option to default.
      But we can't do this.  So we error out here.  G13 needs support
      for this.  */
-  if (category == LC_CTYPE)
+  if (0)
+    ;
+#ifdef LC_CTYPE
+  else if (category == LC_CTYPE)
     {
       catstr = "lc-ctype";
       if (!value && g13->lc_ctype_set)
@@ -355,6 +367,7 @@ g13_set_locale (void *engine, int category, const char *value)
       if (value)
        g13->lc_ctype_set = 1;
     }
+#endif
 #ifdef LC_MESSAGES
   else if (category == LC_MESSAGES)
     {
@@ -385,13 +398,11 @@ g13_set_locale (void *engine, int category, const char *value)
 }
 
 
-/* Forward declaration.  */
-static gpgme_status_code_t parse_status (const char *name);
-
+#if USE_DESCRIPTOR_PASSING
 static gpgme_error_t
 g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
-                            engine_status_handler_t status_fnc,
-                            void *status_fnc_value)
+                          engine_status_handler_t status_fnc,
+                          void *status_fnc_value)
 {
   gpg_error_t err;
   char *line;
@@ -422,7 +433,6 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
               && line[0] == 'S' && line[1] == ' ')
        {
          char *rest;
-         gpgme_status_code_t r;
 
          rest = strchr (line + 2, ' ');
          if (!rest)
@@ -430,12 +440,7 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
          else
            *(rest++) = 0;
 
-         r = parse_status (line + 2);
-
-         if (r >= 0 && status_fnc)
-           err = status_fnc (status_fnc_value, r, rest);
-         else
-           err = gpg_error (GPG_ERR_GENERAL);
+         /* Nothing to do with status lines.  */
        }
       else
        err = gpg_error (GPG_ERR_GENERAL);
@@ -444,13 +449,15 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
 
   return err;
 }
+#endif
 
 
 static gpgme_error_t
 status_handler (void *opaque, int fd)
 {
+  struct io_cb_data *data = (struct io_cb_data *) opaque;
+  engine_g13_t g13 = (engine_g13_t) data->handler_value;
   gpgme_error_t err = 0;
-  engine_g13_t g13 = opaque;
   char *line;
   size_t linelen;
 
@@ -477,17 +484,13 @@ status_handler (void *opaque, int fd)
                  "fd 0x%x: ERR line: %s",
                   fd, err ? gpg_strerror (err) : "ok");
          
-         /* In g13, command execution errors are not fatal, as we use
+         /* Command execution errors are not fatal, as we use
             a session based protocol.  */
-          if (g13->result_cb)
-            err = g13->result_cb (g13->result_cb_value, err);
-          else
-            err = 0;
-          if (!err)
-            {
-              _gpgme_io_close (g13->status_cb.fd);
-              return 0;
-           }
+         data->op_err = err;
+
+         /* The caller will do the rest (namely, call cancel_op,
+            which closes status_fd).  */
+         return 0;
        }
       else if (linelen >= 2
               && line[0] == 'O' && line[1] == 'K'
@@ -495,15 +498,9 @@ status_handler (void *opaque, int fd)
        {
           TRACE1 (DEBUG_CTX, "gpgme:status_handler", g13,
                  "fd 0x%x: OK line", fd);
-          if (g13->result_cb)
-            err = g13->result_cb (g13->result_cb_value, 0);
-          else
-            err = 0;
-         if (!err)
-            {
-              _gpgme_io_close (g13->status_cb.fd);
-              return 0;
-            }
+
+         _gpgme_io_close (g13->status_cb.fd);
+         return 0;
        }
       else if (linelen > 2
               && line[0] == 'D' && line[1] == ' ')
@@ -641,16 +638,21 @@ static gpgme_error_t
 start (engine_g13_t g13, const char *command)
 {
   gpgme_error_t err;
+  assuan_fd_t afdlist[5];
   int fdlist[5];
   int nfds;
+  int i;
 
   /* We need to know the fd used by assuan for reads.  We do this by
      using the assumption that the first returned fd from
      assuan_get_active_fds() is always this one.  */
   nfds = assuan_get_active_fds (g13->assuan_ctx, 0 /* read fds */,
-                                fdlist, DIM (fdlist));
+                                afdlist, DIM (afdlist));
   if (nfds < 1)
     return gpg_error (GPG_ERR_GENERAL);        /* FIXME */
+  /* For now... */
+  for (i = 0; i < nfds; i++)
+    fdlist[i] = (int) afdlist[i];
 
   /* We "duplicate" the file descriptor, so we can close it here (we
      can't close fdlist[0], as that is closed by libassuan, and
@@ -701,8 +703,6 @@ g13_reset (void *engine)
 static gpgme_error_t
 g13_transact (void *engine,
                 const char *command,
-                engine_assuan_result_cb_t result_cb,
-                void *result_cb_value,
                 gpgme_assuan_data_cb_t data_cb,
                 void *data_cb_value,
                 gpgme_assuan_inquire_cb_t inq_cb,
@@ -716,8 +716,6 @@ g13_transact (void *engine,
   if (!g13 || !command || !*command)
     return gpg_error (GPG_ERR_INV_VALUE);
 
-  g13->result_cb = result_cb;
-  g13->result_cb_value = result_cb_value;
   g13->user.data_cb = data_cb;
   g13->user.data_cb_value = data_cb_value;
   g13->user.inq_cb = inq_cb;
@@ -772,7 +770,9 @@ struct engine_ops _gpgme_engine_ops_g13 =
     NULL,              /* set_command_handler */
     NULL,               /* set_colon_line_handler */
     g13_set_locale,
+    NULL,              /* set_protocol */
     NULL,               /* decrypt */
+    NULL,               /* decrypt_verify */
     NULL,               /* delete */
     NULL,              /* edit */
     NULL,               /* encrypt */
@@ -792,5 +792,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
     NULL,              /* conf_save */
     g13_set_io_cbs,
     g13_io_event,
-    g13_cancel
+    g13_cancel,
+    g13_cancel_op,
   };