From 7d9840a0500c6e8820506e3de587c5d1fd945cec Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 28 Apr 2010 15:08:13 +0000 Subject: [PATCH] first work on serialization --- src/fs/fs.c | 350 ++++++++++++++++++++++++++++++-- src/fs/fs.h | 73 +++++-- src/fs/fs_file_information.c | 1 + src/fs/fs_publish.c | 162 +++++++-------- src/include/gnunet_fs_service.h | 13 +- 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 @@ */ #include "platform.h" +#include "gnunet_util_lib.h" #include "gnunet_fs_service.h" #include "fs.h" @@ -145,6 +146,7 @@ process_job_queue (void *cls, h); } + /** * Add a job to the queue. * @@ -212,6 +214,318 @@ GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) } +/** + * Return the full filename where we would store state information + * (for serialization/deserialization). + * + * @param h master context + * @param ext component of the path + * @param ent entity identifier (or emtpy string for the directory) + * @return NULL on error + */ +static char * +get_serialization_file_name (struct GNUNET_FS_Handle *h, + const char *ext, + const char *ent) +{ + char *basename; + char *ret; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (h->cfg, + "fs", + "STATE_DIR", + &basename)) + return NULL; + GNUNET_asprintf (&ret, + "%s%s%s-%s%s%s", + basename, + DIR_SEPARATOR_STR, + h->client_name, + ext, + DIR_SEPARATOR_STR, + ent); + GNUNET_free (basename); + return ret; +} + + +/** + * Return a read handle for deserialization. + * + * @param h master context + * @param ext component of the path + * @param ent entity identifier (or emtpy string for the directory) + * @return NULL on error + */ +static struct GNUNET_BIO_ReadHandle * +get_read_handle (struct GNUNET_FS_Handle *h, + const char *ext, + const char *ent) +{ + char *fn; + struct GNUNET_BIO_ReadHandle *ret; + + fn = get_serialization_file_name (h, ext, ent); + if (fn == NULL) + return NULL; + ret = GNUNET_BIO_read_open (fn); + GNUNET_free (fn); + return ret; +} + + +/** + * Using the given serialization filename, try to deserialize + * the file-information tree associated with it. + * + * @param h master context + * @param filename name of the file (without directory) with + * the infromation + * @return NULL on error + */ +static struct GNUNET_FS_FileInformation * +deserialize_file_information (struct GNUNET_FS_Handle *h, + const char *filename) +{ + struct GNUNET_FS_FileInformation *ret; + struct GNUNET_BIO_ReadHandle *rh; + char *emsg; + + rh = get_read_handle (h, "publish-fi", filename); + if (rh == NULL) + return NULL; + + ret = NULL; + + + if (GNUNET_OK != + GNUNET_BIO_read_close (rh, &emsg)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to resume publishing information `%s': %s\n"), + filename, + emsg); + GNUNET_free (emsg); + } + return ret; +} + + +/** + * Find the entry in the file information struct where the + * serialization filename matches the given name. + * + * @param pos file information to search + * @param srch filename to search for + * @return NULL if srch was not found in this subtree + */ +static struct GNUNET_FS_FileInformation * +find_file_position (struct GNUNET_FS_FileInformation *pos, + const char *srch) +{ + struct GNUNET_FS_FileInformation *r; + + while (pos != NULL) + { + if (0 == strcmp (srch, + pos->serialization_name)) + return pos; + if (pos->is_directory) + { + r = find_file_position (pos->data.dir.entries, + srch); + if (r != NULL) + return r; + } + pos = pos->next; + } + return NULL; +} + + +/** + * Signal the FS's progress function that we are resuming + * an upload. + * + * @param cls closure (of type "struct GNUNET_FS_PublishContext*") + * @param fi the entry in the publish-structure + * @param length length of the file or directory + * @param meta metadata for the file or directory (can be modified) + * @param uri pointer to the keywords that will be used for this entry (can be modified) + * @param anonymity pointer to selected anonymity level (can be modified) + * @param priority pointer to selected priority (can be modified) + * @param expirationTime pointer to selected expiration time (can be modified) + * @param client_info pointer to client context set upon creation (can be modified) + * @return GNUNET_OK to continue (always) + */ +static int +fip_signal_resume(void *cls, + struct GNUNET_FS_FileInformation *fi, + uint64_t length, + struct GNUNET_CONTAINER_MetaData *meta, + struct GNUNET_FS_Uri **uri, + uint32_t *anonymity, + uint32_t *priority, + struct GNUNET_TIME_Absolute *expirationTime, + void **client_info) +{ + struct GNUNET_FS_PublishContext *sc = cls; + struct GNUNET_FS_ProgressInfo pi; + + pi.status = GNUNET_FS_STATUS_PUBLISH_RESUME; + pi.value.publish.specifics.resume.message = sc->fi->emsg; + pi.value.publish.specifics.resume.chk_uri = sc->fi->chk_uri; + *client_info = GNUNET_FS_publish_make_status_ (&pi, sc, fi, 0); + return GNUNET_OK; +} + + +/** + * Function called with a filename of serialized publishing operation + * to deserialize. + * + * @param cls the 'struct GNUNET_FS_Handle*' + * @param filename complete filename (absolute path) + * @return GNUNET_OK (continue to iterate) + */ +static int +deserialize_publish_file (void *cls, + const char *filename) +{ + struct GNUNET_FS_Handle *h = cls; + struct GNUNET_BIO_ReadHandle *rh; + struct GNUNET_FS_PublishContext *pc; + int32_t options; + int32_t all_done; + char *fi_root; + char *ns; + char *fi_pos; + char *emsg; + + rh = GNUNET_BIO_read_open (filename); + if (rh == NULL) + { + if (0 != UNLINK (filename)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "unlink", + filename); + return GNUNET_OK; + } + while (1) + { + fi_root = NULL; + fi_pos = NULL; + ns = NULL; + pc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); + pc->h = h; + if ( (GNUNET_OK != + GNUNET_BIO_read_string (rh, "publish-nid", &pc->nid, 1024)) || + (GNUNET_OK != + GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) || + (GNUNET_OK != + GNUNET_BIO_read_int32 (rh, &options)) || + (GNUNET_OK != + GNUNET_BIO_read_int32 (rh, &all_done)) || + (GNUNET_OK != + GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) || + (GNUNET_OK != + GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) || + (GNUNET_OK != + GNUNET_BIO_read_string (rh, "publish-ns", &ns, 1024)) ) + { + GNUNET_free_non_null (pc->nid); + GNUNET_free_non_null (pc->nuid); + GNUNET_free_non_null (fi_root); + GNUNET_free_non_null (ns); + GNUNET_free (pc); + break; + } + pc->options = options; + pc->all_done = all_done; + pc->fi = deserialize_file_information (h, fi_root); + if (pc->fi == NULL) + { + GNUNET_free_non_null (pc->nid); + GNUNET_free_non_null (pc->nuid); + GNUNET_free_non_null (fi_root); + GNUNET_free_non_null (ns); + GNUNET_free (pc); + continue; + } + if (ns != NULL) + { + pc->namespace = GNUNET_FS_namespace_create (h, ns); + if (pc->namespace == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to recover namespace `%s', cannot resume publishing operation.\n"), + ns); + GNUNET_free_non_null (pc->nid); + GNUNET_free_non_null (pc->nuid); + GNUNET_free_non_null (fi_root); + GNUNET_free_non_null (ns); + GNUNET_free (pc); + continue; + } + } + if (fi_pos != NULL) + { + pc->fi_pos = find_file_position (pc->fi, + fi_pos); + GNUNET_free (fi_pos); + if (pc->fi_pos == NULL) + { + /* failed to find position for resuming, outch! Will start from root! */ + GNUNET_break (0); + if (pc->all_done != GNUNET_YES) + pc->fi_pos = pc->fi; + } + } + pc->serialization = GNUNET_strdup (filename); + /* generate RESUME event(s) */ + GNUNET_FS_file_information_inspect (pc->fi, + &fip_signal_resume, + pc); + + /* re-start publishing (if needed)... */ + if (pc->all_done != GNUNET_YES) + pc->upload_task + = GNUNET_SCHEDULER_add_with_priority (h->sched, + GNUNET_SCHEDULER_PRIORITY_BACKGROUND, + &GNUNET_FS_publish_main_, + pc); + } + if (GNUNET_OK != + GNUNET_BIO_read_close (rh, &emsg)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to resume publishing operation `%s': %s\n"), + filename, + emsg); + GNUNET_free (emsg); + } + return GNUNET_OK; +} + + +/** + * Deserialize information about pending publish operations. + * + * @param h master context + */ +static void +deserialize_publish (struct GNUNET_FS_Handle *h) +{ + char *dn; + + dn = get_serialization_file_name (h, "publish", ""); + if (dn == NULL) + return; + GNUNET_DISK_directory_scan (dn, &deserialize_publish_file, h); + GNUNET_free (dn); +} + + /** * Setup a connection to the file-sharing service. * @@ -274,20 +588,21 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, } } va_end (ap); - // FIXME: setup receive-loop with client - - // FIXME: deserialize state; use client-name to find master-directory! - // Deserialize-Upload: - // * read FNs for upload FIs, deserialize each - // Deserialize Search: - // * read search queries - // * for each query, read file with search results - // * for each search result with active download, deserialize download - // * for each directory search result, check for active downloads of contents - // Deserialize Download: - // * always part of search??? - // Deserialize Unindex: - // * read FNs for unindex with progress offset + // FIXME: setup receive-loop with client (do we need one?) + + if (0 != (GNUNET_FS_FLAGS_PERSISTENCE & flags)) + { + deserialize_publish (ret); + // Deserialize Search: + // * read search queries + // * for each query, read file with search results + // * for each search result with active download, deserialize download + // * for each directory search result, check for active downloads of contents + // Deserialize Download: + // * always part of search??? + // Deserialize Unindex: + // * read FNs for unindex with progress offset + } return ret; } @@ -302,8 +617,11 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched, void GNUNET_FS_stop (struct GNUNET_FS_Handle *h) { - // FIXME: serialize state!? (or is it always serialized???) - // FIXME: terminate receive-loop with client + if (0 != (GNUNET_FS_FLAGS_PERSISTENCE & h->flags)) + { + // FIXME: generate SUSPEND events and clean up state! + } + // FIXME: terminate receive-loop with client (do we need one?) if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (h->sched, 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 /** * Under what filename is this struct serialized - * (for operational persistence). + * (for operational persistence). Should be determined + * using 'mktemp'. */ char *serialization; @@ -341,6 +342,12 @@ struct GNUNET_FS_FileInformation */ char *emsg; + /** + * Filename on disk that is used to track the progress of this + * upload (short name, not the full path). + */ + char *serialization_name; + /** * Data describing either the file or the directory. */ @@ -586,6 +593,32 @@ GNUNET_FS_search_probe_progress_ (void *cls, const struct GNUNET_FS_ProgressInfo *info); +/** + * Main function that performs the upload. + * + * @param cls "struct GNUNET_FS_PublishContext" identifies the upload + * @param tc task context + */ +void +GNUNET_FS_publish_main_ (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Fill in all of the generic fields for a publish event and call the + * callback. + * + * @param pi structure to fill in + * @param sc overall publishing context + * @param p file information for the file being published + * @param offset where in the file are we so far + * @return value returned from callback + */ +void * +GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, + struct GNUNET_FS_PublishContext *sc, + const struct GNUNET_FS_FileInformation *p, + uint64_t offset); /** * Master context for most FS operations. @@ -683,7 +716,7 @@ struct GNUNET_FS_Handle /** - * Handle for controlling an upload. + * Handle for controlling a publication process. */ struct GNUNET_FS_PublishContext { @@ -713,15 +746,19 @@ struct GNUNET_FS_PublishContext char *nuid; /** - * Our own client handle for the FS service; - * only briefly used when we start to index a - * file, otherwise NULL. + * Filename used for serializing information about this operation + * (should be determined using 'mktemp'). + */ + char *serialization; + + /** + * Our own client handle for the FS service; only briefly used when + * we start to index a file, otherwise NULL. */ struct GNUNET_CLIENT_Connection *client; /** - * Current position in the file-tree for the - * upload. + * Current position in the file-tree for the upload. */ struct GNUNET_FS_FileInformation *fi_pos; @@ -731,23 +768,19 @@ struct GNUNET_FS_PublishContext struct GNUNET_DATASTORE_Handle *dsh; /** - * ID of the task performing the upload. NO_TASK - * if the upload has completed. + * ID of the task performing the upload. NO_TASK if the upload has + * completed. */ GNUNET_SCHEDULER_TaskIdentifier upload_task; /** - * Typically GNUNET_NO. Set to GNUNET_YES if - * "upload_task" is GNUNET_SCHEDULER_NO_TASK - * and we're waiting for a response from the - * datastore service (in which case this - * struct must not be freed until we have that - * response). If someone tries to stop the - * download for good during this period, - * "in_network_wait" is set to GNUNET_SYSERR - * which will cause the struct to be destroyed - * right after we have the reply (or timeout) - * from the datastore service. + * Typically GNUNET_NO. Set to GNUNET_YES if "upload_task" is + * GNUNET_SCHEDULER_NO_TASK and we're waiting for a response from + * the datastore service (in which case this struct must not be + * freed until we have that response). If someone tries to stop the + * download for good during this period, "in_network_wait" is set to + * GNUNET_SYSERR which will cause the struct to be destroyed right + * after we have the reply (or timeout) from the datastore service. */ int in_network_wait; 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, &fi->expirationTime, &fi->client_info); } + GNUNET_free_non_null (fi->serialization); GNUNET_free_non_null (fi->emsg); GNUNET_free_non_null (fi->chk_uri); /* 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 @@ #define DEBUG_PUBLISH GNUNET_NO -/** - * Main function that performs the upload. - * @param cls "struct GNUNET_FS_PublishContext" identifies the upload - * @param tc task context - */ -static void -do_upload (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); - /** * Context for "ds_put_cont". @@ -81,18 +72,19 @@ struct PutContCtx /** * Fill in all of the generic fields for - * a publish event. + * a publish event and call the callback. * * @param pi structure to fill in * @param sc overall publishing context * @param p file information for the file being published * @param offset where in the file are we so far + * @return value returned from callback */ -static void -make_publish_status (struct GNUNET_FS_ProgressInfo *pi, - struct GNUNET_FS_PublishContext *sc, - const struct GNUNET_FS_FileInformation *p, - uint64_t offset) +void * +GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, + struct GNUNET_FS_PublishContext *sc, + const struct GNUNET_FS_FileInformation *p, + uint64_t offset) { pi->value.publish.sc = sc; pi->value.publish.fi = p; @@ -111,27 +103,29 @@ make_publish_status (struct GNUNET_FS_ProgressInfo *pi, pi->value.publish.completed = offset; pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (p->start_time); pi->value.publish.anonymity = p->anonymity; + return sc->h->upcb (sc->h->upcb_cls, + pi); } /** - * Cleanup the publish context, we're done - * with it. + * Cleanup the publish context, we're done with it. * - * @param sc struct to clean up after + * @param pc struct to clean up after */ static void -publish_cleanup (struct GNUNET_FS_PublishContext *sc) +publish_cleanup (struct GNUNET_FS_PublishContext *pc) { - GNUNET_FS_file_information_destroy (sc->fi, NULL, NULL); - if (sc->namespace != NULL) - GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO); - GNUNET_free_non_null (sc->nid); - GNUNET_free_non_null (sc->nuid); - GNUNET_DATASTORE_disconnect (sc->dsh, GNUNET_NO); - if (sc->client != NULL) - GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); - GNUNET_free (sc); + GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); + if (pc->namespace != NULL) + GNUNET_FS_namespace_delete (pc->namespace, GNUNET_NO); + GNUNET_free_non_null (pc->nid); + GNUNET_free_non_null (pc->nuid); + GNUNET_free_non_null (pc->serialization); + GNUNET_DATASTORE_disconnect (pc->dsh, GNUNET_NO); + if (pc->client != NULL) + GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); + GNUNET_free (pc); } @@ -167,12 +161,9 @@ ds_put_cont (void *cls, msg); GNUNET_FS_file_information_sync (pcc->p); pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; - make_publish_status (&pi, pcc->sc, pcc->p, 0); pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; pi.value.publish.specifics.error.message = pcc->p->emsg; - pcc->p->client_info - = pcc->sc->h->upcb (pcc->sc->h->upcb_cls, - &pi); + pcc->p->client_info = GNUNET_FS_publish_make_status_ (&pi, pcc->sc, pcc->p, 0); } GNUNET_FS_file_information_sync (pcc->p); if (NULL != pcc->cont) @@ -200,13 +191,10 @@ signal_publish_completion (struct GNUNET_FS_FileInformation *p, struct GNUNET_FS_ProgressInfo pi; pi.status = GNUNET_FS_STATUS_PUBLISH_COMPLETED; - make_publish_status (&pi, sc, p, - GNUNET_ntohll (p->chk_uri->data.chk.file_length)); pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO; pi.value.publish.specifics.completed.chk_uri = p->chk_uri; - p->client_info - = sc->h->upcb (sc->h->upcb_cls, - &pi); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, + GNUNET_ntohll (p->chk_uri->data.chk.file_length)); } @@ -228,12 +216,9 @@ signal_publish_error (struct GNUNET_FS_FileInformation *p, p->emsg = GNUNET_strdup (emsg); pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; - make_publish_status (&pi, sc, p, 0); pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; pi.value.publish.specifics.error.message =emsg; - p->client_info - = sc->h->upcb (sc->h->upcb_cls, - &pi); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); } @@ -314,7 +299,7 @@ publish_kblocks_cont (void *cls, sc->upload_task = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, GNUNET_SCHEDULER_PRIORITY_BACKGROUND, - &do_upload, + &GNUNET_FS_publish_main_, sc); return; } @@ -329,7 +314,7 @@ publish_kblocks_cont (void *cls, sc->upload_task = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, GNUNET_SCHEDULER_PRIORITY_BACKGROUND, - &do_upload, + &GNUNET_FS_publish_main_, sc); } @@ -418,19 +403,16 @@ encode_cont (void *cls, GNUNET_free (emsg); GNUNET_FS_file_information_sync (p); pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; - make_publish_status (&pi, sc, p, 0); pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; pi.value.publish.specifics.error.message = p->emsg; - p->client_info - = sc->h->upcb (sc->h->upcb_cls, - &pi); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); } /* continue with main */ sc->upload_task = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, GNUNET_SCHEDULER_PRIORITY_BACKGROUND, - &do_upload, - sc); + &GNUNET_FS_publish_main_, + sc); } @@ -465,16 +447,16 @@ block_proc (void *cls, { sc->upload_task = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, - GNUNET_SCHEDULER_PRIORITY_BACKGROUND, - &do_upload, - sc); + GNUNET_SCHEDULER_PRIORITY_BACKGROUND, + &GNUNET_FS_publish_main_, + sc); return; } GNUNET_assert (GNUNET_NO == sc->in_network_wait); sc->in_network_wait = GNUNET_YES; dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx)); - dpc_cls->cont = &do_upload; + dpc_cls->cont = &GNUNET_FS_publish_main_; dpc_cls->cont_cls = sc; dpc_cls->sc = sc; dpc_cls->p = p; @@ -550,14 +532,11 @@ progress_proc (void *cls, p = sc->fi_pos; pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; - make_publish_status (&pi, sc, p, offset); pi.value.publish.specifics.progress.data = pt_block; pi.value.publish.specifics.progress.offset = offset; pi.value.publish.specifics.progress.data_len = pt_size; pi.value.publish.specifics.progress.depth = depth; - p->client_info - = sc->h->upcb (sc->h->upcb_cls, - &pi); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, offset); } @@ -800,12 +779,13 @@ hash_for_index_cb (void *cls, /** * Main function that performs the upload. + * * @param cls "struct GNUNET_FS_PublishContext" identifies the upload * @param tc task context */ -static void -do_upload (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +void +GNUNET_FS_publish_main_ (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_PublishContext *sc = cls; struct GNUNET_FS_ProgressInfo pi; @@ -856,12 +836,9 @@ do_upload (void *cls, } GNUNET_FS_file_information_sync (p); pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; - make_publish_status (&pi, sc, p, 0); pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; pi.value.publish.specifics.error.message = p->emsg; - p->client_info - = sc->h->upcb (sc->h->upcb_cls, - &pi); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); } sc->all_done = GNUNET_YES; return; @@ -953,9 +930,7 @@ fip_signal_start(void *cls, struct GNUNET_FS_ProgressInfo pi; pi.status = GNUNET_FS_STATUS_PUBLISH_START; - make_publish_status (&pi, sc, fi, 0); - *client_info = sc->h->upcb (sc->h->upcb_cls, - &pi); + *client_info = GNUNET_FS_publish_make_status_ (&pi, sc, fi, 0); return GNUNET_OK; } @@ -1018,12 +993,12 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, // FIXME: calculate space needed for "fi" // and reserve as first task (then trigger - // "do_upload" from that continuation)! + // "publish_main" from that continuation)! ret->upload_task = GNUNET_SCHEDULER_add_with_priority (h->sched, - GNUNET_SCHEDULER_PRIORITY_BACKGROUND, - &do_upload, - ret); + GNUNET_SCHEDULER_PRIORITY_BACKGROUND, + &GNUNET_FS_publish_main_, + ret); return ret; } @@ -1058,12 +1033,20 @@ fip_signal_stop(void *cls, struct GNUNET_FS_ProgressInfo pi; uint64_t off; + if (fi->serialization != NULL) + { + if (0 != UNLINK (fi->serialization)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "unlink", + fi->serialization); + } + GNUNET_free (fi->serialization); + fi->serialization = NULL; + } off = (fi->chk_uri == NULL) ? 0 : length; pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; - make_publish_status (&pi, sc, fi, off); - GNUNET_break (NULL == - sc->h->upcb (sc->h->upcb_cls, - &pi)); + GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, sc, fi, off)); *client_info = NULL; return GNUNET_OK; } @@ -1075,24 +1058,31 @@ fip_signal_stop(void *cls, * simply clean up the state for completed uploads. * Must NOT be called from within the event callback! * - * @param sc context for the upload to stop + * @param pc context for the upload to stop */ void -GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc) +GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc) { - if (GNUNET_SCHEDULER_NO_TASK != sc->upload_task) - GNUNET_SCHEDULER_cancel (sc->h->sched, sc->upload_task); - // FIXME: remove from persistence DB (?) --- think more about - // shutdown / persistent-resume APIs!!! - GNUNET_FS_file_information_inspect (sc->fi, + if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task) + GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task); + if (pc->serialization != NULL) + { + if (0 != UNLINK (pc->serialization)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "unlink", + pc->serialization); + GNUNET_free (pc->serialization); + pc->serialization = NULL; + } + GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_stop, - sc); - if (GNUNET_YES == sc->in_network_wait) + pc); + if (GNUNET_YES == pc->in_network_wait) { - sc->in_network_wait = GNUNET_SYSERR; + pc->in_network_wait = GNUNET_SYSERR; return; } - publish_cleanup (sc); + publish_cleanup (pc); } 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 }; /** - * Options specified in the VARARGs - * portion of GNUNET_FS_start. + * Options specified in the VARARGs portion of GNUNET_FS_start. */ enum GNUNET_FS_OPTIONS { @@ -1941,15 +1940,15 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, /** - * Stop an upload. Will abort incomplete uploads (but - * not remove blocks that have already been publishd) or - * simply clean up the state for completed uploads. + * Stop a publication. Will abort incomplete publications (but + * not remove blocks that have already been published) or + * simply clean up the state for completed publications. * Must NOT be called from within the event callback! * - * @param sc context for the upload to stop + * @param pc context for the publication to stop */ void -GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc); +GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc); /** -- 2.25.1