diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-10-01 12:53:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-10-01 12:53:07 +0000 |
commit | f7fac7f6736df4e350a8b5ed7d9f51782d7e039e (patch) | |
tree | 6eee38f2dbc4de932c22d213dde60cf06992b127 /src/fs/gnunet-service-fs_indexing.c | |
parent | 760f75d2d87f01ca93ebfb349eedbb4224c03c7c (diff) | |
download | gnunet-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.c | 543 |
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 | */ |
83 | static struct IndexInfo *indexed_files_head; | 84 | static 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 | */ | ||
223 | static void | ||
224 | signal_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 | */ | ||
264 | static void | ||
265 | hash_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 | */ | ||
296 | void | ||
297 | GNUNET_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 | */ | ||
374 | void | ||
375 | GNUNET_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 | */ | ||
417 | void | ||
418 | GNUNET_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 | */ |
500 | int | 276 | int |
501 | GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size, | 277 | GNUNET_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 | */ | ||
426 | void | ||
427 | GNUNET_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 | */ | ||
470 | int | ||
471 | GNUNET_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 | */ | ||
503 | void | ||
504 | GNUNET_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 | */ |
591 | void | 546 | void |
@@ -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 | } |