aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fs/fs.c350
-rw-r--r--src/fs/fs.h73
-rw-r--r--src/fs/fs_file_information.c1
-rw-r--r--src/fs/fs_publish.c162
-rw-r--r--src/include/gnunet_fs_service.h13
5 files changed, 470 insertions, 129 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 */
226static char *
227get_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 */
260static struct GNUNET_BIO_ReadHandle *
261get_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 */
286static struct GNUNET_FS_FileInformation *
287deserialize_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 */
322static struct GNUNET_FS_FileInformation *
323find_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 */
361static int
362fip_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 */
391static int
392deserialize_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 */
516static void
517deserialize_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,
302void 617void
303GNUNET_FS_stop (struct GNUNET_FS_Handle *h) 618GNUNET_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 */
602void
603GNUNET_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 */
617void *
618GNUNET_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 */
688struct GNUNET_FS_PublishContext 721struct 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 */
50static void
51do_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 */
91static void 83void *
92make_publish_status (struct GNUNET_FS_ProgressInfo *pi, 84GNUNET_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 */
123static void 116static void
124publish_cleanup (struct GNUNET_FS_PublishContext *sc) 117publish_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 */
806static void 786void
807do_upload (void *cls, 787GNUNET_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 */
1080void 1063void
1081GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc) 1064GNUNET_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
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index acd059c96..508abeedb 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -1467,8 +1467,7 @@ enum GNUNET_FS_Flags
1467 }; 1467 };
1468 1468
1469/** 1469/**
1470 * Options specified in the VARARGs 1470 * Options specified in the VARARGs portion of GNUNET_FS_start.
1471 * portion of GNUNET_FS_start.
1472 */ 1471 */
1473enum GNUNET_FS_OPTIONS 1472enum GNUNET_FS_OPTIONS
1474 { 1473 {
@@ -1941,15 +1940,15 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
1941 1940
1942 1941
1943/** 1942/**
1944 * Stop an upload. Will abort incomplete uploads (but 1943 * Stop a publication. Will abort incomplete publications (but
1945 * not remove blocks that have already been publishd) or 1944 * not remove blocks that have already been published) or
1946 * simply clean up the state for completed uploads. 1945 * simply clean up the state for completed publications.
1947 * Must NOT be called from within the event callback! 1946 * Must NOT be called from within the event callback!
1948 * 1947 *
1949 * @param sc context for the upload to stop 1948 * @param pc context for the publication to stop
1950 */ 1949 */
1951void 1950void
1952GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc); 1951GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc);
1953 1952
1954 1953
1955/** 1954/**