-towards block plugin for mesh
[oweals/gnunet.git] / src / fs / fs_list_indexed.c
1 /*
2      This file is part of GNUnet.
3      (C) 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file fs/fs_list_indexed.c
23  * @author Christian Grothoff
24  * @brief provide a list of all indexed files
25  */
26
27 #include "platform.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_fs_service.h"
30 #include "gnunet_protocols.h"
31 #include "fs_api.h"
32
33
34 /**
35  * Context for "GNUNET_FS_get_indexed_files".
36  */
37 struct GNUNET_FS_GetIndexedContext
38 {
39   /**
40    * Handle to global FS context.
41    */
42   struct GNUNET_FS_Handle *h;
43
44   /**
45    * Connection to the FS service.
46    */
47   struct GNUNET_CLIENT_Connection *client;
48
49   /**
50    * Function to call for each indexed file.
51    */
52   GNUNET_FS_IndexedFileProcessor iterator;
53
54   /**
55    * Closure for iterator.
56    */
57   void *iterator_cls;
58
59   /**
60    * Continuation to trigger at the end.
61    */
62   GNUNET_SCHEDULER_Task cont;
63
64   /**
65    * Closure for cont.
66    */
67   void *cont_cls;
68 };
69
70
71 /**
72  * Function called on each response from the FS
73  * service with information about indexed files.
74  *
75  * @param cls closure (of type "struct GNUNET_FS_GetIndexedContext*")
76  * @param msg message with indexing information
77  */
78 static void
79 handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg)
80 {
81   struct GNUNET_FS_GetIndexedContext *gic = cls;
82   const struct IndexInfoMessage *iim;
83   uint16_t msize;
84   const char *filename;
85
86   if (NULL == msg)
87   {
88     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
89                 _
90                 ("Failed to receive response for `%s' request from `%s' service.\n"),
91                 "GET_INDEXED", "fs");
92     (void) gic->iterator (gic->iterator_cls, NULL, NULL);
93     GNUNET_FS_get_indexed_files_cancel (gic);
94     return;
95   }
96   if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END)
97   {
98     /* normal end-of-list */
99     (void) gic->iterator (gic->iterator_cls, NULL, NULL);
100     GNUNET_FS_get_indexed_files_cancel (gic);
101     return;
102   }
103   msize = ntohs (msg->size);
104   iim = (const struct IndexInfoMessage *) msg;
105   filename = (const char *) &iim[1];
106   if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) ||
107       (msize <= sizeof (struct IndexInfoMessage)) ||
108       (filename[msize - sizeof (struct IndexInfoMessage) - 1] != '\0'))
109   {
110     /* bogus reply */
111     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
112                 _
113                 ("Failed to receive valid response for `%s' request from `%s' service.\n"),
114                 "GET_INDEXED", "fs");
115     (void) gic->iterator (gic->iterator_cls, NULL, NULL);
116     GNUNET_FS_get_indexed_files_cancel (gic);
117     return;
118   }
119   if (GNUNET_OK != gic->iterator (gic->iterator_cls, filename, &iim->file_id))
120   {
121     GNUNET_FS_get_indexed_files_cancel (gic);
122     return;
123   }
124   /* get more */
125   GNUNET_CLIENT_receive (gic->client, &handle_index_info, gic,
126                          GNUNET_CONSTANTS_SERVICE_TIMEOUT);
127 }
128
129
130 /**
131  * Iterate over all indexed files.
132  *
133  * @param h handle to the file sharing subsystem
134  * @param iterator function to call on each indexed file
135  * @param iterator_cls closure for iterator
136  * @return NULL on error ('iter' is not called)
137  */
138 struct GNUNET_FS_GetIndexedContext *
139 GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
140                              GNUNET_FS_IndexedFileProcessor iterator,
141                              void *iterator_cls)
142 {
143   struct GNUNET_CLIENT_Connection *client;
144   struct GNUNET_FS_GetIndexedContext *gic;
145   struct GNUNET_MessageHeader msg;
146
147   client = GNUNET_CLIENT_connect ("fs", h->cfg);
148   if (NULL == client)
149   {
150     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
151                 _("Failed to not connect to `%s' service.\n"), "fs");
152     return NULL;
153   }
154   gic = GNUNET_malloc (sizeof (struct GNUNET_FS_GetIndexedContext));
155   gic->h = h;
156   gic->client = client;
157   gic->iterator = iterator;
158   gic->iterator_cls = iterator_cls;
159   msg.size = htons (sizeof (struct GNUNET_MessageHeader));
160   msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
161   GNUNET_assert (GNUNET_OK ==
162                  GNUNET_CLIENT_transmit_and_get_response (client, &msg,
163                                                           GNUNET_CONSTANTS_SERVICE_TIMEOUT,
164                                                           GNUNET_YES,
165                                                           &handle_index_info,
166                                                           gic));
167   return gic;
168 }
169
170
171 /**
172  * Cancel iteration over all indexed files.
173  *
174  * @param gic operation to cancel
175  */
176 void
177 GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic)
178 {
179   GNUNET_CLIENT_disconnect (gic->client);
180   GNUNET_free (gic);
181 }
182
183
184 /* end of fs_list_indexed.c */