aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_download.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r--src/fs/fs_download.c2571
1 files changed, 1286 insertions, 1285 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index de70c53a8..e7ea87e50 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -34,16 +34,16 @@
34 * use to try to do a recursive download. 34 * use to try to do a recursive download.
35 */ 35 */
36static int 36static int
37is_recursive_download(struct GNUNET_FS_DownloadContext *dc) 37is_recursive_download (struct GNUNET_FS_DownloadContext *dc)
38{ 38{
39 return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) && 39 return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
40 ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory(dc->meta)) || 40 ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) ||
41 ((NULL == dc->meta) && 41 ((NULL == dc->meta) &&
42 ((NULL == dc->filename) || 42 ((NULL == dc->filename) ||
43 ((strlen(dc->filename) >= strlen(GNUNET_FS_DIRECTORY_EXT)) && 43 ((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
44 (NULL != strstr(dc->filename + strlen(dc->filename) - 44 (NULL != strstr (dc->filename + strlen (dc->filename)
45 strlen(GNUNET_FS_DIRECTORY_EXT), 45 - strlen (GNUNET_FS_DIRECTORY_EXT),
46 GNUNET_FS_DIRECTORY_EXT)))))); 46 GNUNET_FS_DIRECTORY_EXT))))));
47} 47}
48 48
49 49
@@ -64,7 +64,7 @@ is_recursive_download(struct GNUNET_FS_DownloadContext *dc)
64 * with the range for any other block 64 * with the range for any other block
65 */ 65 */
66static uint64_t 66static uint64_t
67compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth) 67compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth)
68{ 68{
69 unsigned int i; 69 unsigned int i;
70 uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */ 70 uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */
@@ -78,16 +78,16 @@ compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth)
78 loff = ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * DBLOCK_SIZE; 78 loff = ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * DBLOCK_SIZE;
79 lsize = 79 lsize =
80 ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * sizeof(struct ContentHashKey); 80 ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * sizeof(struct ContentHashKey);
81 GNUNET_assert(0 == (off % DBLOCK_SIZE)); 81 GNUNET_assert (0 == (off % DBLOCK_SIZE));
82 ioff = (off / DBLOCK_SIZE); 82 ioff = (off / DBLOCK_SIZE);
83 for (i = 1; i < depth; i++) 83 for (i = 1; i < depth; i++)
84 { 84 {
85 loff += lsize; 85 loff += lsize;
86 lsize = (lsize + CHK_PER_INODE - 1) / CHK_PER_INODE; 86 lsize = (lsize + CHK_PER_INODE - 1) / CHK_PER_INODE;
87 GNUNET_assert(lsize > 0); 87 GNUNET_assert (lsize > 0);
88 GNUNET_assert(0 == (ioff % CHK_PER_INODE)); 88 GNUNET_assert (0 == (ioff % CHK_PER_INODE));
89 ioff /= CHK_PER_INODE; 89 ioff /= CHK_PER_INODE;
90 } 90 }
91 return loff + ioff * sizeof(struct ContentHashKey); 91 return loff + ioff * sizeof(struct ContentHashKey);
92} 92}
93 93
@@ -100,8 +100,8 @@ compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth)
100 * @param dc overall download context 100 * @param dc overall download context
101 */ 101 */
102void 102void
103GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi, 103GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
104 struct GNUNET_FS_DownloadContext *dc) 104 struct GNUNET_FS_DownloadContext *dc)
105{ 105{
106 pi->value.download.dc = dc; 106 pi->value.download.dc = dc;
107 pi->value.download.cctx = dc->client_info; 107 pi->value.download.cctx = dc->client_info;
@@ -114,24 +114,25 @@ GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi,
114 pi->value.download.size = dc->length; 114 pi->value.download.size = dc->length;
115 /* FIXME: Fix duration calculation to account for pauses */ 115 /* FIXME: Fix duration calculation to account for pauses */
116 pi->value.download.duration = 116 pi->value.download.duration =
117 GNUNET_TIME_absolute_get_duration(dc->start_time); 117 GNUNET_TIME_absolute_get_duration (dc->start_time);
118 pi->value.download.completed = dc->completed; 118 pi->value.download.completed = dc->completed;
119 pi->value.download.anonymity = dc->anonymity; 119 pi->value.download.anonymity = dc->anonymity;
120 pi->value.download.eta = 120 pi->value.download.eta =
121 GNUNET_TIME_calculate_eta(dc->start_time, dc->completed, dc->length); 121 GNUNET_TIME_calculate_eta (dc->start_time, dc->completed, dc->length);
122 pi->value.download.is_active = (NULL == dc->mq) ? GNUNET_NO : GNUNET_YES; 122 pi->value.download.is_active = (NULL == dc->mq) ? GNUNET_NO : GNUNET_YES;
123 pi->fsh = dc->h; 123 pi->fsh = dc->h;
124 if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) 124 if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
125 dc->client_info = dc->h->upcb(dc->h->upcb_cls, pi); 125 dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi);
126 else 126 else
127 dc->client_info = GNUNET_FS_search_probe_progress_(NULL, pi); 127 dc->client_info = GNUNET_FS_search_probe_progress_ (NULL, pi);
128} 128}
129 129
130 130
131/** 131/**
132 * Closure for iterator processing results. 132 * Closure for iterator processing results.
133 */ 133 */
134struct ProcessResultClosure { 134struct ProcessResultClosure
135{
135 /** 136 /**
136 * Hash of data. 137 * Hash of data.
137 */ 138 */
@@ -189,9 +190,9 @@ struct ProcessResultClosure {
189 * @return #GNUNET_YES (we should continue to iterate); unless serious error 190 * @return #GNUNET_YES (we should continue to iterate); unless serious error
190 */ 191 */
191static int 192static int
192process_result_with_request(void *cls, 193process_result_with_request (void *cls,
193 const struct GNUNET_HashCode *key, 194 const struct GNUNET_HashCode *key,
194 void *value); 195 void *value);
195 196
196 197
197/** 198/**
@@ -208,12 +209,12 @@ process_result_with_request(void *cls,
208 * @return GNUNET_OK on success 209 * @return GNUNET_OK on success
209 */ 210 */
210static int 211static int
211encrypt_existing_match(struct GNUNET_FS_DownloadContext *dc, 212encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
212 const struct ContentHashKey *chk, 213 const struct ContentHashKey *chk,
213 struct DownloadRequest *dr, 214 struct DownloadRequest *dr,
214 const char *block, 215 const char *block,
215 size_t len, 216 size_t len,
216 int do_store) 217 int do_store)
217{ 218{
218 struct ProcessResultClosure prc; 219 struct ProcessResultClosure prc;
219 char enc[len]; 220 char enc[len];
@@ -221,24 +222,24 @@ encrypt_existing_match(struct GNUNET_FS_DownloadContext *dc,
221 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 222 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
222 struct GNUNET_HashCode query; 223 struct GNUNET_HashCode query;
223 224
224 GNUNET_CRYPTO_hash_to_aes_key(&chk->key, &sk, &iv); 225 GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv);
225 if (-1 == GNUNET_CRYPTO_symmetric_encrypt(block, len, &sk, &iv, enc)) 226 if (-1 == GNUNET_CRYPTO_symmetric_encrypt (block, len, &sk, &iv, enc))
226 { 227 {
227 GNUNET_break(0); 228 GNUNET_break (0);
228 return GNUNET_SYSERR; 229 return GNUNET_SYSERR;
229 } 230 }
230 GNUNET_CRYPTO_hash(enc, len, &query); 231 GNUNET_CRYPTO_hash (enc, len, &query);
231 if (0 != memcmp(&query, &chk->query, sizeof(struct GNUNET_HashCode))) 232 if (0 != memcmp (&query, &chk->query, sizeof(struct GNUNET_HashCode)))
232 { 233 {
233 GNUNET_break_op(0); 234 GNUNET_break_op (0);
234 return GNUNET_SYSERR; 235 return GNUNET_SYSERR;
235 } 236 }
236 GNUNET_log( 237 GNUNET_log (
237 GNUNET_ERROR_TYPE_DEBUG, 238 GNUNET_ERROR_TYPE_DEBUG,
238 "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n", 239 "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
239 (unsigned int)len, 240 (unsigned int) len,
240 dc->filename, 241 dc->filename,
241 (unsigned long long)dr->offset); 242 (unsigned long long) dr->offset);
242 /* already got it! */ 243 /* already got it! */
243 prc.dc = dc; 244 prc.dc = dc;
244 prc.data = enc; 245 prc.data = enc;
@@ -248,7 +249,7 @@ encrypt_existing_match(struct GNUNET_FS_DownloadContext *dc,
248 prc.query = chk->query; 249 prc.query = chk->query;
249 prc.do_store = do_store; 250 prc.do_store = do_store;
250 prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS; 251 prc.last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
251 process_result_with_request(&prc, &chk->key, dr); 252 process_result_with_request (&prc, &chk->key, dr);
252 return GNUNET_OK; 253 return GNUNET_OK;
253} 254}
254 255
@@ -261,7 +262,7 @@ encrypt_existing_match(struct GNUNET_FS_DownloadContext *dc,
261 * @param dc download context that is having trouble 262 * @param dc download context that is having trouble
262 */ 263 */
263static void 264static void
264try_reconnect(struct GNUNET_FS_DownloadContext *dc); 265try_reconnect (struct GNUNET_FS_DownloadContext *dc);
265 266
266 267
267/** 268/**
@@ -276,12 +277,12 @@ try_reconnect(struct GNUNET_FS_DownloadContext *dc);
276 * @param data contents of the file (or NULL if they were not inlined) 277 * @param data contents of the file (or NULL if they were not inlined)
277 */ 278 */
278static void 279static void
279trigger_recursive_download(void *cls, 280trigger_recursive_download (void *cls,
280 const char *filename, 281 const char *filename,
281 const struct GNUNET_FS_Uri *uri, 282 const struct GNUNET_FS_Uri *uri,
282 const struct GNUNET_CONTAINER_MetaData *meta, 283 const struct GNUNET_CONTAINER_MetaData *meta,
283 size_t length, 284 size_t length,
284 const void *data); 285 const void *data);
285 286
286 287
287/** 288/**
@@ -291,7 +292,7 @@ trigger_recursive_download(void *cls,
291 * @param dc context of download that just completed 292 * @param dc context of download that just completed
292 */ 293 */
293static void 294static void
294full_recursive_download(struct GNUNET_FS_DownloadContext *dc) 295full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
295{ 296{
296 size_t size; 297 size_t size;
297 uint64_t size64; 298 uint64_t size64;
@@ -299,64 +300,64 @@ full_recursive_download(struct GNUNET_FS_DownloadContext *dc)
299 struct GNUNET_DISK_FileHandle *h; 300 struct GNUNET_DISK_FileHandle *h;
300 struct GNUNET_DISK_MapHandle *m; 301 struct GNUNET_DISK_MapHandle *m;
301 302
302 size64 = GNUNET_FS_uri_chk_get_file_size(dc->uri); 303 size64 = GNUNET_FS_uri_chk_get_file_size (dc->uri);
303 size = (size_t)size64; 304 size = (size_t) size64;
304 if (size64 != (uint64_t)size) 305 if (size64 != (uint64_t) size)
305 { 306 {
306 GNUNET_log( 307 GNUNET_log (
307 GNUNET_ERROR_TYPE_ERROR, 308 GNUNET_ERROR_TYPE_ERROR,
308 _( 309 _ (
309 "Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); 310 "Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
310 return; 311 return;
311 } 312 }
312 if (NULL != dc->filename) 313 if (NULL != dc->filename)
313 { 314 {
314 h = GNUNET_DISK_file_open(dc->filename, 315 h = GNUNET_DISK_file_open (dc->filename,
315 GNUNET_DISK_OPEN_READ, 316 GNUNET_DISK_OPEN_READ,
316 GNUNET_DISK_PERM_NONE); 317 GNUNET_DISK_PERM_NONE);
317 } 318 }
318 else 319 else
319 { 320 {
320 GNUNET_assert(NULL != dc->temp_filename); 321 GNUNET_assert (NULL != dc->temp_filename);
321 h = GNUNET_DISK_file_open(dc->temp_filename, 322 h = GNUNET_DISK_file_open (dc->temp_filename,
322 GNUNET_DISK_OPEN_READ, 323 GNUNET_DISK_OPEN_READ,
323 GNUNET_DISK_PERM_NONE); 324 GNUNET_DISK_PERM_NONE);
324 } 325 }
325 if (NULL == h) 326 if (NULL == h)
326 return; /* oops */ 327 return; /* oops */
327 data = GNUNET_DISK_file_map(h, &m, GNUNET_DISK_MAP_TYPE_READ, size); 328 data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size);
328 if (NULL == data) 329 if (NULL == data)
329 { 330 {
330 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 331 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
331 _("Directory too large for system address space\n")); 332 _ ("Directory too large for system address space\n"));
332 } 333 }
333 else 334 else
334 { 335 {
335 if (GNUNET_OK != 336 if (GNUNET_OK !=
336 GNUNET_FS_directory_list_contents(size, 337 GNUNET_FS_directory_list_contents (size,
337 data, 338 data,
338 0, 339 0,
339 &trigger_recursive_download, 340 &trigger_recursive_download,
340 dc)) 341 dc))
341 { 342 {
342 GNUNET_log( 343 GNUNET_log (
343 GNUNET_ERROR_TYPE_WARNING, 344 GNUNET_ERROR_TYPE_WARNING,
344 _( 345 _ (
345 "Failed to access full directroy contents of `%s' for recursive download\n"), 346 "Failed to access full directroy contents of `%s' for recursive download\n"),
346 dc->filename); 347 dc->filename);
347 } 348 }
348 GNUNET_DISK_file_unmap(m); 349 GNUNET_DISK_file_unmap (m);
349 } 350 }
350 GNUNET_DISK_file_close(h); 351 GNUNET_DISK_file_close (h);
351 if (NULL == dc->filename) 352 if (NULL == dc->filename)
352 { 353 {
353 if (0 != unlink(dc->temp_filename)) 354 if (0 != unlink (dc->temp_filename))
354 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, 355 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
355 "unlink", 356 "unlink",
356 dc->temp_filename); 357 dc->temp_filename);
357 GNUNET_free(dc->temp_filename); 358 GNUNET_free (dc->temp_filename);
358 dc->temp_filename = NULL; 359 dc->temp_filename = NULL;
359 } 360 }
360} 361}
361 362
362 363
@@ -371,48 +372,48 @@ full_recursive_download(struct GNUNET_FS_DownloadContext *dc)
371 * @param dc download to check for completion of children 372 * @param dc download to check for completion of children
372 */ 373 */
373static void 374static void
374check_completed(struct GNUNET_FS_DownloadContext *dc) 375check_completed (struct GNUNET_FS_DownloadContext *dc)
375{ 376{
376 struct GNUNET_FS_ProgressInfo pi; 377 struct GNUNET_FS_ProgressInfo pi;
377 struct GNUNET_FS_DownloadContext *pos; 378 struct GNUNET_FS_DownloadContext *pos;
378 379
379 /* first, check if we need to download children */ 380 /* first, check if we need to download children */
380 if (is_recursive_download(dc)) 381 if (is_recursive_download (dc))
381 full_recursive_download(dc); 382 full_recursive_download (dc);
382 /* then, check if children are done already */ 383 /* then, check if children are done already */
383 for (pos = dc->child_head; NULL != pos; pos = pos->next) 384 for (pos = dc->child_head; NULL != pos; pos = pos->next)
384 { 385 {
385 if ((NULL == pos->emsg) && (pos->completed < pos->length)) 386 if ((NULL == pos->emsg) && (pos->completed < pos->length))
386 return; /* not done yet */ 387 return; /* not done yet */
387 if ((NULL != pos->child_head) && (pos->has_finished != GNUNET_YES)) 388 if ((NULL != pos->child_head) && (pos->has_finished != GNUNET_YES))
388 return; /* not transitively done yet */ 389 return; /* not transitively done yet */
389 } 390 }
390 /* All of our children are done, so mark this download done */ 391 /* All of our children are done, so mark this download done */
391 dc->has_finished = GNUNET_YES; 392 dc->has_finished = GNUNET_YES;
392 if (NULL != dc->job_queue) 393 if (NULL != dc->job_queue)
393 { 394 {
394 GNUNET_FS_dequeue_(dc->job_queue); 395 GNUNET_FS_dequeue_ (dc->job_queue);
395 dc->job_queue = NULL; 396 dc->job_queue = NULL;
396 } 397 }
397 if (NULL != dc->task) 398 if (NULL != dc->task)
398 { 399 {
399 GNUNET_SCHEDULER_cancel(dc->task); 400 GNUNET_SCHEDULER_cancel (dc->task);
400 dc->task = NULL; 401 dc->task = NULL;
401 } 402 }
402 if (NULL != dc->rfh) 403 if (NULL != dc->rfh)
403 { 404 {
404 GNUNET_break(GNUNET_OK == GNUNET_DISK_file_close(dc->rfh)); 405 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh));
405 dc->rfh = NULL; 406 dc->rfh = NULL;
406 } 407 }
407 GNUNET_FS_download_sync_(dc); 408 GNUNET_FS_download_sync_ (dc);
408 409
409 /* signal completion */ 410 /* signal completion */
410 pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED; 411 pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED;
411 GNUNET_FS_download_make_status_(&pi, dc); 412 GNUNET_FS_download_make_status_ (&pi, dc);
412 413
413 /* let parent know */ 414 /* let parent know */
414 if (NULL != dc->parent) 415 if (NULL != dc->parent)
415 check_completed(dc->parent); 416 check_completed (dc->parent);
416} 417}
417 418
418 419
@@ -427,10 +428,10 @@ check_completed(struct GNUNET_FS_DownloadContext *dc)
427 * @param data_len number of bytes in data 428 * @param data_len number of bytes in data
428 */ 429 */
429static void 430static void
430try_match_block(struct GNUNET_FS_DownloadContext *dc, 431try_match_block (struct GNUNET_FS_DownloadContext *dc,
431 struct DownloadRequest *dr, 432 struct DownloadRequest *dr,
432 const char *data, 433 const char *data,
433 size_t data_len) 434 size_t data_len)
434{ 435{
435 struct GNUNET_FS_ProgressInfo pi; 436 struct GNUNET_FS_ProgressInfo pi;
436 unsigned int i; 437 unsigned int i;
@@ -452,130 +453,130 @@ try_match_block(struct GNUNET_FS_DownloadContext *dc,
452 if (BRS_DOWNLOAD_UP == dr->state) 453 if (BRS_DOWNLOAD_UP == dr->state)
453 return; 454 return;
454 if (dr->depth > 0) 455 if (dr->depth > 0)
455 { 456 {
456 if ((dc->offset > 0) || 457 if ((dc->offset > 0) ||
457 (dc->length < GNUNET_ntohll(dc->uri->data.chk.file_length))) 458 (dc->length < GNUNET_ntohll (dc->uri->data.chk.file_length)))
458 { 459 {
459 /* NOTE: this test is not tight, but should suffice; the issue 460 /* NOTE: this test is not tight, but should suffice; the issue
460 here is that 'dr->num_children' may inherently only specify a 461 here is that 'dr->num_children' may inherently only specify a
461 smaller range than what is in the original file; 462 smaller range than what is in the original file;
462 thus, reconstruction of (some) inner blocks will fail. 463 thus, reconstruction of (some) inner blocks will fail.
463 FIXME: we might eventually want to write a tighter test to 464 FIXME: we might eventually want to write a tighter test to
464 maximize the circumstances under which we do succeed with 465 maximize the circumstances under which we do succeed with
465 IBlock reconstruction. (need good tests though). */ 466 IBlock reconstruction. (need good tests though). */
466 return; 467 return;
467 }
468 complete = GNUNET_YES;
469 for (i = 0; i < dr->num_children; i++)
470 {
471 drc = dr->children[i];
472 try_match_block(dc, drc, data, data_len);
473 if (drc->state != BRS_RECONSTRUCT_META_UP)
474 complete = GNUNET_NO;
475 else
476 chks[i] = drc->chk;
477 }
478 if (GNUNET_YES != complete)
479 return;
480 data = (const char *)chks;
481 dlen = dr->num_children * sizeof(struct ContentHashKey);
482 } 468 }
483 else 469 complete = GNUNET_YES;
470 for (i = 0; i < dr->num_children; i++)
484 { 471 {
485 if (dr->offset > data_len) 472 drc = dr->children[i];
486 return; /* oops */ 473 try_match_block (dc, drc, data, data_len);
487 dlen = GNUNET_MIN(data_len - dr->offset, DBLOCK_SIZE); 474 if (drc->state != BRS_RECONSTRUCT_META_UP)
475 complete = GNUNET_NO;
476 else
477 chks[i] = drc->chk;
488 } 478 }
489 GNUNET_CRYPTO_hash(&data[dr->offset], dlen, &in_chk.key); 479 if (GNUNET_YES != complete)
490 GNUNET_CRYPTO_hash_to_aes_key(&in_chk.key, &sk, &iv);
491 if (-1 ==
492 GNUNET_CRYPTO_symmetric_encrypt(&data[dr->offset], dlen, &sk, &iv, enc))
493 {
494 GNUNET_break(0);
495 return; 480 return;
496 } 481 data = (const char *) chks;
497 GNUNET_CRYPTO_hash(enc, dlen, &in_chk.query); 482 dlen = dr->num_children * sizeof(struct ContentHashKey);
483 }
484 else
485 {
486 if (dr->offset > data_len)
487 return; /* oops */
488 dlen = GNUNET_MIN (data_len - dr->offset, DBLOCK_SIZE);
489 }
490 GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key);
491 GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv);
492 if (-1 ==
493 GNUNET_CRYPTO_symmetric_encrypt (&data[dr->offset], dlen, &sk, &iv, enc))
494 {
495 GNUNET_break (0);
496 return;
497 }
498 GNUNET_CRYPTO_hash (enc, dlen, &in_chk.query);
498 switch (dr->state) 499 switch (dr->state)
499 { 500 {
500 case BRS_INIT: 501 case BRS_INIT:
501 dr->chk = in_chk; 502 dr->chk = in_chk;
502 dr->state = BRS_RECONSTRUCT_META_UP; 503 dr->state = BRS_RECONSTRUCT_META_UP;
503 break; 504 break;
504
505 case BRS_CHK_SET:
506 if (0 != memcmp(&in_chk, &dr->chk, sizeof(struct ContentHashKey)))
507 {
508 /* other peer provided bogus meta data */
509 GNUNET_break_op(0);
510 break;
511 }
512 /* write block to disk */
513 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
514 if (NULL != fn)
515 {
516 fh = GNUNET_DISK_file_open(fn,
517 GNUNET_DISK_OPEN_READWRITE |
518 GNUNET_DISK_OPEN_CREATE |
519 GNUNET_DISK_OPEN_TRUNCATE,
520 GNUNET_DISK_PERM_USER_READ |
521 GNUNET_DISK_PERM_USER_WRITE |
522 GNUNET_DISK_PERM_GROUP_READ |
523 GNUNET_DISK_PERM_OTHER_READ);
524 if (NULL == fh)
525 {
526 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "open", fn);
527 GNUNET_asprintf(&dc->emsg,
528 _("Failed to open file `%s' for writing"),
529 fn);
530 GNUNET_DISK_file_close(fh);
531 dr->state = BRS_ERROR;
532 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
533 pi.value.download.specifics.error.message = dc->emsg;
534 GNUNET_FS_download_make_status_(&pi, dc);
535 return;
536 }
537 if (data_len != GNUNET_DISK_file_write(fh, odata, odata_len))
538 {
539 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "write", fn);
540 GNUNET_asprintf(&dc->emsg,
541 _("Failed to open file `%s' for writing"),
542 fn);
543 GNUNET_DISK_file_close(fh);
544 dr->state = BRS_ERROR;
545 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
546 pi.value.download.specifics.error.message = dc->emsg;
547 GNUNET_FS_download_make_status_(&pi, dc);
548 return;
549 }
550 GNUNET_DISK_file_close(fh);
551 }
552 /* signal success */
553 dr->state = BRS_DOWNLOAD_UP;
554 dc->completed = dc->length;
555 GNUNET_FS_download_sync_(dc);
556 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
557 pi.value.download.specifics.progress.data = data;
558 pi.value.download.specifics.progress.offset = 0;
559 pi.value.download.specifics.progress.data_len = dlen;
560 pi.value.download.specifics.progress.depth = 0;
561 pi.value.download.specifics.progress.respect_offered = 0;
562 pi.value.download.specifics.progress.block_download_duration =
563 GNUNET_TIME_UNIT_ZERO;
564 GNUNET_FS_download_make_status_(&pi, dc);
565 if ((NULL != dc->filename) &&
566 (0 != truncate(dc->filename,
567 GNUNET_ntohll(dc->uri->data.chk.file_length))))
568 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING,
569 "truncate",
570 dc->filename);
571 check_completed(dc);
572 break;
573 505
574 default: 506 case BRS_CHK_SET:
575 /* how did we get here? */ 507 if (0 != memcmp (&in_chk, &dr->chk, sizeof(struct ContentHashKey)))
576 GNUNET_break(0); 508 {
509 /* other peer provided bogus meta data */
510 GNUNET_break_op (0);
577 break; 511 break;
578 } 512 }
513 /* write block to disk */
514 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
515 if (NULL != fn)
516 {
517 fh = GNUNET_DISK_file_open (fn,
518 GNUNET_DISK_OPEN_READWRITE
519 | GNUNET_DISK_OPEN_CREATE
520 | GNUNET_DISK_OPEN_TRUNCATE,
521 GNUNET_DISK_PERM_USER_READ
522 | GNUNET_DISK_PERM_USER_WRITE
523 | GNUNET_DISK_PERM_GROUP_READ
524 | GNUNET_DISK_PERM_OTHER_READ);
525 if (NULL == fh)
526 {
527 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
528 GNUNET_asprintf (&dc->emsg,
529 _ ("Failed to open file `%s' for writing"),
530 fn);
531 GNUNET_DISK_file_close (fh);
532 dr->state = BRS_ERROR;
533 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
534 pi.value.download.specifics.error.message = dc->emsg;
535 GNUNET_FS_download_make_status_ (&pi, dc);
536 return;
537 }
538 if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
539 {
540 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn);
541 GNUNET_asprintf (&dc->emsg,
542 _ ("Failed to open file `%s' for writing"),
543 fn);
544 GNUNET_DISK_file_close (fh);
545 dr->state = BRS_ERROR;
546 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
547 pi.value.download.specifics.error.message = dc->emsg;
548 GNUNET_FS_download_make_status_ (&pi, dc);
549 return;
550 }
551 GNUNET_DISK_file_close (fh);
552 }
553 /* signal success */
554 dr->state = BRS_DOWNLOAD_UP;
555 dc->completed = dc->length;
556 GNUNET_FS_download_sync_ (dc);
557 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
558 pi.value.download.specifics.progress.data = data;
559 pi.value.download.specifics.progress.offset = 0;
560 pi.value.download.specifics.progress.data_len = dlen;
561 pi.value.download.specifics.progress.depth = 0;
562 pi.value.download.specifics.progress.respect_offered = 0;
563 pi.value.download.specifics.progress.block_download_duration =
564 GNUNET_TIME_UNIT_ZERO;
565 GNUNET_FS_download_make_status_ (&pi, dc);
566 if ((NULL != dc->filename) &&
567 (0 != truncate (dc->filename,
568 GNUNET_ntohll (dc->uri->data.chk.file_length))))
569 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
570 "truncate",
571 dc->filename);
572 check_completed (dc);
573 break;
574
575 default:
576 /* how did we get here? */
577 GNUNET_break (0);
578 break;
579 }
579} 580}
580 581
581 582
@@ -598,27 +599,27 @@ try_match_block(struct GNUNET_FS_DownloadContext *dc,
598 * @return 0 to continue extracting, 1 to abort 599 * @return 0 to continue extracting, 1 to abort
599 */ 600 */
600static int 601static int
601match_full_data(void *cls, 602match_full_data (void *cls,
602 const char *plugin_name, 603 const char *plugin_name,
603 enum EXTRACTOR_MetaType type, 604 enum EXTRACTOR_MetaType type,
604 enum EXTRACTOR_MetaFormat format, 605 enum EXTRACTOR_MetaFormat format,
605 const char *data_mime_type, 606 const char *data_mime_type,
606 const char *data, 607 const char *data,
607 size_t data_len) 608 size_t data_len)
608{ 609{
609 struct GNUNET_FS_DownloadContext *dc = cls; 610 struct GNUNET_FS_DownloadContext *dc = cls;
610 611
611 if (EXTRACTOR_METATYPE_GNUNET_FULL_DATA != type) 612 if (EXTRACTOR_METATYPE_GNUNET_FULL_DATA != type)
612 return 0; 613 return 0;
613 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
614 "Found %u bytes of FD!\n", 615 "Found %u bytes of FD!\n",
615 (unsigned int)data_len); 616 (unsigned int) data_len);
616 if (GNUNET_FS_uri_chk_get_file_size(dc->uri) != data_len) 617 if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len)
617 { 618 {
618 GNUNET_break_op(0); 619 GNUNET_break_op (0);
619 return 1; /* bogus meta data */ 620 return 1; /* bogus meta data */
620 } 621 }
621 try_match_block(dc, dc->top_request, data, data_len); 622 try_match_block (dc, dc->top_request, data, data_len);
622 return 1; 623 return 1;
623} 624}
624 625
@@ -630,20 +631,20 @@ match_full_data(void *cls,
630 * @param dr download request that is done 631 * @param dr download request that is done
631 */ 632 */
632static void 633static void
633propagate_up(struct DownloadRequest *dr) 634propagate_up (struct DownloadRequest *dr)
634{ 635{
635 unsigned int i; 636 unsigned int i;
636 637
637 do 638 do
638 { 639 {
639 dr->state = BRS_DOWNLOAD_UP; 640 dr->state = BRS_DOWNLOAD_UP;
640 dr = dr->parent; 641 dr = dr->parent;
641 if (NULL == dr) 642 if (NULL == dr)
643 break;
644 for (i = 0; i < dr->num_children; i++)
645 if (dr->children[i]->state != BRS_DOWNLOAD_UP)
642 break; 646 break;
643 for (i = 0; i < dr->num_children; i++) 647 }
644 if (dr->children[i]->state != BRS_DOWNLOAD_UP)
645 break;
646 }
647 while (i == dr->num_children); 648 while (i == dr->num_children);
648} 649}
649 650
@@ -659,8 +660,8 @@ propagate_up(struct DownloadRequest *dr)
659 * @param dr block to reconstruct 660 * @param dr block to reconstruct
660 */ 661 */
661static void 662static void
662try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc, 663try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
663 struct DownloadRequest *dr) 664 struct DownloadRequest *dr)
664{ 665{
665 uint64_t off; 666 uint64_t off;
666 char block[DBLOCK_SIZE]; 667 char block[DBLOCK_SIZE];
@@ -673,64 +674,64 @@ try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc,
673 const struct ContentHashKey *chks; 674 const struct ContentHashKey *chks;
674 int up_done; 675 int up_done;
675 676
676 GNUNET_assert(NULL != dc->rfh); 677 GNUNET_assert (NULL != dc->rfh);
677 GNUNET_assert(BRS_CHK_SET == dr->state); 678 GNUNET_assert (BRS_CHK_SET == dr->state);
678 total = GNUNET_FS_uri_chk_get_file_size(dc->uri); 679 total = GNUNET_FS_uri_chk_get_file_size (dc->uri);
679 GNUNET_assert(dr->depth < dc->treedepth); 680 GNUNET_assert (dr->depth < dc->treedepth);
680 len = GNUNET_FS_tree_calculate_block_size(total, dr->offset, dr->depth); 681 len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth);
681 GNUNET_assert(len <= DBLOCK_SIZE); 682 GNUNET_assert (len <= DBLOCK_SIZE);
682 off = compute_disk_offset(total, dr->offset, dr->depth); 683 off = compute_disk_offset (total, dr->offset, dr->depth);
683 if (dc->old_file_size < off + len) 684 if (dc->old_file_size < off + len)
684 return; /* failure */ 685 return; /* failure */
685 if (off != GNUNET_DISK_file_seek(dc->rfh, off, GNUNET_DISK_SEEK_SET)) 686 if (off != GNUNET_DISK_file_seek (dc->rfh, off, GNUNET_DISK_SEEK_SET))
686 { 687 {
687 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, "seek", dc->filename); 688 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "seek", dc->filename);
688 return; /* failure */ 689 return; /* failure */
689 } 690 }
690 if (len != GNUNET_DISK_file_read(dc->rfh, block, len)) 691 if (len != GNUNET_DISK_file_read (dc->rfh, block, len))
691 { 692 {
692 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, "read", dc->filename); 693 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "read", dc->filename);
693 return; /* failure */ 694 return; /* failure */
694 } 695 }
695 GNUNET_CRYPTO_hash(block, len, &key); 696 GNUNET_CRYPTO_hash (block, len, &key);
696 if (0 != memcmp(&key, &dr->chk.key, sizeof(struct GNUNET_HashCode))) 697 if (0 != memcmp (&key, &dr->chk.key, sizeof(struct GNUNET_HashCode)))
697 return; /* mismatch */ 698 return; /* mismatch */
698 if (GNUNET_OK != 699 if (GNUNET_OK !=
699 encrypt_existing_match(dc, &dr->chk, dr, block, len, GNUNET_NO)) 700 encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO))
701 {
702 /* hash matches but encrypted block does not, really bad */
703 dr->state = BRS_ERROR;
704 /* propagate up */
705 while (NULL != dr->parent)
700 { 706 {
701 /* hash matches but encrypted block does not, really bad */ 707 dr = dr->parent;
702 dr->state = BRS_ERROR; 708 dr->state = BRS_ERROR;
703 /* propagate up */
704 while (NULL != dr->parent)
705 {
706 dr = dr->parent;
707 dr->state = BRS_ERROR;
708 }
709 return;
710 } 709 }
710 return;
711 }
711 /* block matches */ 712 /* block matches */
712 dr->state = BRS_DOWNLOAD_DOWN; 713 dr->state = BRS_DOWNLOAD_DOWN;
713 714
714 /* set CHKs for children */ 715 /* set CHKs for children */
715 up_done = GNUNET_YES; 716 up_done = GNUNET_YES;
716 chks = (const struct ContentHashKey *)block; 717 chks = (const struct ContentHashKey *) block;
717 for (i = 0; i < dr->num_children; i++) 718 for (i = 0; i < dr->num_children; i++)
718 { 719 {
719 drc = dr->children[i]; 720 drc = dr->children[i];
720 GNUNET_assert(drc->offset >= dr->offset); 721 GNUNET_assert (drc->offset >= dr->offset);
721 child_block_size = GNUNET_FS_tree_compute_tree_size(drc->depth); 722 child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
722 GNUNET_assert(0 == (drc->offset - dr->offset) % child_block_size); 723 GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
723 if (BRS_INIT == drc->state) 724 if (BRS_INIT == drc->state)
724 { 725 {
725 drc->state = BRS_CHK_SET; 726 drc->state = BRS_CHK_SET;
726 drc->chk = chks[drc->chk_idx]; 727 drc->chk = chks[drc->chk_idx];
727 try_top_down_reconstruction(dc, drc); 728 try_top_down_reconstruction (dc, drc);
728 } 729 }
729 if (BRS_DOWNLOAD_UP != drc->state) 730 if (BRS_DOWNLOAD_UP != drc->state)
730 up_done = GNUNET_NO; /* children not all done */ 731 up_done = GNUNET_NO; /* children not all done */
731 } 732 }
732 if (GNUNET_YES == up_done) 733 if (GNUNET_YES == up_done)
733 propagate_up(dr); /* children all done (or no children...) */ 734 propagate_up (dr); /* children all done (or no children...) */
734} 735}
735 736
736 737
@@ -743,26 +744,26 @@ try_top_down_reconstruction(struct GNUNET_FS_DownloadContext *dc,
743 * @return #GNUNET_OK 744 * @return #GNUNET_OK
744 */ 745 */
745static int 746static int
746retry_entry(void *cls, const struct GNUNET_HashCode *key, void *entry) 747retry_entry (void *cls, const struct GNUNET_HashCode *key, void *entry)
747{ 748{
748 struct GNUNET_FS_DownloadContext *dc = cls; 749 struct GNUNET_FS_DownloadContext *dc = cls;
749 struct DownloadRequest *dr = entry; 750 struct DownloadRequest *dr = entry;
750 struct SearchMessage *sm; 751 struct SearchMessage *sm;
751 struct GNUNET_MQ_Envelope *env; 752 struct GNUNET_MQ_Envelope *env;
752 753
753 env = GNUNET_MQ_msg(sm, GNUNET_MESSAGE_TYPE_FS_START_SEARCH); 754 env = GNUNET_MQ_msg (sm, GNUNET_MESSAGE_TYPE_FS_START_SEARCH);
754 if (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY)) 755 if (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY))
755 sm->options = htonl(GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY); 756 sm->options = htonl (GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY);
756 else 757 else
757 sm->options = htonl(GNUNET_FS_SEARCH_OPTION_NONE); 758 sm->options = htonl (GNUNET_FS_SEARCH_OPTION_NONE);
758 if (0 == dr->depth) 759 if (0 == dr->depth)
759 sm->type = htonl(GNUNET_BLOCK_TYPE_FS_DBLOCK); 760 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
760 else 761 else
761 sm->type = htonl(GNUNET_BLOCK_TYPE_FS_IBLOCK); 762 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
762 sm->anonymity_level = htonl(dc->anonymity); 763 sm->anonymity_level = htonl (dc->anonymity);
763 sm->target = dc->target; 764 sm->target = dc->target;
764 sm->query = dr->chk.query; 765 sm->query = dr->chk.query;
765 GNUNET_MQ_send(dc->mq, env); 766 GNUNET_MQ_send (dc->mq, env);
766 return GNUNET_OK; 767 return GNUNET_OK;
767} 768}
768 769
@@ -774,62 +775,62 @@ retry_entry(void *cls, const struct GNUNET_HashCode *key, void *entry)
774 * @param dr request to schedule 775 * @param dr request to schedule
775 */ 776 */
776static void 777static void
777schedule_block_download(struct GNUNET_FS_DownloadContext *dc, 778schedule_block_download (struct GNUNET_FS_DownloadContext *dc,
778 struct DownloadRequest *dr) 779 struct DownloadRequest *dr)
779{ 780{
780 unsigned int i; 781 unsigned int i;
781 782
782 switch (dr->state) 783 switch (dr->state)
783 { 784 {
784 case BRS_INIT: 785 case BRS_INIT:
785 GNUNET_assert(0); 786 GNUNET_assert (0);
786 break; 787 break;
787 788
788 case BRS_RECONSTRUCT_DOWN: 789 case BRS_RECONSTRUCT_DOWN:
789 GNUNET_assert(0); 790 GNUNET_assert (0);
790 break; 791 break;
791 792
792 case BRS_RECONSTRUCT_META_UP: 793 case BRS_RECONSTRUCT_META_UP:
793 GNUNET_assert(0); 794 GNUNET_assert (0);
794 break; 795 break;
795 796
796 case BRS_RECONSTRUCT_UP: 797 case BRS_RECONSTRUCT_UP:
797 GNUNET_assert(0); 798 GNUNET_assert (0);
798 break; 799 break;
799 800
800 case BRS_CHK_SET: 801 case BRS_CHK_SET:
801 /* normal case, start download */ 802 /* normal case, start download */
802 break; 803 break;
803 804
804 case BRS_DOWNLOAD_DOWN: 805 case BRS_DOWNLOAD_DOWN:
805 for (i = 0; i < dr->num_children; i++) 806 for (i = 0; i < dr->num_children; i++)
806 schedule_block_download(dc, dr->children[i]); 807 schedule_block_download (dc, dr->children[i]);
807 return; 808 return;
808 809
809 case BRS_DOWNLOAD_UP: 810 case BRS_DOWNLOAD_UP:
810 /* We're done! */ 811 /* We're done! */
811 return; 812 return;
812 813
813 case BRS_ERROR: 814 case BRS_ERROR:
814 GNUNET_break(0); 815 GNUNET_break (0);
815 return; 816 return;
816 } 817 }
817 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
818 "Scheduling download at offset %llu and depth %u for `%s'\n", 819 "Scheduling download at offset %llu and depth %u for `%s'\n",
819 (unsigned long long)dr->offset, 820 (unsigned long long) dr->offset,
820 dr->depth, 821 dr->depth,
821 GNUNET_h2s(&dr->chk.query)); 822 GNUNET_h2s (&dr->chk.query));
822 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains_value(dc->active, 823 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains_value (dc->active,
823 &dr->chk.query, 824 &dr->chk.query,
824 dr)) 825 dr))
825 return; /* already active */ 826 return; /* already active */
826 GNUNET_CONTAINER_multihashmap_put(dc->active, 827 GNUNET_CONTAINER_multihashmap_put (dc->active,
827 &dr->chk.query, 828 &dr->chk.query,
828 dr, 829 dr,
829 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 830 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
830 if (NULL == dc->mq) 831 if (NULL == dc->mq)
831 return; /* download not active */ 832 return; /* download not active */
832 retry_entry(dc, &dr->chk.query, dr); 833 retry_entry (dc, &dr->chk.query, dr);
833} 834}
834 835
835 836
@@ -847,12 +848,12 @@ schedule_block_download(struct GNUNET_FS_DownloadContext *dc,
847 * @param data contents of the file (or NULL if they were not inlined) 848 * @param data contents of the file (or NULL if they were not inlined)
848 */ 849 */
849static void 850static void
850trigger_recursive_download(void *cls, 851trigger_recursive_download (void *cls,
851 const char *filename, 852 const char *filename,
852 const struct GNUNET_FS_Uri *uri, 853 const struct GNUNET_FS_Uri *uri,
853 const struct GNUNET_CONTAINER_MetaData *meta, 854 const struct GNUNET_CONTAINER_MetaData *meta,
854 size_t length, 855 size_t length,
855 const void *data) 856 const void *data)
856{ 857{
857 struct GNUNET_FS_DownloadContext *dc = cls; 858 struct GNUNET_FS_DownloadContext *dc = cls;
858 struct GNUNET_FS_DownloadContext *cpos; 859 struct GNUNET_FS_DownloadContext *cpos;
@@ -869,121 +870,121 @@ trigger_recursive_download(void *cls,
869 return; /* entry for the directory itself */ 870 return; /* entry for the directory itself */
870 cpos = dc->child_head; 871 cpos = dc->child_head;
871 while (NULL != cpos) 872 while (NULL != cpos)
872 { 873 {
873 if ((GNUNET_FS_uri_test_equal(uri, cpos->uri)) || 874 if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) ||
874 ((NULL != filename) && (0 == strcmp(cpos->filename, filename)))) 875 ((NULL != filename) && (0 == strcmp (cpos->filename, filename))))
875 break; 876 break;
876 cpos = cpos->next; 877 cpos = cpos->next;
877 } 878 }
878 if (NULL != cpos) 879 if (NULL != cpos)
879 return; /* already exists */ 880 return; /* already exists */
880 fn = NULL; 881 fn = NULL;
881 if (NULL == filename) 882 if (NULL == filename)
882 { 883 {
883 fn = GNUNET_FS_meta_data_suggest_filename(meta); 884 fn = GNUNET_FS_meta_data_suggest_filename (meta);
884 if (NULL == fn) 885 if (NULL == fn)
885 { 886 {
886 us = GNUNET_FS_uri_to_string(uri); 887 us = GNUNET_FS_uri_to_string (uri);
887 fn = GNUNET_strdup(&us[strlen(GNUNET_FS_URI_CHK_PREFIX)]); 888 fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]);
888 GNUNET_free(us); 889 GNUNET_free (us);
889 } 890 }
890 else if ('.' == fn[0]) 891 else if ('.' == fn[0])
891 { 892 {
892 ext = fn; 893 ext = fn;
893 us = GNUNET_FS_uri_to_string(uri); 894 us = GNUNET_FS_uri_to_string (uri);
894 GNUNET_asprintf(&fn, 895 GNUNET_asprintf (&fn,
895 "%s%s", 896 "%s%s",
896 &us[strlen(GNUNET_FS_URI_CHK_PREFIX)], 897 &us[strlen (GNUNET_FS_URI_CHK_PREFIX)],
897 ext); 898 ext);
898 GNUNET_free(ext); 899 GNUNET_free (ext);
899 GNUNET_free(us); 900 GNUNET_free (us);
900 } 901 }
901 /* change '\' to '/' (this should have happened 902 /* change '\' to '/' (this should have happened
902 * during insertion, but malicious peers may 903 * during insertion, but malicious peers may
903 * not have done this) */ 904 * not have done this) */
904 while (NULL != (pos = strstr(fn, "\\"))) 905 while (NULL != (pos = strstr (fn, "\\")))
905 *pos = '/'; 906 *pos = '/';
906 /* remove '../' everywhere (again, well-behaved 907 /* remove '../' everywhere (again, well-behaved
907 * peers don't do this, but don't trust that 908 * peers don't do this, but don't trust that
908 * we did not get something nasty) */ 909 * we did not get something nasty) */
909 while (NULL != (pos = strstr(fn, "../"))) 910 while (NULL != (pos = strstr (fn, "../")))
910 { 911 {
911 pos[0] = '_'; 912 pos[0] = '_';
912 pos[1] = '_'; 913 pos[1] = '_';
913 pos[2] = '_'; 914 pos[2] = '_';
914 } 915 }
915 filename = fn; 916 filename = fn;
916 } 917 }
917 if (NULL == dc->filename) 918 if (NULL == dc->filename)
918 { 919 {
919 full_name = NULL; 920 full_name = NULL;
920 } 921 }
921 else 922 else
922 { 923 {
923 dn = GNUNET_strdup(dc->filename); 924 dn = GNUNET_strdup (dc->filename);
924 GNUNET_break( 925 GNUNET_break (
925 (strlen(dn) >= strlen(GNUNET_FS_DIRECTORY_EXT)) && 926 (strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
926 (NULL != strstr(dn + strlen(dn) - strlen(GNUNET_FS_DIRECTORY_EXT), 927 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
927 GNUNET_FS_DIRECTORY_EXT))); 928 GNUNET_FS_DIRECTORY_EXT)));
928 sfn = GNUNET_strdup(filename); 929 sfn = GNUNET_strdup (filename);
929 while ((strlen(sfn) > 0) && ('/' == filename[strlen(sfn) - 1])) 930 while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1]))
930 sfn[strlen(sfn) - 1] = '\0'; 931 sfn[strlen (sfn) - 1] = '\0';
931 if ((strlen(dn) >= strlen(GNUNET_FS_DIRECTORY_EXT)) && 932 if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
932 (NULL != strstr(dn + strlen(dn) - strlen(GNUNET_FS_DIRECTORY_EXT), 933 (NULL != strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
933 GNUNET_FS_DIRECTORY_EXT))) 934 GNUNET_FS_DIRECTORY_EXT)))
934 dn[strlen(dn) - strlen(GNUNET_FS_DIRECTORY_EXT)] = '\0'; 935 dn[strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0';
935 if ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory(meta)) && 936 if ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) &&
936 ((strlen(filename) < strlen(GNUNET_FS_DIRECTORY_EXT)) || 937 ((strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) ||
937 (NULL == strstr(filename + strlen(filename) - 938 (NULL == strstr (filename + strlen (filename)
938 strlen(GNUNET_FS_DIRECTORY_EXT), 939 - strlen (GNUNET_FS_DIRECTORY_EXT),
939 GNUNET_FS_DIRECTORY_EXT)))) 940 GNUNET_FS_DIRECTORY_EXT))))
940 { 941 {
941 GNUNET_asprintf(&full_name, 942 GNUNET_asprintf (&full_name,
942 "%s%s%s%s", 943 "%s%s%s%s",
943 dn, 944 dn,
944 DIR_SEPARATOR_STR, 945 DIR_SEPARATOR_STR,
945 sfn, 946 sfn,
946 GNUNET_FS_DIRECTORY_EXT); 947 GNUNET_FS_DIRECTORY_EXT);
947 } 948 }
948 else 949 else
949 { 950 {
950 GNUNET_asprintf(&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn); 951 GNUNET_asprintf (&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn);
951 } 952 }
952 GNUNET_free(sfn); 953 GNUNET_free (sfn);
953 GNUNET_free(dn); 954 GNUNET_free (dn);
954 } 955 }
955 if ((NULL != full_name) && 956 if ((NULL != full_name) &&
956 (GNUNET_OK != GNUNET_DISK_directory_create_for_file(full_name))) 957 (GNUNET_OK != GNUNET_DISK_directory_create_for_file (full_name)))
957 { 958 {
958 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
959 _( 960 _ (
960 "Failed to create directory for recursive download of `%s'\n"), 961 "Failed to create directory for recursive download of `%s'\n"),
961 full_name); 962 full_name);
962 GNUNET_free(full_name); 963 GNUNET_free (full_name);
963 GNUNET_free_non_null(fn); 964 GNUNET_free_non_null (fn);
964 return; 965 return;
965 } 966 }
966 967
967 temp_name = NULL; 968 temp_name = NULL;
968 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 969 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
969 "Triggering recursive download of size %llu with %u bytes MD\n", 970 "Triggering recursive download of size %llu with %u bytes MD\n",
970 (unsigned long long)GNUNET_FS_uri_chk_get_file_size(uri), 971 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri),
971 (unsigned int)GNUNET_CONTAINER_meta_data_get_serialized_size( 972 (unsigned int) GNUNET_CONTAINER_meta_data_get_serialized_size (
972 meta)); 973 meta));
973 GNUNET_FS_download_start(dc->h, 974 GNUNET_FS_download_start (dc->h,
974 uri, 975 uri,
975 meta, 976 meta,
976 full_name, 977 full_name,
977 temp_name, 978 temp_name,
978 0, 979 0,
979 GNUNET_FS_uri_chk_get_file_size(uri), 980 GNUNET_FS_uri_chk_get_file_size (uri),
980 dc->anonymity, 981 dc->anonymity,
981 dc->options, 982 dc->options,
982 NULL, 983 NULL,
983 dc); 984 dc);
984 GNUNET_free_non_null(full_name); 985 GNUNET_free_non_null (full_name);
985 GNUNET_free_non_null(temp_name); 986 GNUNET_free_non_null (temp_name);
986 GNUNET_free_non_null(fn); 987 GNUNET_free_non_null (fn);
987} 988}
988 989
989 990
@@ -993,14 +994,14 @@ trigger_recursive_download(void *cls,
993 * @param dr request to free 994 * @param dr request to free
994 */ 995 */
995void 996void
996GNUNET_FS_free_download_request_(struct DownloadRequest *dr) 997GNUNET_FS_free_download_request_ (struct DownloadRequest *dr)
997{ 998{
998 if (NULL == dr) 999 if (NULL == dr)
999 return; 1000 return;
1000 for (unsigned int i = 0; i < dr->num_children; i++) 1001 for (unsigned int i = 0; i < dr->num_children; i++)
1001 GNUNET_FS_free_download_request_(dr->children[i]); 1002 GNUNET_FS_free_download_request_ (dr->children[i]);
1002 GNUNET_free_non_null(dr->children); 1003 GNUNET_free_non_null (dr->children);
1003 GNUNET_free(dr); 1004 GNUNET_free (dr);
1004} 1005}
1005 1006
1006 1007
@@ -1014,9 +1015,9 @@ GNUNET_FS_free_download_request_(struct DownloadRequest *dr)
1014 * @return #GNUNET_YES (we should continue to iterate); unless serious error 1015 * @return #GNUNET_YES (we should continue to iterate); unless serious error
1015 */ 1016 */
1016static int 1017static int
1017process_result_with_request(void *cls, 1018process_result_with_request (void *cls,
1018 const struct GNUNET_HashCode *key, 1019 const struct GNUNET_HashCode *key,
1019 void *value) 1020 void *value)
1020{ 1021{
1021 struct ProcessResultClosure *prc = cls; 1022 struct ProcessResultClosure *prc = cls;
1022 struct DownloadRequest *dr = value; 1023 struct DownloadRequest *dr = value;
@@ -1033,132 +1034,132 @@ process_result_with_request(void *cls,
1033 int i; 1034 int i;
1034 struct ContentHashKey *chkarr; 1035 struct ContentHashKey *chkarr;
1035 1036
1036 GNUNET_log( 1037 GNUNET_log (
1037 GNUNET_ERROR_TYPE_DEBUG, 1038 GNUNET_ERROR_TYPE_DEBUG,
1038 "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n", 1039 "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n",
1039 (unsigned int)prc->size, 1040 (unsigned int) prc->size,
1040 GNUNET_h2s(key), 1041 GNUNET_h2s (key),
1041 dr->depth, 1042 dr->depth,
1042 (unsigned long long)dr->offset, 1043 (unsigned long long) dr->offset,
1043 (unsigned long long)GNUNET_ntohll(dc->uri->data.chk.file_length)); 1044 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length));
1044 bs = GNUNET_FS_tree_calculate_block_size(GNUNET_ntohll( 1045 bs = GNUNET_FS_tree_calculate_block_size (GNUNET_ntohll (
1045 dc->uri->data.chk.file_length), 1046 dc->uri->data.chk.file_length),
1046 dr->offset, 1047 dr->offset,
1047 dr->depth); 1048 dr->depth);
1048 if (prc->size != bs) 1049 if (prc->size != bs)
1050 {
1051 GNUNET_asprintf (
1052 &dc->emsg,
1053 _ (
1054 "Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"),
1055 bs,
1056 dr->depth,
1057 (unsigned long long) dr->offset,
1058 (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length),
1059 prc->size);
1060 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", dc->emsg);
1061 while (NULL != dr->parent)
1049 { 1062 {
1050 GNUNET_asprintf(
1051 &dc->emsg,
1052 _(
1053 "Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"),
1054 bs,
1055 dr->depth,
1056 (unsigned long long)dr->offset,
1057 (unsigned long long)GNUNET_ntohll(dc->uri->data.chk.file_length),
1058 prc->size);
1059 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", dc->emsg);
1060 while (NULL != dr->parent)
1061 {
1062 dr->state = BRS_ERROR;
1063 dr = dr->parent;
1064 }
1065 dr->state = BRS_ERROR; 1063 dr->state = BRS_ERROR;
1066 goto signal_error; 1064 dr = dr->parent;
1067 } 1065 }
1066 dr->state = BRS_ERROR;
1067 goto signal_error;
1068 }
1068 1069
1069 (void)GNUNET_CONTAINER_multihashmap_remove(dc->active, &prc->query, dr); 1070 (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, &prc->query, dr);
1070 GNUNET_CRYPTO_hash_to_aes_key(&dr->chk.key, &skey, &iv); 1071 GNUNET_CRYPTO_hash_to_aes_key (&dr->chk.key, &skey, &iv);
1071 if (-1 == 1072 if (-1 ==
1072 GNUNET_CRYPTO_symmetric_decrypt(prc->data, prc->size, &skey, &iv, pt)) 1073 GNUNET_CRYPTO_symmetric_decrypt (prc->data, prc->size, &skey, &iv, pt))
1073 { 1074 {
1074 GNUNET_break(0); 1075 GNUNET_break (0);
1075 dc->emsg = GNUNET_strdup(_("internal error decrypting content")); 1076 dc->emsg = GNUNET_strdup (_ ("internal error decrypting content"));
1076 goto signal_error; 1077 goto signal_error;
1077 } 1078 }
1078 off = compute_disk_offset(GNUNET_ntohll(dc->uri->data.chk.file_length), 1079 off = compute_disk_offset (GNUNET_ntohll (dc->uri->data.chk.file_length),
1079 dr->offset, 1080 dr->offset,
1080 dr->depth); 1081 dr->depth);
1081 /* save to disk */ 1082 /* save to disk */
1082 if ((GNUNET_YES == prc->do_store) && 1083 if ((GNUNET_YES == prc->do_store) &&
1083 ((NULL != dc->filename) || (is_recursive_download(dc))) && 1084 ((NULL != dc->filename) || (is_recursive_download (dc))) &&
1084 ((dr->depth == dc->treedepth) || 1085 ((dr->depth == dc->treedepth) ||
1085 (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES)))) 1086 (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES))))
1087 {
1088 fh = GNUNET_DISK_file_open (NULL != dc->filename ? dc->filename
1089 : dc->temp_filename,
1090 GNUNET_DISK_OPEN_READWRITE
1091 | GNUNET_DISK_OPEN_CREATE,
1092 GNUNET_DISK_PERM_USER_READ
1093 | GNUNET_DISK_PERM_USER_WRITE
1094 | GNUNET_DISK_PERM_GROUP_READ
1095 | GNUNET_DISK_PERM_OTHER_READ);
1096 if (NULL == fh)
1097 {
1098 GNUNET_asprintf (&dc->emsg,
1099 _ ("Download failed: could not open file `%s': %s"),
1100 dc->filename,
1101 strerror (errno));
1102 goto signal_error;
1103 }
1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1105 "Saving decrypted block to disk at offset %llu\n",
1106 (unsigned long long) off);
1107 if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)))
1086 { 1108 {
1087 fh = GNUNET_DISK_file_open(NULL != dc->filename ? dc->filename 1109 GNUNET_asprintf (&dc->emsg,
1088 : dc->temp_filename, 1110 _ ("Failed to seek to offset %llu in file `%s': %s"),
1089 GNUNET_DISK_OPEN_READWRITE | 1111 (unsigned long long) off,
1090 GNUNET_DISK_OPEN_CREATE, 1112 dc->filename,
1091 GNUNET_DISK_PERM_USER_READ | 1113 strerror (errno));
1092 GNUNET_DISK_PERM_USER_WRITE | 1114 goto signal_error;
1093 GNUNET_DISK_PERM_GROUP_READ |
1094 GNUNET_DISK_PERM_OTHER_READ);
1095 if (NULL == fh)
1096 {
1097 GNUNET_asprintf(&dc->emsg,
1098 _("Download failed: could not open file `%s': %s"),
1099 dc->filename,
1100 strerror(errno));
1101 goto signal_error;
1102 }
1103 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1104 "Saving decrypted block to disk at offset %llu\n",
1105 (unsigned long long)off);
1106 if ((off != GNUNET_DISK_file_seek(fh, off, GNUNET_DISK_SEEK_SET)))
1107 {
1108 GNUNET_asprintf(&dc->emsg,
1109 _("Failed to seek to offset %llu in file `%s': %s"),
1110 (unsigned long long)off,
1111 dc->filename,
1112 strerror(errno));
1113 goto signal_error;
1114 }
1115 if (prc->size != GNUNET_DISK_file_write(fh, pt, prc->size))
1116 {
1117 GNUNET_asprintf(
1118 &dc->emsg,
1119 _("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
1120 (unsigned int)prc->size,
1121 (unsigned long long)off,
1122 dc->filename,
1123 strerror(errno));
1124 goto signal_error;
1125 }
1126 GNUNET_break(GNUNET_OK == GNUNET_DISK_file_close(fh));
1127 fh = NULL;
1128 } 1115 }
1129 1116 if (prc->size != GNUNET_DISK_file_write (fh, pt, prc->size))
1130 if (0 == dr->depth)
1131 { 1117 {
1132 /* DBLOCK, update progress and try recursion if applicable */ 1118 GNUNET_asprintf (
1133 app = prc->size; 1119 &dc->emsg,
1134 if (dr->offset < dc->offset) 1120 _ ("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
1135 { 1121 (unsigned int) prc->size,
1136 /* starting offset begins in the middle of pt, 1122 (unsigned long long) off,
1137 * do not count first bytes as progress */ 1123 dc->filename,
1138 GNUNET_assert(app > (dc->offset - dr->offset)); 1124 strerror (errno));
1139 app -= (dc->offset - dr->offset); 1125 goto signal_error;
1140 }
1141 if (dr->offset + prc->size > dc->offset + dc->length)
1142 {
1143 /* end of block is after relevant range,
1144 * do not count last bytes as progress */
1145 GNUNET_assert(app >
1146 (dr->offset + prc->size) - (dc->offset + dc->length));
1147 app -= (dr->offset + prc->size) - (dc->offset + dc->length);
1148 }
1149 dc->completed += app;
1150
1151 /* do recursive download if option is set and either meta data
1152 * says it is a directory or if no meta data is given AND filename
1153 * ends in '.gnd' (top-level case) */
1154 if (is_recursive_download(dc))
1155 GNUNET_FS_directory_list_contents(prc->size,
1156 pt,
1157 off,
1158 &trigger_recursive_download,
1159 dc);
1160 } 1126 }
1161 GNUNET_assert(dc->completed <= dc->length); 1127 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
1128 fh = NULL;
1129 }
1130
1131 if (0 == dr->depth)
1132 {
1133 /* DBLOCK, update progress and try recursion if applicable */
1134 app = prc->size;
1135 if (dr->offset < dc->offset)
1136 {
1137 /* starting offset begins in the middle of pt,
1138 * do not count first bytes as progress */
1139 GNUNET_assert (app > (dc->offset - dr->offset));
1140 app -= (dc->offset - dr->offset);
1141 }
1142 if (dr->offset + prc->size > dc->offset + dc->length)
1143 {
1144 /* end of block is after relevant range,
1145 * do not count last bytes as progress */
1146 GNUNET_assert (app >
1147 (dr->offset + prc->size) - (dc->offset + dc->length));
1148 app -= (dr->offset + prc->size) - (dc->offset + dc->length);
1149 }
1150 dc->completed += app;
1151
1152 /* do recursive download if option is set and either meta data
1153 * says it is a directory or if no meta data is given AND filename
1154 * ends in '.gnd' (top-level case) */
1155 if (is_recursive_download (dc))
1156 GNUNET_FS_directory_list_contents (prc->size,
1157 pt,
1158 off,
1159 &trigger_recursive_download,
1160 dc);
1161 }
1162 GNUNET_assert (dc->completed <= dc->length);
1162 dr->state = BRS_DOWNLOAD_DOWN; 1163 dr->state = BRS_DOWNLOAD_DOWN;
1163 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; 1164 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
1164 pi.value.download.specifics.progress.data = pt; 1165 pi.value.download.specifics.progress.data = pt;
@@ -1171,120 +1172,120 @@ process_result_with_request(void *cls,
1171 if (prc->last_transmission.abs_value_us != 1172 if (prc->last_transmission.abs_value_us !=
1172 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 1173 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
1173 pi.value.download.specifics.progress.block_download_duration = 1174 pi.value.download.specifics.progress.block_download_duration =
1174 GNUNET_TIME_absolute_get_duration(prc->last_transmission); 1175 GNUNET_TIME_absolute_get_duration (prc->last_transmission);
1175 else 1176 else
1176 pi.value.download.specifics.progress.block_download_duration = 1177 pi.value.download.specifics.progress.block_download_duration =
1177 GNUNET_TIME_UNIT_ZERO; /* found locally */ 1178 GNUNET_TIME_UNIT_ZERO; /* found locally */
1178 GNUNET_FS_download_make_status_(&pi, dc); 1179 GNUNET_FS_download_make_status_ (&pi, dc);
1179 if (0 == dr->depth) 1180 if (0 == dr->depth)
1180 propagate_up(dr); 1181 propagate_up (dr);
1181 1182
1182 if (dc->completed == dc->length) 1183 if (dc->completed == dc->length)
1183 { 1184 {
1184 /* download completed, signal */ 1185 /* download completed, signal */
1185 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1186 "Download completed, truncating file to desired length %llu\n", 1187 "Download completed, truncating file to desired length %llu\n",
1187 (unsigned long long)GNUNET_ntohll( 1188 (unsigned long long) GNUNET_ntohll (
1188 dc->uri->data.chk.file_length)); 1189 dc->uri->data.chk.file_length));
1189 /* truncate file to size (since we store IBlocks at the end) */ 1190 /* truncate file to size (since we store IBlocks at the end) */
1190 if (NULL != dc->filename) 1191 if (NULL != dc->filename)
1191 { 1192 {
1192 if (0 != truncate(dc->filename, 1193 if (0 != truncate (dc->filename,
1193 GNUNET_ntohll(dc->uri->data.chk.file_length))) 1194 GNUNET_ntohll (dc->uri->data.chk.file_length)))
1194 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, 1195 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
1195 "truncate", 1196 "truncate",
1196 dc->filename); 1197 dc->filename);
1197 } 1198 }
1198 GNUNET_assert(0 == dr->depth); 1199 GNUNET_assert (0 == dr->depth);
1199 check_completed(dc); 1200 check_completed (dc);
1200 } 1201 }
1201 if (0 == dr->depth) 1202 if (0 == dr->depth)
1202 { 1203 {
1203 /* bottom of the tree, no child downloads possible, just sync */ 1204 /* bottom of the tree, no child downloads possible, just sync */
1204 GNUNET_FS_download_sync_(dc); 1205 GNUNET_FS_download_sync_ (dc);
1205 return GNUNET_YES; 1206 return GNUNET_YES;
1206 } 1207 }
1207 1208
1208 GNUNET_log( 1209 GNUNET_log (
1209 GNUNET_ERROR_TYPE_DEBUG, 1210 GNUNET_ERROR_TYPE_DEBUG,
1210 "Triggering downloads of children (this block was at depth %u and offset %llu)\n", 1211 "Triggering downloads of children (this block was at depth %u and offset %llu)\n",
1211 dr->depth, 1212 dr->depth,
1212 (unsigned long long)dr->offset); 1213 (unsigned long long) dr->offset);
1213 GNUNET_assert(0 == (prc->size % sizeof(struct ContentHashKey))); 1214 GNUNET_assert (0 == (prc->size % sizeof(struct ContentHashKey)));
1214 chkarr = (struct ContentHashKey *)pt; 1215 chkarr = (struct ContentHashKey *) pt;
1215 for (i = dr->num_children - 1; i >= 0; i--) 1216 for (i = dr->num_children - 1; i >= 0; i--)
1217 {
1218 drc = dr->children[i];
1219 switch (drc->state)
1216 { 1220 {
1217 drc = dr->children[i]; 1221 case BRS_INIT:
1218 switch (drc->state) 1222 if ((drc->chk_idx + 1) * sizeof(struct ContentHashKey) > prc->size)
1219 { 1223 {
1220 case BRS_INIT: 1224 /* 'chkarr' does not have enough space for this chk_idx;
1221 if ((drc->chk_idx + 1) * sizeof(struct ContentHashKey) > prc->size) 1225 internal error! */
1222 { 1226 GNUNET_break (0);
1223 /* 'chkarr' does not have enough space for this chk_idx; 1227 GNUNET_assert (0);
1224 internal error! */ 1228 dc->emsg = GNUNET_strdup (_ ("internal error decoding tree"));
1225 GNUNET_break(0); 1229 goto signal_error;
1226 GNUNET_assert(0); 1230 }
1227 dc->emsg = GNUNET_strdup(_("internal error decoding tree")); 1231 drc->chk = chkarr[drc->chk_idx];
1228 goto signal_error; 1232 drc->state = BRS_CHK_SET;
1229 } 1233 if (GNUNET_YES == dc->issue_requests)
1230 drc->chk = chkarr[drc->chk_idx]; 1234 schedule_block_download (dc, drc);
1231 drc->state = BRS_CHK_SET; 1235 break;
1232 if (GNUNET_YES == dc->issue_requests) 1236
1233 schedule_block_download(dc, drc); 1237 case BRS_RECONSTRUCT_DOWN:
1234 break; 1238 GNUNET_assert (0);
1235 1239 break;
1236 case BRS_RECONSTRUCT_DOWN: 1240
1237 GNUNET_assert(0); 1241 case BRS_RECONSTRUCT_META_UP:
1238 break; 1242 GNUNET_assert (0);
1239 1243 break;
1240 case BRS_RECONSTRUCT_META_UP: 1244
1241 GNUNET_assert(0); 1245 case BRS_RECONSTRUCT_UP:
1242 break; 1246 GNUNET_assert (0);
1243 1247 break;
1244 case BRS_RECONSTRUCT_UP: 1248
1245 GNUNET_assert(0); 1249 case BRS_CHK_SET:
1246 break; 1250 GNUNET_assert (0);
1247 1251 break;
1248 case BRS_CHK_SET: 1252
1249 GNUNET_assert(0); 1253 case BRS_DOWNLOAD_DOWN:
1250 break; 1254 GNUNET_assert (0);
1251 1255 break;
1252 case BRS_DOWNLOAD_DOWN: 1256
1253 GNUNET_assert(0); 1257 case BRS_DOWNLOAD_UP:
1254 break; 1258 GNUNET_assert (0);
1255 1259 break;
1256 case BRS_DOWNLOAD_UP: 1260
1257 GNUNET_assert(0); 1261 case BRS_ERROR:
1258 break; 1262 GNUNET_assert (0);
1259 1263 break;
1260 case BRS_ERROR: 1264
1261 GNUNET_assert(0); 1265 default:
1262 break; 1266 GNUNET_assert (0);
1263 1267 break;
1264 default:
1265 GNUNET_assert(0);
1266 break;
1267 }
1268 } 1268 }
1269 GNUNET_FS_download_sync_(dc); 1269 }
1270 GNUNET_FS_download_sync_ (dc);
1270 return GNUNET_YES; 1271 return GNUNET_YES;
1271 1272
1272signal_error: 1273signal_error:
1273 if (NULL != fh) 1274 if (NULL != fh)
1274 GNUNET_DISK_file_close(fh); 1275 GNUNET_DISK_file_close (fh);
1275 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; 1276 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
1276 pi.value.download.specifics.error.message = dc->emsg; 1277 pi.value.download.specifics.error.message = dc->emsg;
1277 GNUNET_FS_download_make_status_(&pi, dc); 1278 GNUNET_FS_download_make_status_ (&pi, dc);
1278 GNUNET_MQ_destroy(dc->mq); 1279 GNUNET_MQ_destroy (dc->mq);
1279 dc->mq = NULL; 1280 dc->mq = NULL;
1280 GNUNET_FS_free_download_request_(dc->top_request); 1281 GNUNET_FS_free_download_request_ (dc->top_request);
1281 dc->top_request = NULL; 1282 dc->top_request = NULL;
1282 if (NULL != dc->job_queue) 1283 if (NULL != dc->job_queue)
1283 { 1284 {
1284 GNUNET_FS_dequeue_(dc->job_queue); 1285 GNUNET_FS_dequeue_ (dc->job_queue);
1285 dc->job_queue = NULL; 1286 dc->job_queue = NULL;
1286 } 1287 }
1287 GNUNET_FS_download_sync_(dc); 1288 GNUNET_FS_download_sync_ (dc);
1288 return GNUNET_NO; 1289 return GNUNET_NO;
1289} 1290}
1290 1291
@@ -1297,7 +1298,7 @@ signal_error:
1297 * @param msg message received 1298 * @param msg message received
1298 */ 1299 */
1299static int 1300static int
1300check_put(void *cls, const struct ClientPutMessage *cm) 1301check_put (void *cls, const struct ClientPutMessage *cm)
1301{ 1302{
1302 /* any varsize length is OK */ 1303 /* any varsize length is OK */
1303 return GNUNET_OK; 1304 return GNUNET_OK;
@@ -1312,28 +1313,28 @@ check_put(void *cls, const struct ClientPutMessage *cm)
1312 * @param msg message received 1313 * @param msg message received
1313 */ 1314 */
1314static void 1315static void
1315handle_put(void *cls, const struct ClientPutMessage *cm) 1316handle_put (void *cls, const struct ClientPutMessage *cm)
1316{ 1317{
1317 struct GNUNET_FS_DownloadContext *dc = cls; 1318 struct GNUNET_FS_DownloadContext *dc = cls;
1318 uint16_t msize = ntohs(cm->header.size) - sizeof(*cm); 1319 uint16_t msize = ntohs (cm->header.size) - sizeof(*cm);
1319 struct ProcessResultClosure prc; 1320 struct ProcessResultClosure prc;
1320 1321
1321 prc.dc = dc; 1322 prc.dc = dc;
1322 prc.data = &cm[1]; 1323 prc.data = &cm[1];
1323 prc.last_transmission = GNUNET_TIME_absolute_ntoh(cm->last_transmission); 1324 prc.last_transmission = GNUNET_TIME_absolute_ntoh (cm->last_transmission);
1324 prc.size = msize; 1325 prc.size = msize;
1325 prc.type = ntohl(cm->type); 1326 prc.type = ntohl (cm->type);
1326 prc.do_store = GNUNET_YES; 1327 prc.do_store = GNUNET_YES;
1327 prc.respect_offered = ntohl(cm->respect_offered); 1328 prc.respect_offered = ntohl (cm->respect_offered);
1328 prc.num_transmissions = ntohl(cm->num_transmissions); 1329 prc.num_transmissions = ntohl (cm->num_transmissions);
1329 GNUNET_CRYPTO_hash(prc.data, msize, &prc.query); 1330 GNUNET_CRYPTO_hash (prc.data, msize, &prc.query);
1330 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1331 "Received result for query `%s' from FS service\n", 1332 "Received result for query `%s' from FS service\n",
1332 GNUNET_h2s(&prc.query)); 1333 GNUNET_h2s (&prc.query));
1333 GNUNET_CONTAINER_multihashmap_get_multiple(dc->active, 1334 GNUNET_CONTAINER_multihashmap_get_multiple (dc->active,
1334 &prc.query, 1335 &prc.query,
1335 &process_result_with_request, 1336 &process_result_with_request,
1336 &prc); 1337 &prc);
1337} 1338}
1338 1339
1339 1340
@@ -1346,18 +1347,18 @@ handle_put(void *cls, const struct ClientPutMessage *cm)
1346 * @param error error code 1347 * @param error error code
1347 */ 1348 */
1348static void 1349static void
1349download_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) 1350download_mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
1350{ 1351{
1351 struct GNUNET_FS_DownloadContext *dc = cls; 1352 struct GNUNET_FS_DownloadContext *dc = cls;
1352 1353
1353 if (NULL != dc->mq) 1354 if (NULL != dc->mq)
1354 { 1355 {
1355 GNUNET_MQ_destroy(dc->mq); 1356 GNUNET_MQ_destroy (dc->mq);
1356 dc->mq = NULL; 1357 dc->mq = NULL;
1357 } 1358 }
1358 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1359 "Transmitting download request failed, trying to reconnect\n"); 1360 "Transmitting download request failed, trying to reconnect\n");
1360 try_reconnect(dc); 1361 try_reconnect (dc);
1361} 1362}
1362 1363
1363 1364
@@ -1367,31 +1368,31 @@ download_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
1367 * @param cls our download context 1368 * @param cls our download context
1368 */ 1369 */
1369static void 1370static void
1370do_reconnect(void *cls) 1371do_reconnect (void *cls)
1371{ 1372{
1372 struct GNUNET_FS_DownloadContext *dc = cls; 1373 struct GNUNET_FS_DownloadContext *dc = cls;
1373 struct GNUNET_MQ_MessageHandler handlers[] = 1374 struct GNUNET_MQ_MessageHandler handlers[] =
1374 { GNUNET_MQ_hd_var_size(put, 1375 { GNUNET_MQ_hd_var_size (put,
1375 GNUNET_MESSAGE_TYPE_FS_PUT, 1376 GNUNET_MESSAGE_TYPE_FS_PUT,
1376 struct ClientPutMessage, 1377 struct ClientPutMessage,
1377 dc), 1378 dc),
1378 GNUNET_MQ_handler_end() }; 1379 GNUNET_MQ_handler_end () };
1379 1380
1380 dc->task = NULL; 1381 dc->task = NULL;
1381 dc->mq = GNUNET_CLIENT_connect(dc->h->cfg, 1382 dc->mq = GNUNET_CLIENT_connect (dc->h->cfg,
1382 "fs", 1383 "fs",
1383 handlers, 1384 handlers,
1384 &download_mq_error_handler, 1385 &download_mq_error_handler,
1385 dc); 1386 dc);
1386 if (NULL == dc->mq) 1387 if (NULL == dc->mq)
1387 { 1388 {
1388 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1389 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1389 "Connecting to `%s'-service failed, will try again.\n", 1390 "Connecting to `%s'-service failed, will try again.\n",
1390 "FS"); 1391 "FS");
1391 try_reconnect(dc); 1392 try_reconnect (dc);
1392 return; 1393 return;
1393 } 1394 }
1394 GNUNET_CONTAINER_multihashmap_iterate(dc->active, &retry_entry, dc); 1395 GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc);
1395} 1396}
1396 1397
1397 1398
@@ -1403,27 +1404,27 @@ do_reconnect(void *cls)
1403 * @param dc download context that is having trouble 1404 * @param dc download context that is having trouble
1404 */ 1405 */
1405static void 1406static void
1406try_reconnect(struct GNUNET_FS_DownloadContext *dc) 1407try_reconnect (struct GNUNET_FS_DownloadContext *dc)
1407{ 1408{
1408 if (NULL != dc->mq) 1409 if (NULL != dc->mq)
1409 { 1410 {
1410 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1411 "Moving all requests back to pending list\n"); 1412 "Moving all requests back to pending list\n");
1412 GNUNET_MQ_destroy(dc->mq); 1413 GNUNET_MQ_destroy (dc->mq);
1413 dc->mq = NULL; 1414 dc->mq = NULL;
1414 } 1415 }
1415 if (0 == dc->reconnect_backoff.rel_value_us) 1416 if (0 == dc->reconnect_backoff.rel_value_us)
1416 dc->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS; 1417 dc->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
1417 else 1418 else
1418 dc->reconnect_backoff = GNUNET_TIME_STD_BACKOFF(dc->reconnect_backoff); 1419 dc->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (dc->reconnect_backoff);
1419 1420
1420 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1421 "Will try to reconnect in %s\n", 1422 "Will try to reconnect in %s\n",
1422 GNUNET_STRINGS_relative_time_to_string(dc->reconnect_backoff, 1423 GNUNET_STRINGS_relative_time_to_string (dc->reconnect_backoff,
1423 GNUNET_YES)); 1424 GNUNET_YES));
1424 GNUNET_break(NULL != dc->job_queue); 1425 GNUNET_break (NULL != dc->job_queue);
1425 dc->task = 1426 dc->task =
1426 GNUNET_SCHEDULER_add_delayed(dc->reconnect_backoff, &do_reconnect, dc); 1427 GNUNET_SCHEDULER_add_delayed (dc->reconnect_backoff, &do_reconnect, dc);
1427} 1428}
1428 1429
1429 1430
@@ -1434,18 +1435,18 @@ try_reconnect(struct GNUNET_FS_DownloadContext *dc)
1434 * @param mq handle to use for communcation with FS (we must destroy it!) 1435 * @param mq handle to use for communcation with FS (we must destroy it!)
1435 */ 1436 */
1436static void 1437static void
1437activate_fs_download(void *cls) 1438activate_fs_download (void *cls)
1438{ 1439{
1439 struct GNUNET_FS_DownloadContext *dc = cls; 1440 struct GNUNET_FS_DownloadContext *dc = cls;
1440 struct GNUNET_FS_ProgressInfo pi; 1441 struct GNUNET_FS_ProgressInfo pi;
1441 1442
1442 GNUNET_assert(NULL == dc->mq); 1443 GNUNET_assert (NULL == dc->mq);
1443 GNUNET_assert(NULL != dc->active); 1444 GNUNET_assert (NULL != dc->active);
1444 do_reconnect(dc); 1445 do_reconnect (dc);
1445 if (NULL != dc->mq) 1446 if (NULL != dc->mq)
1446 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Download activated\n"); 1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n");
1447 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; 1448 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE;
1448 GNUNET_FS_download_make_status_(&pi, dc); 1449 GNUNET_FS_download_make_status_ (&pi, dc);
1449} 1450}
1450 1451
1451 1452
@@ -1455,19 +1456,19 @@ activate_fs_download(void *cls)
1455 * @param cls the `struct GNUNET_FS_DownloadContext` 1456 * @param cls the `struct GNUNET_FS_DownloadContext`
1456 */ 1457 */
1457static void 1458static void
1458deactivate_fs_download(void *cls) 1459deactivate_fs_download (void *cls)
1459{ 1460{
1460 struct GNUNET_FS_DownloadContext *dc = cls; 1461 struct GNUNET_FS_DownloadContext *dc = cls;
1461 struct GNUNET_FS_ProgressInfo pi; 1462 struct GNUNET_FS_ProgressInfo pi;
1462 1463
1463 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Download deactivated\n"); 1464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download deactivated\n");
1464 if (NULL != dc->mq) 1465 if (NULL != dc->mq)
1465 { 1466 {
1466 GNUNET_MQ_destroy(dc->mq); 1467 GNUNET_MQ_destroy (dc->mq);
1467 dc->mq = NULL; 1468 dc->mq = NULL;
1468 } 1469 }
1469 pi.status = GNUNET_FS_STATUS_DOWNLOAD_INACTIVE; 1470 pi.status = GNUNET_FS_STATUS_DOWNLOAD_INACTIVE;
1470 GNUNET_FS_download_make_status_(&pi, dc); 1471 GNUNET_FS_download_make_status_ (&pi, dc);
1471} 1472}
1472 1473
1473 1474
@@ -1491,38 +1492,38 @@ deactivate_fs_download(void *cls)
1491 * the specified depth 1492 * the specified depth
1492 */ 1493 */
1493static struct DownloadRequest * 1494static struct DownloadRequest *
1494create_download_request(struct DownloadRequest *parent, 1495create_download_request (struct DownloadRequest *parent,
1495 unsigned int chk_idx, 1496 unsigned int chk_idx,
1496 unsigned int depth, 1497 unsigned int depth,
1497 uint64_t dr_offset, 1498 uint64_t dr_offset,
1498 uint64_t file_start_offset, 1499 uint64_t file_start_offset,
1499 uint64_t desired_length) 1500 uint64_t desired_length)
1500{ 1501{
1501 struct DownloadRequest *dr; 1502 struct DownloadRequest *dr;
1502 unsigned int i; 1503 unsigned int i;
1503 unsigned int head_skip; 1504 unsigned int head_skip;
1504 uint64_t child_block_size; 1505 uint64_t child_block_size;
1505 1506
1506 dr = GNUNET_new(struct DownloadRequest); 1507 dr = GNUNET_new (struct DownloadRequest);
1507 dr->parent = parent; 1508 dr->parent = parent;
1508 dr->depth = depth; 1509 dr->depth = depth;
1509 dr->offset = dr_offset; 1510 dr->offset = dr_offset;
1510 dr->chk_idx = chk_idx; 1511 dr->chk_idx = chk_idx;
1511 if (0 == depth) 1512 if (0 == depth)
1512 return dr; 1513 return dr;
1513 child_block_size = GNUNET_FS_tree_compute_tree_size(depth - 1); 1514 child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1);
1514 1515
1515 /* calculate how many blocks at this level are not interesting 1516 /* calculate how many blocks at this level are not interesting
1516 * from the start (rounded down), either because of the requested 1517 * from the start (rounded down), either because of the requested
1517 * file offset or because this IBlock is further along */ 1518 * file offset or because this IBlock is further along */
1518 if (dr_offset < file_start_offset) 1519 if (dr_offset < file_start_offset)
1519 { 1520 {
1520 head_skip = (file_start_offset - dr_offset) / child_block_size; 1521 head_skip = (file_start_offset - dr_offset) / child_block_size;
1521 } 1522 }
1522 else 1523 else
1523 { 1524 {
1524 head_skip = 0; 1525 head_skip = 0;
1525 } 1526 }
1526 1527
1527 /* calculate index of last block at this level that is interesting (rounded up) */ 1528 /* calculate index of last block at this level that is interesting (rounded up) */
1528 dr->num_children = 1529 dr->num_children =
@@ -1530,32 +1531,32 @@ create_download_request(struct DownloadRequest *parent,
1530 if (dr->num_children * child_block_size < 1531 if (dr->num_children * child_block_size <
1531 file_start_offset + desired_length - dr_offset) 1532 file_start_offset + desired_length - dr_offset)
1532 dr->num_children++; /* round up */ 1533 dr->num_children++; /* round up */
1533 GNUNET_assert(dr->num_children > head_skip); 1534 GNUNET_assert (dr->num_children > head_skip);
1534 dr->num_children -= head_skip; 1535 dr->num_children -= head_skip;
1535 if (dr->num_children > CHK_PER_INODE) 1536 if (dr->num_children > CHK_PER_INODE)
1536 dr->num_children = CHK_PER_INODE; /* cap at max */ 1537 dr->num_children = CHK_PER_INODE; /* cap at max */
1537 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1538 "Block at offset %llu and depth %u has %u children\n", 1539 "Block at offset %llu and depth %u has %u children\n",
1539 (unsigned long long)dr_offset, 1540 (unsigned long long) dr_offset,
1540 depth, 1541 depth,
1541 dr->num_children); 1542 dr->num_children);
1542 1543
1543 /* now we can get the total number of *interesting* children for this block */ 1544 /* now we can get the total number of *interesting* children for this block */
1544 1545
1545 /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ 1546 /* why else would we have gotten here to begin with? (that'd be a bad logic error) */
1546 GNUNET_assert(dr->num_children > 0); 1547 GNUNET_assert (dr->num_children > 0);
1547 1548
1548 dr->children = GNUNET_new_array(dr->num_children, struct DownloadRequest *); 1549 dr->children = GNUNET_new_array (dr->num_children, struct DownloadRequest *);
1549 for (i = 0; i < dr->num_children; i++) 1550 for (i = 0; i < dr->num_children; i++)
1550 { 1551 {
1551 dr->children[i] = 1552 dr->children[i] =
1552 create_download_request(dr, 1553 create_download_request (dr,
1553 i + head_skip, 1554 i + head_skip,
1554 depth - 1, 1555 depth - 1,
1555 dr_offset + (i + head_skip) * child_block_size, 1556 dr_offset + (i + head_skip) * child_block_size,
1556 file_start_offset, 1557 file_start_offset,
1557 desired_length); 1558 desired_length);
1558 } 1559 }
1559 return dr; 1560 return dr;
1560} 1561}
1561 1562
@@ -1567,25 +1568,25 @@ create_download_request(struct DownloadRequest *parent,
1567 * @param cls the 'struct ReconstructContext' 1568 * @param cls the 'struct ReconstructContext'
1568 */ 1569 */
1569static void 1570static void
1570reconstruct_cont(void *cls) 1571reconstruct_cont (void *cls)
1571{ 1572{
1572 struct GNUNET_FS_DownloadContext *dc = cls; 1573 struct GNUNET_FS_DownloadContext *dc = cls;
1573 1574
1574 /* clean up state from tree encoder */ 1575 /* clean up state from tree encoder */
1575 if (NULL != dc->task) 1576 if (NULL != dc->task)
1576 { 1577 {
1577 GNUNET_SCHEDULER_cancel(dc->task); 1578 GNUNET_SCHEDULER_cancel (dc->task);
1578 dc->task = NULL; 1579 dc->task = NULL;
1579 } 1580 }
1580 if (NULL != dc->rfh) 1581 if (NULL != dc->rfh)
1581 { 1582 {
1582 GNUNET_break(GNUNET_OK == GNUNET_DISK_file_close(dc->rfh)); 1583 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh));
1583 dc->rfh = NULL; 1584 dc->rfh = NULL;
1584 } 1585 }
1585 /* start "normal" download */ 1586 /* start "normal" download */
1586 dc->issue_requests = GNUNET_YES; 1587 dc->issue_requests = GNUNET_YES;
1587 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Starting normal download\n"); 1588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting normal download\n");
1588 schedule_block_download(dc, dc->top_request); 1589 schedule_block_download (dc, dc->top_request);
1589} 1590}
1590 1591
1591 1592
@@ -1595,12 +1596,12 @@ reconstruct_cont(void *cls)
1595 * @param cls the 'struct GNUJNET_FS_DownloadContext' we're processing 1596 * @param cls the 'struct GNUJNET_FS_DownloadContext' we're processing
1596 */ 1597 */
1597static void 1598static void
1598get_next_block(void *cls) 1599get_next_block (void *cls)
1599{ 1600{
1600 struct GNUNET_FS_DownloadContext *dc = cls; 1601 struct GNUNET_FS_DownloadContext *dc = cls;
1601 1602
1602 dc->task = NULL; 1603 dc->task = NULL;
1603 GNUNET_FS_tree_encoder_next(dc->te); 1604 GNUNET_FS_tree_encoder_next (dc->te);
1604} 1605}
1605 1606
1606 1607
@@ -1622,13 +1623,13 @@ get_next_block(void *cls)
1622 * @param block_size size of block (in bytes) 1623 * @param block_size size of block (in bytes)
1623 */ 1624 */
1624static void 1625static void
1625reconstruct_cb(void *cls, 1626reconstruct_cb (void *cls,
1626 const struct ContentHashKey *chk, 1627 const struct ContentHashKey *chk,
1627 uint64_t offset, 1628 uint64_t offset,
1628 unsigned int depth, 1629 unsigned int depth,
1629 enum GNUNET_BLOCK_Type type, 1630 enum GNUNET_BLOCK_Type type,
1630 const void *block, 1631 const void *block,
1631 uint16_t block_size) 1632 uint16_t block_size)
1632{ 1633{
1633 struct GNUNET_FS_DownloadContext *dc = cls; 1634 struct GNUNET_FS_DownloadContext *dc = cls;
1634 struct GNUNET_FS_ProgressInfo pi; 1635 struct GNUNET_FS_ProgressInfo pi;
@@ -1639,125 +1640,125 @@ reconstruct_cb(void *cls,
1639 /* find corresponding request entry */ 1640 /* find corresponding request entry */
1640 dr = dc->top_request; 1641 dr = dc->top_request;
1641 while (dr->depth > depth) 1642 while (dr->depth > depth)
1642 { 1643 {
1643 GNUNET_assert(dr->num_children > 0); 1644 GNUNET_assert (dr->num_children > 0);
1644 blen = GNUNET_FS_tree_compute_tree_size(dr->depth - 1); 1645 blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1);
1645 chld = (offset - dr->offset) / blen; 1646 chld = (offset - dr->offset) / blen;
1646 if (chld < dr->children[0]->chk_idx) 1647 if (chld < dr->children[0]->chk_idx)
1647 { 1648 {
1648 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1649 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1649 "Block %u < %u irrelevant for our range\n", 1650 "Block %u < %u irrelevant for our range\n",
1650 chld, 1651 chld,
1651 dr->children[0]->chk_idx); 1652 dr->children[0]->chk_idx);
1652 dc->task = GNUNET_SCHEDULER_add_now(&get_next_block, dc); 1653 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1653 return; /* irrelevant block */ 1654 return; /* irrelevant block */
1654 } 1655 }
1655 if (chld > dr->children[dr->num_children - 1]->chk_idx) 1656 if (chld > dr->children[dr->num_children - 1]->chk_idx)
1656 { 1657 {
1657 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1658 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1658 "Block %u > %u irrelevant for our range\n", 1659 "Block %u > %u irrelevant for our range\n",
1659 chld, 1660 chld,
1660 dr->children[dr->num_children - 1]->chk_idx); 1661 dr->children[dr->num_children - 1]->chk_idx);
1661 dc->task = GNUNET_SCHEDULER_add_now(&get_next_block, dc); 1662 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1662 return; /* irrelevant block */ 1663 return; /* irrelevant block */
1663 } 1664 }
1664 dr = dr->children[chld - dr->children[0]->chk_idx]; 1665 dr = dr->children[chld - dr->children[0]->chk_idx];
1665 } 1666 }
1666 GNUNET_log( 1667 GNUNET_log (
1667 GNUNET_ERROR_TYPE_DEBUG, 1668 GNUNET_ERROR_TYPE_DEBUG,
1668 "Matched TE block with request at offset %llu and depth %u in state %d\n", 1669 "Matched TE block with request at offset %llu and depth %u in state %d\n",
1669 (unsigned long long)dr->offset, 1670 (unsigned long long) dr->offset,
1670 dr->depth, 1671 dr->depth,
1671 dr->state); 1672 dr->state);
1672 /* FIXME: this code needs more testing and might 1673 /* FIXME: this code needs more testing and might
1673 need to handle more states... */ 1674 need to handle more states... */
1674 switch (dr->state) 1675 switch (dr->state)
1675 { 1676 {
1676 case BRS_INIT: 1677 case BRS_INIT:
1677 break; 1678 break;
1678 1679
1679 case BRS_RECONSTRUCT_DOWN: 1680 case BRS_RECONSTRUCT_DOWN:
1680 break; 1681 break;
1681 1682
1682 case BRS_RECONSTRUCT_META_UP: 1683 case BRS_RECONSTRUCT_META_UP:
1683 break; 1684 break;
1684 1685
1685 case BRS_RECONSTRUCT_UP: 1686 case BRS_RECONSTRUCT_UP:
1686 break; 1687 break;
1687 1688
1688 case BRS_CHK_SET: 1689 case BRS_CHK_SET:
1689 if (0 == memcmp(chk, &dr->chk, sizeof(struct ContentHashKey))) 1690 if (0 == memcmp (chk, &dr->chk, sizeof(struct ContentHashKey)))
1691 {
1692 GNUNET_log (
1693 GNUNET_ERROR_TYPE_DEBUG,
1694 "Reconstruction succeeded, can use block at offset %llu, depth %u\n",
1695 (unsigned long long) offset,
1696 depth);
1697 /* block matches, hence tree below matches;
1698 * this request is done! */
1699 dr->state = BRS_DOWNLOAD_UP;
1700 (void) GNUNET_CONTAINER_multihashmap_remove (dc->active,
1701 &dr->chk.query,
1702 dr);
1703 /* calculate how many bytes of payload this block
1704 * corresponds to */
1705 blen = GNUNET_FS_tree_compute_tree_size (dr->depth);
1706 /* how many of those bytes are in the requested range? */
1707 blen = GNUNET_MIN (blen, dc->length + dc->offset - dr->offset);
1708 /* signal progress */
1709 dc->completed += blen;
1710 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
1711 pi.value.download.specifics.progress.data = NULL;
1712 pi.value.download.specifics.progress.offset = offset;
1713 pi.value.download.specifics.progress.data_len = 0;
1714 pi.value.download.specifics.progress.depth = 0;
1715 pi.value.download.specifics.progress.respect_offered = 0;
1716 pi.value.download.specifics.progress.block_download_duration =
1717 GNUNET_TIME_UNIT_ZERO;
1718 GNUNET_FS_download_make_status_ (&pi, dc);
1719 /* FIXME: duplicated code from 'process_result_with_request - refactor */
1720 if (dc->completed == dc->length)
1721 {
1722 /* download completed, signal */
1723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1724 "Download completed, truncating file to desired length %llu\n",
1725 (unsigned long long) GNUNET_ntohll (
1726 dc->uri->data.chk.file_length));
1727 /* truncate file to size (since we store IBlocks at the end) */
1728 if (NULL != dc->filename)
1690 { 1729 {
1691 GNUNET_log( 1730 if (0 != truncate (dc->filename,
1692 GNUNET_ERROR_TYPE_DEBUG, 1731 GNUNET_ntohll (dc->uri->data.chk.file_length)))
1693 "Reconstruction succeeded, can use block at offset %llu, depth %u\n", 1732 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
1694 (unsigned long long)offset, 1733 "truncate",
1695 depth); 1734 dc->filename);
1696 /* block matches, hence tree below matches;
1697 * this request is done! */
1698 dr->state = BRS_DOWNLOAD_UP;
1699 (void)GNUNET_CONTAINER_multihashmap_remove(dc->active,
1700 &dr->chk.query,
1701 dr);
1702 /* calculate how many bytes of payload this block
1703 * corresponds to */
1704 blen = GNUNET_FS_tree_compute_tree_size(dr->depth);
1705 /* how many of those bytes are in the requested range? */
1706 blen = GNUNET_MIN(blen, dc->length + dc->offset - dr->offset);
1707 /* signal progress */
1708 dc->completed += blen;
1709 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
1710 pi.value.download.specifics.progress.data = NULL;
1711 pi.value.download.specifics.progress.offset = offset;
1712 pi.value.download.specifics.progress.data_len = 0;
1713 pi.value.download.specifics.progress.depth = 0;
1714 pi.value.download.specifics.progress.respect_offered = 0;
1715 pi.value.download.specifics.progress.block_download_duration =
1716 GNUNET_TIME_UNIT_ZERO;
1717 GNUNET_FS_download_make_status_(&pi, dc);
1718 /* FIXME: duplicated code from 'process_result_with_request - refactor */
1719 if (dc->completed == dc->length)
1720 {
1721 /* download completed, signal */
1722 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1723 "Download completed, truncating file to desired length %llu\n",
1724 (unsigned long long)GNUNET_ntohll(
1725 dc->uri->data.chk.file_length));
1726 /* truncate file to size (since we store IBlocks at the end) */
1727 if (NULL != dc->filename)
1728 {
1729 if (0 != truncate(dc->filename,
1730 GNUNET_ntohll(dc->uri->data.chk.file_length)))
1731 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING,
1732 "truncate",
1733 dc->filename);
1734 }
1735 }
1736 } 1735 }
1737 else 1736 }
1738 GNUNET_log( 1737 }
1739 GNUNET_ERROR_TYPE_DEBUG, 1738 else
1740 "Reconstruction failed, need to download block at offset %llu, depth %u\n", 1739 GNUNET_log (
1741 (unsigned long long)offset, 1740 GNUNET_ERROR_TYPE_DEBUG,
1742 depth); 1741 "Reconstruction failed, need to download block at offset %llu, depth %u\n",
1743 break; 1742 (unsigned long long) offset,
1743 depth);
1744 break;
1744 1745
1745 case BRS_DOWNLOAD_DOWN: 1746 case BRS_DOWNLOAD_DOWN:
1746 break; 1747 break;
1747 1748
1748 case BRS_DOWNLOAD_UP: 1749 case BRS_DOWNLOAD_UP:
1749 break; 1750 break;
1750 1751
1751 case BRS_ERROR: 1752 case BRS_ERROR:
1752 break; 1753 break;
1753 1754
1754 default: 1755 default:
1755 GNUNET_assert(0); 1756 GNUNET_assert (0);
1756 break; 1757 break;
1757 } 1758 }
1758 dc->task = GNUNET_SCHEDULER_add_now(&get_next_block, dc); 1759 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1759 if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP)) 1760 if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP))
1760 check_completed(dc); 1761 check_completed (dc);
1761} 1762}
1762 1763
1763 1764
@@ -1774,7 +1775,7 @@ reconstruct_cb(void *cls,
1774 * @return number of bytes copied to buf, 0 on error 1775 * @return number of bytes copied to buf, 0 on error
1775 */ 1776 */
1776static size_t 1777static size_t
1777fh_reader(void *cls, uint64_t offset, size_t max, void *buf, char **emsg) 1778fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
1778{ 1779{
1779 struct GNUNET_FS_DownloadContext *dc = cls; 1780 struct GNUNET_FS_DownloadContext *dc = cls;
1780 struct GNUNET_DISK_FileHandle *fh = dc->rfh; 1781 struct GNUNET_DISK_FileHandle *fh = dc->rfh;
@@ -1782,19 +1783,19 @@ fh_reader(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
1782 1783
1783 if (NULL != emsg) 1784 if (NULL != emsg)
1784 *emsg = NULL; 1785 *emsg = NULL;
1785 if (offset != GNUNET_DISK_file_seek(fh, offset, GNUNET_DISK_SEEK_SET)) 1786 if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
1786 { 1787 {
1787 if (NULL != emsg) 1788 if (NULL != emsg)
1788 *emsg = GNUNET_strdup(strerror(errno)); 1789 *emsg = GNUNET_strdup (strerror (errno));
1789 return 0; 1790 return 0;
1790 } 1791 }
1791 ret = GNUNET_DISK_file_read(fh, buf, max); 1792 ret = GNUNET_DISK_file_read (fh, buf, max);
1792 if (ret < 0) 1793 if (ret < 0)
1793 { 1794 {
1794 if (NULL != emsg) 1795 if (NULL != emsg)
1795 *emsg = GNUNET_strdup(strerror(errno)); 1796 *emsg = GNUNET_strdup (strerror (errno));
1796 return 0; 1797 return 0;
1797 } 1798 }
1798 return ret; 1799 return ret;
1799} 1800}
1800 1801
@@ -1806,155 +1807,155 @@ fh_reader(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
1806 * @param cls the 'struct GNUNET_FS_DownloadContext' 1807 * @param cls the 'struct GNUNET_FS_DownloadContext'
1807 */ 1808 */
1808void 1809void
1809GNUNET_FS_download_start_task_(void *cls) 1810GNUNET_FS_download_start_task_ (void *cls)
1810{ 1811{
1811 struct GNUNET_FS_DownloadContext *dc = cls; 1812 struct GNUNET_FS_DownloadContext *dc = cls;
1812 struct GNUNET_FS_ProgressInfo pi; 1813 struct GNUNET_FS_ProgressInfo pi;
1813 struct GNUNET_DISK_FileHandle *fh; 1814 struct GNUNET_DISK_FileHandle *fh;
1814 1815
1815 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n"); 1816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n");
1816 dc->task = NULL; 1817 dc->task = NULL;
1817 if (0 == dc->length) 1818 if (0 == dc->length)
1818 { 1819 {
1819 /* no bytes required! */ 1820 /* no bytes required! */
1820 if (NULL != dc->filename) 1821 if (NULL != dc->filename)
1821 { 1822 {
1822 fh = GNUNET_DISK_file_open(dc->filename, 1823 fh = GNUNET_DISK_file_open (dc->filename,
1823 GNUNET_DISK_OPEN_READWRITE | 1824 GNUNET_DISK_OPEN_READWRITE
1824 GNUNET_DISK_OPEN_CREATE | 1825 | GNUNET_DISK_OPEN_CREATE
1825 ((0 == 1826 | ((0 ==
1826 GNUNET_FS_uri_chk_get_file_size(dc->uri)) 1827 GNUNET_FS_uri_chk_get_file_size (dc->uri))
1827 ? GNUNET_DISK_OPEN_TRUNCATE 1828 ? GNUNET_DISK_OPEN_TRUNCATE
1828 : 0), 1829 : 0),
1829 GNUNET_DISK_PERM_USER_READ | 1830 GNUNET_DISK_PERM_USER_READ
1830 GNUNET_DISK_PERM_USER_WRITE | 1831 | GNUNET_DISK_PERM_USER_WRITE
1831 GNUNET_DISK_PERM_GROUP_READ | 1832 | GNUNET_DISK_PERM_GROUP_READ
1832 GNUNET_DISK_PERM_OTHER_READ); 1833 | GNUNET_DISK_PERM_OTHER_READ);
1833 GNUNET_DISK_file_close(fh); 1834 GNUNET_DISK_file_close (fh);
1834 } 1835 }
1835 GNUNET_FS_download_sync_(dc); 1836 GNUNET_FS_download_sync_ (dc);
1836 pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; 1837 pi.status = GNUNET_FS_STATUS_DOWNLOAD_START;
1837 pi.value.download.specifics.start.meta = dc->meta; 1838 pi.value.download.specifics.start.meta = dc->meta;
1838 GNUNET_FS_download_make_status_(&pi, dc); 1839 GNUNET_FS_download_make_status_ (&pi, dc);
1839 check_completed(dc); 1840 check_completed (dc);
1840 return; 1841 return;
1841 } 1842 }
1842 if (NULL != dc->emsg) 1843 if (NULL != dc->emsg)
1843 return; 1844 return;
1844 if (NULL == dc->top_request) 1845 if (NULL == dc->top_request)
1845 { 1846 {
1846 dc->top_request = create_download_request(NULL, 1847 dc->top_request = create_download_request (NULL,
1847 0, 1848 0,
1848 dc->treedepth - 1, 1849 dc->treedepth - 1,
1849 0, 1850 0,
1850 dc->offset, 1851 dc->offset,
1851 dc->length); 1852 dc->length);
1852 dc->top_request->state = BRS_CHK_SET; 1853 dc->top_request->state = BRS_CHK_SET;
1853 dc->top_request->chk = (dc->uri->type == GNUNET_FS_URI_CHK) 1854 dc->top_request->chk = (dc->uri->type == GNUNET_FS_URI_CHK)
1854 ? dc->uri->data.chk.chk 1855 ? dc->uri->data.chk.chk
1855 : dc->uri->data.loc.fi.chk; 1856 : dc->uri->data.loc.fi.chk;
1856 /* signal start */ 1857 /* signal start */
1857 GNUNET_FS_download_sync_(dc); 1858 GNUNET_FS_download_sync_ (dc);
1858 if (NULL != dc->search) 1859 if (NULL != dc->search)
1859 GNUNET_FS_search_result_sync_(dc->search); 1860 GNUNET_FS_search_result_sync_ (dc->search);
1860 pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; 1861 pi.status = GNUNET_FS_STATUS_DOWNLOAD_START;
1861 pi.value.download.specifics.start.meta = dc->meta; 1862 pi.value.download.specifics.start.meta = dc->meta;
1862 GNUNET_FS_download_make_status_(&pi, dc); 1863 GNUNET_FS_download_make_status_ (&pi, dc);
1863 } 1864 }
1864 GNUNET_FS_download_start_downloading_(dc); 1865 GNUNET_FS_download_start_downloading_ (dc);
1865 /* attempt reconstruction from disk */ 1866 /* attempt reconstruction from disk */
1866 if (GNUNET_YES == GNUNET_DISK_file_test(dc->filename)) 1867 if (GNUNET_YES == GNUNET_DISK_file_test (dc->filename))
1867 dc->rfh = GNUNET_DISK_file_open(dc->filename, 1868 dc->rfh = GNUNET_DISK_file_open (dc->filename,
1868 GNUNET_DISK_OPEN_READ, 1869 GNUNET_DISK_OPEN_READ,
1869 GNUNET_DISK_PERM_NONE); 1870 GNUNET_DISK_PERM_NONE);
1870 if (dc->top_request->state == BRS_CHK_SET) 1871 if (dc->top_request->state == BRS_CHK_SET)
1871 { 1872 {
1872 if (NULL != dc->rfh) 1873 if (NULL != dc->rfh)
1874 {
1875 /* first, try top-down */
1876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1877 "Trying top-down reconstruction for `%s'\n",
1878 dc->filename);
1879 try_top_down_reconstruction (dc, dc->top_request);
1880 switch (dc->top_request->state)
1881 {
1882 case BRS_CHK_SET:
1883 break; /* normal */
1884
1885 case BRS_DOWNLOAD_DOWN:
1886 break; /* normal, some blocks already down */
1887
1888 case BRS_DOWNLOAD_UP:
1889 /* already done entirely, party! */
1890 if (NULL != dc->rfh)
1873 { 1891 {
1874 /* first, try top-down */ 1892 /* avoid hanging on to file handle longer than
1875 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1893 * necessary */
1876 "Trying top-down reconstruction for `%s'\n", 1894 GNUNET_DISK_file_close (dc->rfh);
1877 dc->filename); 1895 dc->rfh = NULL;
1878 try_top_down_reconstruction(dc, dc->top_request);
1879 switch (dc->top_request->state)
1880 {
1881 case BRS_CHK_SET:
1882 break; /* normal */
1883
1884 case BRS_DOWNLOAD_DOWN:
1885 break; /* normal, some blocks already down */
1886
1887 case BRS_DOWNLOAD_UP:
1888 /* already done entirely, party! */
1889 if (NULL != dc->rfh)
1890 {
1891 /* avoid hanging on to file handle longer than
1892 * necessary */
1893 GNUNET_DISK_file_close(dc->rfh);
1894 dc->rfh = NULL;
1895 }
1896 return;
1897
1898 case BRS_ERROR:
1899 GNUNET_asprintf(&dc->emsg, _("Invalid URI"));
1900 GNUNET_FS_download_sync_(dc);
1901 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
1902 pi.value.download.specifics.error.message = dc->emsg;
1903 GNUNET_FS_download_make_status_(&pi, dc);
1904 return;
1905
1906 default:
1907 GNUNET_assert(0);
1908 break;
1909 }
1910 } 1896 }
1897 return;
1898
1899 case BRS_ERROR:
1900 GNUNET_asprintf (&dc->emsg, _ ("Invalid URI"));
1901 GNUNET_FS_download_sync_ (dc);
1902 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
1903 pi.value.download.specifics.error.message = dc->emsg;
1904 GNUNET_FS_download_make_status_ (&pi, dc);
1905 return;
1906
1907 default:
1908 GNUNET_assert (0);
1909 break;
1910 }
1911 } 1911 }
1912 }
1912 /* attempt reconstruction from meta data */ 1913 /* attempt reconstruction from meta data */
1913 if ((GNUNET_FS_uri_chk_get_file_size(dc->uri) <= MAX_INLINE_SIZE) && 1914 if ((GNUNET_FS_uri_chk_get_file_size (dc->uri) <= MAX_INLINE_SIZE) &&
1914 (NULL != dc->meta)) 1915 (NULL != dc->meta))
1916 {
1917 GNUNET_log (
1918 GNUNET_ERROR_TYPE_DEBUG,
1919 "Trying to find embedded meta data for download of size %llu with %u bytes MD\n",
1920 (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri),
1921 (unsigned int) GNUNET_CONTAINER_meta_data_get_serialized_size (dc->meta));
1922 GNUNET_CONTAINER_meta_data_iterate (dc->meta, &match_full_data, dc);
1923 if (BRS_DOWNLOAD_UP == dc->top_request->state)
1915 { 1924 {
1916 GNUNET_log( 1925 if (NULL != dc->rfh)
1917 GNUNET_ERROR_TYPE_DEBUG, 1926 {
1918 "Trying to find embedded meta data for download of size %llu with %u bytes MD\n", 1927 /* avoid hanging on to file handle longer than
1919 (unsigned long long)GNUNET_FS_uri_chk_get_file_size(dc->uri), 1928 * necessary */
1920 (unsigned int)GNUNET_CONTAINER_meta_data_get_serialized_size(dc->meta)); 1929 GNUNET_DISK_file_close (dc->rfh);
1921 GNUNET_CONTAINER_meta_data_iterate(dc->meta, &match_full_data, dc); 1930 dc->rfh = NULL;
1922 if (BRS_DOWNLOAD_UP == dc->top_request->state) 1931 }
1923 { 1932 return; /* finished, status update was already done for us */
1924 if (NULL != dc->rfh) 1933 }
1925 { 1934 }
1926 /* avoid hanging on to file handle longer than
1927 * necessary */
1928 GNUNET_DISK_file_close(dc->rfh);
1929 dc->rfh = NULL;
1930 }
1931 return; /* finished, status update was already done for us */
1932 }
1933 }
1934 if (NULL != dc->rfh) 1935 if (NULL != dc->rfh)
1935 { 1936 {
1936 /* finally, actually run bottom-up */ 1937 /* finally, actually run bottom-up */
1937 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1938 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1938 "Trying bottom-up reconstruction of file `%s'\n", 1939 "Trying bottom-up reconstruction of file `%s'\n",
1939 dc->filename); 1940 dc->filename);
1940 dc->te = 1941 dc->te =
1941 GNUNET_FS_tree_encoder_create(dc->h, 1942 GNUNET_FS_tree_encoder_create (dc->h,
1942 GNUNET_FS_uri_chk_get_file_size(dc->uri), 1943 GNUNET_FS_uri_chk_get_file_size (dc->uri),
1943 dc, 1944 dc,
1944 &fh_reader, 1945 &fh_reader,
1945 &reconstruct_cb, 1946 &reconstruct_cb,
1946 NULL, 1947 NULL,
1947 &reconstruct_cont); 1948 &reconstruct_cont);
1948 dc->task = GNUNET_SCHEDULER_add_now(&get_next_block, dc); 1949 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1949 } 1950 }
1950 else 1951 else
1951 { 1952 {
1952 /* simple, top-level download */ 1953 /* simple, top-level download */
1953 dc->issue_requests = GNUNET_YES; 1954 dc->issue_requests = GNUNET_YES;
1954 schedule_block_download(dc, dc->top_request); 1955 schedule_block_download (dc, dc->top_request);
1955 } 1956 }
1956 if (BRS_DOWNLOAD_UP == dc->top_request->state) 1957 if (BRS_DOWNLOAD_UP == dc->top_request->state)
1957 check_completed(dc); 1958 check_completed (dc);
1958} 1959}
1959 1960
1960 1961
@@ -1965,59 +1966,59 @@ GNUNET_FS_download_start_task_(void *cls)
1965 * @param cls the 'struct GNUNET_FS_DownloadContext' to signal for 1966 * @param cls the 'struct GNUNET_FS_DownloadContext' to signal for
1966 */ 1967 */
1967void 1968void
1968GNUNET_FS_download_signal_suspend_(void *cls) 1969GNUNET_FS_download_signal_suspend_ (void *cls)
1969{ 1970{
1970 struct GNUNET_FS_DownloadContext *dc = cls; 1971 struct GNUNET_FS_DownloadContext *dc = cls;
1971 struct GNUNET_FS_ProgressInfo pi; 1972 struct GNUNET_FS_ProgressInfo pi;
1972 1973
1973 if (NULL != dc->top) 1974 if (NULL != dc->top)
1974 GNUNET_FS_end_top(dc->h, dc->top); 1975 GNUNET_FS_end_top (dc->h, dc->top);
1975 while (NULL != dc->child_head) 1976 while (NULL != dc->child_head)
1976 GNUNET_FS_download_signal_suspend_(dc->child_head); 1977 GNUNET_FS_download_signal_suspend_ (dc->child_head);
1977 if (NULL != dc->search) 1978 if (NULL != dc->search)
1978 { 1979 {
1979 dc->search->download = NULL; 1980 dc->search->download = NULL;
1980 dc->search = NULL; 1981 dc->search = NULL;
1981 } 1982 }
1982 if (NULL != dc->job_queue) 1983 if (NULL != dc->job_queue)
1983 { 1984 {
1984 GNUNET_FS_dequeue_(dc->job_queue); 1985 GNUNET_FS_dequeue_ (dc->job_queue);
1985 dc->job_queue = NULL; 1986 dc->job_queue = NULL;
1986 } 1987 }
1987 if (NULL != dc->parent) 1988 if (NULL != dc->parent)
1988 GNUNET_CONTAINER_DLL_remove(dc->parent->child_head, 1989 GNUNET_CONTAINER_DLL_remove (dc->parent->child_head,
1989 dc->parent->child_tail, 1990 dc->parent->child_tail,
1990 dc); 1991 dc);
1991 if (NULL != dc->task) 1992 if (NULL != dc->task)
1992 { 1993 {
1993 GNUNET_SCHEDULER_cancel(dc->task); 1994 GNUNET_SCHEDULER_cancel (dc->task);
1994 dc->task = NULL; 1995 dc->task = NULL;
1995 } 1996 }
1996 pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND; 1997 pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND;
1997 GNUNET_FS_download_make_status_(&pi, dc); 1998 GNUNET_FS_download_make_status_ (&pi, dc);
1998 if (NULL != dc->te) 1999 if (NULL != dc->te)
1999 { 2000 {
2000 GNUNET_FS_tree_encoder_finish(dc->te, NULL); 2001 GNUNET_FS_tree_encoder_finish (dc->te, NULL);
2001 dc->te = NULL; 2002 dc->te = NULL;
2002 } 2003 }
2003 if (NULL != dc->rfh) 2004 if (NULL != dc->rfh)
2004 { 2005 {
2005 GNUNET_DISK_file_close(dc->rfh); 2006 GNUNET_DISK_file_close (dc->rfh);
2006 dc->rfh = NULL; 2007 dc->rfh = NULL;
2007 } 2008 }
2008 GNUNET_FS_free_download_request_(dc->top_request); 2009 GNUNET_FS_free_download_request_ (dc->top_request);
2009 if (NULL != dc->active) 2010 if (NULL != dc->active)
2010 { 2011 {
2011 GNUNET_CONTAINER_multihashmap_destroy(dc->active); 2012 GNUNET_CONTAINER_multihashmap_destroy (dc->active);
2012 dc->active = NULL; 2013 dc->active = NULL;
2013 } 2014 }
2014 GNUNET_free_non_null(dc->filename); 2015 GNUNET_free_non_null (dc->filename);
2015 GNUNET_CONTAINER_meta_data_destroy(dc->meta); 2016 GNUNET_CONTAINER_meta_data_destroy (dc->meta);
2016 GNUNET_FS_uri_destroy(dc->uri); 2017 GNUNET_FS_uri_destroy (dc->uri);
2017 GNUNET_free_non_null(dc->temp_filename); 2018 GNUNET_free_non_null (dc->temp_filename);
2018 GNUNET_free_non_null(dc->serialization); 2019 GNUNET_free_non_null (dc->serialization);
2019 GNUNET_assert(NULL == dc->job_queue); 2020 GNUNET_assert (NULL == dc->job_queue);
2020 GNUNET_free(dc); 2021 GNUNET_free (dc);
2021} 2022}
2022 2023
2023 2024
@@ -2041,72 +2042,72 @@ GNUNET_FS_download_signal_suspend_(void *cls)
2041 * @return context that can be used to control this download 2042 * @return context that can be used to control this download
2042 */ 2043 */
2043struct GNUNET_FS_DownloadContext * 2044struct GNUNET_FS_DownloadContext *
2044create_download_context(struct GNUNET_FS_Handle *h, 2045create_download_context (struct GNUNET_FS_Handle *h,
2045 const struct GNUNET_FS_Uri *uri, 2046 const struct GNUNET_FS_Uri *uri,
2046 const struct GNUNET_CONTAINER_MetaData *meta, 2047 const struct GNUNET_CONTAINER_MetaData *meta,
2047 const char *filename, 2048 const char *filename,
2048 const char *tempname, 2049 const char *tempname,
2049 uint64_t offset, 2050 uint64_t offset,
2050 uint64_t length, 2051 uint64_t length,
2051 uint32_t anonymity, 2052 uint32_t anonymity,
2052 enum GNUNET_FS_DownloadOptions options, 2053 enum GNUNET_FS_DownloadOptions options,
2053 void *cctx) 2054 void *cctx)
2054{ 2055{
2055 struct GNUNET_FS_DownloadContext *dc; 2056 struct GNUNET_FS_DownloadContext *dc;
2056 2057
2057 GNUNET_assert(GNUNET_FS_uri_test_chk(uri) || GNUNET_FS_uri_test_loc(uri)); 2058 GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri));
2058 if ((offset + length < offset) || 2059 if ((offset + length < offset) ||
2059 (offset + length > GNUNET_FS_uri_chk_get_file_size(uri))) 2060 (offset + length > GNUNET_FS_uri_chk_get_file_size (uri)))
2060 { 2061 {
2061 GNUNET_break(0); 2062 GNUNET_break (0);
2062 return NULL; 2063 return NULL;
2063 } 2064 }
2064 dc = GNUNET_new(struct GNUNET_FS_DownloadContext); 2065 dc = GNUNET_new (struct GNUNET_FS_DownloadContext);
2065 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2066 "Starting download %p, %u bytes at offset %llu\n", 2067 "Starting download %p, %u bytes at offset %llu\n",
2067 dc, 2068 dc,
2068 (unsigned int)length, 2069 (unsigned int) length,
2069 (unsigned long long)offset); 2070 (unsigned long long) offset);
2070 dc->h = h; 2071 dc->h = h;
2071 dc->uri = GNUNET_FS_uri_dup(uri); 2072 dc->uri = GNUNET_FS_uri_dup (uri);
2072 dc->meta = GNUNET_CONTAINER_meta_data_duplicate(meta); 2073 dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
2073 dc->client_info = cctx; 2074 dc->client_info = cctx;
2074 dc->start_time = GNUNET_TIME_absolute_get(); 2075 dc->start_time = GNUNET_TIME_absolute_get ();
2075 if (NULL != filename) 2076 if (NULL != filename)
2076 { 2077 {
2077 dc->filename = GNUNET_strdup(filename); 2078 dc->filename = GNUNET_strdup (filename);
2078 if (GNUNET_YES == GNUNET_DISK_file_test(filename)) 2079 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
2079 GNUNET_break(GNUNET_OK == GNUNET_DISK_file_size(filename, 2080 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (filename,
2080 &dc->old_file_size, 2081 &dc->old_file_size,
2081 GNUNET_YES, 2082 GNUNET_YES,
2082 GNUNET_YES)); 2083 GNUNET_YES));
2083 } 2084 }
2084 if (GNUNET_FS_uri_test_loc(dc->uri)) 2085 if (GNUNET_FS_uri_test_loc (dc->uri))
2085 GNUNET_assert(GNUNET_OK == 2086 GNUNET_assert (GNUNET_OK ==
2086 GNUNET_FS_uri_loc_get_peer_identity(dc->uri, &dc->target)); 2087 GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target));
2087 dc->offset = offset; 2088 dc->offset = offset;
2088 dc->length = length; 2089 dc->length = length;
2089 dc->anonymity = anonymity; 2090 dc->anonymity = anonymity;
2090 dc->options = options; 2091 dc->options = options;
2091 dc->active = 2092 dc->active =
2092 GNUNET_CONTAINER_multihashmap_create(1 + 2 * (length / DBLOCK_SIZE), 2093 GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE),
2093 GNUNET_NO); 2094 GNUNET_NO);
2094 dc->treedepth = 2095 dc->treedepth =
2095 GNUNET_FS_compute_depth(GNUNET_FS_uri_chk_get_file_size(dc->uri)); 2096 GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri));
2096 if ((NULL == filename) && (is_recursive_download(dc))) 2097 if ((NULL == filename) && (is_recursive_download (dc)))
2097 { 2098 {
2098 if (NULL != tempname) 2099 if (NULL != tempname)
2099 dc->temp_filename = GNUNET_strdup(tempname); 2100 dc->temp_filename = GNUNET_strdup (tempname);
2100 else 2101 else
2101 dc->temp_filename = GNUNET_DISK_mktemp("gnunet-directory-download-tmp"); 2102 dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
2102 } 2103 }
2103 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2104 "Starting download `%s' of %llu bytes with tree depth %u\n", 2105 "Starting download `%s' of %llu bytes with tree depth %u\n",
2105 filename, 2106 filename,
2106 (unsigned long long)length, 2107 (unsigned long long) length,
2107 dc->treedepth); 2108 dc->treedepth);
2108 GNUNET_assert(NULL == dc->job_queue); 2109 GNUNET_assert (NULL == dc->job_queue);
2109 dc->task = GNUNET_SCHEDULER_add_now(&GNUNET_FS_download_start_task_, dc); 2110 dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc);
2110 return dc; 2111 return dc;
2111} 2112}
2112 2113
@@ -2142,38 +2143,38 @@ create_download_context(struct GNUNET_FS_Handle *h,
2142 * @return context that can be used to control this download 2143 * @return context that can be used to control this download
2143 */ 2144 */
2144struct GNUNET_FS_DownloadContext * 2145struct GNUNET_FS_DownloadContext *
2145GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, 2146GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
2146 const struct GNUNET_FS_Uri *uri, 2147 const struct GNUNET_FS_Uri *uri,
2147 const struct GNUNET_CONTAINER_MetaData *meta, 2148 const struct GNUNET_CONTAINER_MetaData *meta,
2148 const char *filename, 2149 const char *filename,
2149 const char *tempname, 2150 const char *tempname,
2150 uint64_t offset, 2151 uint64_t offset,
2151 uint64_t length, 2152 uint64_t length,
2152 uint32_t anonymity, 2153 uint32_t anonymity,
2153 enum GNUNET_FS_DownloadOptions options, 2154 enum GNUNET_FS_DownloadOptions options,
2154 void *cctx, 2155 void *cctx,
2155 struct GNUNET_FS_DownloadContext *parent) 2156 struct GNUNET_FS_DownloadContext *parent)
2156{ 2157{
2157 struct GNUNET_FS_DownloadContext *dc; 2158 struct GNUNET_FS_DownloadContext *dc;
2158 2159
2159 dc = create_download_context(h, 2160 dc = create_download_context (h,
2160 uri, 2161 uri,
2161 meta, 2162 meta,
2162 filename, 2163 filename,
2163 tempname, 2164 tempname,
2164 offset, 2165 offset,
2165 length, 2166 length,
2166 anonymity, 2167 anonymity,
2167 options, 2168 options,
2168 cctx); 2169 cctx);
2169 if (NULL == dc) 2170 if (NULL == dc)
2170 return NULL; 2171 return NULL;
2171 dc->parent = parent; 2172 dc->parent = parent;
2172 if (NULL != parent) 2173 if (NULL != parent)
2173 GNUNET_CONTAINER_DLL_insert(parent->child_head, parent->child_tail, dc); 2174 GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc);
2174 else if (0 == (GNUNET_FS_DOWNLOAD_IS_PROBE & options)) 2175 else if (0 == (GNUNET_FS_DOWNLOAD_IS_PROBE & options))
2175 dc->top = 2176 dc->top =
2176 GNUNET_FS_make_top(dc->h, &GNUNET_FS_download_signal_suspend_, dc); 2177 GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc);
2177 return dc; 2178 return dc;
2178} 2179}
2179 2180
@@ -2213,43 +2214,43 @@ GNUNET_FS_download_start(struct GNUNET_FS_Handle *h,
2213 * @return context that can be used to control this download 2214 * @return context that can be used to control this download
2214 */ 2215 */
2215struct GNUNET_FS_DownloadContext * 2216struct GNUNET_FS_DownloadContext *
2216GNUNET_FS_download_start_from_search(struct GNUNET_FS_Handle *h, 2217GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h,
2217 struct GNUNET_FS_SearchResult *sr, 2218 struct GNUNET_FS_SearchResult *sr,
2218 const char *filename, 2219 const char *filename,
2219 const char *tempname, 2220 const char *tempname,
2220 uint64_t offset, 2221 uint64_t offset,
2221 uint64_t length, 2222 uint64_t length,
2222 uint32_t anonymity, 2223 uint32_t anonymity,
2223 enum GNUNET_FS_DownloadOptions options, 2224 enum GNUNET_FS_DownloadOptions options,
2224 void *cctx) 2225 void *cctx)
2225{ 2226{
2226 struct GNUNET_FS_DownloadContext *dc; 2227 struct GNUNET_FS_DownloadContext *dc;
2227 2228
2228 if ((NULL == sr) || (NULL != sr->download)) 2229 if ((NULL == sr) || (NULL != sr->download))
2229 { 2230 {
2230 GNUNET_break(0); 2231 GNUNET_break (0);
2231 return NULL; 2232 return NULL;
2232 } 2233 }
2233 dc = create_download_context(h, 2234 dc = create_download_context (h,
2234 sr->uri, 2235 sr->uri,
2235 sr->meta, 2236 sr->meta,
2236 filename, 2237 filename,
2237 tempname, 2238 tempname,
2238 offset, 2239 offset,
2239 length, 2240 length,
2240 anonymity, 2241 anonymity,
2241 options, 2242 options,
2242 cctx); 2243 cctx);
2243 if (NULL == dc) 2244 if (NULL == dc)
2244 return NULL; 2245 return NULL;
2245 dc->search = sr; 2246 dc->search = sr;
2246 sr->download = dc; 2247 sr->download = dc;
2247 if (NULL != sr->probe_ctx) 2248 if (NULL != sr->probe_ctx)
2248 { 2249 {
2249 GNUNET_FS_download_stop(sr->probe_ctx, GNUNET_YES); 2250 GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
2250 sr->probe_ctx = NULL; 2251 sr->probe_ctx = NULL;
2251 GNUNET_FS_stop_probe_ping_task_(sr); 2252 GNUNET_FS_stop_probe_ping_task_ (sr);
2252 } 2253 }
2253 return dc; 2254 return dc;
2254} 2255}
2255 2256
@@ -2260,28 +2261,28 @@ GNUNET_FS_download_start_from_search(struct GNUNET_FS_Handle *h,
2260 * @param dc our download context 2261 * @param dc our download context
2261 */ 2262 */
2262void 2263void
2263GNUNET_FS_download_start_downloading_(struct GNUNET_FS_DownloadContext *dc) 2264GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc)
2264{ 2265{
2265 if (dc->completed == dc->length) 2266 if (dc->completed == dc->length)
2266 return; 2267 return;
2267 if (NULL != dc->mq) 2268 if (NULL != dc->mq)
2268 return; /* already running */ 2269 return; /* already running */
2269 GNUNET_assert(NULL == dc->job_queue); 2270 GNUNET_assert (NULL == dc->job_queue);
2270 GNUNET_assert(NULL == dc->task); 2271 GNUNET_assert (NULL == dc->task);
2271 GNUNET_assert(NULL != dc->active); 2272 GNUNET_assert (NULL != dc->active);
2272 dc->job_queue = 2273 dc->job_queue =
2273 GNUNET_FS_queue_(dc->h, 2274 GNUNET_FS_queue_ (dc->h,
2274 &activate_fs_download, 2275 &activate_fs_download,
2275 &deactivate_fs_download, 2276 &deactivate_fs_download,
2276 dc, 2277 dc,
2277 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE, 2278 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
2278 (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) 2279 (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
2279 ? GNUNET_FS_QUEUE_PRIORITY_NORMAL 2280 ? GNUNET_FS_QUEUE_PRIORITY_NORMAL
2280 : GNUNET_FS_QUEUE_PRIORITY_PROBE); 2281 : GNUNET_FS_QUEUE_PRIORITY_PROBE);
2281 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2282 "Download %p put into queue as job %p\n", 2283 "Download %p put into queue as job %p\n",
2283 dc, 2284 dc,
2284 dc->job_queue); 2285 dc->job_queue);
2285} 2286}
2286 2287
2287/** 2288/**
@@ -2290,9 +2291,9 @@ GNUNET_FS_download_start_downloading_(struct GNUNET_FS_DownloadContext *dc)
2290 * @param dc handle for the download 2291 * @param dc handle for the download
2291 */ 2292 */
2292void 2293void
2293GNUNET_FS_download_suspend(struct GNUNET_FS_DownloadContext *dc) 2294GNUNET_FS_download_suspend (struct GNUNET_FS_DownloadContext *dc)
2294{ 2295{
2295 deactivate_fs_download(dc); 2296 deactivate_fs_download (dc);
2296} 2297}
2297 2298
2298 2299
@@ -2302,23 +2303,23 @@ GNUNET_FS_download_suspend(struct GNUNET_FS_DownloadContext *dc)
2302 * @param dc handle for the download 2303 * @param dc handle for the download
2303 */ 2304 */
2304void 2305void
2305GNUNET_FS_download_resume(struct GNUNET_FS_DownloadContext *dc) 2306GNUNET_FS_download_resume (struct GNUNET_FS_DownloadContext *dc)
2306{ 2307{
2307 struct GNUNET_FS_ProgressInfo pi; 2308 struct GNUNET_FS_ProgressInfo pi;
2308 2309
2309 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; 2310 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE;
2310 GNUNET_FS_download_make_status_(&pi, dc); 2311 GNUNET_FS_download_make_status_ (&pi, dc);
2311 2312
2312 GNUNET_assert(NULL == dc->task); 2313 GNUNET_assert (NULL == dc->task);
2313 dc->job_queue = 2314 dc->job_queue =
2314 GNUNET_FS_queue_(dc->h, 2315 GNUNET_FS_queue_ (dc->h,
2315 &activate_fs_download, 2316 &activate_fs_download,
2316 &deactivate_fs_download, 2317 &deactivate_fs_download,
2317 dc, 2318 dc,
2318 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE, 2319 (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
2319 (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) 2320 (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
2320 ? GNUNET_FS_QUEUE_PRIORITY_NORMAL 2321 ? GNUNET_FS_QUEUE_PRIORITY_NORMAL
2321 : GNUNET_FS_QUEUE_PRIORITY_PROBE); 2322 : GNUNET_FS_QUEUE_PRIORITY_PROBE);
2322} 2323}
2323 2324
2324 2325
@@ -2329,88 +2330,88 @@ GNUNET_FS_download_resume(struct GNUNET_FS_DownloadContext *dc)
2329 * @param do_delete delete files of incomplete downloads 2330 * @param do_delete delete files of incomplete downloads
2330 */ 2331 */
2331void 2332void
2332GNUNET_FS_download_stop(struct GNUNET_FS_DownloadContext *dc, int do_delete) 2333GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
2333{ 2334{
2334 struct GNUNET_FS_ProgressInfo pi; 2335 struct GNUNET_FS_ProgressInfo pi;
2335 int have_children; 2336 int have_children;
2336 int search_was_null; 2337 int search_was_null;
2337 2338
2338 if (NULL != dc->top) 2339 if (NULL != dc->top)
2339 GNUNET_FS_end_top(dc->h, dc->top); 2340 GNUNET_FS_end_top (dc->h, dc->top);
2340 if (NULL != dc->task) 2341 if (NULL != dc->task)
2341 { 2342 {
2342 GNUNET_SCHEDULER_cancel(dc->task); 2343 GNUNET_SCHEDULER_cancel (dc->task);
2343 dc->task = NULL; 2344 dc->task = NULL;
2344 } 2345 }
2345 search_was_null = (NULL == dc->search); 2346 search_was_null = (NULL == dc->search);
2346 if (NULL != dc->search) 2347 if (NULL != dc->search)
2347 { 2348 {
2348 dc->search->download = NULL; 2349 dc->search->download = NULL;
2349 GNUNET_FS_search_result_sync_(dc->search); 2350 GNUNET_FS_search_result_sync_ (dc->search);
2350 dc->search = NULL; 2351 dc->search = NULL;
2351 } 2352 }
2352 if (NULL != dc->job_queue) 2353 if (NULL != dc->job_queue)
2353 { 2354 {
2354 GNUNET_FS_dequeue_(dc->job_queue); 2355 GNUNET_FS_dequeue_ (dc->job_queue);
2355 dc->job_queue = NULL; 2356 dc->job_queue = NULL;
2356 } 2357 }
2357 if (NULL != dc->te) 2358 if (NULL != dc->te)
2358 { 2359 {
2359 GNUNET_FS_tree_encoder_finish(dc->te, NULL); 2360 GNUNET_FS_tree_encoder_finish (dc->te, NULL);
2360 dc->te = NULL; 2361 dc->te = NULL;
2361 } 2362 }
2362 have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO; 2363 have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO;
2363 while (NULL != dc->child_head) 2364 while (NULL != dc->child_head)
2364 GNUNET_FS_download_stop(dc->child_head, do_delete); 2365 GNUNET_FS_download_stop (dc->child_head, do_delete);
2365 if (NULL != dc->parent) 2366 if (NULL != dc->parent)
2366 GNUNET_CONTAINER_DLL_remove(dc->parent->child_head, 2367 GNUNET_CONTAINER_DLL_remove (dc->parent->child_head,
2367 dc->parent->child_tail, 2368 dc->parent->child_tail,
2368 dc); 2369 dc);
2369 if (NULL != dc->serialization) 2370 if (NULL != dc->serialization)
2370 GNUNET_FS_remove_sync_file_(dc->h, 2371 GNUNET_FS_remove_sync_file_ (dc->h,
2371 ((NULL != dc->parent) || (!search_was_null)) 2372 ((NULL != dc->parent) || (! search_was_null))
2373 ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD
2374 : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
2375 dc->serialization);
2376 if ((GNUNET_YES == have_children) && (NULL == dc->parent))
2377 GNUNET_FS_remove_sync_dir_ (dc->h,
2378 (! search_was_null)
2372 ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD 2379 ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD
2373 : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, 2380 : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
2374 dc->serialization); 2381 dc->serialization);
2375 if ((GNUNET_YES == have_children) && (NULL == dc->parent))
2376 GNUNET_FS_remove_sync_dir_(dc->h,
2377 (!search_was_null)
2378 ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD
2379 : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
2380 dc->serialization);
2381 pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; 2382 pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED;
2382 GNUNET_FS_download_make_status_(&pi, dc); 2383 GNUNET_FS_download_make_status_ (&pi, dc);
2383 GNUNET_FS_free_download_request_(dc->top_request); 2384 GNUNET_FS_free_download_request_ (dc->top_request);
2384 dc->top_request = NULL; 2385 dc->top_request = NULL;
2385 if (NULL != dc->active) 2386 if (NULL != dc->active)
2386 { 2387 {
2387 GNUNET_CONTAINER_multihashmap_destroy(dc->active); 2388 GNUNET_CONTAINER_multihashmap_destroy (dc->active);
2388 dc->active = NULL; 2389 dc->active = NULL;
2389 } 2390 }
2390 if (NULL != dc->filename) 2391 if (NULL != dc->filename)
2391 { 2392 {
2392 if ((dc->completed != dc->length) && (GNUNET_YES == do_delete)) 2393 if ((dc->completed != dc->length) && (GNUNET_YES == do_delete))
2393 { 2394 {
2394 if ((0 != unlink(dc->filename)) && (ENOENT != errno)) 2395 if ((0 != unlink (dc->filename)) && (ENOENT != errno))
2395 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, 2396 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
2396 "unlink", 2397 "unlink",
2397 dc->filename); 2398 dc->filename);
2398 } 2399 }
2399 GNUNET_free(dc->filename); 2400 GNUNET_free (dc->filename);
2400 } 2401 }
2401 GNUNET_CONTAINER_meta_data_destroy(dc->meta); 2402 GNUNET_CONTAINER_meta_data_destroy (dc->meta);
2402 GNUNET_FS_uri_destroy(dc->uri); 2403 GNUNET_FS_uri_destroy (dc->uri);
2403 if (NULL != dc->temp_filename) 2404 if (NULL != dc->temp_filename)
2404 { 2405 {
2405 if (0 != unlink(dc->temp_filename)) 2406 if (0 != unlink (dc->temp_filename))
2406 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, 2407 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
2407 "unlink", 2408 "unlink",
2408 dc->temp_filename); 2409 dc->temp_filename);
2409 GNUNET_free(dc->temp_filename); 2410 GNUNET_free (dc->temp_filename);
2410 } 2411 }
2411 GNUNET_free_non_null(dc->serialization); 2412 GNUNET_free_non_null (dc->serialization);
2412 GNUNET_assert(NULL == dc->job_queue); 2413 GNUNET_assert (NULL == dc->job_queue);
2413 GNUNET_free(dc); 2414 GNUNET_free (dc);
2414} 2415}
2415 2416
2416/* end of fs_download.c */ 2417/* end of fs_download.c */