-fixing #2413
[oweals/gnunet.git] / src / fs / fs_list_indexed.c
index 1a404a078051e25012304084cea09f547fed47d0..ef03dee760bad2d0ab619dcaab4a91f771dde945 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet 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, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include "gnunet_constants.h"
 #include "gnunet_fs_service.h"
 #include "gnunet_protocols.h"
 #include "gnunet_constants.h"
 #include "gnunet_fs_service.h"
 #include "gnunet_protocols.h"
-#include "fs.h"
+#include "fs_api.h"
 
 
 /**
  * Context for "GNUNET_FS_get_indexed_files".
  */
 
 
 /**
  * Context for "GNUNET_FS_get_indexed_files".
  */
-struct GetIndexedContext
+struct GNUNET_FS_GetIndexedContext
 {
   /**
    * Handle to global FS context.
 {
   /**
    * Handle to global FS context.
@@ -72,129 +72,58 @@ struct GetIndexedContext
  * Function called on each response from the FS
  * service with information about indexed files.
  *
  * Function called on each response from the FS
  * service with information about indexed files.
  *
- * @param cls closure (of type "struct GetIndexedContext*")
+ * @param cls closure (of type "struct GNUNET_FS_GetIndexedContext*")
  * @param msg message with indexing information
  */
 static void
  * @param msg message with indexing information
  */
 static void
-handle_index_info (void *cls,
-                  const struct GNUNET_MessageHeader *msg)
+handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg)
 {
 {
-  struct GetIndexedContext *gic = cls;
+  struct GNUNET_FS_GetIndexedContext *gic = cls;
   const struct IndexInfoMessage *iim;
   uint16_t msize;
   const char *filename;
 
   if (NULL == msg)
   const struct IndexInfoMessage *iim;
   uint16_t msize;
   const char *filename;
 
   if (NULL == msg)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Failed to receive response for `%s' request from `%s' service.\n"),
-                 "GET_INDEXED",
-                 "fs");
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_TIMEOUT);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return;
-    }
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _
+                ("Failed to receive response for `%s' request from `%s' service.\n"),
+                "GET_INDEXED", "fs");
+    (void) gic->iterator (gic->iterator_cls, NULL, NULL);
+    GNUNET_FS_get_indexed_files_cancel (gic);
+    return;
+  }
   if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END)
   if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END)
-    {
-      /* normal end-of-list */
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return;
-    }
+  {
+    /* normal end-of-list */
+    (void) gic->iterator (gic->iterator_cls, NULL, NULL);
+    GNUNET_FS_get_indexed_files_cancel (gic);
+    return;
+  }
   msize = ntohs (msg->size);
   msize = ntohs (msg->size);
-  iim = (const struct IndexInfoMessage*) msg;
-  filename = (const char*) &iim[1];
-  if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) ||
-       (msize <= sizeof (struct IndexInfoMessage)) ||
-       (filename[msize-sizeof (struct IndexInfoMessage) -1] != '\0') )
-    {
-      /* bogus reply */
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Failed to receive valid response for `%s' request from `%s' service.\n"),
-                 "GET_INDEXED",
-                 "fs");
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_TIMEOUT);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return;
-    }
-  if (GNUNET_OK !=
-      gic->iterator (gic->iterator_cls,
-                    filename,
-                    &iim->file_id))
-    {
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return;
-    }
+  iim = (const struct IndexInfoMessage *) msg;
+  filename = (const char *) &iim[1];
+  if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) ||
+      (msize <= sizeof (struct IndexInfoMessage)) ||
+      (filename[msize - sizeof (struct IndexInfoMessage) - 1] != '\0'))
+  {
+    /* bogus reply */
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _
+                ("Failed to receive valid response for `%s' request from `%s' service.\n"),
+                "GET_INDEXED", "fs");
+    (void) gic->iterator (gic->iterator_cls, NULL, NULL);
+    GNUNET_FS_get_indexed_files_cancel (gic);
+    return;
+  }
+  if (GNUNET_OK != gic->iterator (gic->iterator_cls, filename, &iim->file_id))
+  {
+    GNUNET_FS_get_indexed_files_cancel (gic);
+    return;
+  }
   /* get more */
   /* get more */
