aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_unindex.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-31 21:14:22 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-31 21:14:22 +0000
commit5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3 (patch)
treef91bd544f2e14d69b9eee907e172588651215a76 /src/fs/fs_unindex.c
parent32716cc62ae96040bde78dacabe18a556290f392 (diff)
downloadgnunet-5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3.tar.gz
gnunet-5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3.zip
working on unindex
Diffstat (limited to 'src/fs/fs_unindex.c')
-rw-r--r--src/fs/fs_unindex.c687
1 files changed, 147 insertions, 540 deletions
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c
index 8f09c44f6..9f1caac3a 100644
--- a/src/fs/fs_unindex.c
+++ b/src/fs/fs_unindex.c
@@ -27,7 +27,6 @@
27 * TODO: 27 * TODO:
28 * - code cleanup (share more with upload.c) 28 * - code cleanup (share more with upload.c)
29 */ 29 */
30
31#include "platform.h" 30#include "platform.h"
32#include "gnunet_constants.h" 31#include "gnunet_constants.h"
33#include "gnunet_fs_service.h" 32#include "gnunet_fs_service.h"
@@ -35,222 +34,144 @@
35#include "fs.h" 34#include "fs.h"
36 35
37 36
37
38
38/** 39/**
39 * Context for "GNUNET_FS_get_indexed_files". 40 * Fill in all of the generic fields for
41 * an unindex event.
42 *
43 * @param pc structure to fill in
44 * @param sc overall unindex context
40 */ 45 */
41struct GetIndexedContext 46static void
47make_unindex_status (struct GNUNET_FS_ProgressInfo *pi,
48 struct GNUNET_FS_UnindexContext *uc)
42{ 49{
43 /** 50 pi->value.unindex.uc = uc;
44 * Handle to global FS context. 51 pi->value.unindex.cctx = uc->client_info;
45 */ 52 pi->value.unindex.filename = uc->filename;
46 struct GNUNET_FS_Handle *h; 53 pi->value.unindex.size = uc->file_size;
47 54 pi->value.unindex.eta
48 /** 55 = GNUNET_TIME_calculate_eta (uc->start_time,
49 * Connection to the FS service. 56 uc->unindex_offset,
50 */ 57 uc->file_size);
51 struct GNUNET_CLIENT_Connection *client; 58 pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (uc->start_time);
52 59 pi->value.publish.completed = uc->unindex_offset;
53 /** 60}
54 * Function to call for each indexed file.
55 */
56 GNUNET_FS_IndexedFileProcessor iterator;
57
58 /**
59 * Closure for iterator.
60 */
61 void *iterator_cls;
62 61
63 /**
64 * Continuation to trigger at the end.
65 */
66 GNUNET_SCHEDULER_Task cont;
67 62
68 /** 63/**
69 * Closure for cont. 64 * We've encountered an error during
70 */ 65 * unindexing. Signal the client.
71 void *cont_cls; 66 *
72}; 67 * @param uc context for the failed unindexing operation
68 * @param emsg the error message
69 */
70static void
71signal_unindex_error (struct GNUNET_FS_UnindexContext *uc,
72 const char *emsg)
73{
74 struct GNUNET_FS_ProgressInfo pi;
75
76 pi.status = GNUNET_FS_STATUS_UNINDEX_ERROR;
77 make_unindex_status (&pi, uc);
78 pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL;
79 pi.value.unindex.specifics.error.message = emsg;
80 uc->client_info
81 = uc->h->upcb (uc->h->upcb_cls,
82 &pi);
83}
73 84
74 85
75/** 86/**
76 * Function called on each response from the FS 87 * Function called with the response from the
77 * service with information about indexed files. 88 * FS service to our unindexing request.
78 * 89 *
79 * @param cls closure (of type "struct GetIndexedContext*") 90 * @param cls closure, unindex context
80 * @param msg message with indexing information 91 * @param msg NULL on timeout, otherwise the response
81 */ 92 */
82static void 93static void
83handle_index_info (void *cls, 94process_fs_response (void *cls,
84 const struct GNUNET_MessageHeader *msg) 95 const struct GNUNET_MessageHeader *msg)
85{ 96{
86 struct GetIndexedContext *gic = cls; 97 struct GNUNET_FS_UnindexContext *uc = cls;
87 const struct IndexInfoMessage *iim;
88 uint16_t msize;
89 const char *filename;
90 98
91 if (NULL == msg) 99 GNUNET_CLIENT_disconnect (uc->client);
100 uc->client = NULL;
101 if (uc->state != UNINDEX_STATE_FS_NOTIFY)
92 { 102 {
93 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 103 GNUNET_FS_unindex_stop (uc);
94 _("Failed to receive response for `%s' request from `%s' service.\n"),
95 "GET_INDEXED",
96 "fs");
97 GNUNET_SCHEDULER_add_continuation (gic->h->sched,
98 GNUNET_NO,
99 gic->cont,
100 gic->cont_cls,
101 GNUNET_SCHEDULER_REASON_TIMEOUT);
102 GNUNET_CLIENT_disconnect (gic->client);
103 GNUNET_free (gic);
104 return; 104 return;
105 } 105 }
106 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) 106 if (NULL == msg)
107 { 107 {
108 /* normal end-of-list */ 108 uc->state = UNINDEX_STATE_ERROR;
109 GNUNET_SCHEDULER_add_continuation (gic->h->sched, 109 signal_unindex_error (uc,
110 GNUNET_NO, 110 _("Timeout waiting for `fs' service."));
111 gic->cont,
112 gic->cont_cls,
113 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
114 GNUNET_CLIENT_disconnect (gic->client);
115 GNUNET_free (gic);
116 return; 111 return;
117 } 112 }
118 msize = ntohs (msg->size); 113 if (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK)
119 iim = (const struct IndexInfoMessage*) msg;
120 filename = (const char*) &iim[1];
121 if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) ||
122 (msize <= sizeof (struct IndexInfoMessage)) ||
123 (filename[msize-sizeof (struct IndexInfoMessage) -1] != '\0') )
124 { 114 {
125 /* bogus reply */ 115 uc->state = UNINDEX_STATE_ERROR;
126 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 116 signal_unindex_error (uc,
127 _("Failed to receive valid response for `%s' request from `%s' service.\n"), 117 _("Invalid response from `fs' service."));
128 "GET_INDEXED", 118 return;
129 "fs");
130 GNUNET_SCHEDULER_add_continuation (gic->h->sched,
131 GNUNET_NO,
132 gic->cont,
133 gic->cont_cls,
134 GNUNET_SCHEDULER_REASON_TIMEOUT);
135 GNUNET_CLIENT_disconnect (gic->client);
136 GNUNET_free (gic);
137 return;
138 } 119 }
139 if (GNUNET_OK != 120 uc->state = UNINDEX_STATE_DS_REMOVE;
140 gic->iterator (gic->iterator_cls, 121 uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg,
141 filename, 122 uc->h->sched);
142 &iim->file_id)) 123 if (NULL == uc->dsh)
143 { 124 {
144 GNUNET_SCHEDULER_add_continuation (gic->h->sched, 125 uc->state = UNINDEX_STATE_ERROR;
145 GNUNET_NO, 126 signal_unindex_error (uc,
146 gic->cont, 127 _("Failed to connect to `datastore' service."));
147 gic->cont_cls,
148 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
149 GNUNET_CLIENT_disconnect (gic->client);
150 GNUNET_free (gic);
151 return; 128 return;
152 } 129 }
153 /* get more */ 130
154 GNUNET_CLIENT_receive (gic->client, 131 // FIXME: call shared code with publishing...
155 &handle_index_info,
156 gic,
157 GNUNET_CONSTANTS_SERVICE_TIMEOUT);
158} 132}
159 133
160 134
161/** 135/**
162 * Transmit the request to get a list of all 136 * Function called once the hash of the file
163 * indexed files to the "FS" service. 137 * that is being unindexed has been computed.
164 * 138 *
165 * @param cls closure (of type "struct GetIndexedContext*") 139 * @param cls closure, unindex context
166 * @param size number of bytes availabe in buf 140 * @param file_id computed hash, NULL on error
167 * @param buf where to write the message, NULL on error
168 * @return number of bytes written to buf
169 */ 141 */
170static size_t 142static void
171transmit_get_indexed (void *cls, 143process_hash (void *cls,
172 size_t size, 144 const GNUNET_HashCode *file_id)
173 void *buf)
174{ 145{
175 struct GetIndexedContext *gic = cls; 146 struct GNUNET_FS_UnindexContext *uc = cls;
176 struct GNUNET_MessageHeader *hdr; 147 struct UnindexMessage req;
177 148
178 if (NULL == buf) 149 if (uc->state != UNINDEX_STATE_HASHING)
179 { 150 {
180 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 151 GNUNET_FS_unindex_stop (uc);
181 _("Failed to transmit `%s' request to `%s' service.\n"), 152 return;
182 "GET_INDEXED",
183 "fs");
184 GNUNET_SCHEDULER_add_continuation (gic->h->sched,
185 GNUNET_NO,
186 gic->cont,
187 gic->cont_cls,
188 GNUNET_SCHEDULER_REASON_TIMEOUT);
189 GNUNET_CLIENT_disconnect (gic->client);
190 GNUNET_free (gic);
191 return 0;
192 } 153 }
193 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); 154 if (file_id == NULL)
194 hdr = buf;
195 hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
196 hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
197 GNUNET_CLIENT_receive (gic->client,
198 &handle_index_info,
199 gic,
200 GNUNET_CONSTANTS_SERVICE_TIMEOUT);
201 return sizeof (struct GNUNET_MessageHeader);
202}
203
204
205/**
206 * Iterate over all indexed files.
207 *
208 * @param h handle to the file sharing subsystem
209 * @param iterator function to call on each indexed file
210 * @param iterator_cls closure for iterator
211 * @param cont continuation to call when done;
212 * reason should be "TIMEOUT" (on
213 * error) or "PREREQ_DONE" (on success)
214 * @param cont_cls closure for cont
215 */
216void
217GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
218 GNUNET_FS_IndexedFileProcessor iterator,
219 void *iterator_cls,
220 GNUNET_SCHEDULER_Task cont,
221 void *cont_cls)
222{
223 struct GNUNET_CLIENT_Connection *client;
224 struct GetIndexedContext *gic;
225
226 client = GNUNET_CLIENT_connect (h->sched,
227 "fs",
228 h->cfg);
229 if (NULL == client)
230 { 155 {
231 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 156 uc->state = UNINDEX_STATE_ERROR;
232 _("Failed to not connect to `%s' service.\n"), 157 signal_unindex_error (uc,
233 "fs"); 158 _("Failed to compute hash of file."));
234 GNUNET_SCHEDULER_add_continuation (h->sched,
235 GNUNET_NO,
236 cont,
237 cont_cls,
238 GNUNET_SCHEDULER_REASON_TIMEOUT);
239 return; 159 return;
240 } 160 }
241 161 uc->file_id = *file_id;
242 gic = GNUNET_malloc (sizeof (struct GetIndexedContext)); 162 uc->state = UNINDEX_STATE_FS_NOTIFY;
243 gic->h = h; 163 uc->client = GNUNET_CLIENT_connect (uc->h->sched,
244 gic->client = client; 164 "fs",
245 gic->iterator = iterator; 165 uc->h->cfg);
246 gic->iterator_cls = iterator_cls; 166 req.header.size = htons (sizeof (struct UnindexMessage));
247 gic->cont = cont; 167 req.header.type = htons (GNUNET_MESSAGE_TYPE_FS_UNINDEX);
248 gic->cont_cls = cont_cls; 168 req.reserved = 0;
249 GNUNET_CLIENT_notify_transmit_ready (client, 169 req.file_id = *file_id;
250 sizeof (struct GNUNET_MessageHeader), 170 GNUNET_CLIENT_transmit_and_get_response (uc->client,
251 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 171 &req.header,
252 &transmit_get_indexed, 172 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
253 gic); 173 &process_fs_response,
174 uc);
254} 175}
255 176
256 177
@@ -265,10 +186,36 @@ struct GNUNET_FS_UnindexContext *
265GNUNET_FS_unindex (struct GNUNET_FS_Handle *h, 186GNUNET_FS_unindex (struct GNUNET_FS_Handle *h,
266 const char *filename) 187 const char *filename)
267{ 188{
268 // 1: compute file-id (hash over entire file) 189 struct GNUNET_FS_UnindexContext *ret;
269 // 2: notify FS service about file no longer being indexed 190 struct GNUNET_FS_ProgressInfo pi;
270 // 3: remove corresponding blocks from datastore! 191 uint64_t size;
271 return NULL; 192
193 if (GNUNET_OK !=
194 GNUNET_DISK_file_size (filename,
195 &size,
196 GNUNET_YES))
197 return NULL;
198 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext));
199 ret->h = h;
200 ret->filename = GNUNET_strdup (filename);
201 ret->start_time = GNUNET_TIME_absolute_get ();
202 ret->file_size = size;
203
204 // FIXME: make persistent!
205 pi.status = GNUNET_FS_STATUS_UNINDEX_START;
206 make_unindex_status (&pi, ret);
207 pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL;
208 ret->client_info
209 = h->upcb (h->upcb_cls,
210 &pi);
211 GNUNET_CRYPTO_hash_file (h->sched,
212 GNUNET_SCHEDULER_PRIORITY_IDLE,
213 GNUNET_NO,
214 filename,
215 HASHING_BLOCKSIZE,
216 &process_hash,
217 ret);
218 return ret;
272} 219}
273 220
274 221
@@ -279,365 +226,25 @@ GNUNET_FS_unindex (struct GNUNET_FS_Handle *h,
279 */ 226 */
280void 227void
281GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) 228GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc)
282{ 229{
283} 230 struct GNUNET_FS_ProgressInfo pi;
284
285
286
287#if 0
288
289#define STRICT_CHECKS GNUNET_NO
290
291/**
292 * Append the given key and query to the iblock[level].
293 * If iblock[level] is already full, compute its chk
294 * and push it to level+1. iblocks is guaranteed to
295 * be big enough.
296 *
297 * This function matches exactly upload.c::pushBlock,
298 * except in the call to 'GNUNET_FS_delete'. TODO: refactor
299 * to avoid code duplication (move to block.c, pass
300 * GNUNET_FS_delete as argument!).
301 */
302static int
303pushBlock (struct GNUNET_ClientServerConnection *sock,
304 const GNUNET_EC_ContentHashKey * chk, unsigned int level,
305 GNUNET_DatastoreValue ** iblocks)
306{
307 unsigned int size;
308 unsigned int present;
309 GNUNET_DatastoreValue *value;
310 GNUNET_EC_DBlock *db;
311 GNUNET_EC_ContentHashKey ichk;
312 231
313 size = ntohl (iblocks[level]->size) - sizeof (GNUNET_DatastoreValue); 232 if ( (uc->state != UNINDEX_STATE_COMPLETE) &&
314 present = 233 (uc->state != UNINDEX_STATE_ERROR) )
315 (size - sizeof (GNUNET_EC_DBlock)) / sizeof (GNUNET_EC_ContentHashKey);
316 db = (GNUNET_EC_DBlock *) & iblocks[level][1];
317 if (present == GNUNET_ECRS_CHK_PER_INODE)
318 { 234 {
319 GNUNET_EC_file_block_get_key (db, size, &ichk.key); 235 uc->state = UNINDEX_STATE_ABORTED;
320 GNUNET_EC_file_block_get_query (db, size, &ichk.query); 236 return;
321 if (GNUNET_OK != pushBlock (sock, &ichk, level + 1, iblocks))
322 {
323 GNUNET_GE_BREAK (NULL, 0);
324 return GNUNET_SYSERR;
325 }
326 GNUNET_EC_file_block_encode (db, size, &ichk.query, &value);
327#if STRICT_CHECKS
328 if (GNUNET_SYSERR == GNUNET_FS_delete (sock, value))
329 {
330 GNUNET_free (value);
331 GNUNET_GE_BREAK (NULL, 0);
332 return GNUNET_SYSERR;
333 }
334#else
335 GNUNET_FS_delete (sock, value);
336#endif
337 GNUNET_free (value);
338 size = sizeof (GNUNET_EC_DBlock);
339 }
340 /* append GNUNET_EC_ContentHashKey */
341 memcpy (&((char *) db)[size], chk, sizeof (GNUNET_EC_ContentHashKey));
342 iblocks[level]->size = htonl (size +
343 sizeof (GNUNET_EC_ContentHashKey) +
344 sizeof (GNUNET_DatastoreValue));
345 return GNUNET_OK;
346}
347
348
349
350/**
351 * Undo sym-linking operation:
352 * a) check if we have a symlink
353 * b) delete symbolic link
354 */
355static int
356undoSymlinking (struct GNUNET_GE_Context *ectx,
357 const char *fn,
358 const GNUNET_HashCode * fileId,
359 struct GNUNET_ClientServerConnection *sock)
360{
361 GNUNET_EncName enc;
362 char *serverDir;
363 char *serverFN;
364 struct stat buf;
365
366#ifndef S_ISLNK
367 if (1)
368 return GNUNET_OK; /* symlinks do not exist? */
369#endif
370 if (0 != LSTAT (fn, &buf))
371 {
372 GNUNET_GE_LOG_STRERROR_FILE (ectx,
373 GNUNET_GE_ERROR | GNUNET_GE_BULK |
374 GNUNET_GE_USER | GNUNET_GE_ADMIN, "stat",
375 fn);
376 return GNUNET_SYSERR;
377 }
378#ifdef S_ISLNK
379 if (!S_ISLNK (buf.st_mode))
380 return GNUNET_OK;
381#endif
382 serverDir =
383 GNUNET_get_daemon_configuration_value (sock, "FS", "INDEX-DIRECTORY");
384 if (serverDir == NULL)
385 return GNUNET_OK;
386 serverFN = GNUNET_malloc (strlen (serverDir) + 2 + sizeof (GNUNET_EncName));
387 strcpy (serverFN, serverDir);
388 GNUNET_free (serverDir);
389 if (serverFN[strlen (serverFN) - 1] != DIR_SEPARATOR)
390 strcat (serverFN, DIR_SEPARATOR_STR);
391 GNUNET_hash_to_enc (fileId, &enc);
392 strcat (serverFN, (char *) &enc);
393
394 if (0 != UNLINK (serverFN))
395 {
396 GNUNET_GE_LOG_STRERROR_FILE (ectx,
397 GNUNET_GE_ERROR | GNUNET_GE_BULK |
398 GNUNET_GE_USER | GNUNET_GE_ADMIN, "unlink",
399 serverFN);
400 GNUNET_free (serverFN);
401 return GNUNET_SYSERR;
402 }
403 GNUNET_free (serverFN);
404 return GNUNET_OK;
405}
406
407
408
409/**
410 * Unindex a file.
411 *
412 * @return GNUNET_SYSERR if the unindexing failed (i.e. not indexed)
413 */
414int
415GNUNET_ECRS_file_unindex (struct GNUNET_GE_Context *ectx,
416 struct GNUNET_GC_Configuration *cfg,
417 const char *filename,
418 GNUNET_ECRS_UploadProgressCallback upcb,
419 void *upcbClosure, GNUNET_ECRS_TestTerminate tt,
420 void *ttClosure)
421{
422 unsigned long long filesize;
423 unsigned long long pos;
424 unsigned int treedepth;
425 int fd;
426 int i;
427 unsigned int size;
428 GNUNET_DatastoreValue **iblocks;
429 GNUNET_DatastoreValue *dblock;
430 GNUNET_EC_DBlock *db;
431 GNUNET_DatastoreValue *value;
432 struct GNUNET_ClientServerConnection *sock;
433 GNUNET_HashCode fileId;
434 GNUNET_EC_ContentHashKey chk;
435 GNUNET_CronTime eta;
436 GNUNET_CronTime start;
437 GNUNET_CronTime now;
438 int wasIndexed;
439
440 start = GNUNET_get_time ();
441 if (GNUNET_YES != GNUNET_disk_file_test (ectx, filename))
442 {
443 GNUNET_GE_BREAK (ectx, 0);
444 return GNUNET_SYSERR;
445 }
446 if (GNUNET_OK !=
447 GNUNET_disk_file_size (ectx, filename, &filesize, GNUNET_YES))
448 return GNUNET_SYSERR;
449 sock = GNUNET_client_connection_create (ectx, cfg);
450 if (sock == NULL)
451 return GNUNET_SYSERR;
452 eta = 0;
453 if (upcb != NULL)
454 upcb (filesize, 0, eta, upcbClosure);
455 if (GNUNET_SYSERR == GNUNET_hash_file (ectx, filename, &fileId))
456 {
457 GNUNET_client_connection_destroy (sock);
458 GNUNET_GE_BREAK (ectx, 0);
459 return GNUNET_SYSERR;
460 }
461 now = GNUNET_get_time ();
462 eta = now + 2 * (now - start);
463 /* very rough estimate: GNUNET_hash reads once through the file,
464 we'll do that once more and write it. But of course
465 the second read may be cached, and we have the encryption,
466 so a factor of two is really, really just a rough estimate */
467 start = now;
468 /* reset the counter since the formula later does not
469 take the time for GNUNET_hash_file into account */
470 treedepth = GNUNET_ECRS_compute_depth (filesize);
471
472 /* Test if file is indexed! */
473 wasIndexed = GNUNET_FS_test_indexed (sock, &fileId);
474
475 fd = GNUNET_disk_file_open (ectx, filename, O_RDONLY | O_LARGEFILE);
476 if (fd == -1)
477 {
478 GNUNET_client_connection_destroy (sock);
479 return GNUNET_SYSERR;
480 }
481 dblock =
482 GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
483 sizeof (GNUNET_EC_DBlock));
484 dblock->size =
485 htonl (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
486 sizeof (GNUNET_EC_DBlock));
487 dblock->anonymity_level = htonl (0);
488 dblock->priority = htonl (0);
489 dblock->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
490 dblock->expiration_time = GNUNET_htonll (0);
491 db = (GNUNET_EC_DBlock *) & dblock[1];
492 db->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
493 iblocks =
494 GNUNET_malloc (sizeof (GNUNET_DatastoreValue *) * (treedepth + 1));
495 for (i = 0; i <= treedepth; i++)
496 {
497 iblocks[i] =
498 GNUNET_malloc (sizeof (GNUNET_DatastoreValue) +
499 GNUNET_ECRS_IBLOCK_SIZE + sizeof (GNUNET_EC_DBlock));
500 iblocks[i]->size =
501 htonl (sizeof (GNUNET_DatastoreValue) + sizeof (GNUNET_EC_DBlock));
502 iblocks[i]->anonymity_level = htonl (0);
503 iblocks[i]->priority = htonl (0);
504 iblocks[i]->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
505 iblocks[i]->expiration_time = GNUNET_htonll (0);
506 ((GNUNET_EC_DBlock *) & iblocks[i][1])->type =
507 htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
508 }
509
510 pos = 0;
511 while (pos < filesize)
512 {
513 if (upcb != NULL)
514 upcb (filesize, pos, eta, upcbClosure);
515 if (tt != NULL)
516 if (GNUNET_OK != tt (ttClosure))
517 goto FAILURE;
518 size = GNUNET_ECRS_DBLOCK_SIZE;
519 if (size > filesize - pos)
520 {
521 size = filesize - pos;
522 memset (&db[1], 0, GNUNET_ECRS_DBLOCK_SIZE);
523 }
524 dblock->size =
525 htonl (sizeof (GNUNET_DatastoreValue) + size +
526 sizeof (GNUNET_EC_DBlock));
527 if (size != READ (fd, &db[1], size))
528 {
529 GNUNET_GE_LOG_STRERROR_FILE (ectx,
530 GNUNET_GE_ERROR | GNUNET_GE_USER |
531 GNUNET_GE_ADMIN | GNUNET_GE_BULK,
532 "READ", filename);
533 goto FAILURE;
534 }
535 if (tt != NULL)
536 if (GNUNET_OK != tt (ttClosure))
537 goto FAILURE;
538 GNUNET_EC_file_block_get_key (db, size + sizeof (GNUNET_EC_DBlock),
539 &chk.key);
540 GNUNET_EC_file_block_get_query (db, size + sizeof (GNUNET_EC_DBlock),
541 &chk.query);
542 if (GNUNET_OK != pushBlock (sock, &chk, 0, /* dblocks are on level 0 */
543 iblocks))
544 {
545 GNUNET_GE_BREAK (ectx, 0);
546 goto FAILURE;
547 }
548 if (!wasIndexed)
549 {
550 if (GNUNET_OK ==
551 GNUNET_EC_file_block_encode (db, size, &chk.query, &value))
552 {
553 *value = *dblock; /* copy options! */
554#if STRICT_CHECKS
555 if (GNUNET_OK != GNUNET_FS_delete (sock, value))
556 {
557 GNUNET_free (value);
558 GNUNET_GE_BREAK (ectx, 0);
559 goto FAILURE;
560 }
561#else
562 GNUNET_FS_delete (sock, value);
563#endif
564 GNUNET_free (value);
565 }
566 else
567 {
568 goto FAILURE;
569 }
570 }
571 pos += size;
572 now = GNUNET_get_time ();
573 eta = (GNUNET_CronTime) (start +
574 (((double) (now - start) / (double) pos))
575 * (double) filesize);
576 }
577 if (tt != NULL)
578 if (GNUNET_OK != tt (ttClosure))
579 goto FAILURE;
580 for (i = 0; i < treedepth; i++)
581 {
582 size = ntohl (iblocks[i]->size) - sizeof (GNUNET_DatastoreValue);
583 db = (GNUNET_EC_DBlock *) & iblocks[i][1];
584 GNUNET_EC_file_block_get_key (db, size, &chk.key);
585 GNUNET_EC_file_block_get_query (db, size, &chk.query);
586 if (GNUNET_OK != pushBlock (sock, &chk, i + 1, iblocks))
587 {
588 GNUNET_GE_BREAK (ectx, 0);
589 goto FAILURE;
590 }
591 GNUNET_EC_file_block_encode (db, size, &chk.query, &value);
592#if STRICT_CHECKS
593 if (GNUNET_OK != GNUNET_FS_delete (sock, value))
594 {
595 GNUNET_free (value);
596 GNUNET_GE_BREAK (ectx, 0);
597 goto FAILURE;
598 }
599#else
600 GNUNET_FS_delete (sock, value);
601#endif
602 GNUNET_free (value);
603 GNUNET_free (iblocks[i]);
604 iblocks[i] = NULL;
605 }
606
607 if (wasIndexed)
608 {
609 if (GNUNET_OK == undoSymlinking (ectx, filename, &fileId, sock))
610 {
611 if (GNUNET_OK !=
612 GNUNET_FS_unindex (sock, GNUNET_ECRS_DBLOCK_SIZE, &fileId))
613 {
614 GNUNET_GE_BREAK (ectx, 0);
615 goto FAILURE;
616 }
617 }
618 else
619 {
620 GNUNET_GE_BREAK (ectx, 0);
621 goto FAILURE;
622 }
623 } 237 }
624 GNUNET_free (iblocks[treedepth]); 238 // FIXME: make unpersistent!
625 /* free resources */ 239 pi.status = GNUNET_FS_STATUS_UNINDEX_STOPPED;
626 GNUNET_free (iblocks); 240 make_unindex_status (&pi, uc);
627 GNUNET_free (dblock); 241 pi.value.unindex.eta = GNUNET_TIME_UNIT_ZERO;
628 CLOSE (fd); 242 uc->client_info
629 GNUNET_client_connection_destroy (sock); 243 = uc->h->upcb (uc->h->upcb_cls,
630 return GNUNET_OK; 244 &pi);
631FAILURE: 245 GNUNET_break (NULL == uc->client_info);
632 for (i = 0; i <= treedepth; i++) 246 GNUNET_free (uc->filename);
633 GNUNET_free_non_null (iblocks[i]); 247 GNUNET_free (uc);
634 GNUNET_free (iblocks);
635 GNUNET_free (dblock);
636 CLOSE (fd);
637 GNUNET_client_connection_destroy (sock);
638 return GNUNET_SYSERR;
639} 248}
640 249
641#endif
642
643/* end of fs_unindex.c */ 250/* end of fs_unindex.c */