diff options
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r-- | src/fs/fs_download.c | 2467 |
1 files changed, 1133 insertions, 1334 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index e515b147d..6b72b4e56 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -40,14 +40,15 @@ | |||
40 | static int | 40 | static int |
41 | is_recursive_download (struct GNUNET_FS_DownloadContext *dc) | 41 | is_recursive_download (struct GNUNET_FS_DownloadContext *dc) |
42 | { | 42 | { |
43 | return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) && | 43 | return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) && |
44 | ( (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) || | 44 | ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) || |
45 | ( (dc->meta == NULL) && | 45 | ((dc->meta == NULL) && |
46 | ( (NULL == dc->filename) || | 46 | ((NULL == dc->filename) || |
47 | ( (strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && | 47 | ((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && |
48 | (NULL != | 48 | (NULL != |
49 | strstr (dc->filename + strlen(dc->filename) - strlen(GNUNET_FS_DIRECTORY_EXT), | 49 | strstr (dc->filename + strlen (dc->filename) - |
50 | GNUNET_FS_DIRECTORY_EXT)) ) ) ) ); | 50 | strlen (GNUNET_FS_DIRECTORY_EXT), |
51 | GNUNET_FS_DIRECTORY_EXT)))))); | ||
51 | } | 52 | } |
52 | 53 | ||
53 | 54 | ||
@@ -68,31 +69,31 @@ is_recursive_download (struct GNUNET_FS_DownloadContext *dc) | |||
68 | * with the range for any other block | 69 | * with the range for any other block |
69 | */ | 70 | */ |
70 | static uint64_t | 71 | static uint64_t |
71 | compute_disk_offset (uint64_t fsize, | 72 | compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth) |
72 | uint64_t off, | ||
73 | unsigned int depth) | ||
74 | { | 73 | { |
75 | unsigned int i; | 74 | unsigned int i; |
76 | uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */ | 75 | uint64_t lsize; /* what is the size of all IBlocks for depth "i"? */ |
77 | uint64_t loff; /* where do IBlocks for depth "i" start? */ | 76 | uint64_t loff; /* where do IBlocks for depth "i" start? */ |
78 | unsigned int ioff; /* which IBlock corresponds to "off" at depth "i"? */ | 77 | unsigned int ioff; /* which IBlock corresponds to "off" at depth "i"? */ |
79 | 78 | ||
80 | if (depth == 0) | 79 | if (depth == 0) |
81 | return off; | 80 | return off; |
82 | /* first IBlocks start at the end of file, rounded up | 81 | /* first IBlocks start at the end of file, rounded up |
83 | to full DBLOCK_SIZE */ | 82 | * to full DBLOCK_SIZE */ |
84 | loff = ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * DBLOCK_SIZE; | 83 | loff = ((fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * DBLOCK_SIZE; |
85 | lsize = ( (fsize + DBLOCK_SIZE - 1) / DBLOCK_SIZE) * sizeof (struct ContentHashKey); | 84 | lsize = |
85 | ((fsize + DBLOCK_SIZE - | ||
86 | 1) / DBLOCK_SIZE) * sizeof (struct ContentHashKey); | ||
86 | GNUNET_assert (0 == (off % DBLOCK_SIZE)); | 87 | GNUNET_assert (0 == (off % DBLOCK_SIZE)); |
87 | ioff = (off / DBLOCK_SIZE); | 88 | ioff = (off / DBLOCK_SIZE); |
88 | for (i=1;i<depth;i++) | 89 | for (i = 1; i < depth; i++) |
89 | { | 90 | { |
90 | loff += lsize; | 91 | loff += lsize; |
91 | lsize = (lsize + CHK_PER_INODE - 1) / CHK_PER_INODE; | 92 | lsize = (lsize + CHK_PER_INODE - 1) / CHK_PER_INODE; |
92 | GNUNET_assert (lsize > 0); | 93 | GNUNET_assert (lsize > 0); |
93 | GNUNET_assert (0 == (ioff % CHK_PER_INODE)); | 94 | GNUNET_assert (0 == (ioff % CHK_PER_INODE)); |
94 | ioff /= CHK_PER_INODE; | 95 | ioff /= CHK_PER_INODE; |
95 | } | 96 | } |
96 | return loff + ioff * sizeof (struct ContentHashKey); | 97 | return loff + ioff * sizeof (struct ContentHashKey); |
97 | } | 98 | } |
98 | 99 | ||
@@ -106,38 +107,28 @@ compute_disk_offset (uint64_t fsize, | |||
106 | */ | 107 | */ |
107 | void | 108 | void |
108 | GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, | 109 | GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, |
109 | struct GNUNET_FS_DownloadContext *dc) | 110 | struct GNUNET_FS_DownloadContext *dc) |
110 | { | 111 | { |
111 | pi->value.download.dc = dc; | 112 | pi->value.download.dc = dc; |
112 | pi->value.download.cctx | 113 | pi->value.download.cctx = dc->client_info; |
113 | = dc->client_info; | ||
114 | pi->value.download.pctx | 114 | pi->value.download.pctx |
115 | = (dc->parent == NULL) ? NULL : dc->parent->client_info; | 115 | = (dc->parent == NULL) ? NULL : dc->parent->client_info; |
116 | pi->value.download.sctx | 116 | pi->value.download.sctx |
117 | = (dc->search == NULL) ? NULL : dc->search->client_info; | 117 | = (dc->search == NULL) ? NULL : dc->search->client_info; |
118 | pi->value.download.uri | 118 | pi->value.download.uri = dc->uri; |
119 | = dc->uri; | 119 | pi->value.download.filename = dc->filename; |
120 | pi->value.download.filename | 120 | pi->value.download.size = dc->length; |
121 | = dc->filename; | ||
122 | pi->value.download.size | ||
123 | = dc->length; | ||
124 | pi->value.download.duration | 121 | pi->value.download.duration |
125 | = GNUNET_TIME_absolute_get_duration (dc->start_time); | 122 | = GNUNET_TIME_absolute_get_duration (dc->start_time); |
126 | pi->value.download.completed | 123 | pi->value.download.completed = dc->completed; |
127 | = dc->completed; | 124 | pi->value.download.anonymity = dc->anonymity; |
128 | pi->value.download.anonymity | ||
129 | = dc->anonymity; | ||
130 | pi->value.download.eta | 125 | pi->value.download.eta |
131 | = GNUNET_TIME_calculate_eta (dc->start_time, | 126 | = GNUNET_TIME_calculate_eta (dc->start_time, dc->completed, dc->length); |
132 | dc->completed, | ||
133 | dc->length); | ||
134 | pi->value.download.is_active = (dc->client == NULL) ? GNUNET_NO : GNUNET_YES; | 127 | pi->value.download.is_active = (dc->client == NULL) ? GNUNET_NO : GNUNET_YES; |
135 | if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) | 128 | if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE)) |
136 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, | 129 | dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi); |
137 | pi); | ||
138 | else | 130 | else |
139 | dc->client_info = GNUNET_FS_search_probe_progress_ (NULL, | 131 | dc->client_info = GNUNET_FS_search_probe_progress_ (NULL, pi); |
140 | pi); | ||
141 | } | 132 | } |
142 | 133 | ||
143 | 134 | ||
@@ -152,10 +143,7 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi, | |||
152 | * @param buf where the callee should write the message | 143 | * @param buf where the callee should write the message |
153 | * @return number of bytes written to buf | 144 | * @return number of bytes written to buf |
154 | */ | 145 | */ |
155 | static size_t | 146 | static size_t transmit_download_request (void *cls, size_t size, void *buf); |
156 | transmit_download_request (void *cls, | ||
157 | size_t size, | ||
158 | void *buf); | ||
159 | 147 | ||
160 | 148 | ||
161 | /** | 149 | /** |
@@ -163,7 +151,7 @@ transmit_download_request (void *cls, | |||
163 | */ | 151 | */ |
164 | struct ProcessResultClosure | 152 | struct ProcessResultClosure |
165 | { | 153 | { |
166 | 154 | ||
167 | /** | 155 | /** |
168 | * Hash of data. | 156 | * Hash of data. |
169 | */ | 157 | */ |
@@ -171,14 +159,14 @@ struct ProcessResultClosure | |||
171 | 159 | ||
172 | /** | 160 | /** |
173 | * Data found in P2P network. | 161 | * Data found in P2P network. |
174 | */ | 162 | */ |
175 | const void *data; | 163 | const void *data; |
176 | 164 | ||
177 | /** | 165 | /** |
178 | * Our download context. | 166 | * Our download context. |
179 | */ | 167 | */ |
180 | struct GNUNET_FS_DownloadContext *dc; | 168 | struct GNUNET_FS_DownloadContext *dc; |
181 | 169 | ||
182 | /** | 170 | /** |
183 | * Number of bytes in data. | 171 | * Number of bytes in data. |
184 | */ | 172 | */ |
@@ -193,7 +181,7 @@ struct ProcessResultClosure | |||
193 | * Flag to indicate if this block should be stored on disk. | 181 | * Flag to indicate if this block should be stored on disk. |
194 | */ | 182 | */ |
195 | int do_store; | 183 | int do_store; |
196 | 184 | ||
197 | }; | 185 | }; |
198 | 186 | ||
199 | 187 | ||
@@ -208,8 +196,7 @@ struct ProcessResultClosure | |||
208 | */ | 196 | */ |
209 | static int | 197 | static int |
210 | process_result_with_request (void *cls, | 198 | process_result_with_request (void *cls, |
211 | const GNUNET_HashCode * key, | 199 | const GNUNET_HashCode * key, void *value); |
212 | void *value); | ||
213 | 200 | ||
214 | 201 | ||
215 | /** | 202 | /** |
@@ -227,53 +214,42 @@ process_result_with_request (void *cls, | |||
227 | */ | 214 | */ |
228 | static int | 215 | static int |
229 | encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, | 216 | encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, |
230 | const struct ContentHashKey *chk, | 217 | const struct ContentHashKey *chk, |
231 | struct DownloadRequest *dr, | 218 | struct DownloadRequest *dr, |
232 | const char * block, | 219 | const char *block, size_t len, int do_store) |
233 | size_t len, | ||
234 | int do_store) | ||
235 | { | 220 | { |
236 | struct ProcessResultClosure prc; | 221 | struct ProcessResultClosure prc; |
237 | char enc[len]; | 222 | char enc[len]; |
238 | struct GNUNET_CRYPTO_AesSessionKey sk; | 223 | struct GNUNET_CRYPTO_AesSessionKey sk; |
239 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 224 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
240 | GNUNET_HashCode query; | 225 | GNUNET_HashCode query; |
241 | 226 | ||
242 | GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv); | 227 | GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv); |
243 | if (-1 == GNUNET_CRYPTO_aes_encrypt (block, len, | 228 | if (-1 == GNUNET_CRYPTO_aes_encrypt (block, len, &sk, &iv, enc)) |
244 | &sk, | 229 | { |
245 | &iv, | 230 | GNUNET_break (0); |
246 | enc)) | 231 | return GNUNET_SYSERR; |
247 | { | 232 | } |
248 | GNUNET_break (0); | ||
249 | return GNUNET_SYSERR; | ||
250 | } | ||
251 | GNUNET_CRYPTO_hash (enc, len, &query); | 233 | GNUNET_CRYPTO_hash (enc, len, &query); |
252 | if (0 != memcmp (&query, | 234 | if (0 != memcmp (&query, &chk->query, sizeof (GNUNET_HashCode))) |
253 | &chk->query, | 235 | { |
254 | sizeof (GNUNET_HashCode))) | 236 | GNUNET_break_op (0); |
255 | { | 237 | return GNUNET_SYSERR; |
256 | GNUNET_break_op (0); | 238 | } |
257 | return GNUNET_SYSERR; | ||
258 | } | ||
259 | #if DEBUG_DOWNLOAD | 239 | #if DEBUG_DOWNLOAD |
260 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 240 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
261 | "Matching block for `%s' at offset %llu already present, no need for download!\n", | 241 | "Matching block for `%s' at offset %llu already present, no need for download!\n", |
262 | dc->filename, | 242 | dc->filename, (unsigned long long) dr->offset); |
263 | (unsigned long long) dr->offset); | ||
264 | #endif | 243 | #endif |
265 | /* already got it! */ | 244 | /* already got it! */ |
266 | prc.dc = dc; | 245 | prc.dc = dc; |
267 | prc.data = enc; | 246 | prc.data = enc; |
268 | prc.size = len; | 247 | prc.size = len; |
269 | prc.type = (0 == dr->depth) | 248 | prc.type = (0 == dr->depth) |
270 | ? GNUNET_BLOCK_TYPE_FS_DBLOCK | 249 | ? GNUNET_BLOCK_TYPE_FS_DBLOCK : GNUNET_BLOCK_TYPE_FS_IBLOCK; |
271 | : GNUNET_BLOCK_TYPE_FS_IBLOCK; | ||
272 | prc.query = chk->query; | 250 | prc.query = chk->query; |
273 | prc.do_store = do_store; | 251 | prc.do_store = do_store; |
274 | process_result_with_request (&prc, | 252 | process_result_with_request (&prc, &chk->key, dr); |
275 | &chk->key, | ||
276 | dr); | ||
277 | return GNUNET_OK; | 253 | return GNUNET_OK; |
278 | } | 254 | } |
279 | 255 | ||
@@ -285,8 +261,7 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, | |||
285 | * | 261 | * |
286 | * @param dc download context that is having trouble | 262 | * @param dc download context that is having trouble |
287 | */ | 263 | */ |
288 | static void | 264 | static void try_reconnect (struct GNUNET_FS_DownloadContext *dc); |
289 | try_reconnect (struct GNUNET_FS_DownloadContext *dc); | ||
290 | 265 | ||
291 | 266 | ||
292 | /** | 267 | /** |
@@ -300,13 +275,12 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc); | |||
300 | * @param length number of bytes in data | 275 | * @param length number of bytes in data |
301 | * @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) |
302 | */ | 277 | */ |
303 | static void | 278 | static void |
304 | trigger_recursive_download (void *cls, | 279 | trigger_recursive_download (void *cls, |
305 | const char *filename, | 280 | const char *filename, |
306 | const struct GNUNET_FS_Uri *uri, | 281 | const struct GNUNET_FS_Uri *uri, |
307 | const struct GNUNET_CONTAINER_MetaData *meta, | 282 | const struct GNUNET_CONTAINER_MetaData *meta, |
308 | size_t length, | 283 | size_t length, const void *data); |
309 | const void *data); | ||
310 | 284 | ||
311 | 285 | ||
312 | /** | 286 | /** |
@@ -323,55 +297,51 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc) | |||
323 | void *data; | 297 | void *data; |
324 | struct GNUNET_DISK_FileHandle *h; | 298 | struct GNUNET_DISK_FileHandle *h; |
325 | struct GNUNET_DISK_MapHandle *m; | 299 | struct GNUNET_DISK_MapHandle *m; |
326 | 300 | ||
327 | size64 = GNUNET_FS_uri_chk_get_file_size (dc->uri); | 301 | size64 = GNUNET_FS_uri_chk_get_file_size (dc->uri); |
328 | size = (size_t) size64; | 302 | size = (size_t) size64; |
329 | if (size64 != (uint64_t) size) | 303 | if (size64 != (uint64_t) size) |
330 | { | 304 | { |
331 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 305 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
332 | _("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); | 306 | _ |
333 | return; | 307 | ("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n")); |
334 | } | 308 | return; |
309 | } | ||
335 | if (dc->filename != NULL) | 310 | if (dc->filename != NULL) |
336 | { | 311 | { |
337 | h = GNUNET_DISK_file_open (dc->filename, | 312 | h = GNUNET_DISK_file_open (dc->filename, |
338 | GNUNET_DISK_OPEN_READ, | 313 | GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); |
339 | GNUNET_DISK_PERM_NONE); | 314 | } |
340 | } | ||
341 | else | 315 | else |
342 | { | 316 | { |
343 | GNUNET_assert (dc->temp_filename != NULL); | 317 | GNUNET_assert (dc->temp_filename != NULL); |
344 | h = GNUNET_DISK_file_open (dc->temp_filename, | 318 | h = GNUNET_DISK_file_open (dc->temp_filename, |
345 | GNUNET_DISK_OPEN_READ, | 319 | GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); |
346 | GNUNET_DISK_PERM_NONE); | 320 | } |
347 | } | ||
348 | if (h == NULL) | 321 | if (h == NULL) |
349 | return; /* oops */ | 322 | return; /* oops */ |
350 | data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size); | 323 | data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size); |
351 | if (data == NULL) | 324 | if (data == NULL) |
352 | { | 325 | { |
353 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 326 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
354 | _("Directory too large for system address space\n")); | 327 | _("Directory too large for system address space\n")); |
355 | } | 328 | } |
356 | else | 329 | else |
357 | { | 330 | { |
358 | GNUNET_FS_directory_list_contents (size, | 331 | GNUNET_FS_directory_list_contents (size, |
359 | data, | 332 | data, |
360 | 0, | 333 | 0, &trigger_recursive_download, dc); |
361 | &trigger_recursive_download, | 334 | GNUNET_DISK_file_unmap (m); |
362 | dc); | 335 | } |
363 | GNUNET_DISK_file_unmap (m); | ||
364 | } | ||
365 | GNUNET_DISK_file_close (h); | 336 | GNUNET_DISK_file_close (h); |
366 | if (dc->filename == NULL) | 337 | if (dc->filename == NULL) |
367 | { | 338 | { |
368 | if (0 != UNLINK (dc->temp_filename)) | 339 | if (0 != UNLINK (dc->temp_filename)) |
369 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | 340 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
370 | "unlink", | 341 | "unlink", dc->temp_filename); |
371 | dc->temp_filename); | 342 | GNUNET_free (dc->temp_filename); |
372 | GNUNET_free (dc->temp_filename); | 343 | dc->temp_filename = NULL; |
373 | dc->temp_filename = NULL; | 344 | } |
374 | } | ||
375 | } | 345 | } |
376 | 346 | ||
377 | 347 | ||
@@ -392,28 +362,25 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) | |||
392 | struct GNUNET_FS_DownloadContext *pos; | 362 | struct GNUNET_FS_DownloadContext *pos; |
393 | 363 | ||
394 | /* first, check if we need to download children */ | 364 | /* first, check if we need to download children */ |
395 | if ( (dc->child_head == NULL) && | 365 | if ((dc->child_head == NULL) && (is_recursive_download (dc))) |
396 | (is_recursive_download (dc)) ) | 366 | full_recursive_download (dc); |
397 | full_recursive_download (dc); | ||
398 | /* then, check if children are done already */ | 367 | /* then, check if children are done already */ |
399 | pos = dc->child_head; | 368 | pos = dc->child_head; |
400 | while (pos != NULL) | 369 | while (pos != NULL) |
401 | { | 370 | { |
402 | if ( (pos->emsg == NULL) && | 371 | if ((pos->emsg == NULL) && (pos->completed < pos->length)) |
403 | (pos->completed < pos->length) ) | 372 | return; /* not done yet */ |
404 | return; /* not done yet */ | 373 | if ((pos->child_head != NULL) && (pos->has_finished != GNUNET_YES)) |
405 | if ( (pos->child_head != NULL) && | 374 | return; /* not transitively done yet */ |
406 | (pos->has_finished != GNUNET_YES) ) | 375 | pos = pos->next; |
407 | return; /* not transitively done yet */ | 376 | } |
408 | pos = pos->next; | ||
409 | } | ||
410 | /* All of our children are done, so mark this download done */ | 377 | /* All of our children are done, so mark this download done */ |
411 | dc->has_finished = GNUNET_YES; | 378 | dc->has_finished = GNUNET_YES; |
412 | if (dc->job_queue != NULL) | 379 | if (dc->job_queue != NULL) |
413 | { | 380 | { |
414 | GNUNET_FS_dequeue_ (dc->job_queue); | 381 | GNUNET_FS_dequeue_ (dc->job_queue); |
415 | dc->job_queue = NULL; | 382 | dc->job_queue = NULL; |
416 | } | 383 | } |
417 | GNUNET_FS_download_sync_ (dc); | 384 | GNUNET_FS_download_sync_ (dc); |
418 | 385 | ||
419 | /* signal completion */ | 386 | /* signal completion */ |
@@ -422,7 +389,7 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) | |||
422 | 389 | ||
423 | /* let parent know */ | 390 | /* let parent know */ |
424 | if (dc->parent != NULL) | 391 | if (dc->parent != NULL) |
425 | check_completed (dc->parent); | 392 | check_completed (dc->parent); |
426 | } | 393 | } |
427 | 394 | ||
428 | 395 | ||
@@ -435,12 +402,10 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) | |||
435 | * @param dr download request to match against | 402 | * @param dr download request to match against |
436 | * @param data plaintext data, starting from the beginning of the file | 403 | * @param data plaintext data, starting from the beginning of the file |
437 | * @param data_len number of bytes in data | 404 | * @param data_len number of bytes in data |
438 | */ | 405 | */ |
439 | static void | 406 | static void |
440 | try_match_block (struct GNUNET_FS_DownloadContext *dc, | 407 | try_match_block (struct GNUNET_FS_DownloadContext *dc, |
441 | struct DownloadRequest *dr, | 408 | struct DownloadRequest *dr, const char *data, size_t data_len) |
442 | const char *data, | ||
443 | size_t data_len) | ||
444 | { | 409 | { |
445 | struct GNUNET_FS_ProgressInfo pi; | 410 | struct GNUNET_FS_ProgressInfo pi; |
446 | unsigned int i; | 411 | unsigned int i; |
@@ -456,134 +421,112 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
456 | const char *fn; | 421 | const char *fn; |
457 | const char *odata; | 422 | const char *odata; |
458 | size_t odata_len; | 423 | size_t odata_len; |
459 | 424 | ||
460 | odata = data; | 425 | odata = data; |
461 | odata_len = data_len; | 426 | odata_len = data_len; |
462 | if (BRS_DOWNLOAD_UP == dr->state) | 427 | if (BRS_DOWNLOAD_UP == dr->state) |
463 | return; | 428 | return; |
464 | if (dr->depth > 0) | 429 | if (dr->depth > 0) |
430 | { | ||
431 | complete = GNUNET_YES; | ||
432 | for (i = 0; i < dr->num_children; i++) | ||
465 | { | 433 | { |
466 | complete = GNUNET_YES; | 434 | drc = dr->children[i]; |
467 | for (i=0;i<dr->num_children;i++) | 435 | try_match_block (dc, drc, data, data_len); |
468 | { | 436 | if (drc->state != BRS_RECONSTRUCT_META_UP) |
469 | drc = dr->children[i]; | 437 | complete = GNUNET_NO; |
470 | try_match_block (dc, | 438 | else |
471 | drc, | 439 | chks[i] = drc->chk; |
472 | data, data_len); | ||
473 | if (drc->state != BRS_RECONSTRUCT_META_UP) | ||
474 | complete = GNUNET_NO; | ||
475 | else | ||
476 | chks[i] = drc->chk; | ||
477 | } | ||
478 | if (GNUNET_YES != complete) | ||
479 | return; | ||
480 | data = (const char*) chks; | ||
481 | dlen = dr->num_children * sizeof (struct ContentHashKey); | ||
482 | } | 440 | } |
441 | if (GNUNET_YES != complete) | ||
442 | return; | ||
443 | data = (const char *) chks; | ||
444 | dlen = dr->num_children * sizeof (struct ContentHashKey); | ||
445 | } | ||
483 | else | 446 | else |
484 | { | 447 | { |
485 | if (dr->offset > data_len) | 448 | if (dr->offset > data_len) |
486 | return; /* oops */ | 449 | return; /* oops */ |
487 | dlen = GNUNET_MIN (data_len - dr->offset, | 450 | dlen = GNUNET_MIN (data_len - dr->offset, DBLOCK_SIZE); |
488 | DBLOCK_SIZE); | 451 | } |
489 | } | 452 | GNUNET_CRYPTO_hash (&data[dr->offset], dlen, &in_chk.key); |
490 | GNUNET_CRYPTO_hash (&data[dr->offset], | ||
491 | dlen, | ||
492 | &in_chk.key); | ||
493 | GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv); | 453 | GNUNET_CRYPTO_hash_to_aes_key (&in_chk.key, &sk, &iv); |
494 | if (-1 == GNUNET_CRYPTO_aes_encrypt (&data[dr->offset], dlen, | 454 | if (-1 == GNUNET_CRYPTO_aes_encrypt (&data[dr->offset], dlen, &sk, &iv, enc)) |
495 | &sk, | 455 | { |
496 | &iv, | 456 | GNUNET_break (0); |
497 | enc)) | 457 | return; |
498 | { | 458 | } |
499 | GNUNET_break (0); | ||
500 | return; | ||
501 | } | ||
502 | GNUNET_CRYPTO_hash (enc, dlen, &in_chk.query); | 459 | GNUNET_CRYPTO_hash (enc, dlen, &in_chk.query); |
503 | switch (dr->state) | 460 | switch (dr->state) |
504 | { | 461 | { |
505 | case BRS_INIT: | 462 | case BRS_INIT: |
506 | dr->chk = in_chk; | 463 | dr->chk = in_chk; |
507 | dr->state = BRS_RECONSTRUCT_META_UP; | 464 | dr->state = BRS_RECONSTRUCT_META_UP; |
465 | break; | ||
466 | case BRS_CHK_SET: | ||
467 | if (0 != memcmp (&in_chk, &dr->chk, sizeof (struct ContentHashKey))) | ||
468 | { | ||
469 | /* other peer provided bogus meta data */ | ||
470 | GNUNET_break_op (0); | ||
508 | break; | 471 | break; |
509 | case BRS_CHK_SET: | 472 | } |
510 | if (0 != memcmp (&in_chk, | 473 | /* write block to disk */ |
511 | &dr->chk, | 474 | fn = dc->filename != NULL ? dc->filename : dc->temp_filename; |
512 | sizeof (struct ContentHashKey))) | 475 | fh = GNUNET_DISK_file_open (fn, |
513 | { | 476 | GNUNET_DISK_OPEN_READWRITE | |
514 | /* other peer provided bogus meta data */ | 477 | GNUNET_DISK_OPEN_CREATE | |
515 | GNUNET_break_op (0); | 478 | GNUNET_DISK_OPEN_TRUNCATE, |
516 | break; | 479 | GNUNET_DISK_PERM_USER_READ | |
517 | } | 480 | GNUNET_DISK_PERM_USER_WRITE | |
518 | /* write block to disk */ | 481 | GNUNET_DISK_PERM_GROUP_READ | |
519 | fn = dc->filename != NULL | 482 | GNUNET_DISK_PERM_OTHER_READ); |
520 | ? dc->filename | 483 | if (fh == NULL) |
521 | : dc->temp_filename; | 484 | { |
522 | fh = GNUNET_DISK_file_open (fn, | 485 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn); |
523 | GNUNET_DISK_OPEN_READWRITE | | 486 | GNUNET_asprintf (&dc->emsg, |
524 | GNUNET_DISK_OPEN_CREATE | | 487 | _("Failed to open file `%s' for writing"), fn); |
525 | GNUNET_DISK_OPEN_TRUNCATE, | ||
526 | GNUNET_DISK_PERM_USER_READ | | ||
527 | GNUNET_DISK_PERM_USER_WRITE | | ||
528 | GNUNET_DISK_PERM_GROUP_READ | | ||
529 | GNUNET_DISK_PERM_OTHER_READ); | ||
530 | if (fh == NULL) | ||
531 | { | ||
532 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
533 | "open", | ||
534 | fn); | ||
535 | GNUNET_asprintf (&dc->emsg, | ||
536 | _("Failed to open file `%s' for writing"), | ||
537 | fn); | ||
538 | GNUNET_DISK_file_close (fh); | ||
539 | dr->state = BRS_ERROR; | ||
540 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | ||
541 | pi.value.download.specifics.error.message = dc->emsg; | ||
542 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
543 | return; | ||
544 | } | ||
545 | if (data_len != | ||
546 | GNUNET_DISK_file_write (fh, | ||
547 | odata, | ||
548 | odata_len)) | ||
549 | { | ||
550 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
551 | "write", | ||
552 | fn); | ||
553 | GNUNET_asprintf (&dc->emsg, | ||
554 | _("Failed to open file `%s' for writing"), | ||
555 | fn); | ||
556 | GNUNET_DISK_file_close (fh); | ||
557 | dr->state = BRS_ERROR; | ||
558 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | ||
559 | pi.value.download.specifics.error.message = dc->emsg; | ||
560 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
561 | return; | ||
562 | } | ||
563 | GNUNET_DISK_file_close (fh); | 488 | GNUNET_DISK_file_close (fh); |
564 | /* signal success */ | 489 | dr->state = BRS_ERROR; |
565 | dr->state = BRS_DOWNLOAD_UP; | 490 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; |
566 | dc->completed = dc->length; | 491 | pi.value.download.specifics.error.message = dc->emsg; |
567 | GNUNET_FS_download_sync_ (dc); | ||
568 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; | ||
569 | pi.value.download.specifics.progress.data = data; | ||
570 | pi.value.download.specifics.progress.offset = 0; | ||
571 | pi.value.download.specifics.progress.data_len = dlen; | ||
572 | pi.value.download.specifics.progress.depth = 0; | ||
573 | GNUNET_FS_download_make_status_ (&pi, dc); | 492 | GNUNET_FS_download_make_status_ (&pi, dc); |
574 | if ( (NULL != dc->filename) && | 493 | return; |
575 | (0 != truncate (dc->filename, | 494 | } |
576 | GNUNET_ntohll (dc->uri->data.chk.file_length))) ) | 495 | if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len)) |
577 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | 496 | { |
578 | "truncate", | 497 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); |
579 | dc->filename); | 498 | GNUNET_asprintf (&dc->emsg, |
580 | check_completed (dc); | 499 | _("Failed to open file `%s' for writing"), fn); |
581 | break; | 500 | GNUNET_DISK_file_close (fh); |
582 | default: | 501 | dr->state = BRS_ERROR; |
583 | /* how did we get here? */ | 502 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; |
584 | GNUNET_break (0); | 503 | pi.value.download.specifics.error.message = dc->emsg; |
585 | break; | 504 | GNUNET_FS_download_make_status_ (&pi, dc); |
505 | return; | ||
586 | } | 506 | } |
507 | GNUNET_DISK_file_close (fh); | ||
508 | /* signal success */ | ||
509 | dr->state = BRS_DOWNLOAD_UP; | ||
510 | dc->completed = dc->length; | ||
511 | GNUNET_FS_download_sync_ (dc); | ||
512 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; | ||
513 | pi.value.download.specifics.progress.data = data; | ||
514 | pi.value.download.specifics.progress.offset = 0; | ||
515 | pi.value.download.specifics.progress.data_len = dlen; | ||
516 | pi.value.download.specifics.progress.depth = 0; | ||
517 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
518 | if ((NULL != dc->filename) && | ||
519 | (0 != truncate (dc->filename, | ||
520 | GNUNET_ntohll (dc->uri->data.chk.file_length)))) | ||
521 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
522 | "truncate", dc->filename); | ||
523 | check_completed (dc); | ||
524 | break; | ||
525 | default: | ||
526 | /* how did we get here? */ | ||
527 | GNUNET_break (0); | ||
528 | break; | ||
529 | } | ||
587 | } | 530 | } |
588 | 531 | ||
589 | 532 | ||
@@ -604,34 +547,28 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, | |||
604 | * @param data actual meta-data found | 547 | * @param data actual meta-data found |
605 | * @param data_len number of bytes in data | 548 | * @param data_len number of bytes in data |
606 | * @return 0 to continue extracting, 1 to abort | 549 | * @return 0 to continue extracting, 1 to abort |
607 | */ | 550 | */ |
608 | static int | 551 | static int |
609 | match_full_data (void *cls, | 552 | match_full_data (void *cls, |
610 | const char *plugin_name, | 553 | const char *plugin_name, |
611 | enum EXTRACTOR_MetaType type, | 554 | enum EXTRACTOR_MetaType type, |
612 | enum EXTRACTOR_MetaFormat format, | 555 | enum EXTRACTOR_MetaFormat format, |
613 | const char *data_mime_type, | 556 | const char *data_mime_type, const char *data, size_t data_len) |
614 | const char *data, | ||
615 | size_t data_len) | ||
616 | { | 557 | { |
617 | struct GNUNET_FS_DownloadContext *dc = cls; | 558 | struct GNUNET_FS_DownloadContext *dc = cls; |
618 | 559 | ||
619 | if (type != EXTRACTOR_METATYPE_GNUNET_FULL_DATA) | 560 | if (type != EXTRACTOR_METATYPE_GNUNET_FULL_DATA) |
620 | return 0; | 561 | return 0; |
621 | #if DEBUG_DOWNLOAD | 562 | #if DEBUG_DOWNLOAD |
622 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
623 | "Found %u bytes of FD!\n", | 564 | "Found %u bytes of FD!\n", (unsigned int) data_len); |
624 | (unsigned int) data_len); | ||
625 | #endif | 565 | #endif |
626 | if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len) | 566 | if (GNUNET_FS_uri_chk_get_file_size (dc->uri) != data_len) |
627 | { | 567 | { |
628 | GNUNET_break_op (0); | 568 | GNUNET_break_op (0); |
629 | return 1; /* bogus meta data */ | 569 | return 1; /* bogus meta data */ |
630 | } | 570 | } |
631 | try_match_block (dc, | 571 | try_match_block (dc, dc->top_request, data, data_len); |
632 | dc->top_request, | ||
633 | data, | ||
634 | data_len); | ||
635 | return 1; | 572 | return 1; |
636 | } | 573 | } |
637 | 574 | ||
@@ -648,15 +585,15 @@ propagate_up (struct DownloadRequest *dr) | |||
648 | unsigned int i; | 585 | unsigned int i; |
649 | 586 | ||
650 | do | 587 | do |
651 | { | 588 | { |
652 | dr->state = BRS_DOWNLOAD_UP; | 589 | dr->state = BRS_DOWNLOAD_UP; |
653 | dr = dr->parent; | 590 | dr = dr->parent; |
654 | if (dr == NULL) | 591 | if (dr == NULL) |
655 | break; | 592 | break; |
656 | for (i=0;i<dr->num_children;i++) | 593 | for (i = 0; i < dr->num_children; i++) |
657 | if (dr->children[i]->state != BRS_DOWNLOAD_UP) | 594 | if (dr->children[i]->state != BRS_DOWNLOAD_UP) |
658 | break; | 595 | break; |
659 | } | 596 | } |
660 | while (i == dr->num_children); | 597 | while (i == dr->num_children); |
661 | } | 598 | } |
662 | 599 | ||
@@ -673,7 +610,7 @@ propagate_up (struct DownloadRequest *dr) | |||
673 | */ | 610 | */ |
674 | static void | 611 | static void |
675 | try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, | 612 | try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, |
676 | struct DownloadRequest *dr) | 613 | struct DownloadRequest *dr) |
677 | { | 614 | { |
678 | uint64_t off; | 615 | uint64_t off; |
679 | char block[DBLOCK_SIZE]; | 616 | char block[DBLOCK_SIZE]; |
@@ -686,87 +623,66 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, | |||
686 | uint64_t child_block_size; | 623 | uint64_t child_block_size; |
687 | const struct ContentHashKey *chks; | 624 | const struct ContentHashKey *chks; |
688 | int up_done; | 625 | int up_done; |
689 | 626 | ||
690 | GNUNET_assert (dc->rfh != NULL); | 627 | GNUNET_assert (dc->rfh != NULL); |
691 | GNUNET_assert (dr->state == BRS_CHK_SET); | 628 | GNUNET_assert (dr->state == BRS_CHK_SET); |
692 | total = GNUNET_FS_uri_chk_get_file_size (dc->uri); | 629 | total = GNUNET_FS_uri_chk_get_file_size (dc->uri); |
693 | GNUNET_assert (dr->depth < dc->treedepth); | 630 | GNUNET_assert (dr->depth < dc->treedepth); |
694 | len = GNUNET_FS_tree_calculate_block_size (total, | 631 | len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth); |
695 | dr->offset, | ||
696 | dr->depth); | ||
697 | GNUNET_assert (len <= DBLOCK_SIZE); | 632 | GNUNET_assert (len <= DBLOCK_SIZE); |
698 | off = compute_disk_offset (total, | 633 | off = compute_disk_offset (total, dr->offset, dr->depth); |
699 | dr->offset, | 634 | if (dc->old_file_size < off + len) |
700 | dr->depth); | 635 | return; /* failure */ |
701 | if (dc->old_file_size < off + len) | 636 | if (off != GNUNET_DISK_file_seek (dc->rfh, off, GNUNET_DISK_SEEK_SET)) |
702 | return; /* failure */ | 637 | { |
703 | if (off != | 638 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "seek", dc->filename); |
704 | GNUNET_DISK_file_seek (dc->rfh, | 639 | return; /* failure */ |
705 | off, | 640 | } |
706 | GNUNET_DISK_SEEK_SET) ) | 641 | if (len != GNUNET_DISK_file_read (dc->rfh, block, len)) |
707 | { | 642 | { |
708 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | 643 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "read", dc->filename); |
709 | "seek", | 644 | return; /* failure */ |
710 | dc->filename); | 645 | } |
711 | return; /* failure */ | ||
712 | } | ||
713 | if (len != | ||
714 | GNUNET_DISK_file_read (dc->rfh, | ||
715 | block, | ||
716 | len)) | ||
717 | { | ||
718 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
719 | "read", | ||
720 | dc->filename); | ||
721 | return; /* failure */ | ||
722 | } | ||
723 | GNUNET_CRYPTO_hash (block, len, &key); | 646 | GNUNET_CRYPTO_hash (block, len, &key); |
724 | if (0 != memcmp (&key, | 647 | if (0 != memcmp (&key, &dr->chk.key, sizeof (GNUNET_HashCode))) |
725 | &dr->chk.key, | 648 | return; /* mismatch */ |
726 | sizeof (GNUNET_HashCode))) | ||
727 | return; /* mismatch */ | ||
728 | if (GNUNET_OK != | 649 | if (GNUNET_OK != |
729 | encrypt_existing_match (dc, | 650 | encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO)) |
730 | &dr->chk, | 651 | { |
731 | dr, | 652 | /* hash matches but encrypted block does not, really bad */ |
732 | block, | 653 | dr->state = BRS_ERROR; |
733 | len, | 654 | /* propagate up */ |
734 | GNUNET_NO)) | 655 | while (dr->parent != NULL) |
735 | { | 656 | { |
736 | /* hash matches but encrypted block does not, really bad */ | 657 | dr = dr->parent; |
737 | dr->state = BRS_ERROR; | 658 | dr->state = BRS_ERROR; |
738 | /* propagate up */ | ||
739 | while (dr->parent != NULL) | ||
740 | { | ||
741 | dr = dr->parent; | ||
742 | dr->state = BRS_ERROR; | ||
743 | } | ||
744 | return; | ||
745 | } | 659 | } |
660 | return; | ||
661 | } | ||
746 | /* block matches */ | 662 | /* block matches */ |
747 | dr->state = BRS_DOWNLOAD_DOWN; | 663 | dr->state = BRS_DOWNLOAD_DOWN; |
748 | 664 | ||
749 | /* set CHKs for children */ | 665 | /* set CHKs for children */ |
750 | up_done = GNUNET_YES; | 666 | up_done = GNUNET_YES; |
751 | chks = (const struct ContentHashKey*) block; | 667 | chks = (const struct ContentHashKey *) block; |
752 | for (i=0;i<dr->num_children;i++) | 668 | for (i = 0; i < dr->num_children; i++) |
753 | { | 669 | { |
754 | drc = dr->children[i]; | 670 | drc = dr->children[i]; |
755 | GNUNET_assert (drc->offset >= dr->offset); | 671 | GNUNET_assert (drc->offset >= dr->offset); |
756 | child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth); | 672 | child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth); |
757 | GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size); | 673 | GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size); |
758 | chk_off = (drc->offset - dr->offset) / child_block_size; | 674 | chk_off = (drc->offset - dr->offset) / child_block_size; |
759 | if (drc->state == BRS_INIT) | 675 | if (drc->state == BRS_INIT) |
760 | { | 676 | { |
761 | drc->state = BRS_CHK_SET; | 677 | drc->state = BRS_CHK_SET; |
762 | drc->chk = chks[chk_off]; | 678 | drc->chk = chks[chk_off]; |
763 | try_top_down_reconstruction (dc, drc); | 679 | try_top_down_reconstruction (dc, drc); |
764 | } | 680 | } |
765 | if (drc->state != BRS_DOWNLOAD_UP) | 681 | if (drc->state != BRS_DOWNLOAD_UP) |
766 | up_done = GNUNET_NO; /* children not all done */ | 682 | up_done = GNUNET_NO; /* children not all done */ |
767 | } | 683 | } |
768 | if (up_done == GNUNET_YES) | 684 | if (up_done == GNUNET_YES) |
769 | propagate_up (dr); /* children all done (or no children...) */ | 685 | propagate_up (dr); /* children all done (or no children...) */ |
770 | } | 686 | } |
771 | 687 | ||
772 | 688 | ||
@@ -778,67 +694,63 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, | |||
778 | */ | 694 | */ |
779 | static void | 695 | static void |
780 | schedule_block_download (struct GNUNET_FS_DownloadContext *dc, | 696 | schedule_block_download (struct GNUNET_FS_DownloadContext *dc, |
781 | struct DownloadRequest *dr) | 697 | struct DownloadRequest *dr) |
782 | { | 698 | { |
783 | unsigned int i; | 699 | unsigned int i; |
784 | 700 | ||
785 | switch (dr->state) | 701 | switch (dr->state) |
786 | { | 702 | { |
787 | case BRS_INIT: | 703 | case BRS_INIT: |
788 | GNUNET_assert (0); | 704 | GNUNET_assert (0); |
789 | break; | 705 | break; |
790 | case BRS_RECONSTRUCT_DOWN: | 706 | case BRS_RECONSTRUCT_DOWN: |
791 | GNUNET_assert (0); | 707 | GNUNET_assert (0); |
792 | break; | 708 | break; |
793 | case BRS_RECONSTRUCT_META_UP: | 709 | case BRS_RECONSTRUCT_META_UP: |
794 | GNUNET_assert (0); | 710 | GNUNET_assert (0); |
795 | break; | 711 | break; |
796 | case BRS_RECONSTRUCT_UP: | 712 | case BRS_RECONSTRUCT_UP: |
797 | GNUNET_assert (0); | 713 | GNUNET_assert (0); |
798 | break; | 714 | break; |
799 | case BRS_CHK_SET: | 715 | case BRS_CHK_SET: |
800 | /* normal case, start download */ | 716 | /* normal case, start download */ |
801 | break; | 717 | break; |
802 | case BRS_DOWNLOAD_DOWN: | 718 | case BRS_DOWNLOAD_DOWN: |
803 | for (i=0;i<dr->num_children;i++) | 719 | for (i = 0; i < dr->num_children; i++) |
804 | schedule_block_download (dc, dr->children[i]); | 720 | schedule_block_download (dc, dr->children[i]); |
805 | return; | 721 | return; |
806 | case BRS_DOWNLOAD_UP: | 722 | case BRS_DOWNLOAD_UP: |
807 | /* We're done! */ | 723 | /* We're done! */ |
808 | return; | 724 | return; |
809 | case BRS_ERROR: | 725 | case BRS_ERROR: |
810 | GNUNET_break (0); | 726 | GNUNET_break (0); |
811 | return; | 727 | return; |
812 | } | 728 | } |
813 | #if DEBUG_DOWNLOAD | 729 | #if DEBUG_DOWNLOAD |
814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 730 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
815 | "Scheduling download at offset %llu and depth %u for `%s'\n", | 731 | "Scheduling download at offset %llu and depth %u for `%s'\n", |
816 | (unsigned long long) dr->offset, | 732 | (unsigned long long) dr->offset, |
817 | dr->depth, | 733 | dr->depth, GNUNET_h2s (&dr->chk.query)); |
818 | GNUNET_h2s (&dr->chk.query)); | ||
819 | #endif | 734 | #endif |
820 | if (GNUNET_NO != | 735 | if (GNUNET_NO != |
821 | GNUNET_CONTAINER_multihashmap_contains_value (dc->active, | 736 | GNUNET_CONTAINER_multihashmap_contains_value (dc->active, |
822 | &dr->chk.query, | 737 | &dr->chk.query, dr)) |
823 | dr)) | 738 | return; /* already active */ |
824 | return; /* already active */ | ||
825 | GNUNET_CONTAINER_multihashmap_put (dc->active, | 739 | GNUNET_CONTAINER_multihashmap_put (dc->active, |
826 | &dr->chk.query, | 740 | &dr->chk.query, |
827 | dr, | 741 | dr, |
828 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 742 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
829 | if (dc->client == NULL) | 743 | if (dc->client == NULL) |
830 | return; /* download not active */ | 744 | return; /* download not active */ |
831 | GNUNET_CONTAINER_DLL_insert (dc->pending_head, | 745 | GNUNET_CONTAINER_DLL_insert (dc->pending_head, dc->pending_tail, dr); |
832 | dc->pending_tail, | ||
833 | dr); | ||
834 | dr->is_pending = GNUNET_YES; | 746 | dr->is_pending = GNUNET_YES; |
835 | if (NULL == dc->th) | 747 | if (NULL == dc->th) |
836 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | 748 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, |
837 | sizeof (struct SearchMessage), | 749 | sizeof (struct SearchMessage), |
838 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 750 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
839 | GNUNET_NO, | 751 | GNUNET_NO, |
840 | &transmit_download_request, | 752 | &transmit_download_request, |
841 | dc); | 753 | dc); |
842 | } | 754 | } |
843 | 755 | ||
844 | 756 | ||
@@ -855,15 +767,14 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc, | |||
855 | * @param length number of bytes in data | 767 | * @param length number of bytes in data |
856 | * @param data contents of the file (or NULL if they were not inlined) | 768 | * @param data contents of the file (or NULL if they were not inlined) |
857 | */ | 769 | */ |
858 | static void | 770 | static void |
859 | trigger_recursive_download (void *cls, | 771 | trigger_recursive_download (void *cls, |
860 | const char *filename, | 772 | const char *filename, |
861 | const struct GNUNET_FS_Uri *uri, | 773 | const struct GNUNET_FS_Uri *uri, |
862 | const struct GNUNET_CONTAINER_MetaData *meta, | 774 | const struct GNUNET_CONTAINER_MetaData *meta, |
863 | size_t length, | 775 | size_t length, const void *data) |
864 | const void *data) | ||
865 | { | 776 | { |
866 | struct GNUNET_FS_DownloadContext *dc = cls; | 777 | struct GNUNET_FS_DownloadContext *dc = cls; |
867 | struct GNUNET_FS_DownloadContext *cpos; | 778 | struct GNUNET_FS_DownloadContext *cpos; |
868 | char *temp_name; | 779 | char *temp_name; |
869 | char *fn; | 780 | char *fn; |
@@ -875,129 +786,116 @@ trigger_recursive_download (void *cls, | |||
875 | char *sfn; | 786 | char *sfn; |
876 | 787 | ||
877 | if (NULL == uri) | 788 | if (NULL == uri) |
878 | return; /* entry for the directory itself */ | 789 | return; /* entry for the directory itself */ |
879 | cpos = dc->child_head; | 790 | cpos = dc->child_head; |
880 | while (cpos != NULL) | 791 | while (cpos != NULL) |
881 | { | 792 | { |
882 | if ( (GNUNET_FS_uri_test_equal (uri, | 793 | if ((GNUNET_FS_uri_test_equal (uri, |
883 | cpos->uri)) || | 794 | cpos->uri)) || |
884 | ( (filename != NULL) && | 795 | ((filename != NULL) && (0 == strcmp (cpos->filename, filename)))) |
885 | (0 == strcmp (cpos->filename, | 796 | break; |
886 | filename)) ) ) | 797 | cpos = cpos->next; |
887 | break; | 798 | } |
888 | cpos = cpos->next; | ||
889 | } | ||
890 | if (cpos != NULL) | 799 | if (cpos != NULL) |
891 | return; /* already exists */ | 800 | return; /* already exists */ |
892 | fn = NULL; | 801 | fn = NULL; |
893 | if (NULL == filename) | 802 | if (NULL == filename) |
894 | { | 803 | { |
895 | fn = GNUNET_FS_meta_data_suggest_filename (meta); | 804 | fn = GNUNET_FS_meta_data_suggest_filename (meta); |
896 | if (fn == NULL) | 805 | if (fn == NULL) |
897 | { | 806 | { |
898 | us = GNUNET_FS_uri_to_string (uri); | 807 | us = GNUNET_FS_uri_to_string (uri); |
899 | fn = GNUNET_strdup (&us [strlen (GNUNET_FS_URI_CHK_PREFIX)]); | 808 | fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]); |
900 | GNUNET_free (us); | 809 | GNUNET_free (us); |
901 | } | 810 | } |
902 | else if (fn[0] == '.') | 811 | else if (fn[0] == '.') |
903 | { | 812 | { |
904 | ext = fn; | 813 | ext = fn; |
905 | us = GNUNET_FS_uri_to_string (uri); | 814 | us = GNUNET_FS_uri_to_string (uri); |
906 | GNUNET_asprintf (&fn, | 815 | GNUNET_asprintf (&fn, |
907 | "%s%s", | 816 | "%s%s", &us[strlen (GNUNET_FS_URI_CHK_PREFIX)], ext); |
908 | &us[strlen (GNUNET_FS_URI_CHK_PREFIX)], ext); | 817 | GNUNET_free (ext); |
909 | GNUNET_free (ext); | 818 | GNUNET_free (us); |
910 | GNUNET_free (us); | 819 | } |
911 | } | 820 | /* change '\' to '/' (this should have happened |
912 | /* change '\' to '/' (this should have happened | 821 | * during insertion, but malicious peers may |
913 | during insertion, but malicious peers may | 822 | * not have done this) */ |
914 | not have done this) */ | 823 | while (NULL != (pos = strstr (fn, "\\"))) |
915 | while (NULL != (pos = strstr (fn, "\\"))) | 824 | *pos = '/'; |
916 | *pos = '/'; | 825 | /* remove '../' everywhere (again, well-behaved |
917 | /* remove '../' everywhere (again, well-behaved | 826 | * peers don't do this, but don't trust that |
918 | peers don't do this, but don't trust that | 827 | * we did not get something nasty) */ |
919 | we did not get something nasty) */ | 828 | while (NULL != (pos = strstr (fn, "../"))) |
920 | while (NULL != (pos = strstr (fn, "../"))) | 829 | { |
921 | { | 830 | pos[0] = '_'; |
922 | pos[0] = '_'; | 831 | pos[1] = '_'; |
923 | pos[1] = '_'; | 832 | pos[2] = '_'; |
924 | pos[2] = '_'; | 833 | } |
925 | } | 834 | filename = fn; |
926 | filename = fn; | 835 | } |
927 | } | ||
928 | if (dc->filename == NULL) | 836 | if (dc->filename == NULL) |
929 | { | 837 | { |
930 | full_name = NULL; | 838 | full_name = NULL; |
931 | } | 839 | } |
932 | else | 840 | else |
933 | { | 841 | { |
934 | dn = GNUNET_strdup (dc->filename); | 842 | dn = GNUNET_strdup (dc->filename); |
935 | GNUNET_break ( (strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && | 843 | GNUNET_break ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && |
936 | (NULL != | 844 | (NULL != |
937 | strstr (dn + strlen(dn) - strlen(GNUNET_FS_DIRECTORY_EXT), | 845 | strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT), |
938 | GNUNET_FS_DIRECTORY_EXT)) ); | 846 | GNUNET_FS_DIRECTORY_EXT))); |
939 | sfn = GNUNET_strdup (filename); | 847 | sfn = GNUNET_strdup (filename); |
940 | while ( (strlen (sfn) > 0) && | 848 | while ((strlen (sfn) > 0) && (filename[strlen (sfn) - 1] == '/')) |
941 | (filename[strlen(sfn)-1] == '/') ) | 849 | sfn[strlen (sfn) - 1] = '\0'; |
942 | sfn[strlen(sfn)-1] = '\0'; | 850 | if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && |
943 | if ( (strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) && | 851 | (NULL != |
944 | (NULL != | 852 | strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT), |
945 | strstr (dn + strlen(dn) - strlen(GNUNET_FS_DIRECTORY_EXT), | 853 | GNUNET_FS_DIRECTORY_EXT))) |
946 | GNUNET_FS_DIRECTORY_EXT)) ) | 854 | dn[strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0'; |
947 | dn[strlen(dn) - strlen (GNUNET_FS_DIRECTORY_EXT)] = '\0'; | 855 | if ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) && |
948 | if ( (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) && | 856 | ((strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) || |
949 | ( (strlen (filename) < strlen (GNUNET_FS_DIRECTORY_EXT)) || | 857 | (NULL == |
950 | (NULL == | 858 | strstr (filename + strlen (filename) - |
951 | strstr (filename + strlen(filename) - strlen(GNUNET_FS_DIRECTORY_EXT), | 859 | strlen (GNUNET_FS_DIRECTORY_EXT), GNUNET_FS_DIRECTORY_EXT)))) |
952 | GNUNET_FS_DIRECTORY_EXT)) ) ) | 860 | { |
953 | { | 861 | GNUNET_asprintf (&full_name, |
954 | GNUNET_asprintf (&full_name, | 862 | "%s%s%s%s", |
955 | "%s%s%s%s", | 863 | dn, DIR_SEPARATOR_STR, sfn, GNUNET_FS_DIRECTORY_EXT); |
956 | dn, | 864 | } |
957 | DIR_SEPARATOR_STR, | 865 | else |
958 | sfn, | 866 | { |
959 | GNUNET_FS_DIRECTORY_EXT); | 867 | GNUNET_asprintf (&full_name, "%s%s%s", dn, DIR_SEPARATOR_STR, sfn); |
960 | } | 868 | } |
961 | else | 869 | GNUNET_free (sfn); |
962 | { | 870 | GNUNET_free (dn); |
963 | GNUNET_asprintf (&full_name, | 871 | } |
964 | "%s%s%s", | 872 | if ((full_name != NULL) && |
965 | dn, | 873 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file (full_name))) |
966 | DIR_SEPARATOR_STR, | 874 | { |
967 | sfn); | 875 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
968 | } | 876 | _ |
969 | GNUNET_free (sfn); | 877 | ("Failed to create directory for recursive download of `%s'\n"), |
970 | GNUNET_free (dn); | 878 | full_name); |
971 | } | 879 | GNUNET_free (full_name); |
972 | if ( (full_name != NULL) && | 880 | GNUNET_free_non_null (fn); |
973 | (GNUNET_OK != | 881 | return; |
974 | GNUNET_DISK_directory_create_for_file (full_name)) ) | 882 | } |
975 | { | ||
976 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
977 | _("Failed to create directory for recursive download of `%s'\n"), | ||
978 | full_name); | ||
979 | GNUNET_free (full_name); | ||
980 | GNUNET_free_non_null (fn); | ||
981 | return; | ||
982 | } | ||
983 | 883 | ||
984 | temp_name = NULL; | 884 | temp_name = NULL; |
985 | #if DEBUG_DOWNLOAD | 885 | #if DEBUG_DOWNLOAD |
986 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 886 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
987 | "Triggering recursive download of size %llu with %u bytes MD\n", | 887 | "Triggering recursive download of size %llu with %u bytes MD\n", |
988 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri), | 888 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (uri), |
989 | (unsigned int) GNUNET_CONTAINER_meta_data_get_serialized_size (meta)); | 889 | (unsigned int) |
890 | GNUNET_CONTAINER_meta_data_get_serialized_size (meta)); | ||
990 | #endif | 891 | #endif |
991 | GNUNET_FS_download_start (dc->h, | 892 | GNUNET_FS_download_start (dc->h, |
992 | uri, | 893 | uri, |
993 | meta, | 894 | meta, |
994 | full_name, temp_name, | 895 | full_name, temp_name, |
995 | 0, | 896 | 0, |
996 | GNUNET_FS_uri_chk_get_file_size (uri), | 897 | GNUNET_FS_uri_chk_get_file_size (uri), |
997 | dc->anonymity, | 898 | dc->anonymity, dc->options, NULL, dc); |
998 | dc->options, | ||
999 | NULL, | ||
1000 | dc); | ||
1001 | GNUNET_free_non_null (full_name); | 899 | GNUNET_free_non_null (full_name); |
1002 | GNUNET_free_non_null (temp_name); | 900 | GNUNET_free_non_null (temp_name); |
1003 | GNUNET_free_non_null (fn); | 901 | GNUNET_free_non_null (fn); |
@@ -1016,7 +914,7 @@ GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) | |||
1016 | 914 | ||
1017 | if (dr == NULL) | 915 | if (dr == NULL) |
1018 | return; | 916 | return; |
1019 | for (i=0;i<dr->num_children;i++) | 917 | for (i = 0; i < dr->num_children; i++) |
1020 | GNUNET_FS_free_download_request_ (dr->children[i]); | 918 | GNUNET_FS_free_download_request_ (dr->children[i]); |
1021 | GNUNET_free_non_null (dr->children); | 919 | GNUNET_free_non_null (dr->children); |
1022 | GNUNET_free (dr); | 920 | GNUNET_free (dr); |
@@ -1034,8 +932,7 @@ GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) | |||
1034 | */ | 932 | */ |
1035 | static int | 933 | static int |
1036 | process_result_with_request (void *cls, | 934 | process_result_with_request (void *cls, |
1037 | const GNUNET_HashCode *key, | 935 | const GNUNET_HashCode * key, void *value) |
1038 | void *value) | ||
1039 | { | 936 | { |
1040 | struct ProcessResultClosure *prc = cls; | 937 | struct ProcessResultClosure *prc = cls; |
1041 | struct DownloadRequest *dr = value; | 938 | struct DownloadRequest *dr = value; |
@@ -1054,152 +951,132 @@ process_result_with_request (void *cls, | |||
1054 | 951 | ||
1055 | #if DEBUG_DOWNLOAD | 952 | #if DEBUG_DOWNLOAD |
1056 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 953 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1057 | "Received block `%s' matching pending request at depth %u and offset %llu/%llu\n", | 954 | "Received block `%s' matching pending request at depth %u and offset %llu/%llu\n", |
1058 | GNUNET_h2s (key), | 955 | GNUNET_h2s (key), |
1059 | dr->depth, | 956 | dr->depth, |
1060 | (unsigned long long) dr->offset, | 957 | (unsigned long long) dr->offset, |
1061 | (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length)); | 958 | (unsigned long long) GNUNET_ntohll (dc->uri->data. |
1062 | 959 | chk.file_length)); | |
960 | |||
1063 | #endif | 961 | #endif |
1064 | bs = GNUNET_FS_tree_calculate_block_size (GNUNET_ntohll (dc->uri->data.chk.file_length), | 962 | bs = GNUNET_FS_tree_calculate_block_size (GNUNET_ntohll |
1065 | dr->offset, | 963 | (dc->uri->data.chk.file_length), |
1066 | dr->depth); | 964 | dr->offset, dr->depth); |
1067 | if (prc->size != bs) | 965 | if (prc->size != bs) |
966 | { | ||
967 | GNUNET_asprintf (&dc->emsg, | ||
968 | _ | ||
969 | ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)\n"), | ||
970 | bs, dr->depth, (unsigned long long) dr->offset, | ||
971 | (unsigned long long) GNUNET_ntohll (dc->uri->data. | ||
972 | chk.file_length), | ||
973 | prc->size); | ||
974 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s", dc->emsg); | ||
975 | while (dr->parent != NULL) | ||
1068 | { | 976 | { |
1069 | GNUNET_asprintf (&dc->emsg, | ||
1070 | _("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)\n"), | ||
1071 | bs, | ||
1072 | dr->depth, | ||
1073 | (unsigned long long) dr->offset, | ||
1074 | (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length), | ||
1075 | prc->size); | ||
1076 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1077 | "%s", | ||
1078 | dc->emsg); | ||
1079 | while (dr->parent != NULL) | ||
1080 | { | ||
1081 | dr->state = BRS_ERROR; | ||
1082 | dr = dr->parent; | ||
1083 | } | ||
1084 | dr->state = BRS_ERROR; | 977 | dr->state = BRS_ERROR; |
1085 | goto signal_error; | 978 | dr = dr->parent; |
1086 | } | 979 | } |
980 | dr->state = BRS_ERROR; | ||
981 | goto signal_error; | ||
982 | } | ||
1087 | 983 | ||
1088 | (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, | 984 | (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, &prc->query, dr); |
1089 | &prc->query, | ||
1090 | dr); | ||
1091 | if (GNUNET_YES == dr->is_pending) | 985 | if (GNUNET_YES == dr->is_pending) |
1092 | { | 986 | { |
1093 | GNUNET_CONTAINER_DLL_remove (dc->pending_head, | 987 | GNUNET_CONTAINER_DLL_remove (dc->pending_head, dc->pending_tail, dr); |
1094 | dc->pending_tail, | 988 | dr->is_pending = GNUNET_NO; |
1095 | dr); | 989 | } |
1096 | dr->is_pending = GNUNET_NO; | ||
1097 | } | ||
1098 | 990 | ||
1099 | 991 | ||
1100 | GNUNET_CRYPTO_hash_to_aes_key (&dr->chk.key, &skey, &iv); | 992 | GNUNET_CRYPTO_hash_to_aes_key (&dr->chk.key, &skey, &iv); |
1101 | if (-1 == GNUNET_CRYPTO_aes_decrypt (prc->data, | 993 | if (-1 == GNUNET_CRYPTO_aes_decrypt (prc->data, prc->size, &skey, &iv, pt)) |
1102 | prc->size, | 994 | { |
1103 | &skey, | 995 | GNUNET_break (0); |
1104 | &iv, | 996 | dc->emsg = GNUNET_strdup (_("internal error decrypting content")); |
1105 | pt)) | 997 | goto signal_error; |
1106 | { | 998 | } |
1107 | GNUNET_break (0); | ||
1108 | dc->emsg = GNUNET_strdup (_("internal error decrypting content")); | ||
1109 | goto signal_error; | ||
1110 | } | ||
1111 | off = compute_disk_offset (GNUNET_ntohll (dc->uri->data.chk.file_length), | 999 | off = compute_disk_offset (GNUNET_ntohll (dc->uri->data.chk.file_length), |
1112 | dr->offset, | 1000 | dr->offset, dr->depth); |
1113 | dr->depth); | ||
1114 | /* save to disk */ | 1001 | /* save to disk */ |
1115 | if ( ( GNUNET_YES == prc->do_store) && | 1002 | if ((GNUNET_YES == prc->do_store) && |
1116 | ( (dc->filename != NULL) || | 1003 | ((dc->filename != NULL) || |
1117 | (is_recursive_download (dc)) ) && | 1004 | (is_recursive_download (dc))) && |
1118 | ( (dr->depth == dc->treedepth) || | 1005 | ((dr->depth == dc->treedepth) || |
1119 | (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES)) ) ) | 1006 | (0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES)))) |
1007 | { | ||
1008 | fh = GNUNET_DISK_file_open (dc->filename != NULL | ||
1009 | ? dc->filename | ||
1010 | : dc->temp_filename, | ||
1011 | GNUNET_DISK_OPEN_READWRITE | | ||
1012 | GNUNET_DISK_OPEN_CREATE, | ||
1013 | GNUNET_DISK_PERM_USER_READ | | ||
1014 | GNUNET_DISK_PERM_USER_WRITE | | ||
1015 | GNUNET_DISK_PERM_GROUP_READ | | ||
1016 | GNUNET_DISK_PERM_OTHER_READ); | ||
1017 | if (NULL == fh) | ||
1120 | { | 1018 | { |
1121 | fh = GNUNET_DISK_file_open (dc->filename != NULL | 1019 | GNUNET_asprintf (&dc->emsg, |
1122 | ? dc->filename | 1020 | _("Download failed: could not open file `%s': %s\n"), |
1123 | : dc->temp_filename, | 1021 | dc->filename, STRERROR (errno)); |
1124 | GNUNET_DISK_OPEN_READWRITE | | 1022 | goto signal_error; |
1125 | GNUNET_DISK_OPEN_CREATE, | 1023 | } |
1126 | GNUNET_DISK_PERM_USER_READ | | ||
1127 | GNUNET_DISK_PERM_USER_WRITE | | ||
1128 | GNUNET_DISK_PERM_GROUP_READ | | ||
1129 | GNUNET_DISK_PERM_OTHER_READ); | ||
1130 | if (NULL == fh) | ||
1131 | { | ||
1132 | GNUNET_asprintf (&dc->emsg, | ||
1133 | _("Download failed: could not open file `%s': %s\n"), | ||
1134 | dc->filename, | ||
1135 | STRERROR (errno)); | ||
1136 | goto signal_error; | ||
1137 | } | ||
1138 | #if DEBUG_DOWNLOAD | 1024 | #if DEBUG_DOWNLOAD |
1139 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1025 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1140 | "Saving decrypted block to disk at offset %llu\n", | 1026 | "Saving decrypted block to disk at offset %llu\n", |
1141 | (unsigned long long) off); | 1027 | (unsigned long long) off); |
1142 | #endif | 1028 | #endif |
1143 | if ( (off != | 1029 | if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET))) |
1144 | GNUNET_DISK_file_seek (fh, | 1030 | { |
1145 | off, | 1031 | GNUNET_asprintf (&dc->emsg, |
1146 | GNUNET_DISK_SEEK_SET) ) ) | 1032 | _("Failed to seek to offset %llu in file `%s': %s\n"), |
1147 | { | 1033 | (unsigned long long) off, |
1148 | GNUNET_asprintf (&dc->emsg, | 1034 | dc->filename, STRERROR (errno)); |
1149 | _("Failed to seek to offset %llu in file `%s': %s\n"), | 1035 | goto signal_error; |
1150 | (unsigned long long) off, | ||
1151 | dc->filename, | ||
1152 | STRERROR (errno)); | ||
1153 | goto signal_error; | ||
1154 | } | ||
1155 | if (prc->size != | ||
1156 | GNUNET_DISK_file_write (fh, | ||
1157 | pt, | ||
1158 | prc->size)) | ||
1159 | { | ||
1160 | GNUNET_asprintf (&dc->emsg, | ||
1161 | _("Failed to write block of %u bytes at offset %llu in file `%s': %s\n"), | ||
1162 | (unsigned int) prc->size, | ||
1163 | (unsigned long long) off, | ||
1164 | dc->filename, | ||
1165 | STRERROR (errno)); | ||
1166 | goto signal_error; | ||
1167 | } | ||
1168 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
1169 | fh = NULL; | ||
1170 | } | 1036 | } |
1037 | if (prc->size != GNUNET_DISK_file_write (fh, pt, prc->size)) | ||
1038 | { | ||
1039 | GNUNET_asprintf (&dc->emsg, | ||
1040 | _ | ||
1041 | ("Failed to write block of %u bytes at offset %llu in file `%s': %s\n"), | ||
1042 | (unsigned int) prc->size, (unsigned long long) off, | ||
1043 | dc->filename, STRERROR (errno)); | ||
1044 | goto signal_error; | ||
1045 | } | ||
1046 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
1047 | fh = NULL; | ||
1048 | } | ||
1171 | 1049 | ||
1172 | if (dr->depth == 0) | 1050 | if (dr->depth == 0) |
1051 | { | ||
1052 | /* DBLOCK, update progress and try recursion if applicable */ | ||
1053 | app = prc->size; | ||
1054 | if (dr->offset < dc->offset) | ||
1173 | { | 1055 | { |
1174 | /* DBLOCK, update progress and try recursion if applicable */ | 1056 | /* starting offset begins in the middle of pt, |
1175 | app = prc->size; | 1057 | * do not count first bytes as progress */ |
1176 | if (dr->offset < dc->offset) | 1058 | GNUNET_assert (app > (dc->offset - dr->offset)); |
1177 | { | 1059 | app -= (dc->offset - dr->offset); |
1178 | /* starting offset begins in the middle of pt, | ||
1179 | do not count first bytes as progress */ | ||
1180 | GNUNET_assert (app > (dc->offset - dr->offset)); | ||
1181 | app -= (dc->offset - dr->offset); | ||
1182 | } | ||
1183 | if (dr->offset + prc->size > dc->offset + dc->length) | ||
1184 | { | ||
1185 | /* end of block is after relevant range, | ||
1186 | do not count last bytes as progress */ | ||
1187 | GNUNET_assert (app > (dr->offset + prc->size) - (dc->offset + dc->length)); | ||
1188 | app -= (dr->offset + prc->size) - (dc->offset + dc->length); | ||
1189 | } | ||
1190 | dc->completed += app; | ||
1191 | |||
1192 | /* do recursive download if option is set and either meta data | ||
1193 | says it is a directory or if no meta data is given AND filename | ||
1194 | ends in '.gnd' (top-level case) */ | ||
1195 | if (is_recursive_download (dc)) | ||
1196 | GNUNET_FS_directory_list_contents (prc->size, | ||
1197 | pt, | ||
1198 | off, | ||
1199 | &trigger_recursive_download, | ||
1200 | dc); | ||
1201 | |||
1202 | } | 1060 | } |
1061 | if (dr->offset + prc->size > dc->offset + dc->length) | ||
1062 | { | ||
1063 | /* end of block is after relevant range, | ||
1064 | * do not count last bytes as progress */ | ||
1065 | GNUNET_assert (app > | ||
1066 | (dr->offset + prc->size) - (dc->offset + dc->length)); | ||
1067 | app -= (dr->offset + prc->size) - (dc->offset + dc->length); | ||
1068 | } | ||
1069 | dc->completed += app; | ||
1070 | |||
1071 | /* do recursive download if option is set and either meta data | ||
1072 | * says it is a directory or if no meta data is given AND filename | ||
1073 | * ends in '.gnd' (top-level case) */ | ||
1074 | if (is_recursive_download (dc)) | ||
1075 | GNUNET_FS_directory_list_contents (prc->size, | ||
1076 | pt, | ||
1077 | off, &trigger_recursive_download, dc); | ||
1078 | |||
1079 | } | ||
1203 | dr->state = BRS_DOWNLOAD_DOWN; | 1080 | dr->state = BRS_DOWNLOAD_DOWN; |
1204 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; | 1081 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; |
1205 | pi.value.download.specifics.progress.data = pt; | 1082 | pi.value.download.specifics.progress.data = pt; |
@@ -1208,84 +1085,83 @@ process_result_with_request (void *cls, | |||
1208 | pi.value.download.specifics.progress.depth = dr->depth; | 1085 | pi.value.download.specifics.progress.depth = dr->depth; |
1209 | GNUNET_FS_download_make_status_ (&pi, dc); | 1086 | GNUNET_FS_download_make_status_ (&pi, dc); |
1210 | GNUNET_assert (dc->completed <= dc->length); | 1087 | GNUNET_assert (dc->completed <= dc->length); |
1211 | if (dr->depth == 0) | 1088 | if (dr->depth == 0) |
1212 | propagate_up (dr); | 1089 | propagate_up (dr); |
1213 | 1090 | ||
1214 | if (dc->completed == dc->length) | 1091 | if (dc->completed == dc->length) |
1215 | { | 1092 | { |
1216 | /* download completed, signal */ | 1093 | /* download completed, signal */ |
1217 | #if DEBUG_DOWNLOAD | 1094 | #if DEBUG_DOWNLOAD |
1218 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1095 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1219 | "Download completed, truncating file to desired length %llu\n", | 1096 | "Download completed, truncating file to desired length %llu\n", |
1220 | (unsigned long long) GNUNET_ntohll (dc->uri->data.chk.file_length)); | 1097 | (unsigned long long) GNUNET_ntohll (dc->uri->data. |
1098 | chk.file_length)); | ||
1221 | #endif | 1099 | #endif |
1222 | /* truncate file to size (since we store IBlocks at the end) */ | 1100 | /* truncate file to size (since we store IBlocks at the end) */ |
1223 | if (dc->filename != NULL) | 1101 | if (dc->filename != NULL) |
1224 | { | ||
1225 | if (0 != truncate (dc->filename, | ||
1226 | GNUNET_ntohll (dc->uri->data.chk.file_length))) | ||
1227 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
1228 | "truncate", | ||
1229 | dc->filename); | ||
1230 | } | ||
1231 | GNUNET_assert (dr->depth == 0); | ||
1232 | check_completed (dc); | ||
1233 | } | ||
1234 | if (dr->depth == 0) | ||
1235 | { | 1102 | { |
1236 | /* bottom of the tree, no child downloads possible, just sync */ | 1103 | if (0 != truncate (dc->filename, |
1237 | GNUNET_FS_download_sync_ (dc); | 1104 | GNUNET_ntohll (dc->uri->data.chk.file_length))) |
1238 | return GNUNET_YES; | 1105 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
1106 | "truncate", dc->filename); | ||
1239 | } | 1107 | } |
1108 | GNUNET_assert (dr->depth == 0); | ||
1109 | check_completed (dc); | ||
1110 | } | ||
1111 | if (dr->depth == 0) | ||
1112 | { | ||
1113 | /* bottom of the tree, no child downloads possible, just sync */ | ||
1114 | GNUNET_FS_download_sync_ (dc); | ||
1115 | return GNUNET_YES; | ||
1116 | } | ||
1240 | 1117 | ||
1241 | #if DEBUG_DOWNLOAD | 1118 | #if DEBUG_DOWNLOAD |
1242 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1119 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1243 | "Triggering downloads of children (this block was at depth %u and offset %llu)\n", | 1120 | "Triggering downloads of children (this block was at depth %u and offset %llu)\n", |
1244 | dr->depth, | 1121 | dr->depth, (unsigned long long) dr->offset); |
1245 | (unsigned long long) dr->offset); | ||
1246 | #endif | 1122 | #endif |
1247 | GNUNET_assert (0 == (prc->size % sizeof(struct ContentHashKey))); | 1123 | GNUNET_assert (0 == (prc->size % sizeof (struct ContentHashKey))); |
1248 | chkarr = (struct ContentHashKey*) pt; | 1124 | chkarr = (struct ContentHashKey *) pt; |
1249 | for (i=(prc->size / sizeof(struct ContentHashKey))-1;i>=0;i--) | 1125 | for (i = (prc->size / sizeof (struct ContentHashKey)) - 1; i >= 0; i--) |
1126 | { | ||
1127 | drc = dr->children[i]; | ||
1128 | switch (drc->state) | ||
1250 | { | 1129 | { |
1251 | drc = dr->children[i]; | 1130 | case BRS_INIT: |
1252 | switch (drc->state) | 1131 | drc->chk = chkarr[i]; |
1253 | { | 1132 | drc->state = BRS_CHK_SET; |
1254 | case BRS_INIT: | 1133 | schedule_block_download (dc, drc); |
1255 | drc->chk = chkarr[i]; | 1134 | break; |
1256 | drc->state = BRS_CHK_SET; | 1135 | case BRS_RECONSTRUCT_DOWN: |
1257 | schedule_block_download (dc, drc); | 1136 | GNUNET_assert (0); |
1258 | break; | 1137 | break; |
1259 | case BRS_RECONSTRUCT_DOWN: | 1138 | case BRS_RECONSTRUCT_META_UP: |
1260 | GNUNET_assert (0); | 1139 | GNUNET_assert (0); |
1261 | break; | 1140 | break; |
1262 | case BRS_RECONSTRUCT_META_UP: | 1141 | case BRS_RECONSTRUCT_UP: |
1263 | GNUNET_assert (0); | 1142 | GNUNET_assert (0); |
1264 | break; | 1143 | break; |
1265 | case BRS_RECONSTRUCT_UP: | 1144 | case BRS_CHK_SET: |
1266 | GNUNET_assert (0); | 1145 | GNUNET_assert (0); |
1267 | break; | 1146 | break; |
1268 | case BRS_CHK_SET: | 1147 | case BRS_DOWNLOAD_DOWN: |
1269 | GNUNET_assert (0); | 1148 | GNUNET_assert (0); |
1270 | break; | 1149 | break; |
1271 | case BRS_DOWNLOAD_DOWN: | 1150 | case BRS_DOWNLOAD_UP: |
1272 | GNUNET_assert (0); | 1151 | GNUNET_assert (0); |
1273 | break; | 1152 | break; |
1274 | case BRS_DOWNLOAD_UP: | 1153 | case BRS_ERROR: |
1275 | GNUNET_assert (0); | 1154 | GNUNET_assert (0); |
1276 | break; | 1155 | break; |
1277 | case BRS_ERROR: | 1156 | default: |
1278 | GNUNET_assert (0); | 1157 | GNUNET_assert (0); |
1279 | break; | 1158 | break; |
1280 | default: | ||
1281 | GNUNET_assert (0); | ||
1282 | break; | ||
1283 | } | ||
1284 | } | 1159 | } |
1160 | } | ||
1285 | GNUNET_FS_download_sync_ (dc); | 1161 | GNUNET_FS_download_sync_ (dc); |
1286 | return GNUNET_YES; | 1162 | return GNUNET_YES; |
1287 | 1163 | ||
1288 | signal_error: | 1164 | signal_error: |
1289 | if (fh != NULL) | 1165 | if (fh != NULL) |
1290 | GNUNET_DISK_file_close (fh); | 1166 | GNUNET_DISK_file_close (fh); |
1291 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | 1167 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; |
@@ -1293,10 +1169,10 @@ process_result_with_request (void *cls, | |||
1293 | GNUNET_FS_download_make_status_ (&pi, dc); | 1169 | GNUNET_FS_download_make_status_ (&pi, dc); |
1294 | /* abort all pending requests */ | 1170 | /* abort all pending requests */ |
1295 | if (NULL != dc->th) | 1171 | if (NULL != dc->th) |
1296 | { | 1172 | { |
1297 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); | 1173 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
1298 | dc->th = NULL; | 1174 | dc->th = NULL; |
1299 | } | 1175 | } |
1300 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | 1176 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); |
1301 | dc->in_receive = GNUNET_NO; | 1177 | dc->in_receive = GNUNET_NO; |
1302 | dc->client = NULL; | 1178 | dc->client = NULL; |
@@ -1321,9 +1197,7 @@ process_result_with_request (void *cls, | |||
1321 | */ | 1197 | */ |
1322 | static void | 1198 | static void |
1323 | process_result (struct GNUNET_FS_DownloadContext *dc, | 1199 | process_result (struct GNUNET_FS_DownloadContext *dc, |
1324 | enum GNUNET_BLOCK_Type type, | 1200 | enum GNUNET_BLOCK_Type type, const void *data, size_t size) |
1325 | const void *data, | ||
1326 | size_t size) | ||
1327 | { | 1201 | { |
1328 | struct ProcessResultClosure prc; | 1202 | struct ProcessResultClosure prc; |
1329 | 1203 | ||
@@ -1335,14 +1209,13 @@ process_result (struct GNUNET_FS_DownloadContext *dc, | |||
1335 | GNUNET_CRYPTO_hash (data, size, &prc.query); | 1209 | GNUNET_CRYPTO_hash (data, size, &prc.query); |
1336 | #if DEBUG_DOWNLOAD | 1210 | #if DEBUG_DOWNLOAD |
1337 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1211 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1338 | "Received result for query `%s' from `%s'-service\n", | 1212 | "Received result for query `%s' from `%s'-service\n", |
1339 | GNUNET_h2s (&prc.query), | 1213 | GNUNET_h2s (&prc.query), "FS"); |
1340 | "FS"); | ||
1341 | #endif | 1214 | #endif |
1342 | GNUNET_CONTAINER_multihashmap_get_multiple (dc->active, | 1215 | GNUNET_CONTAINER_multihashmap_get_multiple (dc->active, |
1343 | &prc.query, | 1216 | &prc.query, |
1344 | &process_result_with_request, | 1217 | &process_result_with_request, |
1345 | &prc); | 1218 | &prc); |
1346 | } | 1219 | } |
1347 | 1220 | ||
1348 | 1221 | ||
@@ -1353,35 +1226,30 @@ process_result (struct GNUNET_FS_DownloadContext *dc, | |||
1353 | * @param cls closure | 1226 | * @param cls closure |
1354 | * @param msg message received, NULL on timeout or fatal error | 1227 | * @param msg message received, NULL on timeout or fatal error |
1355 | */ | 1228 | */ |
1356 | static void | 1229 | static void |
1357 | receive_results (void *cls, | 1230 | receive_results (void *cls, const struct GNUNET_MessageHeader *msg) |
1358 | const struct GNUNET_MessageHeader * msg) | ||
1359 | { | 1231 | { |
1360 | struct GNUNET_FS_DownloadContext *dc = cls; | 1232 | struct GNUNET_FS_DownloadContext *dc = cls; |
1361 | const struct PutMessage *cm; | 1233 | const struct PutMessage *cm; |
1362 | uint16_t msize; | 1234 | uint16_t msize; |
1363 | 1235 | ||
1364 | if ( (NULL == msg) || | 1236 | if ((NULL == msg) || |
1365 | (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) || | 1237 | (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) || |
1366 | (sizeof (struct PutMessage) > ntohs(msg->size)) ) | 1238 | (sizeof (struct PutMessage) > ntohs (msg->size))) |
1367 | { | 1239 | { |
1368 | GNUNET_break (msg == NULL); | 1240 | GNUNET_break (msg == NULL); |
1369 | try_reconnect (dc); | 1241 | try_reconnect (dc); |
1370 | return; | 1242 | return; |
1371 | } | 1243 | } |
1372 | msize = ntohs(msg->size); | 1244 | msize = ntohs (msg->size); |
1373 | cm = (const struct PutMessage*) msg; | 1245 | cm = (const struct PutMessage *) msg; |
1374 | process_result (dc, | 1246 | process_result (dc, |
1375 | ntohl (cm->type), | 1247 | ntohl (cm->type), &cm[1], msize - sizeof (struct PutMessage)); |
1376 | &cm[1], | ||
1377 | msize - sizeof (struct PutMessage)); | ||
1378 | if (dc->client == NULL) | 1248 | if (dc->client == NULL) |
1379 | return; /* fatal error */ | 1249 | return; /* fatal error */ |
1380 | /* continue receiving */ | 1250 | /* continue receiving */ |
1381 | GNUNET_CLIENT_receive (dc->client, | 1251 | GNUNET_CLIENT_receive (dc->client, |
1382 | &receive_results, | 1252 | &receive_results, dc, GNUNET_TIME_UNIT_FOREVER_REL); |
1383 | dc, | ||
1384 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1385 | } | 1253 | } |
1386 | 1254 | ||
1387 | 1255 | ||
@@ -1398,9 +1266,7 @@ receive_results (void *cls, | |||
1398 | * @return number of bytes written to buf | 1266 | * @return number of bytes written to buf |
1399 | */ | 1267 | */ |
1400 | static size_t | 1268 | static size_t |
1401 | transmit_download_request (void *cls, | 1269 | transmit_download_request (void *cls, size_t size, void *buf) |
1402 | size_t size, | ||
1403 | void *buf) | ||
1404 | { | 1270 | { |
1405 | struct GNUNET_FS_DownloadContext *dc = cls; | 1271 | struct GNUNET_FS_DownloadContext *dc = cls; |
1406 | size_t msize; | 1272 | size_t msize; |
@@ -1409,65 +1275,60 @@ transmit_download_request (void *cls, | |||
1409 | 1275 | ||
1410 | dc->th = NULL; | 1276 | dc->th = NULL; |
1411 | if (NULL == buf) | 1277 | if (NULL == buf) |
1412 | { | 1278 | { |
1413 | #if DEBUG_DOWNLOAD | 1279 | #if DEBUG_DOWNLOAD |
1414 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1280 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1415 | "Transmitting download request failed, trying to reconnect\n"); | 1281 | "Transmitting download request failed, trying to reconnect\n"); |
1416 | #endif | 1282 | #endif |
1417 | try_reconnect (dc); | 1283 | try_reconnect (dc); |
1418 | return 0; | 1284 | return 0; |
1419 | } | 1285 | } |
1420 | GNUNET_assert (size >= sizeof (struct SearchMessage)); | 1286 | GNUNET_assert (size >= sizeof (struct SearchMessage)); |
1421 | msize = 0; | 1287 | msize = 0; |
1422 | sm = buf; | 1288 | sm = buf; |
1423 | while ( (NULL != (dr = dc->pending_head)) && | 1289 | while ((NULL != (dr = dc->pending_head)) && |
1424 | (size >= msize + sizeof (struct SearchMessage)) ) | 1290 | (size >= msize + sizeof (struct SearchMessage))) |
1425 | { | 1291 | { |
1426 | #if DEBUG_DOWNLOAD | 1292 | #if DEBUG_DOWNLOAD |
1427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1293 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1428 | "Transmitting download request for `%s' to `%s'-service\n", | 1294 | "Transmitting download request for `%s' to `%s'-service\n", |
1429 | GNUNET_h2s (&dr->chk.query), | 1295 | GNUNET_h2s (&dr->chk.query), "FS"); |
1430 | "FS"); | ||
1431 | #endif | 1296 | #endif |
1432 | memset (sm, 0, sizeof (struct SearchMessage)); | 1297 | memset (sm, 0, sizeof (struct SearchMessage)); |
1433 | sm->header.size = htons (sizeof (struct SearchMessage)); | 1298 | sm->header.size = htons (sizeof (struct SearchMessage)); |
1434 | sm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH); | 1299 | sm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH); |
1435 | if (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY)) | 1300 | if (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY)) |
1436 | sm->options = htonl (1); | 1301 | sm->options = htonl (1); |
1437 | else | 1302 | else |
1438 | sm->options = htonl (0); | 1303 | sm->options = htonl (0); |
1439 | if (dr->depth == 0) | 1304 | if (dr->depth == 0) |
1440 | sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK); | 1305 | sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK); |
1441 | else | 1306 | else |
1442 | sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK); | 1307 | sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK); |
1443 | sm->anonymity_level = htonl (dc->anonymity); | 1308 | sm->anonymity_level = htonl (dc->anonymity); |
1444 | sm->target = dc->target.hashPubKey; | 1309 | sm->target = dc->target.hashPubKey; |
1445 | sm->query = dr->chk.query; | 1310 | sm->query = dr->chk.query; |
1446 | GNUNET_CONTAINER_DLL_remove (dc->pending_head, | 1311 | GNUNET_CONTAINER_DLL_remove (dc->pending_head, dc->pending_tail, dr); |
1447 | dc->pending_tail, | 1312 | dr->is_pending = GNUNET_NO; |
1448 | dr); | 1313 | msize += sizeof (struct SearchMessage); |
1449 | dr->is_pending = GNUNET_NO; | 1314 | sm++; |
1450 | msize += sizeof (struct SearchMessage); | 1315 | } |
1451 | sm++; | ||
1452 | } | ||
1453 | if (dc->pending_head != NULL) | 1316 | if (dc->pending_head != NULL) |
1454 | { | 1317 | { |
1455 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | 1318 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, |
1456 | sizeof (struct SearchMessage), | 1319 | sizeof (struct SearchMessage), |
1457 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 1320 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
1458 | GNUNET_NO, | 1321 | GNUNET_NO, |
1459 | &transmit_download_request, | 1322 | &transmit_download_request, |
1460 | dc); | 1323 | dc); |
1461 | GNUNET_assert (dc->th != NULL); | 1324 | GNUNET_assert (dc->th != NULL); |
1462 | } | 1325 | } |
1463 | if (GNUNET_NO == dc->in_receive) | 1326 | if (GNUNET_NO == dc->in_receive) |
1464 | { | 1327 | { |
1465 | dc->in_receive = GNUNET_YES; | 1328 | dc->in_receive = GNUNET_YES; |
1466 | GNUNET_CLIENT_receive (dc->client, | 1329 | GNUNET_CLIENT_receive (dc->client, |
1467 | &receive_results, | 1330 | &receive_results, dc, GNUNET_TIME_UNIT_FOREVER_REL); |
1468 | dc, | 1331 | } |
1469 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1470 | } | ||
1471 | return msize; | 1332 | return msize; |
1472 | } | 1333 | } |
1473 | 1334 | ||
@@ -1479,34 +1340,31 @@ transmit_download_request (void *cls, | |||
1479 | * @param tc unused | 1340 | * @param tc unused |
1480 | */ | 1341 | */ |
1481 | static void | 1342 | static void |
1482 | do_reconnect (void *cls, | 1343 | do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1483 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1484 | { | 1344 | { |
1485 | struct GNUNET_FS_DownloadContext *dc = cls; | 1345 | struct GNUNET_FS_DownloadContext *dc = cls; |
1486 | struct GNUNET_CLIENT_Connection *client; | 1346 | struct GNUNET_CLIENT_Connection *client; |
1487 | 1347 | ||
1488 | dc->task = GNUNET_SCHEDULER_NO_TASK; | 1348 | dc->task = GNUNET_SCHEDULER_NO_TASK; |
1489 | client = GNUNET_CLIENT_connect ("fs", | 1349 | client = GNUNET_CLIENT_connect ("fs", dc->h->cfg); |
1490 | dc->h->cfg); | ||
1491 | if (NULL == client) | 1350 | if (NULL == client) |
1492 | { | 1351 | { |
1493 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1352 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1494 | "Connecting to `%s'-service failed, will try again.\n", | 1353 | "Connecting to `%s'-service failed, will try again.\n", "FS"); |
1495 | "FS"); | 1354 | try_reconnect (dc); |
1496 | try_reconnect (dc); | 1355 | return; |
1497 | return; | 1356 | } |
1498 | } | ||
1499 | dc->client = client; | 1357 | dc->client = client; |
1500 | if (dc->pending_head != NULL) | 1358 | if (dc->pending_head != NULL) |
1501 | { | 1359 | { |
1502 | dc->th = GNUNET_CLIENT_notify_transmit_ready (client, | 1360 | dc->th = GNUNET_CLIENT_notify_transmit_ready (client, |
1503 | sizeof (struct SearchMessage), | 1361 | sizeof (struct SearchMessage), |
1504 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 1362 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
1505 | GNUNET_NO, | 1363 | GNUNET_NO, |
1506 | &transmit_download_request, | 1364 | &transmit_download_request, |
1507 | dc); | 1365 | dc); |
1508 | GNUNET_assert (dc->th != NULL); | 1366 | GNUNET_assert (dc->th != NULL); |
1509 | } | 1367 | } |
1510 | } | 1368 | } |
1511 | 1369 | ||
1512 | 1370 | ||
@@ -1519,18 +1377,14 @@ do_reconnect (void *cls, | |||
1519 | * @return GNUNET_OK | 1377 | * @return GNUNET_OK |
1520 | */ | 1378 | */ |
1521 | static int | 1379 | static int |
1522 | retry_entry (void *cls, | 1380 | retry_entry (void *cls, const GNUNET_HashCode * key, void *entry) |
1523 | const GNUNET_HashCode *key, | ||
1524 | void *entry) | ||
1525 | { | 1381 | { |
1526 | struct GNUNET_FS_DownloadContext *dc = cls; | 1382 | struct GNUNET_FS_DownloadContext *dc = cls; |
1527 | struct DownloadRequest *dr = entry; | 1383 | struct DownloadRequest *dr = entry; |
1528 | 1384 | ||
1529 | dr->next = NULL; | 1385 | dr->next = NULL; |
1530 | dr->prev = NULL; | 1386 | dr->prev = NULL; |
1531 | GNUNET_CONTAINER_DLL_insert (dc->pending_head, | 1387 | GNUNET_CONTAINER_DLL_insert (dc->pending_head, dc->pending_tail, dr); |
1532 | dc->pending_tail, | ||
1533 | dr); | ||
1534 | dr->is_pending = GNUNET_YES; | 1388 | dr->is_pending = GNUNET_YES; |
1535 | return GNUNET_OK; | 1389 | return GNUNET_OK; |
1536 | } | 1390 | } |
@@ -1546,36 +1400,32 @@ retry_entry (void *cls, | |||
1546 | static void | 1400 | static void |
1547 | try_reconnect (struct GNUNET_FS_DownloadContext *dc) | 1401 | try_reconnect (struct GNUNET_FS_DownloadContext *dc) |
1548 | { | 1402 | { |
1549 | 1403 | ||
1550 | if (NULL != dc->client) | 1404 | if (NULL != dc->client) |
1551 | { | 1405 | { |
1552 | #if DEBUG_DOWNLOAD | 1406 | #if DEBUG_DOWNLOAD |
1553 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1407 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1554 | "Moving all requests back to pending list\n"); | 1408 | "Moving all requests back to pending list\n"); |
1555 | #endif | 1409 | #endif |
1556 | if (NULL != dc->th) | 1410 | if (NULL != dc->th) |
1557 | { | 1411 | { |
1558 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); | 1412 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
1559 | dc->th = NULL; | 1413 | dc->th = NULL; |
1560 | } | ||
1561 | /* full reset of the pending list */ | ||
1562 | dc->pending_head = NULL; | ||
1563 | dc->pending_tail = NULL; | ||
1564 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, | ||
1565 | &retry_entry, | ||
1566 | dc); | ||
1567 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | ||
1568 | dc->in_receive = GNUNET_NO; | ||
1569 | dc->client = NULL; | ||
1570 | } | 1414 | } |
1415 | /* full reset of the pending list */ | ||
1416 | dc->pending_head = NULL; | ||
1417 | dc->pending_tail = NULL; | ||
1418 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc); | ||
1419 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | ||
1420 | dc->in_receive = GNUNET_NO; | ||
1421 | dc->client = NULL; | ||
1422 | } | ||
1571 | #if DEBUG_DOWNLOAD | 1423 | #if DEBUG_DOWNLOAD |
1572 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1424 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will try to reconnect in 1s\n"); |
1573 | "Will try to reconnect in 1s\n"); | ||
1574 | #endif | 1425 | #endif |
1575 | dc->task | 1426 | dc->task |
1576 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 1427 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
1577 | &do_reconnect, | 1428 | &do_reconnect, dc); |
1578 | dc); | ||
1579 | } | 1429 | } |
1580 | 1430 | ||
1581 | 1431 | ||
@@ -1586,15 +1436,13 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) | |||
1586 | * @param client handle to use for communcation with FS (we must destroy it!) | 1436 | * @param client handle to use for communcation with FS (we must destroy it!) |
1587 | */ | 1437 | */ |
1588 | static void | 1438 | static void |
1589 | activate_fs_download (void *cls, | 1439 | activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client) |
1590 | struct GNUNET_CLIENT_Connection *client) | ||
1591 | { | 1440 | { |
1592 | struct GNUNET_FS_DownloadContext *dc = cls; | 1441 | struct GNUNET_FS_DownloadContext *dc = cls; |
1593 | struct GNUNET_FS_ProgressInfo pi; | 1442 | struct GNUNET_FS_ProgressInfo pi; |
1594 | 1443 | ||
1595 | #if DEBUG_DOWNLOAD | 1444 | #if DEBUG_DOWNLOAD |
1596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n"); |
1597 | "Download activated\n"); | ||
1598 | #endif | 1446 | #endif |
1599 | GNUNET_assert (NULL != client); | 1447 | GNUNET_assert (NULL != client); |
1600 | GNUNET_assert (dc->client == NULL); | 1448 | GNUNET_assert (dc->client == NULL); |
@@ -1604,23 +1452,21 @@ activate_fs_download (void *cls, | |||
1604 | GNUNET_FS_download_make_status_ (&pi, dc); | 1452 | GNUNET_FS_download_make_status_ (&pi, dc); |
1605 | dc->pending_head = NULL; | 1453 | dc->pending_head = NULL; |
1606 | dc->pending_tail = NULL; | 1454 | dc->pending_tail = NULL; |
1607 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, | 1455 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc); |
1608 | &retry_entry, | ||
1609 | dc); | ||
1610 | #if DEBUG_DOWNLOAD | 1456 | #if DEBUG_DOWNLOAD |
1611 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1457 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1612 | "Asking for transmission to FS service\n"); | 1458 | "Asking for transmission to FS service\n"); |
1613 | #endif | 1459 | #endif |
1614 | if (dc->pending_head != NULL) | 1460 | if (dc->pending_head != NULL) |
1615 | { | 1461 | { |
1616 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | 1462 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, |
1617 | sizeof (struct SearchMessage), | 1463 | sizeof (struct SearchMessage), |
1618 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 1464 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
1619 | GNUNET_NO, | 1465 | GNUNET_NO, |
1620 | &transmit_download_request, | 1466 | &transmit_download_request, |
1621 | dc); | 1467 | dc); |
1622 | GNUNET_assert (dc->th != NULL); | 1468 | GNUNET_assert (dc->th != NULL); |
1623 | } | 1469 | } |
1624 | } | 1470 | } |
1625 | 1471 | ||
1626 | 1472 | ||
@@ -1636,20 +1482,19 @@ deactivate_fs_download (void *cls) | |||
1636 | struct GNUNET_FS_ProgressInfo pi; | 1482 | struct GNUNET_FS_ProgressInfo pi; |
1637 | 1483 | ||
1638 | #if DEBUG_DOWNLOAD | 1484 | #if DEBUG_DOWNLOAD |
1639 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download deactivated\n"); |
1640 | "Download deactivated\n"); | 1486 | #endif |
1641 | #endif | ||
1642 | if (NULL != dc->th) | 1487 | if (NULL != dc->th) |
1643 | { | 1488 | { |
1644 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); | 1489 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
1645 | dc->th = NULL; | 1490 | dc->th = NULL; |
1646 | } | 1491 | } |
1647 | if (NULL != dc->client) | 1492 | if (NULL != dc->client) |
1648 | { | 1493 | { |
1649 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); | 1494 | GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); |
1650 | dc->in_receive = GNUNET_NO; | 1495 | dc->in_receive = GNUNET_NO; |
1651 | dc->client = NULL; | 1496 | dc->client = NULL; |
1652 | } | 1497 | } |
1653 | dc->pending_head = NULL; | 1498 | dc->pending_head = NULL; |
1654 | dc->pending_tail = NULL; | 1499 | dc->pending_tail = NULL; |
1655 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_INACTIVE; | 1500 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_INACTIVE; |
@@ -1677,54 +1522,55 @@ deactivate_fs_download (void *cls) | |||
1677 | */ | 1522 | */ |
1678 | static struct DownloadRequest * | 1523 | static struct DownloadRequest * |
1679 | create_download_request (struct DownloadRequest *parent, | 1524 | create_download_request (struct DownloadRequest *parent, |
1680 | unsigned int depth, | 1525 | unsigned int depth, |
1681 | uint64_t dr_offset, | 1526 | uint64_t dr_offset, |
1682 | uint64_t file_start_offset, | 1527 | uint64_t file_start_offset, uint64_t desired_length) |
1683 | uint64_t desired_length) | ||
1684 | { | 1528 | { |
1685 | struct DownloadRequest *dr; | 1529 | struct DownloadRequest *dr; |
1686 | unsigned int i; | 1530 | unsigned int i; |
1687 | unsigned int head_skip; | 1531 | unsigned int head_skip; |
1688 | uint64_t child_block_size; | 1532 | uint64_t child_block_size; |
1689 | 1533 | ||
1690 | dr = GNUNET_malloc (sizeof (struct DownloadRequest)); | 1534 | dr = GNUNET_malloc (sizeof (struct DownloadRequest)); |
1691 | dr->parent = parent; | 1535 | dr->parent = parent; |
1692 | dr->depth = depth; | 1536 | dr->depth = depth; |
1693 | dr->offset = dr_offset; | 1537 | dr->offset = dr_offset; |
1694 | if (depth > 0) | 1538 | if (depth > 0) |
1695 | { | 1539 | { |
1696 | child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); | 1540 | child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); |
1697 | 1541 | ||
1698 | /* calculate how many blocks at this level are not interesting | 1542 | /* calculate how many blocks at this level are not interesting |
1699 | from the start (rounded down), either because of the requested | 1543 | * from the start (rounded down), either because of the requested |
1700 | file offset or because this IBlock is further along */ | 1544 | * file offset or because this IBlock is further along */ |
1701 | if (dr_offset < file_start_offset) | 1545 | if (dr_offset < file_start_offset) |
1702 | head_skip = file_start_offset / child_block_size; | 1546 | head_skip = file_start_offset / child_block_size; |
1703 | else | 1547 | else |
1704 | head_skip = dr_offset / child_block_size; | 1548 | head_skip = dr_offset / child_block_size; |
1705 | 1549 | ||
1706 | /* calculate index of last block at this level that is interesting (rounded up) */ | 1550 | /* calculate index of last block at this level that is interesting (rounded up) */ |
1707 | dr->num_children = file_start_offset + desired_length / child_block_size; | 1551 | dr->num_children = file_start_offset + desired_length / child_block_size; |
1708 | if (dr->num_children * child_block_size < file_start_offset + desired_length) | 1552 | if (dr->num_children * child_block_size < |
1709 | dr->num_children++; /* round up */ | 1553 | file_start_offset + desired_length) |
1710 | 1554 | dr->num_children++; /* round up */ | |
1711 | /* now we can get the total number of children for this block */ | 1555 | |
1712 | dr->num_children -= head_skip; | 1556 | /* now we can get the total number of children for this block */ |
1713 | if (dr->num_children > CHK_PER_INODE) | 1557 | dr->num_children -= head_skip; |
1714 | dr->num_children = CHK_PER_INODE; /* cap at max */ | 1558 | if (dr->num_children > CHK_PER_INODE) |
1715 | 1559 | dr->num_children = CHK_PER_INODE; /* cap at max */ | |
1716 | /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ | 1560 | |
1717 | GNUNET_assert (dr->num_children > 0); | 1561 | /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ |
1718 | 1562 | GNUNET_assert (dr->num_children > 0); | |
1719 | dr->children = GNUNET_malloc (dr->num_children * | 1563 | |
1720 | sizeof (struct DownloadRequest *)); | 1564 | dr->children = GNUNET_malloc (dr->num_children * |
1721 | for (i=0;i<dr->num_children;i++) | 1565 | sizeof (struct DownloadRequest *)); |
1722 | dr->children[i] = create_download_request (dr, | 1566 | for (i = 0; i < dr->num_children; i++) |
1723 | depth - 1, | 1567 | dr->children[i] = create_download_request (dr, |
1724 | dr_offset + i * child_block_size, | 1568 | depth - 1, |
1725 | file_start_offset, | 1569 | dr_offset + |
1726 | desired_length); | 1570 | i * child_block_size, |
1727 | } | 1571 | file_start_offset, |
1572 | desired_length); | ||
1573 | } | ||
1728 | return dr; | 1574 | return dr; |
1729 | } | 1575 | } |
1730 | 1576 | ||
@@ -1737,30 +1583,28 @@ create_download_request (struct DownloadRequest *parent, | |||
1737 | * @param tc scheduler context | 1583 | * @param tc scheduler context |
1738 | */ | 1584 | */ |
1739 | static void | 1585 | static void |
1740 | reconstruct_cont (void *cls, | 1586 | reconstruct_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1741 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1742 | { | 1587 | { |
1743 | struct GNUNET_FS_DownloadContext *dc = cls; | 1588 | struct GNUNET_FS_DownloadContext *dc = cls; |
1744 | 1589 | ||
1745 | /* clean up state from tree encoder */ | 1590 | /* clean up state from tree encoder */ |
1746 | if (dc->te != NULL) | 1591 | if (dc->te != NULL) |
1747 | { | 1592 | { |
1748 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); | 1593 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); |
1749 | dc->te = NULL; | 1594 | dc->te = NULL; |
1750 | } | 1595 | } |
1751 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) | 1596 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) |
1752 | { | 1597 | { |
1753 | GNUNET_SCHEDULER_cancel (dc->task); | 1598 | GNUNET_SCHEDULER_cancel (dc->task); |
1754 | dc->task = GNUNET_SCHEDULER_NO_TASK; | 1599 | dc->task = GNUNET_SCHEDULER_NO_TASK; |
1755 | } | 1600 | } |
1756 | if (dc->rfh != NULL) | 1601 | if (dc->rfh != NULL) |
1757 | { | 1602 | { |
1758 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh)); | 1603 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh)); |
1759 | dc->rfh = NULL; | 1604 | dc->rfh = NULL; |
1760 | } | 1605 | } |
1761 | /* start "normal" download */ | 1606 | /* start "normal" download */ |
1762 | schedule_block_download (dc, | 1607 | schedule_block_download (dc, dc->top_request); |
1763 | dc->top_request); | ||
1764 | } | 1608 | } |
1765 | 1609 | ||
1766 | 1610 | ||
@@ -1771,8 +1615,7 @@ reconstruct_cont (void *cls, | |||
1771 | * @param tc task context | 1615 | * @param tc task context |
1772 | */ | 1616 | */ |
1773 | static void | 1617 | static void |
1774 | get_next_block (void *cls, | 1618 | get_next_block (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1775 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1776 | { | 1619 | { |
1777 | struct GNUNET_FS_DownloadContext *dc = cls; | 1620 | struct GNUNET_FS_DownloadContext *dc = cls; |
1778 | 1621 | ||
@@ -1799,14 +1642,13 @@ get_next_block (void *cls, | |||
1799 | * @param block the (encrypted) block | 1642 | * @param block the (encrypted) block |
1800 | * @param block_size size of block (in bytes) | 1643 | * @param block_size size of block (in bytes) |
1801 | */ | 1644 | */ |
1802 | static void | 1645 | static void |
1803 | reconstruct_cb (void *cls, | 1646 | reconstruct_cb (void *cls, |
1804 | const struct ContentHashKey *chk, | 1647 | const struct ContentHashKey *chk, |
1805 | uint64_t offset, | 1648 | uint64_t offset, |
1806 | unsigned int depth, | 1649 | unsigned int depth, |
1807 | enum GNUNET_BLOCK_Type type, | 1650 | enum GNUNET_BLOCK_Type type, |
1808 | const void *block, | 1651 | const void *block, uint16_t block_size) |
1809 | uint16_t block_size) | ||
1810 | { | 1652 | { |
1811 | struct GNUNET_FS_DownloadContext *dc = cls; | 1653 | struct GNUNET_FS_DownloadContext *dc = cls; |
1812 | struct GNUNET_FS_ProgressInfo pi; | 1654 | struct GNUNET_FS_ProgressInfo pi; |
@@ -1817,67 +1659,62 @@ reconstruct_cb (void *cls, | |||
1817 | /* find corresponding request entry */ | 1659 | /* find corresponding request entry */ |
1818 | dr = dc->top_request; | 1660 | dr = dc->top_request; |
1819 | while (dr->depth > depth) | 1661 | while (dr->depth > depth) |
1820 | { | 1662 | { |
1821 | blen = GNUNET_FS_tree_compute_tree_size (dr->depth); | 1663 | blen = GNUNET_FS_tree_compute_tree_size (dr->depth); |
1822 | chld = (offset - dr->offset) / blen; | 1664 | chld = (offset - dr->offset) / blen; |
1823 | GNUNET_assert (chld < dr->num_children); | 1665 | GNUNET_assert (chld < dr->num_children); |
1824 | dr = dr->children[chld]; | 1666 | dr = dr->children[chld]; |
1825 | } | 1667 | } |
1826 | switch (dr->state) | 1668 | switch (dr->state) |
1827 | { | 1669 | { |
1828 | case BRS_INIT: | 1670 | case BRS_INIT: |
1829 | break; | 1671 | break; |
1830 | case BRS_RECONSTRUCT_DOWN: | 1672 | case BRS_RECONSTRUCT_DOWN: |
1831 | break; | 1673 | break; |
1832 | case BRS_RECONSTRUCT_META_UP: | 1674 | case BRS_RECONSTRUCT_META_UP: |
1833 | break; | 1675 | break; |
1834 | case BRS_RECONSTRUCT_UP: | 1676 | case BRS_RECONSTRUCT_UP: |
1835 | break; | 1677 | break; |
1836 | case BRS_CHK_SET: | 1678 | case BRS_CHK_SET: |
1837 | if (0 == memcmp (chk, | 1679 | if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey))) |
1838 | &dr->chk, | 1680 | { |
1839 | sizeof (struct ContentHashKey))) | 1681 | /* block matches, hence tree below matches; |
1840 | { | 1682 | * this request is done! */ |
1841 | /* block matches, hence tree below matches; | 1683 | dr->state = BRS_DOWNLOAD_UP; |
1842 | this request is done! */ | 1684 | /* calculate how many bytes of payload this block |
1843 | dr->state = BRS_DOWNLOAD_UP; | 1685 | * corresponds to */ |
1844 | /* calculate how many bytes of payload this block | 1686 | blen = GNUNET_FS_tree_compute_tree_size (dr->depth); |
1845 | corresponds to */ | 1687 | /* how many of those bytes are in the requested range? */ |
1846 | blen = GNUNET_FS_tree_compute_tree_size (dr->depth); | 1688 | blen = GNUNET_MIN (blen, dc->length + dc->offset - dr->offset); |
1847 | /* how many of those bytes are in the requested range? */ | 1689 | /* signal progress */ |
1848 | blen = GNUNET_MIN (blen, | 1690 | dc->completed += blen; |
1849 | dc->length + dc->offset - dr->offset); | 1691 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; |
1850 | /* signal progress */ | 1692 | pi.value.download.specifics.progress.data = NULL; |
1851 | dc->completed += blen; | 1693 | pi.value.download.specifics.progress.offset = offset; |
1852 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; | 1694 | pi.value.download.specifics.progress.data_len = 0; |
1853 | pi.value.download.specifics.progress.data = NULL; | 1695 | pi.value.download.specifics.progress.depth = 0; |
1854 | pi.value.download.specifics.progress.offset = offset; | 1696 | GNUNET_FS_download_make_status_ (&pi, dc); |
1855 | pi.value.download.specifics.progress.data_len = 0; | ||
1856 | pi.value.download.specifics.progress.depth = 0; | ||
1857 | GNUNET_FS_download_make_status_ (&pi, dc); | ||
1858 | } | ||
1859 | else | ||
1860 | { | ||
1861 | } | ||
1862 | break; | ||
1863 | case BRS_DOWNLOAD_DOWN: | ||
1864 | break; | ||
1865 | case BRS_DOWNLOAD_UP: | ||
1866 | break; | ||
1867 | case BRS_ERROR: | ||
1868 | break; | ||
1869 | default: | ||
1870 | GNUNET_assert (0); | ||
1871 | break; | ||
1872 | } | ||
1873 | if ( (dr == dc->top_request) && | ||
1874 | (dr->state == BRS_DOWNLOAD_UP) ) | ||
1875 | { | ||
1876 | check_completed (dc); | ||
1877 | return; | ||
1878 | } | 1697 | } |
1879 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, | 1698 | else |
1880 | dc); | 1699 | { |
1700 | } | ||
1701 | break; | ||
1702 | case BRS_DOWNLOAD_DOWN: | ||
1703 | break; | ||
1704 | case BRS_DOWNLOAD_UP: | ||
1705 | break; | ||
1706 | case BRS_ERROR: | ||
1707 | break; | ||
1708 | default: | ||
1709 | GNUNET_assert (0); | ||
1710 | break; | ||
1711 | } | ||
1712 | if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP)) | ||
1713 | { | ||
1714 | check_completed (dc); | ||
1715 | return; | ||
1716 | } | ||
1717 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); | ||
1881 | } | 1718 | } |
1882 | 1719 | ||
1883 | 1720 | ||
@@ -1894,31 +1731,24 @@ reconstruct_cb (void *cls, | |||
1894 | * @return number of bytes copied to buf, 0 on error | 1731 | * @return number of bytes copied to buf, 0 on error |
1895 | */ | 1732 | */ |
1896 | static size_t | 1733 | static size_t |
1897 | fh_reader (void *cls, | 1734 | fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) |
1898 | uint64_t offset, | ||
1899 | size_t max, | ||
1900 | void *buf, | ||
1901 | char **emsg) | ||
1902 | { | 1735 | { |
1903 | struct GNUNET_FS_DownloadContext *dc = cls; | 1736 | struct GNUNET_FS_DownloadContext *dc = cls; |
1904 | struct GNUNET_DISK_FileHandle *fh = dc->rfh; | 1737 | struct GNUNET_DISK_FileHandle *fh = dc->rfh; |
1905 | ssize_t ret; | 1738 | ssize_t ret; |
1906 | 1739 | ||
1907 | *emsg = NULL; | 1740 | *emsg = NULL; |
1908 | if (offset != | 1741 | if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET)) |
1909 | GNUNET_DISK_file_seek (fh, | 1742 | { |
1910 | offset, | 1743 | *emsg = GNUNET_strdup (strerror (errno)); |
1911 | GNUNET_DISK_SEEK_SET)) | 1744 | return 0; |
1912 | { | 1745 | } |
1913 | *emsg = GNUNET_strdup (strerror (errno)); | ||
1914 | return 0; | ||
1915 | } | ||
1916 | ret = GNUNET_DISK_file_read (fh, buf, max); | 1746 | ret = GNUNET_DISK_file_read (fh, buf, max); |
1917 | if (ret < 0) | 1747 | if (ret < 0) |
1918 | { | 1748 | { |
1919 | *emsg = GNUNET_strdup (strerror (errno)); | 1749 | *emsg = GNUNET_strdup (strerror (errno)); |
1920 | return 0; | 1750 | return 0; |
1921 | } | 1751 | } |
1922 | return ret; | 1752 | return ret; |
1923 | } | 1753 | } |
1924 | 1754 | ||
@@ -1932,149 +1762,141 @@ fh_reader (void *cls, | |||
1932 | */ | 1762 | */ |
1933 | void | 1763 | void |
1934 | GNUNET_FS_download_start_task_ (void *cls, | 1764 | GNUNET_FS_download_start_task_ (void *cls, |
1935 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1765 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1936 | { | 1766 | { |
1937 | struct GNUNET_FS_DownloadContext *dc = cls; | 1767 | struct GNUNET_FS_DownloadContext *dc = cls; |
1938 | struct GNUNET_FS_ProgressInfo pi; | 1768 | struct GNUNET_FS_ProgressInfo pi; |
1939 | struct GNUNET_DISK_FileHandle *fh; | 1769 | struct GNUNET_DISK_FileHandle *fh; |
1940 | 1770 | ||
1941 | #if DEBUG_DOWNLOAD | 1771 | #if DEBUG_DOWNLOAD |
1942 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1772 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n"); |
1943 | "Start task running...\n"); | ||
1944 | #endif | 1773 | #endif |
1945 | dc->task = GNUNET_SCHEDULER_NO_TASK; | 1774 | dc->task = GNUNET_SCHEDULER_NO_TASK; |
1946 | if (dc->length == 0) | 1775 | if (dc->length == 0) |
1947 | { | 1776 | { |
1948 | /* no bytes required! */ | 1777 | /* no bytes required! */ |
1949 | if (dc->filename != NULL) | 1778 | if (dc->filename != NULL) |
1950 | { | 1779 | { |
1951 | fh = GNUNET_DISK_file_open (dc->filename, | 1780 | fh = GNUNET_DISK_file_open (dc->filename, |
1952 | GNUNET_DISK_OPEN_READWRITE | | 1781 | GNUNET_DISK_OPEN_READWRITE | |
1953 | GNUNET_DISK_OPEN_CREATE | | 1782 | GNUNET_DISK_OPEN_CREATE | |
1954 | ( (0 == GNUNET_FS_uri_chk_get_file_size (dc->uri)) | 1783 | ((0 == |
1955 | ? GNUNET_DISK_OPEN_TRUNCATE : 0), | 1784 | GNUNET_FS_uri_chk_get_file_size (dc->uri)) ? |
1956 | GNUNET_DISK_PERM_USER_READ | | 1785 | GNUNET_DISK_OPEN_TRUNCATE : 0), |
1957 | GNUNET_DISK_PERM_USER_WRITE | | 1786 | GNUNET_DISK_PERM_USER_READ | |
1958 | GNUNET_DISK_PERM_GROUP_READ | | 1787 | GNUNET_DISK_PERM_USER_WRITE | |
1959 | GNUNET_DISK_PERM_OTHER_READ); | 1788 | GNUNET_DISK_PERM_GROUP_READ | |
1960 | GNUNET_DISK_file_close (fh); | 1789 | GNUNET_DISK_PERM_OTHER_READ); |
1961 | } | 1790 | GNUNET_DISK_file_close (fh); |
1962 | GNUNET_FS_download_sync_ (dc); | ||
1963 | check_completed (dc); | ||
1964 | return; | ||
1965 | } | 1791 | } |
1966 | if (dc->emsg != NULL) | 1792 | GNUNET_FS_download_sync_ (dc); |
1793 | check_completed (dc); | ||
1794 | return; | ||
1795 | } | ||
1796 | if (dc->emsg != NULL) | ||
1967 | return; | 1797 | return; |
1968 | if (dc->top_request == NULL) | 1798 | if (dc->top_request == NULL) |
1969 | { | 1799 | { |
1970 | dc->top_request = create_download_request (NULL, dc->treedepth - 1, 0, | 1800 | dc->top_request = create_download_request (NULL, dc->treedepth - 1, 0, |
1971 | dc->offset, dc->length); | 1801 | dc->offset, dc->length); |
1972 | dc->top_request->state = BRS_CHK_SET; | 1802 | dc->top_request->state = BRS_CHK_SET; |
1973 | dc->top_request->chk = (dc->uri->type == chk) | 1803 | dc->top_request->chk = (dc->uri->type == chk) |
1974 | ? dc->uri->data.chk.chk | 1804 | ? dc->uri->data.chk.chk : dc->uri->data.loc.fi.chk; |
1975 | : dc->uri->data.loc.fi.chk; | 1805 | /* signal start */ |
1976 | /* signal start */ | 1806 | GNUNET_FS_download_sync_ (dc); |
1977 | GNUNET_FS_download_sync_ (dc); | 1807 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; |
1978 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; | 1808 | pi.value.download.specifics.start.meta = dc->meta; |
1979 | pi.value.download.specifics.start.meta = dc->meta; | 1809 | GNUNET_FS_download_make_status_ (&pi, dc); |
1980 | GNUNET_FS_download_make_status_ (&pi, dc); | 1810 | } |
1981 | } | ||
1982 | GNUNET_FS_download_start_downloading_ (dc); | 1811 | GNUNET_FS_download_start_downloading_ (dc); |
1983 | /* attempt reconstruction from disk */ | 1812 | /* attempt reconstruction from disk */ |
1984 | if (GNUNET_YES == GNUNET_DISK_file_test (dc->filename)) | 1813 | if (GNUNET_YES == GNUNET_DISK_file_test (dc->filename)) |
1985 | dc->rfh = GNUNET_DISK_file_open (dc->filename, | 1814 | dc->rfh = GNUNET_DISK_file_open (dc->filename, |
1986 | GNUNET_DISK_OPEN_READ, | 1815 | GNUNET_DISK_OPEN_READ, |
1987 | GNUNET_DISK_PERM_NONE); | 1816 | GNUNET_DISK_PERM_NONE); |
1988 | if (dc->top_request->state == BRS_CHK_SET) | 1817 | if (dc->top_request->state == BRS_CHK_SET) |
1818 | { | ||
1819 | if (dc->rfh != NULL) | ||
1989 | { | 1820 | { |
1990 | if (dc->rfh != NULL) | 1821 | /* first, try top-down */ |
1991 | { | ||
1992 | /* first, try top-down */ | ||
1993 | #if DEBUG_DOWNLOAD | 1822 | #if DEBUG_DOWNLOAD |
1994 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1823 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1995 | "Trying top-down reconstruction for `%s'\n", | 1824 | "Trying top-down reconstruction for `%s'\n", dc->filename); |
1996 | dc->filename); | ||
1997 | #endif | 1825 | #endif |
1998 | try_top_down_reconstruction (dc, dc->top_request); | 1826 | try_top_down_reconstruction (dc, dc->top_request); |
1999 | switch (dc->top_request->state) | 1827 | switch (dc->top_request->state) |
2000 | { | 1828 | { |
2001 | case BRS_CHK_SET: | 1829 | case BRS_CHK_SET: |
2002 | break; /* normal */ | 1830 | break; /* normal */ |
2003 | case BRS_DOWNLOAD_DOWN: | 1831 | case BRS_DOWNLOAD_DOWN: |
2004 | break; /* normal, some blocks already down */ | 1832 | break; /* normal, some blocks already down */ |
2005 | case BRS_DOWNLOAD_UP: | 1833 | case BRS_DOWNLOAD_UP: |
2006 | /* already done entirely, party! */ | 1834 | /* already done entirely, party! */ |
2007 | if (dc->rfh != NULL) | 1835 | if (dc->rfh != NULL) |
2008 | { | 1836 | { |
2009 | /* avoid hanging on to file handle longer than | 1837 | /* avoid hanging on to file handle longer than |
2010 | necessary */ | 1838 | * necessary */ |
2011 | GNUNET_DISK_file_close (dc->rfh); | 1839 | GNUNET_DISK_file_close (dc->rfh); |
2012 | dc->rfh = NULL; | 1840 | dc->rfh = NULL; |
2013 | } | 1841 | } |
2014 | return; | 1842 | return; |
2015 | case BRS_ERROR: | 1843 | case BRS_ERROR: |
2016 | GNUNET_asprintf (&dc->emsg, | 1844 | GNUNET_asprintf (&dc->emsg, _("Invalid URI")); |
2017 | _("Invalid URI")); | 1845 | GNUNET_FS_download_sync_ (dc); |
2018 | GNUNET_FS_download_sync_ (dc); | 1846 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; |
2019 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; | 1847 | pi.value.download.specifics.error.message = dc->emsg; |
2020 | pi.value.download.specifics.error.message = dc->emsg; | 1848 | GNUNET_FS_download_make_status_ (&pi, dc); |
2021 | GNUNET_FS_download_make_status_ (&pi, dc); | 1849 | return; |
2022 | return; | 1850 | default: |
2023 | default: | 1851 | GNUNET_assert (0); |
2024 | GNUNET_assert (0); | 1852 | break; |
2025 | break; | 1853 | } |
2026 | } | 1854 | } |
2027 | } | 1855 | } |
2028 | } | ||
2029 | /* attempt reconstruction from meta data */ | 1856 | /* attempt reconstruction from meta data */ |
2030 | if ( (GNUNET_FS_uri_chk_get_file_size (dc->uri) <= MAX_INLINE_SIZE) && | 1857 | if ((GNUNET_FS_uri_chk_get_file_size (dc->uri) <= MAX_INLINE_SIZE) && |
2031 | (NULL != dc->meta) ) | 1858 | (NULL != dc->meta)) |
2032 | { | 1859 | { |
2033 | #if DEBUG_DOWNLOAD | 1860 | #if DEBUG_DOWNLOAD |
2034 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1861 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2035 | "Trying to find embedded meta data for download of size %llu with %u bytes MD\n", | 1862 | "Trying to find embedded meta data for download of size %llu with %u bytes MD\n", |
2036 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri), | 1863 | (unsigned long long) GNUNET_FS_uri_chk_get_file_size (dc->uri), |
2037 | (unsigned int) GNUNET_CONTAINER_meta_data_get_serialized_size (dc->meta)); | 1864 | (unsigned int) |
1865 | GNUNET_CONTAINER_meta_data_get_serialized_size (dc->meta)); | ||
2038 | #endif | 1866 | #endif |
2039 | GNUNET_CONTAINER_meta_data_iterate (dc->meta, | 1867 | GNUNET_CONTAINER_meta_data_iterate (dc->meta, &match_full_data, dc); |
2040 | &match_full_data, | 1868 | if (dc->top_request->state == BRS_DOWNLOAD_UP) |
2041 | dc); | ||
2042 | if (dc->top_request->state == BRS_DOWNLOAD_UP) | ||
2043 | { | ||
2044 | if (dc->rfh != NULL) | ||
2045 | { | ||
2046 | /* avoid hanging on to file handle longer than | ||
2047 | necessary */ | ||
2048 | GNUNET_DISK_file_close (dc->rfh); | ||
2049 | dc->rfh = NULL; | ||
2050 | } | ||
2051 | return; /* finished, status update was already done for us */ | ||
2052 | } | ||
2053 | } | ||
2054 | if (dc->rfh != NULL) | ||
2055 | { | 1869 | { |
2056 | /* finally, try bottom-up */ | 1870 | if (dc->rfh != NULL) |
1871 | { | ||
1872 | /* avoid hanging on to file handle longer than | ||
1873 | * necessary */ | ||
1874 | GNUNET_DISK_file_close (dc->rfh); | ||
1875 | dc->rfh = NULL; | ||
1876 | } | ||
1877 | return; /* finished, status update was already done for us */ | ||
1878 | } | ||
1879 | } | ||
1880 | if (dc->rfh != NULL) | ||
1881 | { | ||
1882 | /* finally, try bottom-up */ | ||
2057 | #if DEBUG_DOWNLOAD | 1883 | #if DEBUG_DOWNLOAD |
2058 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1884 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2059 | "Trying bottom-up reconstruction of file `%s'\n", | 1885 | "Trying bottom-up reconstruction of file `%s'\n", dc->filename); |
2060 | dc->filename); | ||
2061 | #endif | 1886 | #endif |
2062 | dc->te = GNUNET_FS_tree_encoder_create (dc->h, | 1887 | dc->te = GNUNET_FS_tree_encoder_create (dc->h, |
2063 | dc->old_file_size, | 1888 | dc->old_file_size, |
2064 | dc, | 1889 | dc, |
2065 | &fh_reader, | 1890 | &fh_reader, |
2066 | &reconstruct_cb, | 1891 | &reconstruct_cb, |
2067 | NULL, | 1892 | NULL, &reconstruct_cont); |
2068 | &reconstruct_cont); | 1893 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); |
2069 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, | 1894 | } |
2070 | dc); | ||
2071 | } | ||
2072 | else | 1895 | else |
2073 | { | 1896 | { |
2074 | /* simple, top-level download */ | 1897 | /* simple, top-level download */ |
2075 | schedule_block_download (dc, | 1898 | schedule_block_download (dc, dc->top_request); |
2076 | dc->top_request); | 1899 | } |
2077 | } | ||
2078 | if (dc->top_request->state == BRS_DOWNLOAD_UP) | 1900 | if (dc->top_request->state == BRS_DOWNLOAD_UP) |
2079 | check_completed (dc); | 1901 | check_completed (dc); |
2080 | } | 1902 | } |
@@ -2095,44 +1917,43 @@ GNUNET_FS_download_signal_suspend_ (void *cls) | |||
2095 | if (dc->top != NULL) | 1917 | if (dc->top != NULL) |
2096 | GNUNET_FS_end_top (dc->h, dc->top); | 1918 | GNUNET_FS_end_top (dc->h, dc->top); |
2097 | while (NULL != dc->child_head) | 1919 | while (NULL != dc->child_head) |
2098 | GNUNET_FS_download_signal_suspend_ (dc->child_head); | 1920 | GNUNET_FS_download_signal_suspend_ (dc->child_head); |
2099 | if (dc->search != NULL) | 1921 | if (dc->search != NULL) |
2100 | { | 1922 | { |
2101 | dc->search->download = NULL; | 1923 | dc->search->download = NULL; |
2102 | dc->search = NULL; | 1924 | dc->search = NULL; |
2103 | } | 1925 | } |
2104 | if (dc->job_queue != NULL) | 1926 | if (dc->job_queue != NULL) |
2105 | { | 1927 | { |
2106 | GNUNET_FS_dequeue_ (dc->job_queue); | 1928 | GNUNET_FS_dequeue_ (dc->job_queue); |
2107 | dc->job_queue = NULL; | 1929 | dc->job_queue = NULL; |
2108 | } | 1930 | } |
2109 | if (dc->parent != NULL) | 1931 | if (dc->parent != NULL) |
2110 | GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, | 1932 | GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, |
2111 | dc->parent->child_tail, | 1933 | dc->parent->child_tail, dc); |
2112 | dc); | ||
2113 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) | 1934 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) |
2114 | { | 1935 | { |
2115 | GNUNET_SCHEDULER_cancel (dc->task); | 1936 | GNUNET_SCHEDULER_cancel (dc->task); |
2116 | dc->task = GNUNET_SCHEDULER_NO_TASK; | 1937 | dc->task = GNUNET_SCHEDULER_NO_TASK; |
2117 | } | 1938 | } |
2118 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND; | 1939 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND; |
2119 | GNUNET_FS_download_make_status_ (&pi, dc); | 1940 | GNUNET_FS_download_make_status_ (&pi, dc); |
2120 | if (dc->te != NULL) | 1941 | if (dc->te != NULL) |
2121 | { | 1942 | { |
2122 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); | 1943 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); |
2123 | dc->te = NULL; | 1944 | dc->te = NULL; |
2124 | } | 1945 | } |
2125 | if (dc->rfh != NULL) | 1946 | if (dc->rfh != NULL) |
2126 | { | 1947 | { |
2127 | GNUNET_DISK_file_close (dc->rfh); | 1948 | GNUNET_DISK_file_close (dc->rfh); |
2128 | dc->rfh = NULL; | 1949 | dc->rfh = NULL; |
2129 | } | 1950 | } |
2130 | GNUNET_FS_free_download_request_ (dc->top_request); | 1951 | GNUNET_FS_free_download_request_ (dc->top_request); |
2131 | if (dc->active != NULL) | 1952 | if (dc->active != NULL) |
2132 | { | 1953 | { |
2133 | GNUNET_CONTAINER_multihashmap_destroy (dc->active); | 1954 | GNUNET_CONTAINER_multihashmap_destroy (dc->active); |
2134 | dc->active = NULL; | 1955 | dc->active = NULL; |
2135 | } | 1956 | } |
2136 | GNUNET_free_non_null (dc->filename); | 1957 | GNUNET_free_non_null (dc->filename); |
2137 | GNUNET_CONTAINER_meta_data_destroy (dc->meta); | 1958 | GNUNET_CONTAINER_meta_data_destroy (dc->meta); |
2138 | GNUNET_FS_uri_destroy (dc->uri); | 1959 | GNUNET_FS_uri_destroy (dc->uri); |
@@ -2174,87 +1995,77 @@ GNUNET_FS_download_signal_suspend_ (void *cls) | |||
2174 | */ | 1995 | */ |
2175 | struct GNUNET_FS_DownloadContext * | 1996 | struct GNUNET_FS_DownloadContext * |
2176 | GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | 1997 | GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, |
2177 | const struct GNUNET_FS_Uri *uri, | 1998 | const struct GNUNET_FS_Uri *uri, |
2178 | const struct GNUNET_CONTAINER_MetaData *meta, | 1999 | const struct GNUNET_CONTAINER_MetaData *meta, |
2179 | const char *filename, | 2000 | const char *filename, |
2180 | const char *tempname, | 2001 | const char *tempname, |
2181 | uint64_t offset, | 2002 | uint64_t offset, |
2182 | uint64_t length, | 2003 | uint64_t length, |
2183 | uint32_t anonymity, | 2004 | uint32_t anonymity, |
2184 | enum GNUNET_FS_DownloadOptions options, | 2005 | enum GNUNET_FS_DownloadOptions options, |
2185 | void *cctx, | 2006 | void *cctx, struct GNUNET_FS_DownloadContext *parent) |
2186 | struct GNUNET_FS_DownloadContext *parent) | ||
2187 | { | 2007 | { |
2188 | struct GNUNET_FS_DownloadContext *dc; | 2008 | struct GNUNET_FS_DownloadContext *dc; |
2189 | 2009 | ||
2190 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || | 2010 | GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri)); |
2191 | GNUNET_FS_uri_test_loc (uri) ); | 2011 | |
2192 | 2012 | if ((offset + length < offset) || | |
2193 | if ( (offset + length < offset) || | 2013 | (offset + length > GNUNET_FS_uri_chk_get_file_size (uri))) |
2194 | (offset + length > GNUNET_FS_uri_chk_get_file_size (uri)) ) | 2014 | { |
2195 | { | 2015 | GNUNET_break (0); |
2196 | GNUNET_break (0); | 2016 | return NULL; |
2197 | return NULL; | 2017 | } |
2198 | } | ||
2199 | #if DEBUG_DOWNLOAD | 2018 | #if DEBUG_DOWNLOAD |
2200 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2019 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2201 | "Starting download `%s' of %llu bytes\n", | 2020 | "Starting download `%s' of %llu bytes\n", |
2202 | filename, | 2021 | filename, (unsigned long long) length); |
2203 | (unsigned long long) length); | ||
2204 | #endif | 2022 | #endif |
2205 | dc = GNUNET_malloc (sizeof(struct GNUNET_FS_DownloadContext)); | 2023 | dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); |
2206 | dc->h = h; | 2024 | dc->h = h; |
2207 | dc->parent = parent; | 2025 | dc->parent = parent; |
2208 | if (parent != NULL) | 2026 | if (parent != NULL) |
2209 | { | 2027 | { |
2210 | GNUNET_CONTAINER_DLL_insert (parent->child_head, | 2028 | GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); |
2211 | parent->child_tail, | 2029 | } |
2212 | dc); | ||
2213 | } | ||
2214 | dc->uri = GNUNET_FS_uri_dup (uri); | 2030 | dc->uri = GNUNET_FS_uri_dup (uri); |
2215 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); | 2031 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); |
2216 | dc->client_info = cctx; | 2032 | dc->client_info = cctx; |
2217 | dc->start_time = GNUNET_TIME_absolute_get (); | 2033 | dc->start_time = GNUNET_TIME_absolute_get (); |
2218 | if (NULL != filename) | 2034 | if (NULL != filename) |
2219 | { | 2035 | { |
2220 | dc->filename = GNUNET_strdup (filename); | 2036 | dc->filename = GNUNET_strdup (filename); |
2221 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | 2037 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) |
2222 | GNUNET_DISK_file_size (filename, | 2038 | GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES); |
2223 | &dc->old_file_size, | 2039 | } |
2224 | GNUNET_YES); | ||
2225 | } | ||
2226 | if (GNUNET_FS_uri_test_loc (dc->uri)) | 2040 | if (GNUNET_FS_uri_test_loc (dc->uri)) |
2227 | GNUNET_assert (GNUNET_OK == | 2041 | GNUNET_assert (GNUNET_OK == |
2228 | GNUNET_FS_uri_loc_get_peer_identity (dc->uri, | 2042 | GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target)); |
2229 | &dc->target)); | ||
2230 | dc->offset = offset; | 2043 | dc->offset = offset; |
2231 | dc->length = length; | 2044 | dc->length = length; |
2232 | dc->anonymity = anonymity; | 2045 | dc->anonymity = anonymity; |
2233 | dc->options = options; | 2046 | dc->options = options; |
2234 | dc->active = GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); | 2047 | dc->active = |
2235 | dc->treedepth = GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size(dc->uri)); | 2048 | GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); |
2236 | if ( (filename == NULL) && | 2049 | dc->treedepth = |
2237 | (is_recursive_download (dc) ) ) | 2050 | GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); |
2238 | { | 2051 | if ((filename == NULL) && (is_recursive_download (dc))) |
2239 | if (tempname != NULL) | 2052 | { |
2240 | dc->temp_filename = GNUNET_strdup (tempname); | 2053 | if (tempname != NULL) |
2241 | else | 2054 | dc->temp_filename = GNUNET_strdup (tempname); |
2242 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); | 2055 | else |
2243 | } | 2056 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); |
2057 | } | ||
2244 | 2058 | ||
2245 | #if DEBUG_DOWNLOAD | 2059 | #if DEBUG_DOWNLOAD |
2246 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2060 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2247 | "Download tree has depth %u\n", | 2061 | "Download tree has depth %u\n", dc->treedepth); |
2248 | dc->treedepth); | ||
2249 | #endif | 2062 | #endif |
2250 | if (parent == NULL) | 2063 | if (parent == NULL) |
2251 | { | 2064 | { |
2252 | dc->top = GNUNET_FS_make_top (dc->h, | 2065 | dc->top = GNUNET_FS_make_top (dc->h, |
2253 | &GNUNET_FS_download_signal_suspend_, | 2066 | &GNUNET_FS_download_signal_suspend_, dc); |
2254 | dc); | 2067 | } |
2255 | } | 2068 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); |
2256 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, | ||
2257 | dc); | ||
2258 | return dc; | 2069 | return dc; |
2259 | } | 2070 | } |
2260 | 2071 | ||
@@ -2295,85 +2106,79 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, | |||
2295 | */ | 2106 | */ |
2296 | struct GNUNET_FS_DownloadContext * | 2107 | struct GNUNET_FS_DownloadContext * |
2297 | GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, | 2108 | GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, |
2298 | struct GNUNET_FS_SearchResult *sr, | 2109 | struct GNUNET_FS_SearchResult *sr, |
2299 | const char *filename, | 2110 | const char *filename, |
2300 | const char *tempname, | 2111 | const char *tempname, |
2301 | uint64_t offset, | 2112 | uint64_t offset, |
2302 | uint64_t length, | 2113 | uint64_t length, |
2303 | uint32_t anonymity, | 2114 | uint32_t anonymity, |
2304 | enum GNUNET_FS_DownloadOptions options, | 2115 | enum GNUNET_FS_DownloadOptions options, |
2305 | void *cctx) | 2116 | void *cctx) |
2306 | { | 2117 | { |
2307 | struct GNUNET_FS_DownloadContext *dc; | 2118 | struct GNUNET_FS_DownloadContext *dc; |
2308 | 2119 | ||
2309 | if ( (sr == NULL) || | 2120 | if ((sr == NULL) || (sr->download != NULL)) |
2310 | (sr->download != NULL) ) | 2121 | { |
2311 | { | 2122 | GNUNET_break (0); |
2312 | GNUNET_break (0); | 2123 | return NULL; |
2313 | return NULL; | 2124 | } |
2314 | } | ||
2315 | GNUNET_assert (GNUNET_FS_uri_test_chk (sr->uri) || | 2125 | GNUNET_assert (GNUNET_FS_uri_test_chk (sr->uri) || |
2316 | GNUNET_FS_uri_test_loc (sr->uri) ); | 2126 | GNUNET_FS_uri_test_loc (sr->uri)); |
2317 | if ( (offset + length < offset) || | 2127 | if ((offset + length < offset) || |
2318 | (offset + length > sr->uri->data.chk.file_length) ) | 2128 | (offset + length > sr->uri->data.chk.file_length)) |
2319 | { | 2129 | { |
2320 | GNUNET_break (0); | 2130 | GNUNET_break (0); |
2321 | return NULL; | 2131 | return NULL; |
2322 | } | 2132 | } |
2323 | #if DEBUG_DOWNLOAD | 2133 | #if DEBUG_DOWNLOAD |
2324 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2134 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2325 | "Starting download `%s' of %llu bytes\n", | 2135 | "Starting download `%s' of %llu bytes\n", |
2326 | filename, | 2136 | filename, (unsigned long long) length); |
2327 | (unsigned long long) length); | ||
2328 | #endif | 2137 | #endif |
2329 | dc = GNUNET_malloc (sizeof(struct GNUNET_FS_DownloadContext)); | 2138 | dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); |
2330 | dc->h = h; | 2139 | dc->h = h; |
2331 | dc->search = sr; | 2140 | dc->search = sr; |
2332 | sr->download = dc; | 2141 | sr->download = dc; |
2333 | if (sr->probe_ctx != NULL) | 2142 | if (sr->probe_ctx != NULL) |
2334 | { | 2143 | { |
2335 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); | 2144 | GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); |
2336 | sr->probe_ctx = NULL; | 2145 | sr->probe_ctx = NULL; |
2337 | } | 2146 | } |
2338 | dc->uri = GNUNET_FS_uri_dup (sr->uri); | 2147 | dc->uri = GNUNET_FS_uri_dup (sr->uri); |
2339 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta); | 2148 | dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta); |
2340 | dc->client_info = cctx; | 2149 | dc->client_info = cctx; |
2341 | dc->start_time = GNUNET_TIME_absolute_get (); | 2150 | dc->start_time = GNUNET_TIME_absolute_get (); |
2342 | if (NULL != filename) | 2151 | if (NULL != filename) |
2343 | { | 2152 | { |
2344 | dc->filename = GNUNET_strdup (filename); | 2153 | dc->filename = GNUNET_strdup (filename); |
2345 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | 2154 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) |
2346 | GNUNET_DISK_file_size (filename, | 2155 | GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES); |
2347 | &dc->old_file_size, | 2156 | } |
2348 | GNUNET_YES); | ||
2349 | } | ||
2350 | if (GNUNET_FS_uri_test_loc (dc->uri)) | 2157 | if (GNUNET_FS_uri_test_loc (dc->uri)) |
2351 | GNUNET_assert (GNUNET_OK == | 2158 | GNUNET_assert (GNUNET_OK == |
2352 | GNUNET_FS_uri_loc_get_peer_identity (dc->uri, | 2159 | GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target)); |
2353 | &dc->target)); | ||
2354 | dc->offset = offset; | 2160 | dc->offset = offset; |
2355 | dc->length = length; | 2161 | dc->length = length; |
2356 | dc->anonymity = anonymity; | 2162 | dc->anonymity = anonymity; |
2357 | dc->options = options; | 2163 | dc->options = options; |
2358 | dc->active = GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); | 2164 | dc->active = |
2359 | dc->treedepth = GNUNET_FS_compute_depth (GNUNET_ntohll(dc->uri->data.chk.file_length)); | 2165 | GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); |
2360 | if ( (filename == NULL) && | 2166 | dc->treedepth = |
2361 | (is_recursive_download (dc) ) ) | 2167 | GNUNET_FS_compute_depth (GNUNET_ntohll (dc->uri->data.chk.file_length)); |
2362 | { | 2168 | if ((filename == NULL) && (is_recursive_download (dc))) |
2363 | if (tempname != NULL) | 2169 | { |
2364 | dc->temp_filename = GNUNET_strdup (tempname); | 2170 | if (tempname != NULL) |
2365 | else | 2171 | dc->temp_filename = GNUNET_strdup (tempname); |
2366 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); | 2172 | else |
2367 | } | 2173 | dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp"); |
2174 | } | ||
2368 | 2175 | ||
2369 | #if DEBUG_DOWNLOAD | 2176 | #if DEBUG_DOWNLOAD |
2370 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2177 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2371 | "Download tree has depth %u\n", | 2178 | "Download tree has depth %u\n", dc->treedepth); |
2372 | dc->treedepth); | ||
2373 | #endif | 2179 | #endif |
2374 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, | 2180 | dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc); |
2375 | dc); | 2181 | return dc; |
2376 | return dc; | ||
2377 | } | 2182 | } |
2378 | 2183 | ||
2379 | 2184 | ||
@@ -2388,11 +2193,12 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc) | |||
2388 | if (dc->completed == dc->length) | 2193 | if (dc->completed == dc->length) |
2389 | return; | 2194 | return; |
2390 | GNUNET_assert (dc->job_queue == NULL); | 2195 | GNUNET_assert (dc->job_queue == NULL); |
2391 | dc->job_queue = GNUNET_FS_queue_ (dc->h, | 2196 | dc->job_queue = GNUNET_FS_queue_ (dc->h, |
2392 | &activate_fs_download, | 2197 | &activate_fs_download, |
2393 | &deactivate_fs_download, | 2198 | &deactivate_fs_download, |
2394 | dc, | 2199 | dc, |
2395 | (dc->length + DBLOCK_SIZE-1) / DBLOCK_SIZE); | 2200 | (dc->length + DBLOCK_SIZE - |
2201 | 1) / DBLOCK_SIZE); | ||
2396 | } | 2202 | } |
2397 | 2203 | ||
2398 | 2204 | ||
@@ -2403,8 +2209,7 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc) | |||
2403 | * @param do_delete delete files of incomplete downloads | 2209 | * @param do_delete delete files of incomplete downloads |
2404 | */ | 2210 | */ |
2405 | void | 2211 | void |
2406 | GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, | 2212 | GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) |
2407 | int do_delete) | ||
2408 | { | 2213 | { |
2409 | struct GNUNET_FS_ProgressInfo pi; | 2214 | struct GNUNET_FS_ProgressInfo pi; |
2410 | int have_children; | 2215 | int have_children; |
@@ -2414,77 +2219,71 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, | |||
2414 | 2219 | ||
2415 | 2220 | ||
2416 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) | 2221 | if (dc->task != GNUNET_SCHEDULER_NO_TASK) |
2417 | { | 2222 | { |
2418 | GNUNET_SCHEDULER_cancel (dc->task); | 2223 | GNUNET_SCHEDULER_cancel (dc->task); |
2419 | dc->task = GNUNET_SCHEDULER_NO_TASK; | 2224 | dc->task = GNUNET_SCHEDULER_NO_TASK; |
2420 | } | 2225 | } |
2421 | if (dc->search != NULL) | 2226 | if (dc->search != NULL) |
2422 | { | 2227 | { |
2423 | dc->search->download = NULL; | 2228 | dc->search->download = NULL; |
2424 | dc->search = NULL; | 2229 | dc->search = NULL; |
2425 | } | 2230 | } |
2426 | if (dc->job_queue != NULL) | 2231 | if (dc->job_queue != NULL) |
2427 | { | 2232 | { |
2428 | GNUNET_FS_dequeue_ (dc->job_queue); | 2233 | GNUNET_FS_dequeue_ (dc->job_queue); |
2429 | dc->job_queue = NULL; | 2234 | dc->job_queue = NULL; |
2430 | } | 2235 | } |
2431 | if (dc->te != NULL) | 2236 | if (dc->te != NULL) |
2432 | { | 2237 | { |
2433 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); | 2238 | GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL); |
2434 | dc->te = NULL; | 2239 | dc->te = NULL; |
2435 | } | 2240 | } |
2436 | have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO; | 2241 | have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO; |
2437 | while (NULL != dc->child_head) | 2242 | while (NULL != dc->child_head) |
2438 | GNUNET_FS_download_stop (dc->child_head, | 2243 | GNUNET_FS_download_stop (dc->child_head, do_delete); |
2439 | do_delete); | ||
2440 | if (dc->parent != NULL) | 2244 | if (dc->parent != NULL) |
2441 | GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, | 2245 | GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, |
2442 | dc->parent->child_tail, | 2246 | dc->parent->child_tail, dc); |
2443 | dc); | ||
2444 | if (dc->serialization != NULL) | 2247 | if (dc->serialization != NULL) |
2445 | GNUNET_FS_remove_sync_file_ (dc->h, | 2248 | GNUNET_FS_remove_sync_file_ (dc->h, |
2446 | ( (dc->parent != NULL) || (dc->search != NULL) ) | 2249 | ((dc->parent != NULL) || (dc->search != NULL)) |
2447 | ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD | 2250 | ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD |
2448 | : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD , | 2251 | : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, |
2449 | dc->serialization); | 2252 | dc->serialization); |
2450 | if ( (GNUNET_YES == have_children) && | 2253 | if ((GNUNET_YES == have_children) && (dc->parent == NULL)) |
2451 | (dc->parent == NULL) ) | 2254 | GNUNET_FS_remove_sync_dir_ (dc->h, |
2452 | GNUNET_FS_remove_sync_dir_ (dc->h, | 2255 | (dc->search != NULL) |
2453 | (dc->search != NULL) | 2256 | ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD |
2454 | ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD | 2257 | : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, |
2455 | : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, | 2258 | dc->serialization); |
2456 | dc->serialization); | ||
2457 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; | 2259 | pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; |
2458 | GNUNET_FS_download_make_status_ (&pi, dc); | 2260 | GNUNET_FS_download_make_status_ (&pi, dc); |
2459 | GNUNET_FS_free_download_request_ (dc->top_request); | 2261 | GNUNET_FS_free_download_request_ (dc->top_request); |
2460 | dc->top_request = NULL; | 2262 | dc->top_request = NULL; |
2461 | if (dc->active != NULL) | 2263 | if (dc->active != NULL) |
2462 | { | 2264 | { |
2463 | GNUNET_CONTAINER_multihashmap_destroy (dc->active); | 2265 | GNUNET_CONTAINER_multihashmap_destroy (dc->active); |
2464 | dc->active = NULL; | 2266 | dc->active = NULL; |
2465 | } | 2267 | } |
2466 | if (dc->filename != NULL) | 2268 | if (dc->filename != NULL) |
2269 | { | ||
2270 | if ((dc->completed != dc->length) && (GNUNET_YES == do_delete)) | ||
2467 | { | 2271 | { |
2468 | if ( (dc->completed != dc->length) && | 2272 | if (0 != UNLINK (dc->filename)) |
2469 | (GNUNET_YES == do_delete) ) | 2273 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
2470 | { | 2274 | "unlink", dc->filename); |
2471 | if (0 != UNLINK (dc->filename)) | ||
2472 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
2473 | "unlink", | ||
2474 | dc->filename); | ||
2475 | } | ||
2476 | GNUNET_free (dc->filename); | ||
2477 | } | 2275 | } |
2276 | GNUNET_free (dc->filename); | ||
2277 | } | ||
2478 | GNUNET_CONTAINER_meta_data_destroy (dc->meta); | 2278 | GNUNET_CONTAINER_meta_data_destroy (dc->meta); |
2479 | GNUNET_FS_uri_destroy (dc->uri); | 2279 | GNUNET_FS_uri_destroy (dc->uri); |
2480 | if (NULL != dc->temp_filename) | 2280 | if (NULL != dc->temp_filename) |
2481 | { | 2281 | { |
2482 | if (0 != UNLINK (dc->temp_filename)) | 2282 | if (0 != UNLINK (dc->temp_filename)) |
2483 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | 2283 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
2484 | "unlink", | 2284 | "unlink", dc->temp_filename); |
2485 | dc->temp_filename); | 2285 | GNUNET_free (dc->temp_filename); |
2486 | GNUNET_free (dc->temp_filename); | 2286 | } |
2487 | } | ||
2488 | GNUNET_free_non_null (dc->serialization); | 2287 | GNUNET_free_non_null (dc->serialization); |
2489 | GNUNET_free (dc); | 2288 | GNUNET_free (dc); |
2490 | } | 2289 | } |