aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-service-fs_indexing.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-10-01 12:53:07 +0000
committerChristian Grothoff <christian@grothoff.org>2016-10-01 12:53:07 +0000
commitf7fac7f6736df4e350a8b5ed7d9f51782d7e039e (patch)
tree6eee38f2dbc4de932c22d213dde60cf06992b127 /src/fs/gnunet-service-fs_indexing.c
parent760f75d2d87f01ca93ebfb349eedbb4224c03c7c (diff)
downloadgnunet-f7fac7f6736df4e350a8b5ed7d9f51782d7e039e.tar.gz
gnunet-f7fac7f6736df4e350a8b5ed7d9f51782d7e039e.zip
migrating fs to new service API
Diffstat (limited to 'src/fs/gnunet-service-fs_indexing.c')
-rw-r--r--src/fs/gnunet-service-fs_indexing.c543
1 files changed, 250 insertions, 293 deletions
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index 385c88fe2..3ce68f487 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -79,6 +79,7 @@ struct IndexInfo
79 79
80/** 80/**
81 * Head of linked list of indexed files. 81 * Head of linked list of indexed files.
82 * FIXME: we don't need both a DLL and a hashmap here!
82 */ 83 */
83static struct IndexInfo *indexed_files_head; 84static struct IndexInfo *indexed_files_head;
84 85
@@ -117,29 +118,38 @@ write_index_list ()
117 struct IndexInfo *pos; 118 struct IndexInfo *pos;
118 119
119 if (GNUNET_OK != 120 if (GNUNET_OK !=
120 GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn)) 121 GNUNET_CONFIGURATION_get_value_filename (cfg, "FS",
122 "INDEXDB",
123 &fn))
121 { 124 {
122 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 125 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
123 "fs", "INDEXDB"); 126 "fs",
127 "INDEXDB");
124 return; 128 return;
125 } 129 }
126 wh = GNUNET_BIO_write_open (fn); 130 wh = GNUNET_BIO_write_open (fn);
127 if (NULL == wh) 131 if (NULL == wh)
128 { 132 {
129 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 133 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
130 _("Could not open `%s'.\n"), fn); 134 _("Could not open `%s'.\n"),
135 fn);
131 GNUNET_free (fn); 136 GNUNET_free (fn);
132 return; 137 return;
133 } 138 }
134 for (pos = indexed_files_head; NULL != pos; pos = pos->next) 139 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
135 if ((GNUNET_OK != 140 if ((GNUNET_OK !=
136 GNUNET_BIO_write (wh, &pos->file_id, sizeof (struct GNUNET_HashCode))) || 141 GNUNET_BIO_write (wh,
137 (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename))) 142 &pos->file_id,
143 sizeof (struct GNUNET_HashCode))) ||
144 (GNUNET_OK !=
145 GNUNET_BIO_write_string (wh,
146 pos->filename)))
138 break; 147 break;
139 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 148 if (GNUNET_OK != GNUNET_BIO_write_close (wh))
140 { 149 {
141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
142 _("Error writing `%s'.\n"), fn); 151 _("Error writing `%s'.\n"),
152 fn);
143 GNUNET_free (fn); 153 GNUNET_free (fn);
144 return; 154 return;
145 } 155 }
@@ -162,10 +172,14 @@ read_index_list ()
162 char *emsg; 172 char *emsg;
163 173
164 if (GNUNET_OK != 174 if (GNUNET_OK !=
165 GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn)) 175 GNUNET_CONFIGURATION_get_value_filename (cfg,
176 "FS",
177 "INDEXDB",
178 &fn))
166 { 179 {
167 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 180 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
168 "fs", "INDEXDB"); 181 "fs",
182 "INDEXDB");
169 return; 183 return;
170 } 184 }
171 if (GNUNET_NO == GNUNET_DISK_file_test (fn)) 185 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
@@ -178,16 +192,22 @@ read_index_list ()
178 if (NULL == rh) 192 if (NULL == rh)
179 { 193 {
180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
181 _("Could not open `%s'.\n"), fn); 195 _("Could not open `%s'.\n"),
196 fn);
182 GNUNET_free (fn); 197 GNUNET_free (fn);
183 return; 198 return;
184 } 199 }
185 while ((GNUNET_OK == 200 while ( (GNUNET_OK ==
186 GNUNET_BIO_read (rh, "Hash of indexed file", &hc, 201 GNUNET_BIO_read (rh,
187 sizeof (struct GNUNET_HashCode))) && 202 "Hash of indexed file",
188 (GNUNET_OK == 203 &hc,
189 GNUNET_BIO_read_string (rh, "Name of indexed file", &fname, 204 sizeof (struct GNUNET_HashCode))) &&
190 1024 * 16)) && (fname != NULL)) 205 (GNUNET_OK ==
206 GNUNET_BIO_read_string (rh,
207 "Name of indexed file",
208 &fname,
209 1024 * 16)) &&
210 (fname != NULL) )
191 { 211 {
192 slen = strlen (fname) + 1; 212 slen = strlen (fname) + 1;
193 pos = GNUNET_malloc (sizeof (struct IndexInfo) + slen); 213 pos = GNUNET_malloc (sizeof (struct IndexInfo) + slen);
@@ -215,250 +235,6 @@ read_index_list ()
215 235
216 236
217/** 237/**
218 * We've validated the hash of the file we're about to index. Signal
219 * success to the client and update our internal data structures.
220 *
221 * @param ii the index info entry for the request
222 */
223static void
224signal_index_ok (struct IndexInfo *ii)
225{
226 struct IndexInfo *ir;
227 if (GNUNET_SYSERR ==
228 GNUNET_CONTAINER_multihashmap_put (ifm, &ii->file_id,
229 ii,
230 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
231 {
232 ir = GNUNET_CONTAINER_multihashmap_get (ifm,
233 &ii->file_id);
234 GNUNET_assert (NULL != ir);
235 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
236 _
237 ("Index request received for file `%s' is already indexed as `%s'. Permitting anyway.\n"),
238 ii->filename,
239 ir->filename);
240 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
241 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK);
242 GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES);
243 GNUNET_free (ii);
244 return;
245 }
246 GNUNET_CONTAINER_DLL_insert (indexed_files_head,
247 indexed_files_tail,
248 ii);
249 write_index_list ();
250 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
251 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK);
252 GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES);
253 ii->tc = NULL;
254}
255
256
257/**
258 * Function called once the hash computation over an
259 * indexed file has completed.
260 *
261 * @param cls closure, our publishing context
262 * @param res resulting hash, NULL on error
263 */
264static void
265hash_for_index_val (void *cls, const struct GNUNET_HashCode * res)
266{
267 struct IndexInfo *ii = cls;
268
269 ii->fhc = NULL;
270 if ((res == NULL) ||
271 (0 != memcmp (res, &ii->file_id, sizeof (struct GNUNET_HashCode))))
272 {
273 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
274 _
275 ("Hash mismatch trying to index file `%s' which has hash `%s'\n"),
276 ii->filename, GNUNET_h2s (res));
277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Wanted `%s'\n",
278 GNUNET_h2s (&ii->file_id));
279 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
280 GNUNET_MESSAGE_TYPE_FS_INDEX_START_FAILED);
281 GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES);
282 GNUNET_free (ii);
283 return;
284 }
285 signal_index_ok (ii);
286}
287
288
289/**
290 * Handle INDEX_START-message.
291 *
292 * @param cls closure
293 * @param client identification of the client
294 * @param message the actual message
295 */
296void
297GNUNET_FS_handle_index_start (void *cls, struct GNUNET_SERVER_Client *client,
298 const struct GNUNET_MessageHeader *message)
299{
300 const struct IndexStartMessage *ism;
301 char *fn;
302 uint16_t msize;
303 struct IndexInfo *ii;
304 size_t slen;
305 uint64_t dev;
306 uint64_t ino;
307 uint64_t mydev;
308 uint64_t myino;
309
310 msize = ntohs (message->size);
311 if ((msize <= sizeof (struct IndexStartMessage)) ||
312 (((const char *) message)[msize - 1] != '\0'))
313 {
314 GNUNET_break (0);
315 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
316 return;
317 }
318 ism = (const struct IndexStartMessage *) message;
319 if (0 != ism->reserved)
320 {
321 GNUNET_break (0);
322 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
323 return;
324 }
325 fn = GNUNET_STRINGS_filename_expand ((const char *) &ism[1]);
326 if (fn == NULL)
327 {
328 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
329 return;
330 }
331 dev = GNUNET_ntohll (ism->device);
332 ino = GNUNET_ntohll (ism->inode);
333 ism = (const struct IndexStartMessage *) message;
334 slen = strlen (fn) + 1;
335 ii = GNUNET_malloc (sizeof (struct IndexInfo) + slen);
336 ii->filename = (const char *) &ii[1];
337 GNUNET_memcpy (&ii[1], fn, slen);
338 ii->file_id = ism->file_id;
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message for file `%s'\n",
340 "START_INDEX", ii->filename);
341 ii->tc = GNUNET_SERVER_transmit_context_create (client);
342 mydev = 0;
343 myino = 0;
344 if (((dev != 0) || (ino != 0)) &&
345 (GNUNET_OK == GNUNET_DISK_file_get_identifiers (fn, &mydev, &myino)) &&
346 ((dev == mydev) && (ino == myino)))
347 {
348 /* fast validation OK! */
349 signal_index_ok (ii);
350 GNUNET_free (fn);
351 return;
352 }
353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
354 "Mismatch in file identifiers (%llu != %llu or %u != %u), need to hash.\n",
355 (unsigned long long) ino, (unsigned long long) myino,
356 (unsigned int) dev, (unsigned int) mydev);
357 /* slow validation, need to hash full file (again) */
358 ii->fhc =
359 GNUNET_CRYPTO_hash_file (GNUNET_SCHEDULER_PRIORITY_IDLE, fn,
360 HASHING_BLOCKSIZE, &hash_for_index_val, ii);
361 if (ii->fhc == NULL)
362 hash_for_index_val (ii, NULL);
363 GNUNET_free (fn);
364}
365
366
367/**
368 * Handle INDEX_LIST_GET-message.
369 *
370 * @param cls closure
371 * @param client identification of the client
372 * @param message the actual message
373 */
374void
375GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client,
376 const struct GNUNET_MessageHeader *message)
377{
378 struct GNUNET_SERVER_TransmitContext *tc;
379 struct IndexInfoMessage *iim;
380 char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
381 size_t slen;
382 const char *fn;
383 struct IndexInfo *pos;
384
385 tc = GNUNET_SERVER_transmit_context_create (client);
386 iim = (struct IndexInfoMessage *) buf;
387 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
388 {
389 fn = pos->filename;
390 slen = strlen (fn) + 1;
391 if (slen + sizeof (struct IndexInfoMessage) >=
392 GNUNET_SERVER_MAX_MESSAGE_SIZE)
393 {
394 GNUNET_break (0);
395 break;
396 }
397 iim->header.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY);
398 iim->header.size = htons (slen + sizeof (struct IndexInfoMessage));
399 iim->reserved = 0;
400 iim->file_id = pos->file_id;
401 GNUNET_memcpy (&iim[1], fn, slen);
402 GNUNET_SERVER_transmit_context_append_message (tc, &iim->header);
403 }
404 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
405 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END);
406 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_MINUTES);
407}
408
409
410/**
411 * Handle UNINDEX-message.
412 *
413 * @param cls closure
414 * @param client identification of the client
415 * @param message the actual message
416 */
417void
418GNUNET_FS_handle_unindex (void *cls, struct GNUNET_SERVER_Client *client,
419 const struct GNUNET_MessageHeader *message)
420{
421 const struct UnindexMessage *um;
422 struct IndexInfo *pos;
423 struct GNUNET_SERVER_TransmitContext *tc;
424 int found;
425
426 um = (const struct UnindexMessage *) message;
427 if (0 != um->reserved)
428 {
429 GNUNET_break (0);
430 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
431 return;
432 }
433 found = GNUNET_NO;
434 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
435 {
436 if (0 == memcmp (&pos->file_id, &um->file_id, sizeof (struct GNUNET_HashCode)))
437 {
438 GNUNET_CONTAINER_DLL_remove (indexed_files_head,
439 indexed_files_tail,
440 pos);
441 GNUNET_break (GNUNET_OK ==
442 GNUNET_CONTAINER_multihashmap_remove (ifm, &pos->file_id,
443 pos));
444 GNUNET_free (pos);
445 found = GNUNET_YES;
446 break;
447 }
448 }
449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
450 "Client requested unindexing of file `%s': %s\n",
451 GNUNET_h2s (&um->file_id), found ? "found" : "not found");
452 if (GNUNET_YES == found)
453 write_index_list ();
454 tc = GNUNET_SERVER_transmit_context_create (client);
455 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
456 GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK);
457 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_MINUTES);
458}
459
460
461/**
462 * Continuation called from datastore's remove 238 * Continuation called from datastore's remove
463 * function. 239 * function.
464 * 240 *
@@ -498,9 +274,12 @@ remove_cont (void *cls, int success,
498 * @return GNUNET_OK on success 274 * @return GNUNET_OK on success
499 */ 275 */
500int 276int
501GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size, 277GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key,
502 const void *data, enum GNUNET_BLOCK_Type type, 278 uint32_t size,
503 uint32_t priority, uint32_t anonymity, 279 const void *data,
280 enum GNUNET_BLOCK_Type type,
281 uint32_t priority,
282 uint32_t anonymity,
504 struct GNUNET_TIME_Absolute expiration, 283 struct GNUNET_TIME_Absolute expiration,
505 uint64_t uid, 284 uint64_t uid,
506 GNUNET_DATASTORE_DatumProcessor cont, 285 GNUNET_DATASTORE_DatumProcessor cont,
@@ -522,70 +301,246 @@ GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t s
522 if (size != sizeof (struct OnDemandBlock)) 301 if (size != sizeof (struct OnDemandBlock))
523 { 302 {
524 GNUNET_break (0); 303 GNUNET_break (0);
525 GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1, 304 GNUNET_DATASTORE_remove (dsh,
305 key,
306 size,
307 data,
308 -1,
309 -1,
526 &remove_cont, NULL); 310 &remove_cont, NULL);
527 return GNUNET_SYSERR; 311 return GNUNET_SYSERR;
528 } 312 }
529 odb = (const struct OnDemandBlock *) data; 313 odb = (const struct OnDemandBlock *) data;
530 off = GNUNET_ntohll (odb->offset); 314 off = GNUNET_ntohll (odb->offset);
531 ii = GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id); 315 ii = GNUNET_CONTAINER_multihashmap_get (ifm,
316 &odb->file_id);
532 if (NULL == ii) 317 if (NULL == ii)
533 { 318 {
534 GNUNET_break (0); 319 GNUNET_break (0);
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321 "Failed to find index %s\n",
322 GNUNET_h2s (&odb->file_id));
535 return GNUNET_SYSERR; 323 return GNUNET_SYSERR;
536 } 324 }
537 fn = ii->filename; 325 fn = ii->filename;
538 if ((NULL == fn) || (0 != ACCESS (fn, R_OK))) 326 if ((NULL == fn) || (0 != ACCESS (fn, R_OK)))
539 { 327 {
540 GNUNET_STATISTICS_update (GSF_stats, 328 GNUNET_STATISTICS_update (GSF_stats,
541 gettext_noop 329 gettext_noop ("# index blocks removed: original file inaccessible"),
542 ("# index blocks removed: original file inaccessible"), 330 1,
543 1, GNUNET_YES); 331 GNUNET_YES);
544 GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1, 332 GNUNET_DATASTORE_remove (dsh,
545 &remove_cont, NULL); 333 key,
334 size,
335 data,
336 -1,
337 -1,
338 &remove_cont,
339 NULL);
546 return GNUNET_SYSERR; 340 return GNUNET_SYSERR;
547 } 341 }
548 if ((NULL == 342 if ( (NULL ==
549 (fh = 343 (fh =
550 GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, 344 GNUNET_DISK_file_open (fn,
551 GNUNET_DISK_PERM_NONE))) || 345 GNUNET_DISK_OPEN_READ,
552 (off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)) || 346 GNUNET_DISK_PERM_NONE))) ||
553 (-1 == (nsize = GNUNET_DISK_file_read (fh, ndata, sizeof (ndata))))) 347 (off != GNUNET_DISK_file_seek (fh,
348 off,
349 GNUNET_DISK_SEEK_SET)) ||
350 (-1 == (nsize = GNUNET_DISK_file_read (fh,
351 ndata,
352 sizeof (ndata)))) )
554 { 353 {
555 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 354 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
556 _ 355 _("Could not access indexed file `%s' (%s) at offset %llu: %s\n"),
557 ("Could not access indexed file `%s' (%s) at offset %llu: %s\n"), 356 GNUNET_h2s (&odb->file_id),
558 GNUNET_h2s (&odb->file_id), fn, (unsigned long long) off, 357 fn,
358 (unsigned long long) off,
559 (fn == NULL) ? _("not indexed") : STRERROR (errno)); 359 (fn == NULL) ? _("not indexed") : STRERROR (errno));
560 if (fh != NULL) 360 if (fh != NULL)
561 GNUNET_DISK_file_close (fh); 361 GNUNET_DISK_file_close (fh);
562 GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1, 362 GNUNET_DATASTORE_remove (dsh,
563 &remove_cont, NULL); 363 key,
364 size,
365 data,
366 -1,
367 -1,
368 &remove_cont,
369 NULL);
564 return GNUNET_SYSERR; 370 return GNUNET_SYSERR;
565 } 371 }
566 GNUNET_DISK_file_close (fh); 372 GNUNET_DISK_file_close (fh);
567 GNUNET_CRYPTO_hash (ndata, nsize, &nkey); 373 GNUNET_CRYPTO_hash (ndata,
568 GNUNET_CRYPTO_hash_to_aes_key (&nkey, &skey, &iv); 374 nsize,
569 GNUNET_CRYPTO_symmetric_encrypt (ndata, nsize, &skey, &iv, edata); 375 &nkey);
570 GNUNET_CRYPTO_hash (edata, nsize, &query); 376 GNUNET_CRYPTO_hash_to_aes_key (&nkey,
571 if (0 != memcmp (&query, key, sizeof (struct GNUNET_HashCode))) 377 &skey,
378 &iv);
379 GNUNET_CRYPTO_symmetric_encrypt (ndata,
380 nsize,
381 &skey,
382 &iv,
383 edata);
384 GNUNET_CRYPTO_hash (edata,
385 nsize,
386 &query);
387 if (0 != memcmp (&query,
388 key,
389 sizeof (struct GNUNET_HashCode)))
572 { 390 {
573 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 391 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
574 _("Indexed file `%s' changed at offset %llu\n"), fn, 392 _("Indexed file `%s' changed at offset %llu\n"),
393 fn,
575 (unsigned long long) off); 394 (unsigned long long) off);
576 GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1, 395 GNUNET_DATASTORE_remove (dsh,
577 &remove_cont, NULL); 396 key,
397 size,
398 data,
399 -1,
400 -1,
401 &remove_cont,
402 NULL);
578 return GNUNET_SYSERR; 403 return GNUNET_SYSERR;
579 } 404 }
580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
581 "On-demand encoded block for query `%s'\n", GNUNET_h2s (key)); 406 "On-demand encoded block for query `%s'\n",
582 cont (cont_cls, key, nsize, edata, GNUNET_BLOCK_TYPE_FS_DBLOCK, priority, 407 GNUNET_h2s (key));
583 anonymity, expiration, uid); 408 cont (cont_cls,
409 key,
410 nsize,
411 edata,
412 GNUNET_BLOCK_TYPE_FS_DBLOCK,
413 priority,
414 anonymity,
415 expiration,
416 uid);
584 return GNUNET_OK; 417 return GNUNET_OK;
585} 418}
586 419
587 420
588/** 421/**
422 * Transmit information about indexed files to @a mq.
423 *
424 * @param mq message queue to send information to
425 */
426void
427GNUNET_FS_indexing_send_list (struct GNUNET_MQ_Handle *mq)
428{
429 struct GNUNET_MQ_Envelope *env;
430 struct IndexInfoMessage *iim;
431 struct GNUNET_MessageHeader *iem;
432 size_t slen;
433 const char *fn;
434 struct IndexInfo *pos;
435
436 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
437 {
438 fn = pos->filename;
439 slen = strlen (fn) + 1;
440 if (slen + sizeof (struct IndexInfoMessage) >=
441 GNUNET_SERVER_MAX_MESSAGE_SIZE)
442 {
443 GNUNET_break (0);
444 break;
445 }
446 env = GNUNET_MQ_msg_extra (iim,
447 slen,
448 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY);
449 iim->reserved = 0;
450 iim->file_id = pos->file_id;
451 GNUNET_memcpy (&iim[1],
452 fn,
453 slen);
454 GNUNET_MQ_send (mq,
455 env);
456 }
457 env = GNUNET_MQ_msg (iem,
458 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END);
459 GNUNET_MQ_send (mq,
460 env);
461}
462
463
464/**
465 * Remove a file from the index.
466 *
467 * @param fid identifier of the file to remove
468 * @return #GNUNET_YES if the @a fid was found
469 */
470int
471GNUNET_FS_indexing_do_unindex (const struct GNUNET_HashCode *fid)
472{
473 struct IndexInfo *pos;
474
475 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
476 {
477 if (0 == memcmp (&pos->file_id,
478 fid,
479 sizeof (struct GNUNET_HashCode)))
480 {
481 GNUNET_CONTAINER_DLL_remove (indexed_files_head,
482 indexed_files_tail,
483 pos);
484 GNUNET_break (GNUNET_OK ==
485 GNUNET_CONTAINER_multihashmap_remove (ifm,
486 &pos->file_id,
487 pos));
488 GNUNET_free (pos);
489 write_index_list ();
490 return GNUNET_YES;
491 }
492 }
493 return GNUNET_NO;
494}
495
496
497/**
498 * Add the given file to the list of indexed files.
499 *
500 * @param filename name of the file
501 * @param file_id hash identifier for @a filename
502 */
503void
504GNUNET_FS_add_to_index (const char *filename,
505 const struct GNUNET_HashCode *file_id)
506{
507 struct IndexInfo *ii;
508 size_t slen;
509
510 ii = GNUNET_CONTAINER_multihashmap_get (ifm,
511 file_id);
512 if (NULL != ii)
513 {
514 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
515 _("Index request received for file `%s' is already indexed as `%s'. Permitting anyway.\n"),
516 filename,
517 ii->filename);
518 return;
519 }
520 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
521 "Adding file %s to index as %s\n",
522 filename,
523 GNUNET_h2s (file_id));
524 slen = strlen (filename) + 1;
525 ii = GNUNET_malloc (sizeof (struct IndexInfo) + slen);
526 ii->file_id = *file_id;
527 ii->filename = (const char *) &ii[1];
528 memcpy (&ii[1],
529 filename,
530 slen);
531 GNUNET_CONTAINER_DLL_insert (indexed_files_head,
532 indexed_files_tail,
533 ii);
534 GNUNET_assert (GNUNET_OK ==
535 GNUNET_CONTAINER_multihashmap_put (ifm,
536 &ii->file_id,
537 ii,
538 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
539 write_index_list ();
540}
541
542
543/**
589 * Shutdown the module. 544 * Shutdown the module.
590 */ 545 */
591void 546void
@@ -602,7 +557,8 @@ GNUNET_FS_indexing_done ()
602 GNUNET_CRYPTO_hash_file_cancel (pos->fhc); 557 GNUNET_CRYPTO_hash_file_cancel (pos->fhc);
603 GNUNET_break (GNUNET_OK == 558 GNUNET_break (GNUNET_OK ==
604 GNUNET_CONTAINER_multihashmap_remove (ifm, 559 GNUNET_CONTAINER_multihashmap_remove (ifm,
605 &pos->file_id, pos)); 560 &pos->file_id,
561 pos));
606 GNUNET_free (pos); 562 GNUNET_free (pos);
607 } 563 }
608 GNUNET_CONTAINER_multihashmap_destroy (ifm); 564 GNUNET_CONTAINER_multihashmap_destroy (ifm);
@@ -623,7 +579,8 @@ GNUNET_FS_indexing_init (const struct GNUNET_CONFIGURATION_Handle *c,
623{ 579{
624 cfg = c; 580 cfg = c;
625 dsh = d; 581 dsh = d;
626 ifm = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_YES); 582 ifm = GNUNET_CONTAINER_multihashmap_create (128,
583 GNUNET_YES);
627 read_index_list (); 584 read_index_list ();
628 return GNUNET_OK; 585 return GNUNET_OK;
629} 586}