diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-28 15:08:13 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-28 15:08:13 +0000 |
commit | 7d9840a0500c6e8820506e3de587c5d1fd945cec (patch) | |
tree | 1e518f6303af98fbaa39e228b3ae1b498f5abea1 /src/fs | |
parent | 6893f9fb1ae5f4569d2207e4fbf4f38cc4e849f6 (diff) | |
download | gnunet-7d9840a0500c6e8820506e3de587c5d1fd945cec.tar.gz gnunet-7d9840a0500c6e8820506e3de587c5d1fd945cec.zip |
first work on serialization
Diffstat (limited to 'src/fs')
-rw-r--r-- | src/fs/fs.c | 350 | ||||
-rw-r--r-- | src/fs/fs.h | 73 | ||||
-rw-r--r-- | src/fs/fs_file_information.c | 1 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 162 |
4 files changed, 464 insertions, 122 deletions
diff --git a/src/fs/fs.c b/src/fs/fs.c index 6dbc182b7..7577a8130 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_fs_service.h" | 29 | #include "gnunet_fs_service.h" |
29 | #include "fs.h" | 30 | #include "fs.h" |
30 | 31 | ||
@@ -145,6 +146,7 @@ process_job_queue (void *cls, | |||
145 | h); | 146 | h); |
146 | } | 147 | } |
147 | 148 | ||
149 | |||
148 | /** | 150 | /** |
149 | * Add a job to the queue. | 151 | * Add a job to the queue. |
150 | * | 152 | * |
@@ -213,6 +215,318 @@ GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) | |||
213 | 215 | ||
214 | 216 | ||
215 | /** | 217 | /** |
218 | * Return the full filename where we would store state information | ||
219 | * (for serialization/deserialization). | ||
220 | * | ||
221 | * @param h master context | ||
222 | * @param ext component of the path | ||
223 | * @param ent entity identifier (or emtpy string for the directory) | ||
224 | * @return NULL on error | ||
225 | */ | ||
226 | static char * | ||
227 | get_serialization_file_name (struct GNUNET_FS_Handle *h, | ||
228 | const char *ext, | ||
229 | const char *ent) | ||
230 | { | ||
231 | char *basename; | ||
232 | char *ret; | ||
233 | if (GNUNET_OK != | ||
234 | GNUNET_CONFIGURATION_get_value_filename (h->cfg, | ||
235 | "fs", | ||
236 | "STATE_DIR", | ||
237 | &basename)) | ||
238 | return NULL; | ||
239 | GNUNET_asprintf (&ret, | ||
240 | "%s%s%s-%s%s%s", | ||
241 | basename, | ||
242 | DIR_SEPARATOR_STR, | ||
243 | h->client_name, | ||
244 | ext, | ||
245 | DIR_SEPARATOR_STR, | ||
246 | ent); | ||
247 | GNUNET_free (basename); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | |||
252 | /** | ||
253 | * Return a read handle for deserialization. | ||
254 | * | ||
255 | * @param h master context | ||
256 | * @param ext component of the path | ||
257 | * @param ent entity identifier (or emtpy string for the directory) | ||
258 | * @return NULL on error | ||
259 | */ | ||
260 | static struct GNUNET_BIO_ReadHandle * | ||
261 | get_read_handle (struct GNUNET_FS_Handle *h, | ||
262 | const char *ext, | ||
263 | const char *ent) | ||
264 | { | ||
265 | char *fn; | ||
266 | struct GNUNET_BIO_ReadHandle *ret; | ||
267 | |||
268 | fn = get_serialization_file_name (h, ext, ent); | ||
269 | if (fn == NULL) | ||
270 | return NULL; | ||
271 | ret = GNUNET_BIO_read_open (fn); | ||
272 | GNUNET_free (fn); | ||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Using the given serialization filename, try to deserialize | ||
279 | * the file-information tree associated with it. | ||
280 | * | ||
281 | * @param h master context | ||
282 | * @param filename name of the file (without directory) with | ||
283 | * the infromation | ||
284 | * @return NULL on error | ||
285 | */ | ||
286 | static struct GNUNET_FS_FileInformation * | ||
287 | deserialize_file_information (struct GNUNET_FS_Handle *h, | ||
288 | const char *filename) | ||
289 | { | ||
290 | struct GNUNET_FS_FileInformation *ret; | ||
291 | struct GNUNET_BIO_ReadHandle *rh; | ||
292 | char *emsg; | ||
293 | |||
294 | rh = get_read_handle (h, "publish-fi", filename); | ||
295 | if (rh == NULL) | ||
296 | return NULL; | ||
297 | |||
298 | ret = NULL; | ||
299 | |||
300 | |||
301 | if (GNUNET_OK != | ||
302 | GNUNET_BIO_read_close (rh, &emsg)) | ||
303 | { | ||
304 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
305 | _("Failed to resume publishing information `%s': %s\n"), | ||
306 | filename, | ||
307 | emsg); | ||
308 | GNUNET_free (emsg); | ||
309 | } | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | |||
314 | /** | ||
315 | * Find the entry in the file information struct where the | ||
316 | * serialization filename matches the given name. | ||
317 | * | ||
318 | * @param pos file information to search | ||
319 | * @param srch filename to search for | ||
320 | * @return NULL if srch was not found in this subtree | ||
321 | */ | ||
322 | static struct GNUNET_FS_FileInformation * | ||
323 | find_file_position (struct GNUNET_FS_FileInformation *pos, | ||
324 | const char *srch) | ||
325 | { | ||
326 | struct GNUNET_FS_FileInformation *r; | ||
327 | |||
328 | while (pos != NULL) | ||
329 | { | ||
330 | if (0 == strcmp (srch, | ||
331 | pos->serialization_name)) | ||
332 | return pos; | ||
333 | if (pos->is_directory) | ||
334 | { | ||
335 | r = find_file_position (pos->data.dir.entries, | ||
336 | srch); | ||
337 | if (r != NULL) | ||
338 | return r; | ||
339 | } | ||
340 | pos = pos->next; | ||
341 | } | ||
342 | return NULL; | ||
343 | } | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Signal the FS's progress function that we are resuming | ||
348 | * an upload. | ||
349 | * | ||
350 | * @param cls closure (of type "struct GNUNET_FS_PublishContext*") | ||
351 | * @param fi the entry in the publish-structure | ||
352 | * @param length length of the file or directory | ||
353 | * @param meta metadata for the file or directory (can be modified) | ||
354 | * @param uri pointer to the keywords that will be used for this entry (can be modified) | ||
355 | * @param anonymity pointer to selected anonymity level (can be modified) | ||
356 | * @param priority pointer to selected priority (can be modified) | ||
357 | * @param expirationTime pointer to selected expiration time (can be modified) | ||
358 | * @param client_info pointer to client context set upon creation (can be modified) | ||
359 | * @return GNUNET_OK to continue (always) | ||
360 | */ | ||
361 | static int | ||
362 | fip_signal_resume(void *cls, | ||
363 | struct GNUNET_FS_FileInformation *fi, | ||
364 | uint64_t length, | ||
365 | struct GNUNET_CONTAINER_MetaData *meta, | ||
366 | struct GNUNET_FS_Uri **uri, | ||
367 | uint32_t *anonymity, | ||
368 | uint32_t *priority, | ||
369 | struct GNUNET_TIME_Absolute *expirationTime, | ||
370 | void **client_info) | ||
371 | { | ||
372 | struct GNUNET_FS_PublishContext *sc = cls; | ||
373 | struct GNUNET_FS_ProgressInfo pi; | ||
374 | |||
375 | pi.status = GNUNET_FS_STATUS_PUBLISH_RESUME; | ||
376 | pi.value.publish.specifics.resume.message = sc->fi->emsg; | ||
377 | pi.value.publish.specifics.resume.chk_uri = sc->fi->chk_uri; | ||
378 | *client_info = GNUNET_FS_publish_make_status_ (&pi, sc, fi, 0); | ||
379 | return GNUNET_OK; | ||
380 | } | ||
381 | |||
382 | |||
383 | /** | ||
384 | * Function called with a filename of serialized publishing operation | ||
385 | * to deserialize. | ||
386 | * | ||
387 | * @param cls the 'struct GNUNET_FS_Handle*' | ||
388 | * @param filename complete filename (absolute path) | ||
389 | * @return GNUNET_OK (continue to iterate) | ||
390 | */ | ||
391 | static int | ||
392 | deserialize_publish_file (void *cls, | ||
393 | const char *filename) | ||
394 | { | ||
395 | struct GNUNET_FS_Handle *h = cls; | ||
396 | struct GNUNET_BIO_ReadHandle *rh; | ||
397 | struct GNUNET_FS_PublishContext *pc; | ||
398 | int32_t options; | ||
399 | int32_t all_done; | ||
400 | char *fi_root; | ||
401 | char *ns; | ||
402 | char *fi_pos; | ||
403 | char *emsg; | ||
404 | |||
405 | rh = GNUNET_BIO_read_open (filename); | ||
406 | if (rh == NULL) | ||
407 | { | ||
408 | if (0 != UNLINK (filename)) | ||
409 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
410 | "unlink", | ||
411 | filename); | ||
412 | return GNUNET_OK; | ||
413 | } | ||
414 | while (1) | ||
415 | { | ||
416 | fi_root = NULL; | ||
417 | fi_pos = NULL; | ||
418 | ns = NULL; | ||
419 | pc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); | ||
420 | pc->h = h; | ||
421 | if ( (GNUNET_OK != | ||
422 | GNUNET_BIO_read_string (rh, "publish-nid", &pc->nid, 1024)) || | ||
423 | (GNUNET_OK != | ||
424 | GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) || | ||
425 | (GNUNET_OK != | ||
426 | GNUNET_BIO_read_int32 (rh, &options)) || | ||
427 | (GNUNET_OK != | ||
428 | GNUNET_BIO_read_int32 (rh, &all_done)) || | ||
429 | (GNUNET_OK != | ||
430 | GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) || | ||
431 | (GNUNET_OK != | ||
432 | GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) || | ||
433 | (GNUNET_OK != | ||
434 | GNUNET_BIO_read_string (rh, "publish-ns", &ns, 1024)) ) | ||
435 | { | ||
436 | GNUNET_free_non_null (pc->nid); | ||
437 | GNUNET_free_non_null (pc->nuid); | ||
438 | GNUNET_free_non_null (fi_root); | ||
439 | GNUNET_free_non_null (ns); | ||
440 | GNUNET_free (pc); | ||
441 | break; | ||
442 | } | ||
443 | pc->options = options; | ||
444 | pc->all_done = all_done; | ||
445 | pc->fi = deserialize_file_information (h, fi_root); | ||
446 | if (pc->fi == NULL) | ||
447 | { | ||
448 | GNUNET_free_non_null (pc->nid); | ||
449 | GNUNET_free_non_null (pc->nuid); | ||
450 | GNUNET_free_non_null (fi_root); | ||
451 | GNUNET_free_non_null (ns); | ||
452 | GNUNET_free (pc); | ||
453 | continue; | ||
454 | } | ||
455 | if (ns != NULL) | ||
456 | { | ||
457 | pc->namespace = GNUNET_FS_namespace_create (h, ns); | ||
458 | if (pc->namespace == NULL) | ||
459 | { | ||
460 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
461 | _("Failed to recover namespace `%s', cannot resume publishing operation.\n"), | ||
462 | ns); | ||
463 | GNUNET_free_non_null (pc->nid); | ||
464 | GNUNET_free_non_null (pc->nuid); | ||
465 | GNUNET_free_non_null (fi_root); | ||
466 | GNUNET_free_non_null (ns); | ||
467 | GNUNET_free (pc); | ||
468 | continue; | ||
469 | } | ||
470 | } | ||
471 | if (fi_pos != NULL) | ||
472 | { | ||
473 | pc->fi_pos = find_file_position (pc->fi, | ||
474 | fi_pos); | ||
475 | GNUNET_free (fi_pos); | ||
476 | if (pc->fi_pos == NULL) | ||
477 | { | ||
478 | /* failed to find position for resuming, outch! Will start from root! */ | ||
479 | GNUNET_break (0); | ||
480 | if (pc->all_done != GNUNET_YES) | ||
481 | pc->fi_pos = pc->fi; | ||
482 | } | ||
483 | } | ||
484 | pc->serialization = GNUNET_strdup (filename); | ||
485 | /* generate RESUME event(s) */ | ||
486 | GNUNET_FS_file_information_inspect (pc->fi, | ||
487 | &fip_signal_resume, | ||
488 | pc); | ||
489 | |||
490 | /* re-start publishing (if needed)... */ | ||
491 | if (pc->all_done != GNUNET_YES) | ||
492 | pc->upload_task | ||
493 | = GNUNET_SCHEDULER_add_with_priority (h->sched, | ||
494 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | ||
495 | &GNUNET_FS_publish_main_, | ||
496 | pc); | ||
497 | } | ||
498 | if (GNUNET_OK != | ||
499 | GNUNET_BIO_read_close (rh, &emsg)) | ||
500 | { | ||
501 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
502 | _("Failed to resume publishing operation `%s': %s\n"), | ||
503 | filename, | ||
504 | emsg); | ||
505 | GNUNET_free (emsg); | ||
506 | } | ||
507 | return GNUNET_OK; | ||
508 | } | ||
509 | |||
510 | |||
511 | /** | ||
512 | * Deserialize information about pending publish operations. | ||
513 | * | ||
514 | * @param h master context | ||
515 | */ | ||
516 | static void | ||
517 | deserialize_publish (struct GNUNET_FS_Handle *h) | ||
518 | { | ||
519 | char *dn; | ||
520 | |||
521 | dn = get_serialization_file_name (h, "publish", ""); | ||
522 | if (dn == NULL) | ||
523 | return; | ||
524 | GNUNET_DISK_directory_scan (dn, &deserialize_publish_file, h); | ||
525 | GNUNET_free (dn); | ||
526 | } | ||
527 | |||
528 | |||
529 | /** | ||
216 | * Setup a connection to the file-sharing service. | 530 | * Setup a connection to the file-sharing service. |
217 | * | 531 | * |
218 | * @param sched scheduler to use | 532 | * @param sched scheduler to use |
@@ -274,20 +588,21 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
274 | } | 588 | } |
275 | } | 589 | } |
276 | va_end (ap); | 590 | va_end (ap); |
277 | // FIXME: setup receive-loop with client | 591 | // FIXME: setup receive-loop with client (do we need one?) |
278 | 592 | ||
279 | // FIXME: deserialize state; use client-name to find master-directory! | 593 | if (0 != (GNUNET_FS_FLAGS_PERSISTENCE & flags)) |
280 | // Deserialize-Upload: | 594 | { |
281 | // * read FNs for upload FIs, deserialize each | 595 | deserialize_publish (ret); |
282 | // Deserialize Search: | 596 | // Deserialize Search: |
283 | // * read search queries | 597 | // * read search queries |
284 | // * for each query, read file with search results | 598 | // * for each query, read file with search results |
285 | // * for each search result with active download, deserialize download | 599 | // * for each search result with active download, deserialize download |
286 | // * for each directory search result, check for active downloads of contents | 600 | // * for each directory search result, check for active downloads of contents |
287 | // Deserialize Download: | 601 | // Deserialize Download: |
288 | // * always part of search??? | 602 | // * always part of search??? |
289 | // Deserialize Unindex: | 603 | // Deserialize Unindex: |
290 | // * read FNs for unindex with progress offset | 604 | // * read FNs for unindex with progress offset |
605 | } | ||
291 | return ret; | 606 | return ret; |
292 | } | 607 | } |
293 | 608 | ||
@@ -302,8 +617,11 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
302 | void | 617 | void |
303 | GNUNET_FS_stop (struct GNUNET_FS_Handle *h) | 618 | GNUNET_FS_stop (struct GNUNET_FS_Handle *h) |
304 | { | 619 | { |
305 | // FIXME: serialize state!? (or is it always serialized???) | 620 | if (0 != (GNUNET_FS_FLAGS_PERSISTENCE & h->flags)) |
306 | // FIXME: terminate receive-loop with client | 621 | { |
622 | // FIXME: generate SUSPEND events and clean up state! | ||
623 | } | ||
624 | // FIXME: terminate receive-loop with client (do we need one?) | ||
307 | if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) | 625 | if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) |
308 | GNUNET_SCHEDULER_cancel (h->sched, | 626 | GNUNET_SCHEDULER_cancel (h->sched, |
309 | h->queue_job); | 627 | h->queue_job); |
diff --git a/src/fs/fs.h b/src/fs/fs.h index a6a12b9cd..8726deb6e 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -326,7 +326,8 @@ struct GNUNET_FS_FileInformation | |||
326 | 326 | ||
327 | /** | 327 | /** |
328 | * Under what filename is this struct serialized | 328 | * Under what filename is this struct serialized |
329 | * (for operational persistence). | 329 | * (for operational persistence). Should be determined |
330 | * using 'mktemp'. | ||
330 | */ | 331 | */ |
331 | char *serialization; | 332 | char *serialization; |
332 | 333 | ||
@@ -342,6 +343,12 @@ struct GNUNET_FS_FileInformation | |||
342 | char *emsg; | 343 | char *emsg; |
343 | 344 | ||
344 | /** | 345 | /** |
346 | * Filename on disk that is used to track the progress of this | ||
347 | * upload (short name, not the full path). | ||
348 | */ | ||
349 | char *serialization_name; | ||
350 | |||
351 | /** | ||
345 | * Data describing either the file or the directory. | 352 | * Data describing either the file or the directory. |
346 | */ | 353 | */ |
347 | union | 354 | union |
@@ -586,6 +593,32 @@ GNUNET_FS_search_probe_progress_ (void *cls, | |||
586 | const struct GNUNET_FS_ProgressInfo *info); | 593 | const struct GNUNET_FS_ProgressInfo *info); |
587 | 594 | ||
588 | 595 | ||
596 | /** | ||
597 | * Main function that performs the upload. | ||
598 | * | ||
599 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload | ||
600 | * @param tc task context | ||
601 | */ | ||
602 | void | ||
603 | GNUNET_FS_publish_main_ (void *cls, | ||
604 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
605 | |||
606 | |||
607 | /** | ||
608 | * Fill in all of the generic fields for a publish event and call the | ||
609 | * callback. | ||
610 | * | ||
611 | * @param pi structure to fill in | ||
612 | * @param sc overall publishing context | ||
613 | * @param p file information for the file being published | ||
614 | * @param offset where in the file are we so far | ||
615 | * @return value returned from callback | ||
616 | */ | ||
617 | void * | ||
618 | GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, | ||
619 | struct GNUNET_FS_PublishContext *sc, | ||
620 | const struct GNUNET_FS_FileInformation *p, | ||
621 | uint64_t offset); | ||
589 | 622 | ||
590 | /** | 623 | /** |
591 | * Master context for most FS operations. | 624 | * Master context for most FS operations. |
@@ -683,7 +716,7 @@ struct GNUNET_FS_Handle | |||
683 | 716 | ||
684 | 717 | ||
685 | /** | 718 | /** |
686 | * Handle for controlling an upload. | 719 | * Handle for controlling a publication process. |
687 | */ | 720 | */ |
688 | struct GNUNET_FS_PublishContext | 721 | struct GNUNET_FS_PublishContext |
689 | { | 722 | { |
@@ -713,15 +746,19 @@ struct GNUNET_FS_PublishContext | |||
713 | char *nuid; | 746 | char *nuid; |
714 | 747 | ||
715 | /** | 748 | /** |
716 | * Our own client handle for the FS service; | 749 | * Filename used for serializing information about this operation |
717 | * only briefly used when we start to index a | 750 | * (should be determined using 'mktemp'). |
718 | * file, otherwise NULL. | 751 | */ |
752 | char *serialization; | ||
753 | |||
754 | /** | ||
755 | * Our own client handle for the FS service; only briefly used when | ||
756 | * we start to index a file, otherwise NULL. | ||
719 | */ | 757 | */ |
720 | struct GNUNET_CLIENT_Connection *client; | 758 | struct GNUNET_CLIENT_Connection *client; |
721 | 759 | ||
722 | /** | 760 | /** |
723 | * Current position in the file-tree for the | 761 | * Current position in the file-tree for the upload. |
724 | * upload. | ||
725 | */ | 762 | */ |
726 | struct GNUNET_FS_FileInformation *fi_pos; | 763 | struct GNUNET_FS_FileInformation *fi_pos; |
727 | 764 | ||
@@ -731,23 +768,19 @@ struct GNUNET_FS_PublishContext | |||
731 | struct GNUNET_DATASTORE_Handle *dsh; | 768 | struct GNUNET_DATASTORE_Handle *dsh; |
732 | 769 | ||
733 | /** | 770 | /** |
734 | * ID of the task performing the upload. NO_TASK | 771 | * ID of the task performing the upload. NO_TASK if the upload has |
735 | * if the upload has completed. | 772 | * completed. |
736 | */ | 773 | */ |
737 | GNUNET_SCHEDULER_TaskIdentifier upload_task; | 774 | GNUNET_SCHEDULER_TaskIdentifier upload_task; |
738 | 775 | ||
739 | /** | 776 | /** |
740 | * Typically GNUNET_NO. Set to GNUNET_YES if | 777 | * Typically GNUNET_NO. Set to GNUNET_YES if "upload_task" is |
741 | * "upload_task" is GNUNET_SCHEDULER_NO_TASK | 778 | * GNUNET_SCHEDULER_NO_TASK and we're waiting for a response from |
742 | * and we're waiting for a response from the | 779 | * the datastore service (in which case this struct must not be |
743 | * datastore service (in which case this | 780 | * freed until we have that response). If someone tries to stop the |
744 | * struct must not be freed until we have that | 781 | * download for good during this period, "in_network_wait" is set to |
745 | * response). If someone tries to stop the | 782 | * GNUNET_SYSERR which will cause the struct to be destroyed right |
746 | * download for good during this period, | 783 | * after we have the reply (or timeout) from the datastore service. |
747 | * "in_network_wait" is set to GNUNET_SYSERR | ||
748 | * which will cause the struct to be destroyed | ||
749 | * right after we have the reply (or timeout) | ||
750 | * from the datastore service. | ||
751 | */ | 784 | */ |
752 | int in_network_wait; | 785 | int in_network_wait; |
753 | 786 | ||
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index fe20a3159..d1ab980e3 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c | |||
@@ -863,6 +863,7 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, | |||
863 | &fi->expirationTime, | 863 | &fi->expirationTime, |
864 | &fi->client_info); | 864 | &fi->client_info); |
865 | } | 865 | } |
866 | GNUNET_free_non_null (fi->serialization); | ||
866 | GNUNET_free_non_null (fi->emsg); | 867 | GNUNET_free_non_null (fi->emsg); |
867 | GNUNET_free_non_null (fi->chk_uri); | 868 | GNUNET_free_non_null (fi->chk_uri); |
868 | /* clean up serialization */ | 869 | /* clean up serialization */ |
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 1260d1c7c..f9970e409 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -42,15 +42,6 @@ | |||
42 | 42 | ||
43 | #define DEBUG_PUBLISH GNUNET_NO | 43 | #define DEBUG_PUBLISH GNUNET_NO |
44 | 44 | ||
45 | /** | ||
46 | * Main function that performs the upload. | ||
47 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload | ||
48 | * @param tc task context | ||
49 | */ | ||
50 | static void | ||
51 | do_upload (void *cls, | ||
52 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
53 | |||
54 | 45 | ||
55 | /** | 46 | /** |
56 | * Context for "ds_put_cont". | 47 | * Context for "ds_put_cont". |
@@ -81,18 +72,19 @@ struct PutContCtx | |||
81 | 72 | ||
82 | /** | 73 | /** |
83 | * Fill in all of the generic fields for | 74 | * Fill in all of the generic fields for |
84 | * a publish event. | 75 | * a publish event and call the callback. |
85 | * | 76 | * |
86 | * @param pi structure to fill in | 77 | * @param pi structure to fill in |
87 | * @param sc overall publishing context | 78 | * @param sc overall publishing context |
88 | * @param p file information for the file being published | 79 | * @param p file information for the file being published |
89 | * @param offset where in the file are we so far | 80 | * @param offset where in the file are we so far |
81 | * @return value returned from callback | ||
90 | */ | 82 | */ |
91 | static void | 83 | void * |
92 | make_publish_status (struct GNUNET_FS_ProgressInfo *pi, | 84 | GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, |
93 | struct GNUNET_FS_PublishContext *sc, | 85 | struct GNUNET_FS_PublishContext *sc, |
94 | const struct GNUNET_FS_FileInformation *p, | 86 | const struct GNUNET_FS_FileInformation *p, |
95 | uint64_t offset) | 87 | uint64_t offset) |
96 | { | 88 | { |
97 | pi->value.publish.sc = sc; | 89 | pi->value.publish.sc = sc; |
98 | pi->value.publish.fi = p; | 90 | pi->value.publish.fi = p; |
@@ -111,27 +103,29 @@ make_publish_status (struct GNUNET_FS_ProgressInfo *pi, | |||
111 | pi->value.publish.completed = offset; | 103 | pi->value.publish.completed = offset; |
112 | pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (p->start_time); | 104 | pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (p->start_time); |
113 | pi->value.publish.anonymity = p->anonymity; | 105 | pi->value.publish.anonymity = p->anonymity; |
106 | return sc->h->upcb (sc->h->upcb_cls, | ||
107 | pi); | ||
114 | } | 108 | } |
115 | 109 | ||
116 | 110 | ||
117 | /** | 111 | /** |
118 | * Cleanup the publish context, we're done | 112 | * Cleanup the publish context, we're done with it. |
119 | * with it. | ||
120 | * | 113 | * |
121 | * @param sc struct to clean up after | 114 | * @param pc struct to clean up after |
122 | */ | 115 | */ |
123 | static void | 116 | static void |
124 | publish_cleanup (struct GNUNET_FS_PublishContext *sc) | 117 | publish_cleanup (struct GNUNET_FS_PublishContext *pc) |
125 | { | 118 | { |
126 | GNUNET_FS_file_information_destroy (sc->fi, NULL, NULL); | 119 | GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); |
127 | if (sc->namespace != NULL) | 120 | if (pc->namespace != NULL) |
128 | GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO); | 121 | GNUNET_FS_namespace_delete (pc->namespace, GNUNET_NO); |
129 | GNUNET_free_non_null (sc->nid); | 122 | GNUNET_free_non_null (pc->nid); |
130 | GNUNET_free_non_null (sc->nuid); | 123 | GNUNET_free_non_null (pc->nuid); |
131 | GNUNET_DATASTORE_disconnect (sc->dsh, GNUNET_NO); | 124 | GNUNET_free_non_null (pc->serialization); |
132 | if (sc->client != NULL) | 125 | GNUNET_DATASTORE_disconnect (pc->dsh, GNUNET_NO); |
133 | GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); | 126 | if (pc->client != NULL) |
134 | GNUNET_free (sc); | 127 | GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); |
128 | GNUNET_free (pc); | ||
135 | } | 129 | } |
136 | 130 | ||
137 | 131 | ||
@@ -167,12 +161,9 @@ ds_put_cont (void *cls, | |||
167 | msg); | 161 | msg); |
168 | GNUNET_FS_file_information_sync (pcc->p); | 162 | GNUNET_FS_file_information_sync (pcc->p); |
169 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | 163 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; |
170 | make_publish_status (&pi, pcc->sc, pcc->p, 0); | ||
171 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | 164 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; |
172 | pi.value.publish.specifics.error.message = pcc->p->emsg; | 165 | pi.value.publish.specifics.error.message = pcc->p->emsg; |
173 | pcc->p->client_info | 166 | pcc->p->client_info = GNUNET_FS_publish_make_status_ (&pi, pcc->sc, pcc->p, 0); |
174 | = pcc->sc->h->upcb (pcc->sc->h->upcb_cls, | ||
175 | &pi); | ||
176 | } | 167 | } |
177 | GNUNET_FS_file_information_sync (pcc->p); | 168 | GNUNET_FS_file_information_sync (pcc->p); |
178 | if (NULL != pcc->cont) | 169 | if (NULL != pcc->cont) |
@@ -200,13 +191,10 @@ signal_publish_completion (struct GNUNET_FS_FileInformation *p, | |||
200 | struct GNUNET_FS_ProgressInfo pi; | 191 | struct GNUNET_FS_ProgressInfo pi; |
201 | 192 | ||
202 | pi.status = GNUNET_FS_STATUS_PUBLISH_COMPLETED; | 193 | pi.status = GNUNET_FS_STATUS_PUBLISH_COMPLETED; |
203 | make_publish_status (&pi, sc, p, | ||
204 | GNUNET_ntohll (p->chk_uri->data.chk.file_length)); | ||
205 | pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO; | 194 | pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO; |
206 | pi.value.publish.specifics.completed.chk_uri = p->chk_uri; | 195 | pi.value.publish.specifics.completed.chk_uri = p->chk_uri; |
207 | p->client_info | 196 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, |
208 | = sc->h->upcb (sc->h->upcb_cls, | 197 | GNUNET_ntohll (p->chk_uri->data.chk.file_length)); |
209 | &pi); | ||
210 | } | 198 | } |
211 | 199 | ||
212 | 200 | ||
@@ -228,12 +216,9 @@ signal_publish_error (struct GNUNET_FS_FileInformation *p, | |||
228 | 216 | ||
229 | p->emsg = GNUNET_strdup (emsg); | 217 | p->emsg = GNUNET_strdup (emsg); |
230 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | 218 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; |
231 | make_publish_status (&pi, sc, p, 0); | ||
232 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | 219 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; |
233 | pi.value.publish.specifics.error.message =emsg; | 220 | pi.value.publish.specifics.error.message =emsg; |
234 | p->client_info | 221 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); |
235 | = sc->h->upcb (sc->h->upcb_cls, | ||
236 | &pi); | ||
237 | } | 222 | } |
238 | 223 | ||
239 | 224 | ||
@@ -314,7 +299,7 @@ publish_kblocks_cont (void *cls, | |||
314 | sc->upload_task | 299 | sc->upload_task |
315 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, | 300 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, |
316 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | 301 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, |
317 | &do_upload, | 302 | &GNUNET_FS_publish_main_, |
318 | sc); | 303 | sc); |
319 | return; | 304 | return; |
320 | } | 305 | } |
@@ -329,7 +314,7 @@ publish_kblocks_cont (void *cls, | |||
329 | sc->upload_task | 314 | sc->upload_task |
330 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, | 315 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, |
331 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | 316 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, |
332 | &do_upload, | 317 | &GNUNET_FS_publish_main_, |
333 | sc); | 318 | sc); |
334 | } | 319 | } |
335 | 320 | ||
@@ -418,19 +403,16 @@ encode_cont (void *cls, | |||
418 | GNUNET_free (emsg); | 403 | GNUNET_free (emsg); |
419 | GNUNET_FS_file_information_sync (p); | 404 | GNUNET_FS_file_information_sync (p); |
420 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | 405 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; |
421 | make_publish_status (&pi, sc, p, 0); | ||
422 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | 406 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; |
423 | pi.value.publish.specifics.error.message = p->emsg; | 407 | pi.value.publish.specifics.error.message = p->emsg; |
424 | p->client_info | 408 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); |
425 | = sc->h->upcb (sc->h->upcb_cls, | ||
426 | &pi); | ||
427 | } | 409 | } |
428 | /* continue with main */ | 410 | /* continue with main */ |
429 | sc->upload_task | 411 | sc->upload_task |
430 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, | 412 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, |
431 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | 413 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, |
432 | &do_upload, | 414 | &GNUNET_FS_publish_main_, |
433 | sc); | 415 | sc); |
434 | } | 416 | } |
435 | 417 | ||
436 | 418 | ||
@@ -465,16 +447,16 @@ block_proc (void *cls, | |||
465 | { | 447 | { |
466 | sc->upload_task | 448 | sc->upload_task |
467 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, | 449 | = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, |
468 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | 450 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, |
469 | &do_upload, | 451 | &GNUNET_FS_publish_main_, |
470 | sc); | 452 | sc); |
471 | return; | 453 | return; |
472 | } | 454 | } |
473 | 455 | ||
474 | GNUNET_assert (GNUNET_NO == sc->in_network_wait); | 456 | GNUNET_assert (GNUNET_NO == sc->in_network_wait); |
475 | sc->in_network_wait = GNUNET_YES; | 457 | sc->in_network_wait = GNUNET_YES; |
476 | dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx)); | 458 | dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx)); |
477 | dpc_cls->cont = &do_upload; | 459 | dpc_cls->cont = &GNUNET_FS_publish_main_; |
478 | dpc_cls->cont_cls = sc; | 460 | dpc_cls->cont_cls = sc; |
479 | dpc_cls->sc = sc; | 461 | dpc_cls->sc = sc; |
480 | dpc_cls->p = p; | 462 | dpc_cls->p = p; |
@@ -550,14 +532,11 @@ progress_proc (void *cls, | |||
550 | 532 | ||
551 | p = sc->fi_pos; | 533 | p = sc->fi_pos; |
552 | pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; | 534 | pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; |
553 | make_publish_status (&pi, sc, p, offset); | ||
554 | pi.value.publish.specifics.progress.data = pt_block; | 535 | pi.value.publish.specifics.progress.data = pt_block; |
555 | pi.value.publish.specifics.progress.offset = offset; | 536 | pi.value.publish.specifics.progress.offset = offset; |
556 | pi.value.publish.specifics.progress.data_len = pt_size; | 537 | pi.value.publish.specifics.progress.data_len = pt_size; |
557 | pi.value.publish.specifics.progress.depth = depth; | 538 | pi.value.publish.specifics.progress.depth = depth; |
558 | p->client_info | 539 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, offset); |
559 | = sc->h->upcb (sc->h->upcb_cls, | ||
560 | &pi); | ||
561 | } | 540 | } |
562 | 541 | ||
563 | 542 | ||
@@ -800,12 +779,13 @@ hash_for_index_cb (void *cls, | |||
800 | 779 | ||
801 | /** | 780 | /** |
802 | * Main function that performs the upload. | 781 | * Main function that performs the upload. |
782 | * | ||
803 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload | 783 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload |
804 | * @param tc task context | 784 | * @param tc task context |
805 | */ | 785 | */ |
806 | static void | 786 | void |
807 | do_upload (void *cls, | 787 | GNUNET_FS_publish_main_ (void *cls, |
808 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 788 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
809 | { | 789 | { |
810 | struct GNUNET_FS_PublishContext *sc = cls; | 790 | struct GNUNET_FS_PublishContext *sc = cls; |
811 | struct GNUNET_FS_ProgressInfo pi; | 791 | struct GNUNET_FS_ProgressInfo pi; |
@@ -856,12 +836,9 @@ do_upload (void *cls, | |||
856 | } | 836 | } |
857 | GNUNET_FS_file_information_sync (p); | 837 | GNUNET_FS_file_information_sync (p); |
858 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | 838 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; |
859 | make_publish_status (&pi, sc, p, 0); | ||
860 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | 839 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; |
861 | pi.value.publish.specifics.error.message = p->emsg; | 840 | pi.value.publish.specifics.error.message = p->emsg; |
862 | p->client_info | 841 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); |
863 | = sc->h->upcb (sc->h->upcb_cls, | ||
864 | &pi); | ||
865 | } | 842 | } |
866 | sc->all_done = GNUNET_YES; | 843 | sc->all_done = GNUNET_YES; |
867 | return; | 844 | return; |
@@ -953,9 +930,7 @@ fip_signal_start(void *cls, | |||
953 | struct GNUNET_FS_ProgressInfo pi; | 930 | struct GNUNET_FS_ProgressInfo pi; |
954 | 931 | ||
955 | pi.status = GNUNET_FS_STATUS_PUBLISH_START; | 932 | pi.status = GNUNET_FS_STATUS_PUBLISH_START; |
956 | make_publish_status (&pi, sc, fi, 0); | 933 | *client_info = GNUNET_FS_publish_make_status_ (&pi, sc, fi, 0); |
957 | *client_info = sc->h->upcb (sc->h->upcb_cls, | ||
958 | &pi); | ||
959 | return GNUNET_OK; | 934 | return GNUNET_OK; |
960 | } | 935 | } |
961 | 936 | ||
@@ -1018,12 +993,12 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, | |||
1018 | 993 | ||
1019 | // FIXME: calculate space needed for "fi" | 994 | // FIXME: calculate space needed for "fi" |
1020 | // and reserve as first task (then trigger | 995 | // and reserve as first task (then trigger |
1021 | // "do_upload" from that continuation)! | 996 | // "publish_main" from that continuation)! |
1022 | ret->upload_task | 997 | ret->upload_task |
1023 | = GNUNET_SCHEDULER_add_with_priority (h->sched, | 998 | = GNUNET_SCHEDULER_add_with_priority (h->sched, |
1024 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | 999 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, |
1025 | &do_upload, | 1000 | &GNUNET_FS_publish_main_, |
1026 | ret); | 1001 | ret); |
1027 | return ret; | 1002 | return ret; |
1028 | } | 1003 | } |
1029 | 1004 | ||
@@ -1058,12 +1033,20 @@ fip_signal_stop(void *cls, | |||
1058 | struct GNUNET_FS_ProgressInfo pi; | 1033 | struct GNUNET_FS_ProgressInfo pi; |
1059 | uint64_t off; | 1034 | uint64_t off; |
1060 | 1035 | ||
1036 | if (fi->serialization != NULL) | ||
1037 | { | ||
1038 | if (0 != UNLINK (fi->serialization)) | ||
1039 | { | ||
1040 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
1041 | "unlink", | ||
1042 | fi->serialization); | ||
1043 | } | ||
1044 | GNUNET_free (fi->serialization); | ||
1045 | fi->serialization = NULL; | ||
1046 | } | ||
1061 | off = (fi->chk_uri == NULL) ? 0 : length; | 1047 | off = (fi->chk_uri == NULL) ? 0 : length; |
1062 | pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; | 1048 | pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; |
1063 | make_publish_status (&pi, sc, fi, off); | 1049 | GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, sc, fi, off)); |
1064 | GNUNET_break (NULL == | ||
1065 | sc->h->upcb (sc->h->upcb_cls, | ||
1066 | &pi)); | ||
1067 | *client_info = NULL; | 1050 | *client_info = NULL; |
1068 | return GNUNET_OK; | 1051 | return GNUNET_OK; |
1069 | } | 1052 | } |
@@ -1075,24 +1058,31 @@ fip_signal_stop(void *cls, | |||
1075 | * simply clean up the state for completed uploads. | 1058 | * simply clean up the state for completed uploads. |
1076 | * Must NOT be called from within the event callback! | 1059 | * Must NOT be called from within the event callback! |
1077 | * | 1060 | * |
1078 | * @param sc context for the upload to stop | 1061 | * @param pc context for the upload to stop |
1079 | */ | 1062 | */ |
1080 | void | 1063 | void |
1081 | GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc) | 1064 | GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc) |
1082 | { | 1065 | { |
1083 | if (GNUNET_SCHEDULER_NO_TASK != sc->upload_task) | 1066 | if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task) |
1084 | GNUNET_SCHEDULER_cancel (sc->h->sched, sc->upload_task); | 1067 | GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task); |
1085 | // FIXME: remove from persistence DB (?) --- think more about | 1068 | if (pc->serialization != NULL) |
1086 | // shutdown / persistent-resume APIs!!! | 1069 | { |
1087 | GNUNET_FS_file_information_inspect (sc->fi, | 1070 | if (0 != UNLINK (pc->serialization)) |
1071 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
1072 | "unlink", | ||
1073 | pc->serialization); | ||
1074 | GNUNET_free (pc->serialization); | ||
1075 | pc->serialization = NULL; | ||
1076 | } | ||
1077 | GNUNET_FS_file_information_inspect (pc->fi, | ||
1088 | &fip_signal_stop, | 1078 | &fip_signal_stop, |
1089 | sc); | 1079 | pc); |
1090 | if (GNUNET_YES == sc->in_network_wait) | 1080 | if (GNUNET_YES == pc->in_network_wait) |
1091 | { | 1081 | { |
1092 | sc->in_network_wait = GNUNET_SYSERR; | 1082 | pc->in_network_wait = GNUNET_SYSERR; |
1093 | return; | 1083 | return; |
1094 | } | 1084 | } |
1095 | publish_cleanup (sc); | 1085 | publish_cleanup (pc); |
1096 | } | 1086 | } |
1097 | 1087 | ||
1098 | 1088 | ||