aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-15 14:55:13 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-15 14:55:13 +0000
commit8d4671bb0e9e1ae40053a8250203e281b53c7d5c (patch)
tree2148fc9844a0931b9f0c8cb369f8a81a447a7777 /src
parent943110ad52014e30c1ea29b0c68166149902ab85 (diff)
downloadgnunet-8d4671bb0e9e1ae40053a8250203e281b53c7d5c.tar.gz
gnunet-8d4671bb0e9e1ae40053a8250203e281b53c7d5c.zip
-LRN: use filescanner in gnunet-publish
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs_dirmetascan.c68
-rw-r--r--src/fs/gnunet-publish.c217
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
872static DWORD 879DWORD
873#else 880#else
874static void * 881static 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
67static GNUNET_SCHEDULER_TaskIdentifier kill_task; 67static GNUNET_SCHEDULER_TaskIdentifier kill_task;
68 68
69static struct GNUNET_FS_DirScanner *ds;
70
71static struct GNUNET_FS_ShareTreeItem * directory_scan_intermediary_result;
72
73static struct GNUNET_FS_ShareTreeItem * directory_scan_result;
74
75static struct GNUNET_FS_ProcessMetadataContext *pmc;
76
77static 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
352static struct GNUNET_FS_FileInformation *
353get_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
390static void
391directory_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
429static int
430directory_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
353run (void *cls, char *const *args, const char *cfgfile, 506run (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);