diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-02-19 13:52:24 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-02-19 13:52:24 +0000 |
commit | 5bad33167fe0e7c696144ae7060eb89b0862f7b0 (patch) | |
tree | 3f4499669fb06ca1d8f1d3f8d6155475ffdfe86c /src/fs/fs_download.c | |
parent | 61cf48f3f9caab1c98686e5012fd400853f8fbdd (diff) | |
download | gnunet-5bad33167fe0e7c696144ae7060eb89b0862f7b0.tar.gz gnunet-5bad33167fe0e7c696144ae7060eb89b0862f7b0.zip |
handle case where partial download prevents proper bottom-up reconstruction as not all child-nodes are even attempted; handle case where probe returns results immediately while being created (do not break on that)
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r-- | src/fs/fs_download.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 5d4c6d899..f8933bb9d 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -450,6 +450,18 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
450 | return; | 450 | return; |
451 | if (dr->depth > 0) | 451 | if (dr->depth > 0) |
452 | { | 452 | { |
453 | if ( (dc->offset > 0) || | ||
454 | (dc->length < GNUNET_ntohll (dc->uri->data.chk.file_length)) ) | ||
455 | { | ||
456 | /* NOTE: this test is not tight, but should suffice; the issue | ||
457 | here is that 'dr->num_children' may inherently only specify a | ||
458 | smaller range than what is in the original file; | ||
459 | thus, reconstruction of (some) inner blocks will fail. | ||
460 | FIXME: we might eventually want to write a tighter test to | ||
461 | maximize the circumstances under which we do succeed with | ||
462 | IBlock reconstruction. (need good tests though). */ | ||
463 | return; | ||
464 | } | ||
453 | complete = GNUNET_YES; | 465 | complete = GNUNET_YES; |
454 | for (i = 0; i < dr->num_children; i++) | 466 | for (i = 0; i < dr->num_children; i++) |
455 | { | 467 | { |
@@ -494,39 +506,43 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
494 | } | 506 | } |
495 | /* write block to disk */ | 507 | /* write block to disk */ |
496 | fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename; | 508 | fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename; |
497 | fh = GNUNET_DISK_file_open (fn, | 509 | if (NULL != fn) |
498 | GNUNET_DISK_OPEN_READWRITE | | ||
499 | GNUNET_DISK_OPEN_CREATE | | ||
500 | GNUNET_DISK_OPEN_TRUNCATE, | ||
501 | GNUNET_DISK_PERM_USER_READ | | ||
502 | GNUNET_DISK_PERM_USER_WRITE | | ||
503 | GNUNET_DISK_PERM_GROUP_READ | | ||
504 | GNUNET_DISK_PERM_OTHER_READ); | ||
505 | if (NULL == fh) | ||
506 | { | 510 | { |
507 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn); | 511 | fh = GNUNET_DISK_file_open (fn, |
508 | GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), | 512 | GNUNET_DISK_OPEN_READWRITE | |
509 | fn); | 513 | GNUNET_DISK_OPEN_CREATE | |
510 | GNUNET_DISK_file_close (fh); | 514 | GNUNET_DISK_OPEN_TRUNCATE, |
511 | dr->state = BRS_ERROR; | 515 | GNUNET_DISK_PERM_USER_READ | |
512 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | 516 | GNUNET_DISK_PERM_USER_WRITE | |
513 | pi.value.download.specifics.error.message = dc->emsg; | 517 | GNUNET_DISK_PERM_GROUP_READ | |
514 | GNUNET_FS_download_make_status_ (&pi, dc); | 518 | GNUNET_DISK_PERM_OTHER_READ); |
515 | return; | 519 | if (NULL == fh) |
516 | } | 520 | { |
517 | if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len)) | 521 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn); |
518 | { | 522 | GNUNET_asprintf (&dc->emsg, |
519 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); | 523 | _("Failed to open file `%s' for writing"), |
520 | GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), | 524 | fn); |
521 | fn); | 525 | GNUNET_DISK_file_close (fh); |
526 | dr->state = BRS_ERROR; | ||
527 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | ||
528 | pi.value.download.specifics.error.message = dc->emsg; | ||
529 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
530 | return; | ||
531 | } | ||
532 | if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len)) | ||
533 | { | ||
534 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); | ||
535 | GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), | ||
536 | fn); | ||
537 | GNUNET_DISK_file_close (fh); | ||
538 | dr->state = BRS_ERROR; | ||
539 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | ||
540 | pi.value.download.specifics.error.message = dc->emsg; | ||
541 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
542 | return; | ||
543 | } | ||
522 | GNUNET_DISK_file_close (fh); | 544 | GNUNET_DISK_file_close (fh); |
523 | dr->state = BRS_ERROR; | ||
524 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | ||
525 | pi.value.download.specifics.error.message = dc->emsg; | ||
526 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
527 | return; | ||
528 | } | 545 | } |
529 | GNUNET_DISK_file_close (fh); | ||
530 | /* signal success */ | 546 | /* signal success */ |
531 | dr->state = BRS_DOWNLOAD_UP; | 547 | dr->state = BRS_DOWNLOAD_UP; |
532 | dc->completed = dc->length; | 548 | dc->completed = dc->length; |