uncrustify as demanded.
[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 Affero 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      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
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    * Connection to the FS service.
40    */
41   struct GNUNET_MQ_Handle *mq;
42
43   /**
44    * Function to call for each indexed file.
45    */
46   GNUNET_FS_IndexedFileProcessor iterator;
47
48   /**
49    * Closure for @e iterator.
50    */
51   void *iterator_cls;
52
53   /**
54    * Continuation to trigger at the end.
55    */
56   GNUNET_SCHEDULER_TaskCallback cont;
57
58   /**
59    * Closure for @e cont.
60    */
61   void *cont_cls;
62 };
63
64
65 /**
66  * Function called on each response from the FS
67  * service with information about indexed files.
68  *
69  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
70  * @param msg message with indexing information
71  */
72 static void
73 handle_index_info_end(void *cls,
74                       const struct GNUNET_MessageHeader *msg)
75 {
76   struct GNUNET_FS_GetIndexedContext *gic = cls;
77
78   (void)gic->iterator(gic->iterator_cls,
79                       NULL,
80                       NULL);
81   GNUNET_FS_get_indexed_files_cancel(gic);
82 }
83
84
85 /**
86  * Check validity of response from the FS
87  * service with information about indexed files.
88  *
89  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
90  * @param iim message with indexing information
91  */
92 static int
93 check_index_info(void *cls,
94                  const struct IndexInfoMessage *iim)
95 {
96   uint16_t msize = ntohs(iim->header.size) - sizeof(*iim);
97   const char *filename;
98
99   filename = (const char *)&iim[1];
100   if (filename[msize - 1] != '\0')
101     {
102       GNUNET_break(0);
103       return GNUNET_SYSERR;
104     }
105   return GNUNET_OK;
106 }
107
108
109 /**
110  * Function called on each response from the FS
111  * service with information about indexed files.
112  *
113  * @param cls closure (of type `struct GNUNET_FS_GetIndexedContext *`)
114  * @param iim message with indexing information
115  */
116 static void
117 handle_index_info(void *cls,
118                   const struct IndexInfoMessage *iim)
119 {
120   struct GNUNET_FS_GetIndexedContext *gic = cls;
121   const char *filename;
122
123   filename = (const char *)&iim[1];
124   if (GNUNET_OK !=
125       gic->iterator(gic->iterator_cls,
126                     filename,
127                     &iim->file_id))
128     {
129       GNUNET_FS_get_indexed_files_cancel(gic);
130       return;
131     }
132 }
133
134
135 /**
136  * Generic error handler, called with the appropriate error code and
137  * the same closure specified at the creation of the message queue.
138  * Not every message queue implementation supports an error handler.
139  *
140  * @param cls closure with the `struct GNUNET_FS_GetIndexedContent *`
141  * @param error error code
142  */
143 static void
144 mq_error_handler(void *cls,
145                  enum GNUNET_MQ_Error error)
146 {
147   struct GNUNET_FS_GetIndexedContext *gic = cls;
148
149   GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
150              _("Failed to receive response from `%s' service.\n"),
151              "fs");
152   (void)gic->iterator(gic->iterator_cls, NULL, NULL);
153   GNUNET_FS_get_indexed_files_cancel(gic);
154 }
155
156
157 /**
158  * Iterate over all indexed files.
159  *
160  * @param h handle to the file sharing subsystem
161  * @param iterator function to call on each indexed file
162  * @param iterator_cls closure for iterator
163  * @return NULL on error ('iter' is not called)
164  */
165 struct GNUNET_FS_GetIndexedContext *
166 GNUNET_FS_get_indexed_files(struct GNUNET_FS_Handle *h,
167                             GNUNET_FS_IndexedFileProcessor iterator,
168                             void *iterator_cls)
169 {
170   struct GNUNET_FS_GetIndexedContext *gic
171     = GNUNET_new(struct GNUNET_FS_GetIndexedContext);
172   struct GNUNET_MQ_MessageHandler handlers[] = {
173     GNUNET_MQ_hd_fixed_size(index_info_end,
174                             GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END,
175                             struct GNUNET_MessageHeader,
176                             gic),
177     GNUNET_MQ_hd_var_size(index_info,
178                           GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY,
179                           struct IndexInfoMessage,
180                           gic),
181     GNUNET_MQ_handler_end()
182   };
183   struct GNUNET_MQ_Envelope *env;
184   struct GNUNET_MessageHeader *msg;
185
186   gic->mq = GNUNET_CLIENT_connect(h->cfg,
187                                   "fs",
188                                   handlers,
189                                   &mq_error_handler,
190                                   h);
191   if (NULL == gic->mq)
192     {
193       GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
194                  _("Failed to not connect to `%s' service.\n"),
195                  "fs");
196       GNUNET_free(gic);
197       return NULL;
198     }
199   gic->iterator = iterator;
200   gic->iterator_cls = iterator_cls;
201   env = GNUNET_MQ_msg(msg,
202                       GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
203   GNUNET_MQ_send(gic->mq,
204                  env);
205   return gic;
206 }
207
208
209 /**
210  * Cancel iteration over all indexed files.
211  *
212  * @param gic operation to cancel
213  */
214 void
215 GNUNET_FS_get_indexed_files_cancel(struct GNUNET_FS_GetIndexedContext *gic)
216 {
217   GNUNET_MQ_destroy(gic->mq);
218   GNUNET_free(gic);
219 }
220
221
222 /* end of fs_list_indexed.c */