diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-15 14:55:13 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-15 14:55:13 +0000 |
commit | 8d4671bb0e9e1ae40053a8250203e281b53c7d5c (patch) | |
tree | 2148fc9844a0931b9f0c8cb369f8a81a447a7777 /src | |
parent | 943110ad52014e30c1ea29b0c68166149902ab85 (diff) | |
download | gnunet-8d4671bb0e9e1ae40053a8250203e281b53c7d5c.tar.gz gnunet-8d4671bb0e9e1ae40053a8250203e281b53c7d5c.zip |
-LRN: use filescanner in gnunet-publish
Diffstat (limited to 'src')
-rw-r--r-- | src/fs/fs_dirmetascan.c | 68 | ||||
-rw-r--r-- | src/fs/gnunet-publish.c | 217 |
2 files changed, 196 insertions, 89 deletions
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c index b9e400c00..b9fa45c1f 100644 --- a/src/fs/fs_dirmetascan.c +++ b/src/fs/fs_dirmetascan.c | |||
@@ -568,6 +568,13 @@ extract_file (struct AddDirStack *ads, const char *filename) | |||
568 | EXTRACTOR_METATYPE_FILENAME, | 568 | EXTRACTOR_METATYPE_FILENAME, |
569 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", | 569 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", |
570 | short_fn, strlen (short_fn) + 1); | 570 | short_fn, strlen (short_fn) + 1); |
571 | if (ads->parent == NULL) | ||
572 | { | ||
573 | /* we're finished with the scan, make sure caller gets the top-level | ||
574 | * directory pointer | ||
575 | */ | ||
576 | ads->adc->toplevel = item; | ||
577 | } | ||
571 | } | 578 | } |
572 | 579 | ||
573 | /** | 580 | /** |
@@ -869,7 +876,7 @@ GNUNET_FS_directory_scan_cleanup (struct GNUNET_FS_DirScanner *ds) | |||
869 | * The function from which the scanner thread starts | 876 | * The function from which the scanner thread starts |
870 | */ | 877 | */ |
871 | #if WINDOWS | 878 | #if WINDOWS |
872 | static DWORD | 879 | DWORD |
873 | #else | 880 | #else |
874 | static void * | 881 | static void * |
875 | #endif | 882 | #endif |
@@ -1043,12 +1050,7 @@ GNUNET_FS_directory_scan_start (const char *filename, | |||
1043 | 1050 | ||
1044 | if (0 != STAT (filename, &sbuf)) | 1051 | if (0 != STAT (filename, &sbuf)) |
1045 | return NULL; | 1052 | return NULL; |
1046 | /* TODO: consider generalizing this for files too! */ | 1053 | |
1047 | if (!S_ISDIR (sbuf.st_mode)) | ||
1048 | { | ||
1049 | GNUNET_break (0); | ||
1050 | return NULL; | ||
1051 | } | ||
1052 | /* scan_directory() is guaranteed to be given expanded filenames, | 1054 | /* scan_directory() is guaranteed to be given expanded filenames, |
1053 | * so expand we will! | 1055 | * so expand we will! |
1054 | */ | 1056 | */ |
@@ -1211,30 +1213,35 @@ trim_share_tree_task (void *cls, | |||
1211 | /* process a child entry (a file or a directory) and move to the next one*/ | 1213 | /* process a child entry (a file or a directory) and move to the next one*/ |
1212 | if (stack->item->is_directory) | 1214 | if (stack->item->is_directory) |
1213 | stack->end_directory = GNUNET_NO; | 1215 | stack->end_directory = GNUNET_NO; |
1214 | stack->dir_entry_count++; | 1216 | if (stack->ctx->toplevel->is_directory) |
1215 | GNUNET_CONTAINER_meta_data_iterate (stack->item->meta, &add_to_meta_counter, stack->metacounter); | ||
1216 | |||
1217 | if (stack->item->is_directory) | ||
1218 | { | 1217 | { |
1219 | char *user = getenv ("USER"); | 1218 | stack->dir_entry_count++; |
1220 | if ((user == NULL) || (0 != strncasecmp (user, stack->item->short_filename, strlen(user)))) | 1219 | GNUNET_CONTAINER_meta_data_iterate (stack->item->meta, &add_to_meta_counter, stack->metacounter); |
1220 | |||
1221 | if (stack->item->is_directory) | ||
1221 | { | 1222 | { |
1222 | /* only use filename if it doesn't match $USER */ | 1223 | char *user = getenv ("USER"); |
1223 | GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>", | 1224 | if ((user == NULL) || (0 != strncasecmp (user, stack->item->short_filename, strlen(user)))) |
1224 | EXTRACTOR_METATYPE_FILENAME, | 1225 | { |
1225 | EXTRACTOR_METAFORMAT_UTF8, | 1226 | /* only use filename if it doesn't match $USER */ |
1226 | "text/plain", stack->item->short_filename, | 1227 | GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>", |
1227 | strlen (stack->item->short_filename) + 1); | 1228 | EXTRACTOR_METATYPE_FILENAME, |
1228 | GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>", | 1229 | EXTRACTOR_METAFORMAT_UTF8, |
1229 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, | 1230 | "text/plain", stack->item->short_filename, |
1230 | EXTRACTOR_METAFORMAT_UTF8, | 1231 | strlen (stack->item->short_filename) + 1); |
1231 | "text/plain", stack->item->short_filename, | 1232 | GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>", |
1232 | strlen (stack->item->short_filename) + 1); | 1233 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, |
1234 | EXTRACTOR_METAFORMAT_UTF8, | ||
1235 | "text/plain", stack->item->short_filename, | ||
1236 | strlen (stack->item->short_filename) + 1); | ||
1237 | } | ||
1233 | } | 1238 | } |
1234 | } | 1239 | } |
1235 | |||
1236 | stack->item->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (stack->item->meta); | 1240 | stack->item->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (stack->item->meta); |
1237 | GNUNET_FS_uri_ksk_get_keywords (stack->item->ksk_uri, &add_to_keyword_counter, stack->keywordcounter); | 1241 | if (stack->ctx->toplevel->is_directory) |
1242 | { | ||
1243 | GNUNET_FS_uri_ksk_get_keywords (stack->item->ksk_uri, &add_to_keyword_counter, stack->keywordcounter); | ||
1244 | } | ||
1238 | stack->item = stack->item->next; | 1245 | stack->item = stack->item->next; |
1239 | } | 1246 | } |
1240 | /* Call this task again later, if there are more entries to process */ | 1247 | /* Call this task again later, if there are more entries to process */ |
@@ -1270,8 +1277,13 @@ GNUNET_FS_trim_share_tree (struct GNUNET_FS_ShareTreeItem *toplevel, | |||
1270 | ret->stack = GNUNET_malloc (sizeof (struct ProcessMetadataStackItem)); | 1277 | ret->stack = GNUNET_malloc (sizeof (struct ProcessMetadataStackItem)); |
1271 | ret->stack->ctx = ret; | 1278 | ret->stack->ctx = ret; |
1272 | ret->stack->item = toplevel; | 1279 | ret->stack->item = toplevel; |
1273 | ret->stack->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024); | 1280 | |
1274 | ret->stack->metacounter = GNUNET_CONTAINER_multihashmap_create (1024); | 1281 | if (ret->stack->ctx->toplevel->is_directory) |
1282 | { | ||
1283 | ret->stack->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024); | ||
1284 | ret->stack->metacounter = GNUNET_CONTAINER_multihashmap_create (1024); | ||
1285 | } | ||
1286 | |||
1275 | ret->stack->dir_entry_count = 0; | 1287 | ret->stack->dir_entry_count = 0; |
1276 | ret->stack->end_directory = GNUNET_NO; | 1288 | ret->stack->end_directory = GNUNET_NO; |
1277 | 1289 | ||
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index dd3bf6810..9e0602862 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c | |||
@@ -66,6 +66,15 @@ static int do_disable_creation_time; | |||
66 | 66 | ||
67 | static GNUNET_SCHEDULER_TaskIdentifier kill_task; | 67 | static GNUNET_SCHEDULER_TaskIdentifier kill_task; |
68 | 68 | ||
69 | static struct GNUNET_FS_DirScanner *ds; | ||
70 | |||
71 | static struct GNUNET_FS_ShareTreeItem * directory_scan_intermediary_result; | ||
72 | |||
73 | static struct GNUNET_FS_ShareTreeItem * directory_scan_result; | ||
74 | |||
75 | static struct GNUNET_FS_ProcessMetadataContext *pmc; | ||
76 | |||
77 | static struct GNUNET_FS_Namespace *namespace; | ||
69 | 78 | ||
70 | /** | 79 | /** |
71 | * FIXME: docu | 80 | * FIXME: docu |
@@ -340,6 +349,150 @@ uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri, | |||
340 | ctx = NULL; | 349 | ctx = NULL; |
341 | } | 350 | } |
342 | 351 | ||
352 | static struct GNUNET_FS_FileInformation * | ||
353 | get_file_information (struct GNUNET_FS_ShareTreeItem *item) | ||
354 | { | ||
355 | struct GNUNET_FS_FileInformation *fi; | ||
356 | struct GNUNET_FS_FileInformation *fic; | ||
357 | struct GNUNET_FS_ShareTreeItem *child; | ||
358 | |||
359 | if (item->is_directory) | ||
360 | { | ||
361 | GNUNET_CONTAINER_meta_data_delete (item->meta, | ||
362 | EXTRACTOR_METATYPE_MIMETYPE, NULL, 0); | ||
363 | GNUNET_FS_meta_data_make_directory (item->meta); | ||
364 | GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri, GNUNET_FS_DIRECTORY_MIME, | ||
365 | GNUNET_NO); | ||
366 | fi = GNUNET_FS_file_information_create_empty_directory ( | ||
367 | ctx, NULL, item->ksk_uri, | ||
368 | item->meta, &bo, item->filename); | ||
369 | for (child = item->children_head; child; child = child->next) | ||
370 | { | ||
371 | fic = get_file_information (child); | ||
372 | GNUNET_break (GNUNET_OK == GNUNET_FS_file_information_add (fi, fic)); | ||
373 | } | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | fi = GNUNET_FS_file_information_create_from_file ( | ||
378 | ctx, NULL, item->filename, | ||
379 | item->ksk_uri, item->meta, !do_insert, | ||
380 | &bo); | ||
381 | } | ||
382 | GNUNET_CONTAINER_meta_data_destroy (item->meta); | ||
383 | GNUNET_FS_uri_destroy (item->ksk_uri); | ||
384 | GNUNET_free (item->short_filename); | ||
385 | GNUNET_free (item->filename); | ||
386 | GNUNET_free (item); | ||
387 | return fi; | ||
388 | } | ||
389 | |||
390 | static void | ||
391 | directory_trim_complete (void *cls, | ||
392 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
393 | { | ||
394 | struct GNUNET_FS_FileInformation *fi; | ||
395 | directory_scan_result = directory_scan_intermediary_result; | ||
396 | fi = get_file_information (directory_scan_result); | ||
397 | directory_scan_result = NULL; | ||
398 | if (fi == NULL) | ||
399 | { | ||
400 | FPRINTF (stderr, "%s", _("Could not publish\n")); | ||
401 | if (namespace != NULL) | ||
402 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); | ||
403 | GNUNET_FS_stop (ctx); | ||
404 | ret = 1; | ||
405 | return; | ||
406 | } | ||
407 | GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL); | ||
408 | if (extract_only) | ||
409 | { | ||
410 | if (namespace != NULL) | ||
411 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); | ||
412 | GNUNET_FS_file_information_destroy (fi, NULL, NULL); | ||
413 | GNUNET_FS_stop (ctx); | ||
414 | return; | ||
415 | } | ||
416 | pc = GNUNET_FS_publish_start (ctx, fi, namespace, this_id, next_id, | ||
417 | (do_simulate) ? | ||
418 | GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY : | ||
419 | GNUNET_FS_PUBLISH_OPTION_NONE); | ||
420 | if (NULL == pc) | ||
421 | { | ||
422 | FPRINTF (stderr, "%s", _("Could not start publishing.\n")); | ||
423 | GNUNET_FS_stop (ctx); | ||
424 | ret = 1; | ||
425 | return; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | static int | ||
430 | directory_scan_cb (void *cls, struct GNUNET_FS_DirScanner *ds, | ||
431 | const char *filename, char is_directory, | ||
432 | enum GNUNET_FS_DirScannerProgressUpdateReason reason) | ||
433 | { | ||
434 | switch (reason) | ||
435 | { | ||
436 | case GNUNET_DIR_SCANNER_NEW_FILE: | ||
437 | if (filename != NULL) | ||
438 | { | ||
439 | if (is_directory) | ||
440 | FPRINTF (stdout, _("Scanning directory `%s'.\n"), filename); | ||
441 | else | ||
442 | FPRINTF (stdout, _("Scanning file `%s'.\n"), filename); | ||
443 | } | ||
444 | break; | ||
445 | case GNUNET_DIR_SCANNER_DOES_NOT_EXIST: | ||
446 | if (filename != NULL) | ||
447 | { | ||
448 | FPRINTF (stdout, | ||
449 | _("Failed to scan `%s', because it does not exist.\n"), | ||
450 | filename); | ||
451 | } | ||
452 | break; | ||
453 | case GNUNET_DIR_SCANNER_ASKED_TO_STOP: | ||
454 | if (filename != NULL) | ||
455 | { | ||
456 | FPRINTF (stdout, | ||
457 | _("Scanner was about to scan `%s', but is now stopping.\n"), | ||
458 | filename); | ||
459 | } | ||
460 | else | ||
461 | FPRINTF (stdout, "%s", _("Scanner is stopping.\n")); | ||
462 | break; | ||
463 | case GNUNET_DIR_SCANNER_SHUTDOWN: | ||
464 | FPRINTF (stdout, "%s", _("Client is shutting down.\n")); | ||
465 | break; | ||
466 | case GNUNET_DIR_SCANNER_FINISHED: | ||
467 | FPRINTF (stdout, "%s", _("Scanner has finished.\n")); | ||
468 | break; | ||
469 | case GNUNET_DIR_SCANNER_PROTOCOL_ERROR: | ||
470 | FPRINTF (stdout, "%s", | ||
471 | _("There was a failure communicating with the scanner.\n")); | ||
472 | break; | ||
473 | default: | ||
474 | FPRINTF (stdout, _("Got unknown scanner update with filename `%s'.\n"), | ||
475 | filename); | ||
476 | break; | ||
477 | } | ||
478 | if ((filename == NULL && GNUNET_DIR_SCANNER_FINISHED) | ||
479 | || reason == GNUNET_DIR_SCANNER_PROTOCOL_ERROR | ||
480 | || reason == GNUNET_DIR_SCANNER_SHUTDOWN) | ||
481 | { | ||
482 | /* Any of this causes us to try to clean up the scanner */ | ||
483 | directory_scan_intermediary_result = GNUNET_FS_directory_scan_cleanup (ds); | ||
484 | pmc = GNUNET_FS_trim_share_tree (directory_scan_intermediary_result, | ||
485 | &directory_trim_complete, NULL); | ||
486 | |||
487 | ds = NULL; | ||
488 | /* FIXME: change the tree processor to be able to free untrimmed trees | ||
489 | * right here instead of waiting for trimming to complete, if we need to | ||
490 | * cancel everything. | ||
491 | */ | ||
492 | } | ||
493 | return 0; | ||
494 | } | ||
495 | |||
343 | 496 | ||
344 | /** | 497 | /** |
345 | * Main function that will be run by the scheduler. | 498 | * Main function that will be run by the scheduler. |
@@ -353,11 +506,7 @@ static void | |||
353 | run (void *cls, char *const *args, const char *cfgfile, | 506 | run (void *cls, char *const *args, const char *cfgfile, |
354 | const struct GNUNET_CONFIGURATION_Handle *c) | 507 | const struct GNUNET_CONFIGURATION_Handle *c) |
355 | { | 508 | { |
356 | struct GNUNET_FS_FileInformation *fi; | ||
357 | struct GNUNET_FS_Namespace *namespace; | ||
358 | struct EXTRACTOR_PluginList *plugins; | 509 | struct EXTRACTOR_PluginList *plugins; |
359 | struct GNUNET_FS_Uri *keywords; | ||
360 | struct stat sbuf; | ||
361 | char *ex; | 510 | char *ex; |
362 | char *emsg; | 511 | char *emsg; |
363 | 512 | ||
@@ -451,6 +600,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
451 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); | 600 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); |
452 | return; | 601 | return; |
453 | } | 602 | } |
603 | ds = GNUNET_FS_directory_scan_start (args[0], | ||
604 | GNUNET_NO, NULL, directory_scan_cb, NULL); | ||
605 | |||
454 | plugins = NULL; | 606 | plugins = NULL; |
455 | if (!disable_extractor) | 607 | if (!disable_extractor) |
456 | { | 608 | { |
@@ -465,63 +617,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
465 | GNUNET_free (ex); | 617 | GNUNET_free (ex); |
466 | } | 618 | } |
467 | } | 619 | } |
468 | emsg = NULL; | ||
469 | GNUNET_assert (NULL != args[0]); | ||
470 | if (0 != STAT (args[0], &sbuf)) | ||
471 | { | ||
472 | GNUNET_asprintf (&emsg, _("Could not access file: %s\n"), STRERROR (errno)); | ||
473 | fi = NULL; | ||
474 | } | ||
475 | else if (S_ISDIR (sbuf.st_mode)) | ||
476 | { | ||
477 | fi = GNUNET_FS_file_information_create_from_directory (ctx, NULL, args[0], | ||
478 | &GNUNET_FS_directory_scanner_default, | ||
479 | plugins, !do_insert, | ||
480 | &bo, &emsg); | ||
481 | } | ||
482 | else | ||
483 | { | ||
484 | if (meta == NULL) | ||
485 | meta = GNUNET_CONTAINER_meta_data_create (); | ||
486 | GNUNET_FS_meta_data_extract_from_file (meta, args[0], plugins); | ||
487 | keywords = GNUNET_FS_uri_ksk_create_from_meta_data (meta); | ||
488 | fi = GNUNET_FS_file_information_create_from_file (ctx, NULL, args[0], | ||
489 | keywords, NULL, | ||
490 | !do_insert, &bo); | ||
491 | GNUNET_break (fi != NULL); | ||
492 | GNUNET_FS_uri_destroy (keywords); | ||
493 | } | ||
494 | EXTRACTOR_plugin_remove_all (plugins); | ||
495 | if (fi == NULL) | ||
496 | { | ||
497 | FPRINTF (stderr, _("Could not publish `%s': %s\n"), args[0], emsg); | ||
498 | GNUNET_free (emsg); | ||
499 | if (namespace != NULL) | ||
500 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); | ||
501 | GNUNET_FS_stop (ctx); | ||
502 | ret = 1; | ||
503 | return; | ||
504 | } | ||
505 | GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL); | ||
506 | if (extract_only) | ||
507 | { | ||
508 | if (namespace != NULL) | ||
509 | GNUNET_FS_namespace_delete (namespace, GNUNET_NO); | ||
510 | GNUNET_FS_file_information_destroy (fi, NULL, NULL); | ||
511 | GNUNET_FS_stop (ctx); | ||
512 | return; | ||
513 | } | ||
514 | pc = GNUNET_FS_publish_start (ctx, fi, namespace, this_id, next_id, | ||
515 | (do_simulate) ? | ||
516 | GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY : | ||
517 | GNUNET_FS_PUBLISH_OPTION_NONE); | ||
518 | if (NULL == pc) | ||
519 | { | ||
520 | FPRINTF (stderr, "%s", _("Could not start publishing.\n")); | ||
521 | GNUNET_FS_stop (ctx); | ||
522 | ret = 1; | ||
523 | return; | ||
524 | } | ||
525 | kill_task = | 620 | kill_task = |
526 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task, | 621 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task, |
527 | NULL); | 622 | NULL); |