diff options
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r-- | src/fs/fs_download.c | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 0789162bf..ce852f2d0 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -37,14 +37,14 @@ static int | |||
37 | is_recursive_download (struct GNUNET_FS_DownloadContext *dc) | 37 | is_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 != | 44 | (NULL != |
45 | strstr (dc->filename + strlen (dc->filename) - | 45 | strstr (dc->filename + strlen (dc->filename) - |
46 | strlen (GNUNET_FS_DIRECTORY_EXT), | 46 | strlen (GNUNET_FS_DIRECTORY_EXT), |
47 | GNUNET_FS_DIRECTORY_EXT)))))); | 47 | GNUNET_FS_DIRECTORY_EXT)) ) ) ) ); |
48 | } | 48 | } |
49 | 49 | ||
50 | 50 | ||
@@ -278,10 +278,12 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc); | |||
278 | * @param data contents of the file (or NULL if they were not inlined) | 278 | * @param data contents of the file (or NULL if they were not inlined) |
279 | */ | 279 | */ |
280 | static void | 280 | static void |
281 | trigger_recursive_download (void *cls, const char *filename, | 281 | trigger_recursive_download (void *cls, |
282 | const char *filename, | ||
282 | const struct GNUNET_FS_Uri *uri, | 283 | const struct GNUNET_FS_Uri *uri, |
283 | const struct GNUNET_CONTAINER_MetaData *meta, | 284 | const struct GNUNET_CONTAINER_MetaData *meta, |
284 | size_t length, const void *data); | 285 | size_t length, |
286 | const void *data); | ||
285 | 287 | ||
286 | 288 | ||
287 | /** | 289 | /** |
@@ -304,24 +306,28 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) | |||
304 | if (size64 != (uint64_t) size) | 306 | if (size64 != (uint64_t) size) |
305 | { | 307 | { |
306 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 308 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
307 | _ | 309 | _("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); |
308 | ("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); | ||
309 | return; | 310 | return; |
310 | } | 311 | } |
311 | if (NULL != dc->filename) | 312 | if (NULL != dc->filename) |
312 | { | 313 | { |
313 | h = GNUNET_DISK_file_open (dc->filename, GNUNET_DISK_OPEN_READ, | 314 | h = GNUNET_DISK_file_open (dc->filename, |
315 | GNUNET_DISK_OPEN_READ, | ||
314 | GNUNET_DISK_PERM_NONE); | 316 | GNUNET_DISK_PERM_NONE); |
315 | } | 317 | } |
316 | else | 318 | else |
317 | { | 319 | { |
318 | GNUNET_assert (NULL != dc->temp_filename); | 320 | GNUNET_assert (NULL != dc->temp_filename); |
319 | h = GNUNET_DISK_file_open (dc->temp_filename, GNUNET_DISK_OPEN_READ, | 321 | h = GNUNET_DISK_file_open (dc->temp_filename, |
322 | GNUNET_DISK_OPEN_READ, | ||
320 | GNUNET_DISK_PERM_NONE); | 323 | GNUNET_DISK_PERM_NONE); |
321 | } | 324 | } |
322 | if (NULL == h) | 325 | if (NULL == h) |
323 | return; /* oops */ | 326 | return; /* oops */ |
324 | data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size); | 327 | data = GNUNET_DISK_file_map (h, |
328 | &m, | ||
329 | GNUNET_DISK_MAP_TYPE_READ, | ||
330 | size); | ||
325 | if (NULL == data) | 331 | if (NULL == data) |
326 | { | 332 | { |
327 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 333 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -329,15 +335,25 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) | |||
329 | } | 335 | } |
330 | else | 336 | else |
331 | { | 337 | { |
332 | GNUNET_FS_directory_list_contents (size, data, 0, | 338 | if (GNUNET_OK != |
333 | &trigger_recursive_download, dc); | 339 | GNUNET_FS_directory_list_contents (size, |
340 | data, | ||
341 | 0, | ||
342 | &trigger_recursive_download, | ||
343 | dc)) | ||
344 | { | ||
345 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
346 | _("Failed to access full directroy contents of `%s' for recursive download\n"), | ||
347 | dc->filename); | ||
348 | } | ||
334 | GNUNET_DISK_file_unmap (m); | 349 | GNUNET_DISK_file_unmap (m); |
335 | } | 350 | } |
336 | GNUNET_DISK_file_close (h); | 351 | GNUNET_DISK_file_close (h); |
337 | if (NULL == dc->filename) | 352 | if (NULL == dc->filename) |
338 | { | 353 | { |
339 | if (0 != UNLINK (dc->temp_filename)) | 354 | if (0 != UNLINK (dc->temp_filename)) |
340 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", | 355 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
356 | "unlink", | ||
341 | dc->temp_filename); | 357 | dc->temp_filename); |
342 | GNUNET_free (dc->temp_filename); | 358 | GNUNET_free (dc->temp_filename); |
343 | dc->temp_filename = NULL; | 359 | dc->temp_filename = NULL; |
@@ -362,14 +378,16 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) | |||
362 | struct GNUNET_FS_DownloadContext *pos; | 378 | struct GNUNET_FS_DownloadContext *pos; |
363 | 379 | ||
364 | /* first, check if we need to download children */ | 380 | /* first, check if we need to download children */ |
365 | if ((NULL == dc->child_head) && (is_recursive_download (dc))) | 381 | if (is_recursive_download (dc)) |
366 | full_recursive_download (dc); | 382 | full_recursive_download (dc); |
367 | /* then, check if children are done already */ | 383 | /* then, check if children are done already */ |
368 | for (pos = dc->child_head; NULL != pos; pos = pos->next) | 384 | for (pos = dc->child_head; NULL != pos; pos = pos->next) |
369 | { | 385 | { |
370 | if ((pos->emsg == NULL) && (pos->completed < pos->length)) | 386 | if ( (NULL == pos->emsg) && |
387 | (pos->completed < pos->length) ) | ||
371 | return; /* not done yet */ | 388 | return; /* not done yet */ |
372 | if ((pos->child_head != NULL) && (pos->has_finished != GNUNET_YES)) | 389 | if ( (NULL != pos->child_head) && |
390 | (pos->has_finished != GNUNET_YES) ) | ||
373 | return; /* not transitively done yet */ | 391 | return; /* not transitively done yet */ |
374 | } | 392 | } |
375 | /* All of our children are done, so mark this download done */ | 393 | /* All of our children are done, so mark this download done */ |
@@ -471,7 +489,11 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
471 | } | 489 | } |
472 | GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key); | 490 | GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key); |
473 | GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv); | 491 | GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv); |
474 | if (-1 == GNUNET_CRYPTO_symmetric_encrypt (&data[dr->offset], dlen, &sk, &iv, enc)) | 492 | if (-1 == GNUNET_CRYPTO_symmetric_encrypt (&data[dr->offset], |
493 | dlen, | ||
494 | &sk, | ||
495 | &iv, | ||
496 | enc)) | ||
475 | { | 497 | { |
476 | GNUNET_break (0); | 498 | GNUNET_break (0); |
477 | return; | 499 | return; |
@@ -484,7 +506,9 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
484 | dr->state = BRS_RECONSTRUCT_META_UP; | 506 | dr->state = BRS_RECONSTRUCT_META_UP; |
485 | break; | 507 | break; |
486 | case BRS_CHK_SET: | 508 | case BRS_CHK_SET: |
487 | if (0 != memcmp (&in_chk, &dr->chk, sizeof (struct ContentHashKey))) | 509 | if (0 != memcmp (&in_chk, |
510 | &dr->chk, | ||
511 | sizeof (struct ContentHashKey))) | ||
488 | { | 512 | { |
489 | /* other peer provided bogus meta data */ | 513 | /* other peer provided bogus meta data */ |
490 | GNUNET_break_op (0); | 514 | GNUNET_break_op (0); |
@@ -591,7 +615,10 @@ match_full_data (void *cls, const char *plugin_name, | |||
591 | GNUNET_break_op (0); | 615 | GNUNET_break_op (0); |
592 | return 1; /* bogus meta data */ | 616 | return 1; /* bogus meta data */ |
593 | } | 617 | } |
594 | try_match_block (dc, dc->top_request, data, data_len); | 618 | try_match_block (dc, |
619 | dc->top_request, | ||
620 | data, | ||
621 | data_len); | ||
595 | return 1; | 622 | return 1; |
596 | } | 623 | } |
597 | 624 | ||
@@ -820,10 +847,12 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc, | |||
820 | * @param data contents of the file (or NULL if they were not inlined) | 847 | * @param data contents of the file (or NULL if they were not inlined) |
821 | */ | 848 | */ |
822 | static void | 849 | static void |
823 | trigger_recursive_download (void *cls, const char *filename, | 850 | trigger_recursive_download (void *cls, |
851 | const char *filename, | ||
824 | const struct GNUNET_FS_Uri *uri, | 852 | const struct GNUNET_FS_Uri *uri, |
825 | const struct GNUNET_CONTAINER_MetaData *meta, | 853 | const struct GNUNET_CONTAINER_MetaData *meta, |
826 | size_t length, const void *data) | 854 | size_t length, |
855 | const void *data) | ||
827 | { | 856 | { |
828 | struct GNUNET_FS_DownloadContext *dc = cls; | 857 | struct GNUNET_FS_DownloadContext *dc = cls; |
829 | struct GNUNET_FS_DownloadContext *cpos; | 858 | struct GNUNET_FS_DownloadContext *cpos; |
@@ -936,9 +965,17 @@ trigger_recursive_download (void *cls, const char *filename, | |||
936 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri), | 965 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri), |
937 | (unsigned int) | 966 | (unsigned int) |
938 | GNUNET_CONTAINER_meta_data_get_serialized_size (meta)); | 967 | GNUNET_CONTAINER_meta_data_get_serialized_size (meta)); |
939 | GNUNET_FS_download_start (dc->h, uri, meta, full_name, temp_name, 0, | 968 | GNUNET_FS_download_start (dc->h, |
969 | uri, | ||
970 | meta, | ||
971 | full_name, | ||
972 | temp_name, | ||
973 | 0, | ||
940 | GNUNET_FS_uri_chk_get_file_size (uri), | 974 | GNUNET_FS_uri_chk_get_file_size (uri), |
941 | dc->anonymity, dc->options, NULL, dc); | 975 | dc->anonymity, |
976 | dc->options, | ||
977 | NULL, | ||
978 | dc); | ||
942 | GNUNET_free_non_null (full_name); | 979 | GNUNET_free_non_null (full_name); |
943 | GNUNET_free_non_null (temp_name); | 980 | GNUNET_free_non_null (temp_name); |
944 | GNUNET_free_non_null (fn); | 981 | GNUNET_free_non_null (fn); |
@@ -953,11 +990,9 @@ trigger_recursive_download (void *cls, const char *filename, | |||
953 | void | 990 | void |
954 | GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) | 991 | GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) |
955 | { | 992 | { |
956 | unsigned int i; | ||
957 | |||
958 | if (NULL == dr) | 993 | if (NULL == dr) |
959 | return; | 994 | return; |
960 | for (i = 0; i < dr->num_children; i++) | 995 | for (unsigned int i = 0; i < dr->num_children; i++) |
961 | GNUNET_FS_free_download_request_ (dr->children[i]); | 996 | GNUNET_FS_free_download_request_ (dr->children[i]); |
962 | GNUNET_free_non_null (dr->children); | 997 | GNUNET_free_non_null (dr->children); |
963 | GNUNET_free (dr); | 998 | GNUNET_free (dr); |
@@ -1509,13 +1544,17 @@ create_download_request (struct DownloadRequest *parent, | |||
1509 | GNUNET_assert (dr->num_children > 0); | 1544 | GNUNET_assert (dr->num_children > 0); |
1510 | 1545 | ||
1511 | dr->children = | 1546 | dr->children = |
1512 | GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); | 1547 | GNUNET_new_array (dr->num_children, |
1548 | struct DownloadRequest *); | ||
1513 | for (i = 0; i < dr->num_children; i++) | 1549 | for (i = 0; i < dr->num_children; i++) |
1514 | { | 1550 | { |
1515 | dr->children[i] = | 1551 | dr->children[i] = |
1516 | create_download_request (dr, i + head_skip, depth - 1, | 1552 | create_download_request (dr, |
1553 | i + head_skip, | ||
1554 | depth - 1, | ||
1517 | dr_offset + (i + head_skip) * child_block_size, | 1555 | dr_offset + (i + head_skip) * child_block_size, |
1518 | file_start_offset, desired_length); | 1556 | file_start_offset, |
1557 | desired_length); | ||
1519 | } | 1558 | } |
1520 | return dr; | 1559 | return dr; |
1521 | } | 1560 | } |