aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_download.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r--src/fs/fs_download.c2574
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 */
36static int 36static int
37is_recursive_download (struct GNUNET_FS_DownloadContext *dc) 37is_recursive_download(struct GNUNET_FS_DownloadContext *dc)
38{ 38{
39 return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) && 39 return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
40 ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) || 40 ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory(dc->meta)) ||
41 ((NULL == dc->meta) && 41 ((NULL == dc->meta) &&
42 ((NULL == dc->filename) || 42 ((NULL == dc->filename) ||
43 ((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && 43 ((strlen(dc->filename) >= strlen(GNUNET_FS_DIRECTORY_EXT)) &&
44 (NULL != strstr (dc->filename + strlen (dc->filename) - 44 (NULL != strstr(dc->filename + strlen(dc->filename) -
45 strlen (GNUNET_FS_DIRECTORY_EXT), 45 strlen(GNUNET_FS_DIRECTORY_EXT),
46 GNUNET_FS_DIRECTORY_EXT)))))); 46 GNUNET_FS_DIRECTORY_EXT))))));
47} 47}
48 48
49 49
@@ -64,7 +64,7 @@ is_recursive_download (struct GNUNET_FS_DownloadContext *dc)
64 * with the range for any other block 64 * with the range for any other block
65 */ 65 */
66static uint64_t 66static uint64_t
67compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth) 67compute_disk_offset(uint64_t fsize, uint64_t off, unsigned int depth)
68{ 68{
69 unsigned int i; 69 unsigned int i;
70 uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */ 70 uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */
@@ -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 */
102void 102void
103GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, 103GNUNET_FS_download_make_status_(struct GNUNET_FS_ProgressInfo *pi,
104 struct GNUNET_FS_DownloadContext *dc) 104 struct GNUNET_FS_DownloadContext *dc)
105{ 105{
106 pi->value.download.dc = dc; 106 pi->value.download.dc = dc;
107 pi->value.download.cctx = dc->client_info; 107 pi->value.download.cctx = dc->client_info;
@@ -114,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 */
134struct ProcessResultClosure 134struct 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 */
193static int 191static int
194process_result_with_request (void *cls, 192process_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 */
212static int 210static int
213encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, 211encrypt_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 */
265static void 263static void
266try_reconnect (struct GNUNET_FS_DownloadContext *dc); 264try_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 */
280static void 278static void
281trigger_recursive_download (void *cls, 279trigger_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 */
295static void 293static void
296full_recursive_download (struct GNUNET_FS_DownloadContext *dc) 294full_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 */
375static void 373static void
376check_completed (struct GNUNET_FS_DownloadContext *dc) 374check_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 */
431static void 429static void
432try_match_block (struct GNUNET_FS_DownloadContext *dc, 430try_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 */
600static int 600static int
601match_full_data (void *cls, 601match_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 */
632static void 632static void
633propagate_up (struct DownloadRequest *dr) 633propagate_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 */
660static void 661static void
661try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, 662try_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 */
744static int 745static int
745retry_entry (void *cls, const struct GNUNET_HashCode *key, void *entry) 746retry_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 */
775static void 776static void
776schedule_block_download (struct GNUNET_FS_DownloadContext *dc, 777schedule_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 */
841static void 849static void
842trigger_recursive_download (void *cls, 850trigger_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 */
987void 995void
988GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) 996GNUNET_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 */
1008static int 1016static int
1009process_result_with_request (void *cls, 1017process_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
1256signal_error: 1272signal_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 */
1283static int 1299static int
1284check_put (void *cls, const struct ClientPutMessage *cm) 1300check_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 */
1298static void 1314static void
1299handle_put (void *cls, const struct ClientPutMessage *cm) 1315handle_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 */
1332static void 1348static void
1333download_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) 1349download_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 */
1353static void 1369static void
1354do_reconnect (void *cls) 1370do_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 */
1389static void 1405static void
1390try_reconnect (struct GNUNET_FS_DownloadContext *dc) 1406try_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 */
1420static void 1436static void
1421activate_fs_download (void *cls) 1437activate_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 */
1441static void 1457static void
1442deactivate_fs_download (void *cls) 1458deactivate_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 */
1477static struct DownloadRequest * 1493static struct DownloadRequest *
1478create_download_request (struct DownloadRequest *parent, 1494create_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 */
1553static void 1569static void
1554reconstruct_cont (void *cls) 1570reconstruct_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 */
1581static void 1597static void
1582get_next_block (void *cls) 1598get_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 */
1608static void 1624static void
1609reconstruct_cb (void *cls, 1625reconstruct_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 */
1752static size_t 1776static size_t
1753fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) 1777fh_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 */
1784void 1808void
1785GNUNET_FS_download_start_task_ (void *cls) 1809GNUNET_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 */
1939void 1967void
1940GNUNET_FS_download_signal_suspend_ (void *cls) 1968GNUNET_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 */
2015struct GNUNET_FS_DownloadContext * 2043struct GNUNET_FS_DownloadContext *
2016create_download_context (struct GNUNET_FS_Handle *h, 2044create_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 */
2116struct GNUNET_FS_DownloadContext * 2144struct GNUNET_FS_DownloadContext *
2117GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, 2145GNUNET_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 */
2187struct GNUNET_FS_DownloadContext * 2215struct GNUNET_FS_DownloadContext *
2188GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, 2216GNUNET_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 */
2234void 2262void
2235GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc) 2263GNUNET_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 */
2264void 2292void
2265GNUNET_FS_download_suspend (struct GNUNET_FS_DownloadContext *dc) 2293GNUNET_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 */
2276void 2304void
2277GNUNET_FS_download_resume (struct GNUNET_FS_DownloadContext *dc) 2305GNUNET_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 */
2303void 2331void
2304GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) 2332GNUNET_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 */