+ chk_uri = GNUNET_FS_uri_parse (pt, NULL);
+ if (NULL == chk_uri)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to parse URI `%s' from KBlock!\n"),
+ pt);
+ GNUNET_break (0);
+ goto get_next;
+ }
+ }
+ if (0 != memcmp (&uc->chk,
+ &chk_uri->data.chk.chk,
+ sizeof (struct ContentHashKey)))
+ {
+ /* different CHK, ignore */
+ GNUNET_FS_uri_destroy (chk_uri);
+ goto get_next;
+ }
+ GNUNET_FS_uri_destroy (chk_uri);
+ /* matches! */
+ uc->dqe = GNUNET_DATASTORE_remove (uc->dsh,
+ key, size, data,
+ 0 /* priority */, 1 /* queue size */,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &continue_after_remove,
+ uc);
+ return;
+ get_next:
+ uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
+ uc->roff++,
+ &uc->query,
+ GNUNET_BLOCK_TYPE_FS_KBLOCK,
+ 0 /* priority */, 1 /* queue size */,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &process_kblock_for_unindex,
+ uc);
+}
+
+
+/**
+ * If necessary, connect to the datastore and remove the KBlocks.
+ *
+ * @param uc context for the unindex operation.
+ */
+void
+GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc)
+{
+ const char *keyword;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+
+ if (NULL == uc->dsh)
+ uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
+ if (NULL == uc->dsh)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ if ( (NULL == uc->ksk_uri) ||
+ (uc->ksk_offset >= uc->ksk_uri->data.ksk.keywordCount) )
+ {
+ unindex_finish (uc);
+ return;
+ }
+ /* FIXME: code duplication with fs_search.c here... */
+ keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1];
+ GNUNET_CRYPTO_hash (keyword, strlen (keyword), &uc->key);
+ pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&uc->key);
+ GNUNET_assert (pk != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
+ GNUNET_CRYPTO_rsa_key_free (pk);
+ GNUNET_CRYPTO_hash (&pub,
+ sizeof (struct
+ GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ &uc->query);
+ uc->first_uid = 0;
+ uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
+ uc->roff++,
+ &uc->query,
+ GNUNET_BLOCK_TYPE_FS_KBLOCK,
+ 0 /* priority */, 1 /* queue size */,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &process_kblock_for_unindex,
+ uc);
+}
+
+
+/**
+ * Function called when the tree encoder has
+ * processed all blocks. Clean up.
+ *
+ * @param cls our unindexing context
+ * @param tc not used
+ */
+static void
+unindex_extract_keywords (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+
+ uc->state = UNINDEX_STATE_EXTRACT_KEYWORDS;
+ GNUNET_FS_unindex_sync_ (uc);
+ GNUNET_FS_unindex_do_extract_keywords_ (uc);
+}
+
+
+/**
+ * Connect to the datastore and remove the blocks.
+ *
+ * @param uc context for the unindex operation.
+ */
+void
+GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc)
+{
+ if (NULL == uc->dsh)
+ uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
+ if (NULL == uc->dsh)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ uc->fh =
+ GNUNET_DISK_file_open (uc->filename, GNUNET_DISK_OPEN_READ,
+ GNUNET_DISK_PERM_NONE);
+ if (NULL == uc->fh)
+ {
+ GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO);
+ uc->dsh = NULL;
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg = GNUNET_strdup (_("Failed to open file for unindexing."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ uc->tc =
+ GNUNET_FS_tree_encoder_create (uc->h, uc->file_size, uc, &unindex_reader,
+ &unindex_process, &unindex_progress,
+ &unindex_extract_keywords);