first batch of license fixes (boring)
[oweals/gnunet.git] / src / fs / fs_list_indexed.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2003, 2004, 2006, 2009 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15
16 /**
17  * @file fs/fs_list_indexed.c
18  * @author Christian Grothoff
19  * @brief provide a list of all indexed files
20  */
21
22 #include "platform.h"
23 #include "gnunet_constants.h"
24 #include "gnunet_fs_service.h"
25 #include "gnunet_protocols.h"
26 #include "fs_api.h"
27
28
29 /**
30  * Context for #GNUNET_FS_get_indexed_files().
31  */
32 struct GNUNET_FS_GetIndexedContext
33 {
34
35   /**
36    * Connection to the FS service.
37    */
38   struct GNUNET_MQ_Handle *mq;
39
40   /**
41    * Function to call for each indexed file.
42    */
43   GNUNET_FS_IndexedFileProcessor iterator;
44
45   /**
46    * Closure for @e iterator.
47    */
48   void *iterator_cls;
49
50   /**
51    * Continuation to trigger at the end.
52    */
53   GNUNET_SCHEDULER_TaskCallback cont;
54
55   /**
56    * Closure for @e cont.
57    */
58   void *cont_cls;
59 };
60
61
62 /**
63  * Function called on each response from the FS
64  * service with information about indexed files.
65  *
66  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
67  * @param msg message with indexing information
68  */
69 static void
70 handle_index_info_end (void *cls,
71                        const struct GNUNET_MessageHeader *msg)
72 {
73   struct GNUNET_FS_GetIndexedContext *gic = cls;
74
75   (void) gic->iterator (gic->iterator_cls,
76                         NULL,
77                         NULL);
78   GNUNET_FS_get_indexed_files_cancel (gic);
79 }
80
81
82 /**
83  * Check validity of response from the FS
84  * service with information about indexed files.
85  *
86  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
87  * @param iim message with indexing information
88  */
89 static int
90 check_index_info (void *cls,
91                   const struct IndexInfoMessage *iim)
92 {
93   uint16_t msize = ntohs (iim->header.size) - sizeof (*iim);
94   const char *filename;
95
96   filename = (const char *) &iim[1];
97   if (filename[msize - 1] != '\0')
98   {
99     GNUNET_break (0);
100     return GNUNET_SYSERR;
101   }
102   return GNUNET_OK;
103 }
104
105
106 /**
107  * Function called on each response from the FS
108  * service with information about indexed files.
109  *
110  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
111  * @param iim message with indexing information
112  */
113 static void
114 handle_index_info (void *cls,
115                    const struct IndexInfoMessage *iim)
116 {
117   struct GNUNET_FS_GetIndexedContext *gic = cls;
118   const char *filename;
119
120   filename = (const char *) &iim[1];
121   if (GNUNET_OK !=
122       gic->iterator (gic->iterator_cls,
123                      filename,
124                      &iim->file_id))
125   {
126     GNUNET_FS_get_indexed_files_cancel (gic);
127     return;
128   }
129 }
130
131
132 /**
133  * Generic error handler, called with the appropriate error code and
134  * the same closure specified at the creation of the message queue.
135  * Not every message queue implementation supports an error handler.
136  *
137  * @param cls closure with the `struct GNUNET_FS_GetIndexedContent *`
138  * @param error error code
139  */
140 static void
141 mq_error_handler (void *cls,
142                   enum GNUNET_MQ_Error error)
143 {
144   struct GNUNET_FS_GetIndexedContext *gic = cls;
145
146   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
147               _("Failed to receive response from `%s' service.\n"),
148               "fs");
149   (void) gic->iterator (gic->iterator_cls, NULL, NULL);
150   GNUNET_FS_get_indexed_files_cancel (gic);
151 }
152
153
154 /**
155  * Iterate over all indexed files.
156  *
157  * @param h handle to the file sharing subsystem
158  * @param iterator function to call on each indexed file
159  * @param iterator_cls closure for iterator
160  * @return NULL on error ('iter' is not called)
161  */
162 struct GNUNET_FS_GetIndexedContext *
163 GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
164                              GNUNET_FS_IndexedFileProcessor iterator,
165                              void *iterator_cls)
166 {
167   struct GNUNET_FS_GetIndexedContext *gic
168     = GNUNET_new (struct GNUNET_FS_GetIndexedContext);
169   struct GNUNET_MQ_MessageHandler handlers[] = {
170     GNUNET_MQ_hd_fixed_size (index_info_end,
171                              GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END,
172                              struct GNUNET_MessageHeader,
173                              gic),
174     GNUNET_MQ_hd_var_size (index_info,
175                            GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY,
176                            struct IndexInfoMessage,
177                            gic),
178     GNUNET_MQ_handler_end ()
179   };
180   struct GNUNET_MQ_Envelope *env;
181   struct GNUNET_MessageHeader *msg;
182
183   gic->mq = GNUNET_CLIENT_connect (h->cfg,
184                                    "fs",
185                                    handlers,
186                                    &mq_error_handler,
187                                    h);
188   if (NULL == gic->mq)
189   {
190     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
191                 _("Failed to not connect to `%s' service.\n"),
192                 "fs");
193     GNUNET_free (gic);
194     return NULL;
195   }
196   gic->iterator = iterator;
197   gic->iterator_cls = iterator_cls;
198   env = GNUNET_MQ_msg (msg,
199                        GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
200   GNUNET_MQ_send (gic->mq,
201                   env);
202   return gic;
203 }
204
205
206 /**
207  * Cancel iteration over all indexed files.
208  *
209  * @param gic operation to cancel
210  */
211 void
212 GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic)
213 {
214   GNUNET_MQ_destroy (gic->mq);
215   GNUNET_free (gic);
216 }
217
218
219 /* end of fs_list_indexed.c */