+ if (type != GNUNET_BLOCK_TYPE_FS_DBLOCK)
+ {
+ size = block_size;
+ data = block;
+ }
+ else /* on-demand encoded DBLOCK */
+ {
+ size = sizeof (struct OnDemandBlock);
+ odb.offset = GNUNET_htonll (offset);
+ odb.file_id = uc->file_id;
+ data = &odb;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending REMOVE request to DATASTORE service\n");
+ GNUNET_DATASTORE_remove (uc->dsh, &chk->query, size, data, -2, 1,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT, &process_cont, uc);
+ uc->chk = *chk;
+}
+
+
+/**
+ * Function called with the response from the
+ * FS service to our unindexing request.
+ *
+ * @param cls closure, unindex context
+ * @param msg NULL on timeout, otherwise the response
+ */
+static void
+process_fs_response (void *cls, const struct GNUNET_MessageHeader *msg)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+ struct GNUNET_FS_ProgressInfo pi;
+
+ if (uc->client != NULL)
+ {
+ GNUNET_CLIENT_disconnect (uc->client);
+ uc->client = NULL;
+ }
+ if (uc->state != UNINDEX_STATE_FS_NOTIFY)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg =
+ GNUNET_strdup (_("Unexpected time for a response from `fs' service."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ if (NULL == msg)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg = GNUNET_strdup (_("Timeout waiting for `fs' service."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg = GNUNET_strdup (_("Invalid response from `fs' service."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ uc->state = UNINDEX_STATE_COMPLETE;
+ pi.status = GNUNET_FS_STATUS_UNINDEX_COMPLETED;
+ pi.value.unindex.eta = GNUNET_TIME_UNIT_ZERO;
+ GNUNET_FS_unindex_sync_ (uc);
+ GNUNET_FS_unindex_make_status_ (&pi, uc, uc->file_size);
+}
+
+
+/**
+ * Function called when we are done with removing KBlocks.
+ * Disconnect from datastore and notify FS service about
+ * the unindex event.
+ *
+ * @param uc our unindexing context
+ */
+static void
+unindex_finish (struct GNUNET_FS_UnindexContext *uc)
+{
+ char *emsg;
+ struct GNUNET_FS_Uri *uri;
+ struct UnindexMessage req;
+
+ /* generate final progress message */
+ unindex_progress (uc, uc->file_size, NULL, 0, 0);
+ GNUNET_FS_tree_encoder_finish (uc->tc, &uri, &emsg);
+ uc->tc = NULL;
+ if (uri != NULL)
+ GNUNET_FS_uri_destroy (uri);
+ GNUNET_DISK_file_close (uc->fh);
+ uc->fh = NULL;
+ GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO);
+ uc->dsh = NULL;
+ uc->state = UNINDEX_STATE_FS_NOTIFY;
+ GNUNET_FS_unindex_sync_ (uc);
+ uc->client = GNUNET_CLIENT_connect ("fs", uc->h->cfg);
+ if (uc->client == NULL)
+ {
+ uc->state = UNINDEX_STATE_ERROR;
+ uc->emsg =
+ GNUNET_strdup (_("Failed to connect to FS service for unindexing."));
+ GNUNET_FS_unindex_sync_ (uc);
+ signal_unindex_error (uc);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending UNINDEX message to FS service\n");
+ req.header.size = htons (sizeof (struct UnindexMessage));
+ req.header.type = htons (GNUNET_MESSAGE_TYPE_FS_UNINDEX);
+ req.reserved = 0;
+ req.file_id = uc->file_id;
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CLIENT_transmit_and_get_response (uc->client,
+ &req.header,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+ GNUNET_YES,
+ &process_fs_response,
+ uc));
+}
+
+
+
+/**
+ * Function called by the directory scanner as we extract keywords
+ * that we will need to remove KBlocks.
+ *
+ * @param cls the 'struct GNUNET_FS_UnindexContext *'
+ * @param filename which file we are making progress on
+ * @param is_directory GNUNET_YES if this is a directory,
+ * GNUNET_NO if this is a file
+ * GNUNET_SYSERR if it is neither (or unknown)
+ * @param reason kind of progress we are making
+ */
+static void
+unindex_directory_scan_cb (void *cls,
+ const char *filename,
+ int is_directory,
+ enum GNUNET_FS_DirScannerProgressUpdateReason reason)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+ static struct GNUNET_FS_ShareTreeItem * directory_scan_result;
+
+ switch (reason)
+ {
+ case GNUNET_FS_DIRSCANNER_FINISHED:
+ directory_scan_result = GNUNET_FS_directory_scan_get_result (uc->dscan);
+ uc->dscan = NULL;
+ if (NULL != directory_scan_result->ksk_uri)