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