2003-01-30 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / trustlist.c
index 11acbf5..8dbc9f5 100644 (file)
@@ -1,25 +1,26 @@
-/* trustlist.c -  key listing
*     Copyright (C) 2000 Werner Koch (dd9jn)
*      Copyright (C) 2001, 2002 g10 Code GmbH
- *
* This file is part of GPGME.
- *
- * GPGME is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
- * GPGME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
- *
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
+/* trustlist.c - Trust item listing.
+   Copyright (C) 2000 Werner Koch (dd9jn)
  Copyright (C) 2001, 2002, 2003 g10 Code GmbH
+
  This file is part of GPGME.
+   GPGME is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
+   GPGME is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  You should have received a copy of the GNU General Public License
+   along with GPGME; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if HAVE_CONFIG_H
 #include <config.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -46,53 +47,46 @@ trust_item_new (void)
 {
   GpgmeTrustItem item;
 
-  item = xtrycalloc (1, sizeof *item);
+  item = calloc (1, sizeof *item);
   return item;
 }
 
 
-static void
-trustlist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+static GpgmeError
+trustlist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
 {
-  if (ctx->out_of_core)
-    return;
-
   switch (code)
     {
-    case STATUS_EOF:
+    case GPGME_STATUS_EOF:
       break;
 
     default:
       break;
     }
+  return 0;
 }
 
 
-/* 
- * This handler is used to parse the output of --list-trust-path:
- * Format:
- *   level:keyid:type:recno:ot:val:mc:cc:name:
- * With TYPE = U for a user ID
- *            K for a key
- * The RECNO is either the one of the dir record or the one of the uid record.
- * OT is the the usual trust letter and only availabel on K lines.
- * VAL is the calcualted validity
- * MC is the marginal trust counter and only available on U lines
- * CC is the same for the complete count
- * NAME ist the username and only printed on U lines
- */
-static void
+/* This handler is used to parse the output of --list-trust-path:
+   Format:
+   level:keyid:type:recno:ot:val:mc:cc:name:
+   With TYPE = U for a user ID
+               K for a key
+   The RECNO is either the one of the dir record or the one of the uid
+   record.  OT is the the usual trust letter and only availabel on K
+   lines.  VAL is the calcualted validity MC is the marginal trust
+   counter and only available on U lines CC is the same for the
+   complete count NAME ist the username and only printed on U
+   lines.  */
+static GpgmeError
 trustlist_colon_handler (GpgmeCtx ctx, char *line)
 {
   char *p, *pend;
   int field = 0;
   GpgmeTrustItem item = NULL;
-  struct trust_queue_item_s *q, *q2;
 
-  if (ctx->out_of_core)
-    return;
   if (!line)
-    return; /* EOF */
+    return 0; /* EOF */
 
   for (p = line; p; p = pend)
     {
@@ -104,31 +98,9 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line)
       switch (field)
        {
        case 1: /* level */
-         q = xtrymalloc (sizeof *q);
-         if (!q)
-           {
-             ctx->out_of_core = 1;
-             return;
-            }
-         q->next = NULL;
-         q->item = item = trust_item_new ();
-         if (!q->item)
-           {
-             xfree (q);
-             ctx->out_of_core = 1;
-             return;
-            }
-         /* fixme: lock queue, keep a tail pointer */
-         q2 = ctx->trust_queue;
-         if (!q2)
-           ctx->trust_queue = q;
-         else
-           {
-             while (q2->next)
-               q2 = q2->next;
-             q2->next = q;
-            }
-         /* fixme: unlock queue */
+         item = trust_item_new ();
+         if (!item)
+           return GPGME_Out_Of_Core;
          item->level = atoi (p);
          break;
        case 2: /* long keyid */
@@ -147,15 +119,50 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line)
          item->val[1] = 0;
          break;
        case 9: /* user ID */
-         item->name = xtrystrdup (p);
+         item->name = strdup (p);
          if (!item->name)
-           ctx->out_of_core = 1;
+           return GPGME_Out_Of_Core;
          break;
         }
     }
 
-  if (field)
-    ctx->key_cond = 1;
+  if (item)
+    _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item);
+  return 0;
+}
+
+
+void
+_gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data)
+{
+  GpgmeCtx ctx = (GpgmeCtx) data;
+  GpgmeTrustItem item = (GpgmeTrustItem) type_data;
+  struct trust_queue_item_s *q, *q2;
+
+  assert (type == GPGME_EVENT_NEXT_TRUSTITEM);
+
+  q = malloc (sizeof *q);
+  if (!q)
+    {
+      gpgme_trust_item_release (item);
+      /* FIXME */
+      /* ctx->error = GPGME_Out_Of_Core; */
+      return;
+    }
+  q->item = item;
+  q->next = NULL;
+  /* FIXME: lock queue, keep a tail pointer */
+  q2 = ctx->trust_queue;
+  if (!q2)
+    ctx->trust_queue = q;
+  else
+    {
+      while (q2->next)
+       q2 = q2->next;
+      q2->next = q;
+    }
+  /* FIXME: unlock queue */
+  ctx->key_cond = 1;
 }
 
 
