diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-08-29 20:58:34 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-08-29 20:58:34 +0000 |
commit | 70e446850e82317805db0a2f1508e3edc81b6a7f (patch) | |
tree | 651dcd40fe9148256f2d5de239e40e31ce3661d9 /src/fs | |
parent | 61b1c378568bbf7ca7cb1a51d2f1920d5d36fd26 (diff) | |
download | gnunet-70e446850e82317805db0a2f1508e3edc81b6a7f.tar.gz gnunet-70e446850e82317805db0a2f1508e3edc81b6a7f.zip |
more
Diffstat (limited to 'src/fs')
-rw-r--r-- | src/fs/fs.h | 11 | ||||
-rw-r--r-- | src/fs/fs_file_information.c | 1 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 136 |
3 files changed, 144 insertions, 4 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h index 3c92b42ae..3f1ffad30 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -220,6 +220,11 @@ struct GNUNET_FS_FileInformation | |||
220 | struct GNUNET_TIME_Absolute expirationTime; | 220 | struct GNUNET_TIME_Absolute expirationTime; |
221 | 221 | ||
222 | /** | 222 | /** |
223 | * At what time did we start this upload? | ||
224 | */ | ||
225 | struct GNUNET_TIME_Absolute start_time; | ||
226 | |||
227 | /** | ||
223 | * Under what filename is this struct serialized | 228 | * Under what filename is this struct serialized |
224 | * (for operational persistence). | 229 | * (for operational persistence). |
225 | */ | 230 | */ |
@@ -237,6 +242,12 @@ struct GNUNET_FS_FileInformation | |||
237 | * finally freed once the upload is complete. | 242 | * finally freed once the upload is complete. |
238 | */ | 243 | */ |
239 | struct ContentHashKey *chk_tree; | 244 | struct ContentHashKey *chk_tree; |
245 | |||
246 | /** | ||
247 | * Error message (non-NULL if this operation | ||
248 | * failed). | ||
249 | */ | ||
250 | char *emsg; | ||
240 | 251 | ||
241 | /** | 252 | /** |
242 | * Number of entries in "chk_tree". | 253 | * Number of entries in "chk_tree". |
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 60bcc2529..e72f42f9a 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c | |||
@@ -822,6 +822,7 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, | |||
822 | &fi->expirationTime, | 822 | &fi->expirationTime, |
823 | &fi->client_info); | 823 | &fi->client_info); |
824 | } | 824 | } |
825 | GNUNET_free_non_null (fi->emsg); | ||
825 | GNUNET_free_non_null (fi->chk_tree); | 826 | GNUNET_free_non_null (fi->chk_tree); |
826 | /* clean up serialization */ | 827 | /* clean up serialization */ |
827 | if (0 != UNLINK (fi->serialization)) | 828 | if (0 != UNLINK (fi->serialization)) |
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index f5c2b4cdc..eae97b1d8 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -76,6 +76,38 @@ struct PutContCtx | |||
76 | GNUNET_SCHEDULER_Task cont; | 76 | GNUNET_SCHEDULER_Task cont; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | |||
80 | /** | ||
81 | * Fill in all of the generic fields for | ||
82 | * a publish event. | ||
83 | * | ||
84 | * @param pc structure to fill in | ||
85 | * @param sc overall publishing context | ||
86 | * @param p file information for the file being published | ||
87 | */ | ||
88 | static void | ||
89 | make_publish_status (struct GNUNET_FS_ProgressInfo *pi, | ||
90 | struct GNUNET_FS_PublishContext *sc, | ||
91 | const struct GNUNET_FS_FileInformation *p) | ||
92 | { | ||
93 | pi->value.publish.sc = sc; | ||
94 | pi->value.publish.fi = p; | ||
95 | pi->value.publish.cctx | ||
96 | = p->client_info; | ||
97 | pi->value.publish.pctx | ||
98 | = (NULL == p->dir) ? NULL : p->dir->client_info; | ||
99 | pi->value.publish.size | ||
100 | = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size; | ||
101 | pi->value.publish.eta | ||
102 | = GNUNET_TIME_calculate_eta (p->start_time, | ||
103 | p->publish_offset, | ||
104 | pi->value.publish.size); | ||
105 | pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (p->start_time); | ||
106 | pi->value.publish.completed = p->publish_offset; | ||
107 | pi->value.publish.anonymity = p->anonymity; | ||
108 | } | ||
109 | |||
110 | |||
79 | /** | 111 | /** |
80 | * Function called by the datastore API with | 112 | * Function called by the datastore API with |
81 | * the result from the PUT request. | 113 | * the result from the PUT request. |
@@ -90,12 +122,20 @@ ds_put_cont (void *cls, | |||
90 | const char *msg) | 122 | const char *msg) |
91 | { | 123 | { |
92 | struct PutContCtx *pcc = cls; | 124 | struct PutContCtx *pcc = cls; |
125 | struct GNUNET_FS_ProgressInfo pi; | ||
93 | 126 | ||
94 | if (GNUNET_OK != success) | 127 | if (GNUNET_OK != success) |
95 | { | 128 | { |
96 | // FIXME: call progress CB with error | 129 | GNUNET_asprintf (&pcc->p->emsg, |
97 | // FIXME: update pcc->p to indicate abort | 130 | _("Upload failed: %s"), |
131 | msg); | ||
98 | GNUNET_FS_file_information_sync (pcc->p); | 132 | GNUNET_FS_file_information_sync (pcc->p); |
133 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | ||
134 | make_publish_status (&pi, pcc->sc, pcc->p); | ||
135 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | ||
136 | pi.value.publish.specifics.error.message = pcc->p->emsg; | ||
137 | pcc->sc->h->upcb (pcc->sc->h->upcb_cls, | ||
138 | &pi); | ||
99 | return; | 139 | return; |
100 | } | 140 | } |
101 | GNUNET_FS_file_information_sync (pcc->p); | 141 | GNUNET_FS_file_information_sync (pcc->p); |
@@ -159,6 +199,29 @@ publish_block (struct GNUNET_FS_PublishContext *sc, | |||
159 | 199 | ||
160 | 200 | ||
161 | /** | 201 | /** |
202 | * Generate the callback that signals clients | ||
203 | * that a file (or directory) has been completely | ||
204 | * published. | ||
205 | * | ||
206 | * @param p the completed upload | ||
207 | * @param sc context of the publication | ||
208 | */ | ||
209 | static void | ||
210 | signal_publish_completion (struct GNUNET_FS_FileInformation *p, | ||
211 | struct GNUNET_FS_PublishContext *sc) | ||
212 | { | ||
213 | struct GNUNET_FS_ProgressInfo pi; | ||
214 | |||
215 | pi.status = GNUNET_FS_STATUS_PUBLISH_COMPLETED; | ||
216 | make_publish_status (&pi, sc, p); | ||
217 | pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO; | ||
218 | pi.value.publish.specifics.completed.chk_uri = p->chk_uri; | ||
219 | sc->h->upcb (sc->h->upcb_cls, | ||
220 | &pi); | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
162 | * We are almost done publishing the structure, | 225 | * We are almost done publishing the structure, |
163 | * add SBlocks (if needed). | 226 | * add SBlocks (if needed). |
164 | * | 227 | * |
@@ -175,6 +238,8 @@ publish_sblock (struct GNUNET_FS_PublishContext *sc) | |||
175 | // FIXME: continuation should | 238 | // FIXME: continuation should |
176 | // be releasing the datastore reserve | 239 | // be releasing the datastore reserve |
177 | // (once implemented) | 240 | // (once implemented) |
241 | // FIXME: finally, signal overall completion | ||
242 | signal_publish_completion (p, sc); | ||
178 | } | 243 | } |
179 | 244 | ||
180 | 245 | ||
@@ -194,6 +259,12 @@ publish_kblocks (struct GNUNET_FS_PublishContext *sc, | |||
194 | { | 259 | { |
195 | // FIXME: build all kblocks | 260 | // FIXME: build all kblocks |
196 | // call publish_kblock on each | 261 | // call publish_kblock on each |
262 | |||
263 | |||
264 | GNUNET_FS_file_information_sync (p); | ||
265 | if (NULL != p->dir) | ||
266 | signal_publish_completion (p, sc); | ||
267 | |||
197 | // last continuation should then call the main continuation again | 268 | // last continuation should then call the main continuation again |
198 | } | 269 | } |
199 | 270 | ||
@@ -306,6 +377,7 @@ static void | |||
306 | publish_content (struct GNUNET_FS_PublishContext *sc, | 377 | publish_content (struct GNUNET_FS_PublishContext *sc, |
307 | struct GNUNET_FS_FileInformation *p) | 378 | struct GNUNET_FS_FileInformation *p) |
308 | { | 379 | { |
380 | struct GNUNET_FS_ProgressInfo pi; | ||
309 | struct ContentHashKey *mychk; | 381 | struct ContentHashKey *mychk; |
310 | const void *pt_block; | 382 | const void *pt_block; |
311 | uint16_t pt_size; | 383 | uint16_t pt_size; |
@@ -397,8 +469,27 @@ publish_content (struct GNUNET_FS_PublishContext *sc, | |||
397 | iob, | 469 | iob, |
398 | &emsg)) | 470 | &emsg)) |
399 | { | 471 | { |
400 | // FIXME: abort with error "emsg" | 472 | GNUNET_asprintf (&p->emsg, |
473 | _("Upload failed: %s"), | ||
474 | emsg); | ||
401 | GNUNET_free (emsg); | 475 | GNUNET_free (emsg); |
476 | GNUNET_FS_file_information_sync (p); | ||
477 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | ||
478 | make_publish_status (&pi, sc, p); | ||
479 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | ||
480 | pi.value.publish.specifics.error.message = p->emsg; | ||
481 | sc->h->upcb (sc->h->upcb_cls, | ||
482 | &pi); | ||
483 | /* continue with main (to propagate error up) */ | ||
484 | sc->upload_task | ||
485 | = GNUNET_SCHEDULER_add_delayed (sc->h->sched, | ||
486 | GNUNET_NO, | ||
487 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | ||
488 | GNUNET_SCHEDULER_NO_TASK, | ||
489 | GNUNET_TIME_UNIT_ZERO, | ||
490 | &do_upload, | ||
491 | sc); | ||
492 | return; | ||
402 | } | 493 | } |
403 | pt_block = iob; | 494 | pt_block = iob; |
404 | } | 495 | } |
@@ -432,7 +523,16 @@ publish_content (struct GNUNET_FS_PublishContext *sc, | |||
432 | ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK | 523 | ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK |
433 | : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK, | 524 | : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK, |
434 | &do_upload); | 525 | &do_upload); |
435 | // FIXME: should call progress function somewhere here! | 526 | if (p->current_depth == p->chk_tree_depth) |
527 | { | ||
528 | pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; | ||
529 | make_publish_status (&pi, sc, p); | ||
530 | pi.value.publish.specifics.progress.data = pt_block; | ||
531 | pi.value.publish.specifics.progress.offset = p->publish_offset; | ||
532 | pi.value.publish.specifics.progress.data_len = pt_size; | ||
533 | sc->h->upcb (sc->h->upcb_cls, | ||
534 | &pi); | ||
535 | } | ||
436 | GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query); | 536 | GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query); |
437 | if (p->current_depth == p->chk_tree_depth) | 537 | if (p->current_depth == p->chk_tree_depth) |
438 | { | 538 | { |
@@ -471,7 +571,9 @@ do_upload (void *cls, | |||
471 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 571 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
472 | { | 572 | { |
473 | struct GNUNET_FS_PublishContext *sc = cls; | 573 | struct GNUNET_FS_PublishContext *sc = cls; |
574 | struct GNUNET_FS_ProgressInfo pi; | ||
474 | struct GNUNET_FS_FileInformation *p; | 575 | struct GNUNET_FS_FileInformation *p; |
576 | char *fn; | ||
475 | 577 | ||
476 | sc->upload_task = GNUNET_SCHEDULER_NO_TASK; | 578 | sc->upload_task = GNUNET_SCHEDULER_NO_TASK; |
477 | p = sc->fi_pos; | 579 | p = sc->fi_pos; |
@@ -482,6 +584,29 @@ do_upload (void *cls, | |||
482 | publish_sblock (sc); | 584 | publish_sblock (sc); |
483 | return; | 585 | return; |
484 | } | 586 | } |
587 | if (NULL != p->emsg) | ||
588 | { | ||
589 | /* error with current file, abort all | ||
590 | related files as well! */ | ||
591 | while (NULL != p->dir) | ||
592 | { | ||
593 | fn = GNUNET_CONTAINER_meta_data_get_by_type (p->meta, | ||
594 | EXTRACTOR_FILENAME); | ||
595 | p = p->dir; | ||
596 | GNUNET_asprintf (&p->emsg, | ||
597 | _("Recursive upload failed at `%s'"), | ||
598 | fn); | ||
599 | GNUNET_free (fn); | ||
600 | GNUNET_FS_file_information_sync (p); | ||
601 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | ||
602 | make_publish_status (&pi, sc, p); | ||
603 | pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; | ||
604 | pi.value.publish.specifics.error.message = p->emsg; | ||
605 | sc->h->upcb (sc->h->upcb_cls, | ||
606 | &pi); | ||
607 | } | ||
608 | return; | ||
609 | } | ||
485 | if (NULL != p->chk_uri) | 610 | if (NULL != p->chk_uri) |
486 | { | 611 | { |
487 | /* move on to next file */ | 612 | /* move on to next file */ |
@@ -551,6 +676,9 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, | |||
551 | } | 676 | } |
552 | // FIXME: make upload persistent! | 677 | // FIXME: make upload persistent! |
553 | 678 | ||
679 | /* signal start */ | ||
680 | |||
681 | |||
554 | /* find first leaf, DFS */ | 682 | /* find first leaf, DFS */ |
555 | p = ret->fi; | 683 | p = ret->fi; |
556 | while ( (p->is_directory) && | 684 | while ( (p->is_directory) && |