-/**
- * Task that post-processes the share item tree.
- * This processing has to be done in the main thread, because
- * it requires access to libgcrypt's hashing functions, and
- * libgcrypt is not thread-safe without some special magic.
- *
- * @param cls top of the stack
- * @param tc task context
- */
-static void
-trim_share_tree_task (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct ProcessMetadataStackItem *stack = cls;
- struct ProcessMetadataStackItem *next = stack;
- /* FIXME: figure out what to do when tc says we're shutting down */
-
- /* item == NULL means that we've just finished going over the children of
- * current directory.
- */
- if (stack->item == NULL)
- {
- if (stack->parent->item != NULL)
- {
- /* end of a directory */
- struct GNUNET_FS_Uri *ksk;
-
- /* use keyword and metadata counters to create lists of keywords to move
- * and metadata to copy.
- */
- process_keywords_and_metadata (stack, &stack->parent->exclude_ksk, &stack->parent->item->meta);
-
- /* create keywords from metadata (copies all text-metadata as keywords,
- * AND parses the directory name we've just added, producing even more
- * keywords.
- * then merge these keywords with the ones moved from children.
- */
- ksk = GNUNET_FS_uri_ksk_create_from_meta_data (stack->parent->item->meta);
- stack->parent->item->ksk_uri = GNUNET_FS_uri_ksk_merge (ksk, stack->parent->exclude_ksk);
- GNUNET_FS_uri_destroy (ksk);
-
- /* remove moved keywords from children (complete the move) */
- remove_keywords (stack->parent, stack->parent->item);
- GNUNET_FS_uri_destroy (stack->parent->exclude_ksk);
-
- /* go up the stack */
- next = stack->parent;
- GNUNET_free (stack);
- next->end_directory = GNUNET_YES;
- }
- else
- {
- /* we've just finished processing the toplevel directory */
- struct GNUNET_FS_ProcessMetadataContext *ctx = stack->ctx;
- next = NULL;
- GNUNET_SCHEDULER_add_continuation (ctx->cb, ctx->cls,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
- GNUNET_free (stack->parent);
- GNUNET_free (stack);
- GNUNET_free (ctx);
- }
- }
- else if (stack->item->is_directory
- && !stack->end_directory
- && stack->item->children_head != NULL)
- {
- /* recurse into subdirectory */
- next = GNUNET_malloc (sizeof (struct ProcessMetadataStackItem));
- next->ctx = stack->ctx;
- next->item = stack->item->children_head;
- next->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024);
- next->metacounter = GNUNET_CONTAINER_multihashmap_create (1024);
- next->dir_entry_count = 0;
- next->parent = stack;
- }
- else
- {
- /* process a child entry (a file or a directory) and move to the next one*/
- if (stack->item->is_directory)
- stack->end_directory = GNUNET_NO;
- stack->dir_entry_count++;
- GNUNET_CONTAINER_meta_data_iterate (stack->item->meta, &add_to_meta_counter, stack->metacounter);
-
- if (stack->item->is_directory)
- {
- char *user = getenv ("USER");
- if ((user == NULL) || (0 != strncasecmp (user, stack->item->short_filename, strlen(user))))
- {
- /* only use filename if it doesn't match $USER */
- GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>",
- EXTRACTOR_METATYPE_FILENAME,
- EXTRACTOR_METAFORMAT_UTF8,
- "text/plain", stack->item->short_filename,
- strlen (stack->item->short_filename) + 1);
- GNUNET_CONTAINER_meta_data_insert (stack->item->meta, "<libgnunetfs>",
- EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
- EXTRACTOR_METAFORMAT_UTF8,
- "text/plain", stack->item->short_filename,
- strlen (stack->item->short_filename) + 1);
- }
- }
-
- stack->item->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (stack->item->meta);
- GNUNET_FS_uri_ksk_get_keywords (stack->item->ksk_uri, &add_to_keyword_counter, stack->keywordcounter);
- stack->item = stack->item->next;
- }
- /* Call this task again later, if there are more entries to process */
- if (next)
- GNUNET_SCHEDULER_add_continuation (&trim_share_tree_task, next,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-}
-
-/**
- * Process a share item tree, moving frequent keywords up and
- * copying frequent metadata up.
- *
- * @param toplevel toplevel directory in the tree, returned by the scanner
- * @param cb called after processing is done
- * @param cls closure for 'cb'
- */
-struct GNUNET_FS_ProcessMetadataContext *
-GNUNET_FS_trim_share_tree (struct GNUNET_FS_ShareTreeItem *toplevel,
- GNUNET_SCHEDULER_Task cb, void *cls)
-{
- struct GNUNET_FS_ProcessMetadataContext *ret;