@@ -164,27 +171,15 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
 {
   GpgmeError err = 0;
 
-  fail_on_pending_request (ctx);
   if (!pattern || !*pattern)
-    return mk_error (Invalid_Value);
-
-  ctx->pending = 1;
-
-  _gpgme_release_result (ctx);
-  ctx->out_of_core = 0;
-
-  if (ctx->engine)
-    {
-      _gpgme_engine_release (ctx->engine); 
-      ctx->engine = NULL;
-    }
+    return GPGME_Invalid_Value;
 
-  err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
-                          : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
+  err = _gpgme_op_reset (ctx, 2);
   if (err)
     goto leave;
 
-  _gpgme_engine_set_status_handler (ctx->engine, trustlist_status_handler, ctx);
+  _gpgme_engine_set_status_handler (ctx->engine,
+                                   trustlist_status_handler, ctx);
   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
                                              trustlist_colon_handler, ctx);
   if (err)
@@ -192,9 +187,6 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
 
   err =_gpgme_engine_op_trustlist (ctx->engine, pattern);
 
-  if (!err)    /* And kick off the process.  */
-    err = _gpgme_engine_start (ctx->engine, ctx);
-
  leave:
   if (err)
     {
@@ -207,35 +199,48 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
 
 
 GpgmeError
-gpgme_op_trustlist_next (GpgmeCtx c, GpgmeTrustItem *r_item)
+gpgme_op_trustlist_next (GpgmeCtx ctx, GpgmeTrustItem *r_item)
 {
   struct trust_queue_item_s *q;
 
   if (!r_item)
-    return mk_error (Invalid_Value);
+    return GPGME_Invalid_Value;
   *r_item = NULL;
-  if (!c)
-    return mk_error (Invalid_Value);
-  if (!c->pending)
-    return mk_error (No_Request);
-  if (c->out_of_core)
-    return mk_error (Out_Of_Core);
-
-  if (!c->trust_queue)
+  if (!ctx)
+    return GPGME_Invalid_Value;
+  if (!ctx->pending)
+    return GPGME_No_Request;
+
+  if (!ctx->trust_queue)
     {
-      _gpgme_wait_on_condition (c, 1, &c->key_cond);
-      if (c->out_of_core)
-       return mk_error (Out_Of_Core);
-      if (!c->key_cond)
-       return mk_error (EOF);
-      c->key_cond = 0; 
-      assert (c->trust_queue);
+      GpgmeError err = _gpgme_wait_on_condition (ctx, &ctx->key_cond);
+      if (err)
+       {
+         ctx->pending = 0;
+         return err;
+       }
+      if (!ctx->pending)
+       {
+         /* The operation finished.  Because not all keys might have
+            been returned to the caller yet, we just reset the
+            pending flag to 1.  This will cause us to call
+            _gpgme_wait_on_condition without any active file
+            descriptors, but that is a no-op, so it is safe.  */
+         ctx->pending = 1;
+       }
+      if (!ctx->key_cond)
+       {
+         ctx->pending = 0;
+         return GPGME_EOF;
+       }
+      ctx->key_cond = 0; 
+      assert (ctx->trust_queue);
     }
-  q = c->trust_queue;
-  c->trust_queue = q->next;
+  q = ctx->trust_queue;
+  ctx->trust_queue = q->next;
 
   *r_item = q->item;
-  xfree (q);
+  free (q);
   return 0;
 }
 
@@ -251,11 +256,9 @@ GpgmeError
 gpgme_op_trustlist_end (GpgmeCtx ctx)
 {
   if (!ctx)
-    return mk_error (Invalid_Value);
+    return GPGME_Invalid_Value;
   if (!ctx->pending)
-    return mk_error (No_Request);
-  if (ctx->out_of_core)
-    return mk_error (Out_Of_Core);
+    return GPGME_No_Request;
 
   ctx->pending = 0;
   return 0;
@@ -267,8 +270,8 @@ gpgme_trust_item_release (GpgmeTrustItem item)
 {
   if (!item)
     return;
-  xfree (item->name);
-  xfree (item);
+  free (item->name);
+  free (item);
 }
 
 
@@ -332,4 +335,3 @@ gpgme_trust_item_get_int_attr (GpgmeTrustItem item, GpgmeAttr what,
     }
   return val;
 }
-