-  GNUNET_CLIENT_receive (gic->client,
-                        &handle_index_info,
-                        gic,
-                        GNUNET_CONSTANTS_SERVICE_TIMEOUT);  
-}
-
-
-/**
- * Transmit the request to get a list of all 
- * indexed files to the "FS" service.
- *
- * @param cls closure (of type "struct GetIndexedContext*")
- * @param size number of bytes availabe in buf
- * @param buf where to write the message, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-transmit_get_indexed (void *cls,
-                     size_t size,
-                     void *buf)
-{
-  struct GetIndexedContext *gic = cls;
-  struct GNUNET_MessageHeader *hdr;
-
-  if (NULL == buf)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Failed to transmit `%s' request to `%s' service.\n"),
-                 "GET_INDEXED",
-                 "fs");
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_TIMEOUT);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return 0;
-    }
-  GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
-  hdr = buf;
-  hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
-  hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
-  GNUNET_CLIENT_receive (gic->client,
-                        &handle_index_info,
-                        gic,
-                        GNUNET_CONSTANTS_SERVICE_TIMEOUT);
-  return sizeof (struct GNUNET_MessageHeader);
+  GNUNET_CLIENT_receive (gic->client, &handle_index_info, gic,
+                         GNUNET_CONSTANTS_SERVICE_TIMEOUT);
 }
 
 
 }
 
 
@@ -204,49 +133,52 @@ transmit_get_indexed (void *cls,
  * @param h handle to the file sharing subsystem
  * @param iterator function to call on each indexed file
  * @param iterator_cls closure for iterator
  * @param h handle to the file sharing subsystem
  * @param iterator function to call on each indexed file
  * @param iterator_cls closure for iterator
- * @param cont continuation to call when done;
- *             reason should be "TIMEOUT" (on
- *             error) or  "PREREQ_DONE" (on success)
- * @param cont_cls closure for cont
+ * @return NULL on error ('iter' is not called)
  */
  */
-void 
+struct GNUNET_FS_GetIndexedContext *
 GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
 GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
-                            GNUNET_FS_IndexedFileProcessor iterator,
-                            void *iterator_cls,
-                            GNUNET_SCHEDULER_Task cont,
-                            void *cont_cls)
+                             GNUNET_FS_IndexedFileProcessor iterator,
+                             void *iterator_cls)
 {
   struct GNUNET_CLIENT_Connection *client;
 {
   struct GNUNET_CLIENT_Connection *client;
-  struct GetIndexedContext *gic;
+  struct GNUNET_FS_GetIndexedContext *gic;
+  struct GNUNET_MessageHeader msg;
 
 
-  client = GNUNET_CLIENT_connect (h->sched,
-                                 "fs",
-                                 h->cfg);
+  client = GNUNET_CLIENT_connect ("fs", h->cfg);
   if (NULL == client)
   if (NULL == client)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Failed to not connect to `%s' service.\n"),
-                 "fs");
-      GNUNET_SCHEDULER_add_continuation (h->sched,
-                                        GNUNET_NO,
-                                        cont,
-                                        cont_cls,
-                                        GNUNET_SCHEDULER_REASON_TIMEOUT);
-      return;
-    }
-
-  gic = GNUNET_malloc (sizeof (struct GetIndexedContext));
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Failed to not connect to `%s' service.\n"), "fs");
+    return NULL;
+  }
+  gic = GNUNET_malloc (sizeof (struct GNUNET_FS_GetIndexedContext));
   gic->h = h;
   gic->client = client;
   gic->iterator = iterator;
   gic->iterator_cls = iterator_cls;
   gic->h = h;
   gic->client = client;
   gic->iterator = iterator;
   gic->iterator_cls = iterator_cls;
-  gic->cont = cont;
-  gic->cont_cls = cont_cls;
-  GNUNET_CLIENT_notify_transmit_ready (client,
-                                      sizeof (struct GNUNET_MessageHeader),
-                                      GNUNET_CONSTANTS_SERVICE_TIMEOUT,
-                                      &transmit_get_indexed,
-                                      gic);
+  msg.size = htons (sizeof (struct GNUNET_MessageHeader));
+  msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CLIENT_transmit_and_get_response (client, &msg,
+                                                          GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                                          GNUNET_YES,
+                                                          &handle_index_info,
+                                                          gic));
+  return gic;
 }
 
 }
 
+
+/**
+ * Cancel iteration over all indexed files.
+ *
+ * @param gic operation to cancel
+ */
+void
+GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic)
+{
+  GNUNET_CLIENT_disconnect (gic->client);
+  GNUNET_free (gic);
+}
+
+
 /* end of fs_list_indexed.c */
 /* end of fs_list_indexed.c */