X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ffs%2Ffs_publish.c;h=6f8a9d2486a13734b6b8eabb832493f199f43b71;hb=6c471eeb15e27f8226492b4860a3c2acb94c5f25;hp=315e3a157a355451e6294ac5b20e593575bb4bf8;hpb=0ec759513a49b4219d6a6b235ecca50c123a6522;p=oweals%2Fgnunet.git diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 315e3a157..6f8a9d248 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -57,7 +57,7 @@ GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, pi->value.publish.pctx = (NULL == p->dir) ? NULL : p->dir->client_info; pi->value.publish.filename = p->filename; pi->value.publish.size = - (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size; + (p->is_directory == GNUNET_YES) ? p->data.dir.dir_size : p->data.file.file_size; pi->value.publish.eta = GNUNET_TIME_calculate_eta (p->start_time, offset, pi->value.publish.size); pi->value.publish.completed = offset; @@ -98,7 +98,7 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc) } if (pc->client != NULL) { - GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (pc->client); pc->client = NULL; } GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); @@ -132,7 +132,7 @@ ds_put_cont (void *cls, int success, pi.value.publish.specifics.error.message = pc->fi_pos->emsg; pc->fi_pos->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, pc->fi_pos, 0); - if ((pc->fi_pos->is_directory == GNUNET_NO) && + if ((pc->fi_pos->is_directory != GNUNET_YES) && (pc->fi_pos->filename != NULL) && (pc->fi_pos->data.file.do_index == GNUNET_YES)) { @@ -191,7 +191,7 @@ signal_publish_error (struct GNUNET_FS_FileInformation *p, pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL; pi.value.publish.specifics.error.message = emsg; p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0); - if ((p->is_directory == GNUNET_NO) && (p->filename != NULL) && + if ((p->is_directory != GNUNET_YES) && (p->filename != NULL) && (p->data.file.do_index == GNUNET_YES)) { /* run unindex to clean up */ @@ -347,7 +347,7 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) const char *dd; p = pc->fi_pos; - if (p->is_directory) + if (p->is_directory == GNUNET_YES) { pt_size = GNUNET_MIN (max, p->data.dir.dir_size - offset); dd = p->data.dir.dir_data; @@ -355,6 +355,8 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) } else { + if (UINT64_MAX == offset) + return p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL); pt_size = GNUNET_MIN (max, p->data.file.file_size - offset); if (pt_size == 0) return 0; /* calling reader with pt_size==0 @@ -385,10 +387,10 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *emsg; uint64_t flen; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); p = pc->fi_pos; GNUNET_FS_tree_encoder_finish (p->te, &p->chk_uri, &emsg); p->te = NULL; - GNUNET_FS_file_information_sync_ (p); if (NULL != emsg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error during tree walk: %s\n", emsg); @@ -399,16 +401,19 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) pi.value.publish.specifics.error.message = p->emsg; p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); + else + { /* final progress event */ - flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); - pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; - pi.value.publish.specifics.progress.data = NULL; - pi.value.publish.specifics.progress.offset = flen; - pi.value.publish.specifics.progress.data_len = 0; - pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen); - p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen); - + GNUNET_assert (NULL != p->chk_uri); + flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); + pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; + pi.value.publish.specifics.progress.data = NULL; + pi.value.publish.specifics.progress.offset = flen; + pi.value.publish.specifics.progress.data_len = 0; + pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen); + p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen); + } + GNUNET_FS_file_information_sync_ (p); /* continue with main */ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); pc->upload_task = @@ -451,7 +456,7 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, return; } - if ((!p->is_directory) && (GNUNET_YES == p->data.file.do_index) && + if ((p->is_directory != GNUNET_YES) && (GNUNET_YES == p->data.file.do_index) && (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -462,7 +467,7 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, odb.file_id = p->data.file.file_id; GNUNET_assert (pc->qre == NULL); pc->qre = - GNUNET_DATASTORE_put (pc->dsh, (p->is_directory) ? 0 : pc->rid, + GNUNET_DATASTORE_put (pc->dsh, (p->is_directory == GNUNET_YES) ? 0 : pc->rid, &chk->query, sizeof (struct OnDemandBlock), &odb, GNUNET_BLOCK_TYPE_FS_ONDEMAND, p->bo.content_priority, p->bo.anonymity_level, @@ -477,7 +482,7 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, (unsigned int) block_size); GNUNET_assert (pc->qre == NULL); pc->qre = - GNUNET_DATASTORE_put (pc->dsh, (p->is_directory) ? 0 : pc->rid, + GNUNET_DATASTORE_put (pc->dsh, (p->is_directory == GNUNET_YES) ? 0 : pc->rid, &chk->query, block_size, block, type, p->bo.content_priority, p->bo.anonymity_level, p->bo.replication_level, p->bo.expiration_time, -2, @@ -535,14 +540,14 @@ publish_content (struct GNUNET_FS_PublishContext *pc) GNUNET_assert (p != NULL); if (NULL == p->te) { - if (p->is_directory) + if (p->is_directory == GNUNET_YES) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating directory\n"); db = GNUNET_FS_directory_builder_create (p->meta); dirpos = p->data.dir.entries; while (NULL != dirpos) { - if (dirpos->is_directory) + if (dirpos->is_directory == GNUNET_YES) { raw_data = dirpos->data.dir.dir_data; dirpos->data.dir.dir_data = NULL; @@ -564,6 +569,7 @@ publish_content (struct GNUNET_FS_PublishContext *pc) GNUNET_free (raw_data); raw_data = NULL; } + dirpos->data.file.reader (dirpos->data.file.reader_cls, UINT64_MAX, 0, 0, NULL); } } GNUNET_FS_directory_builder_add (db, dirpos->chk_uri, dirpos->meta, @@ -578,7 +584,7 @@ publish_content (struct GNUNET_FS_PublishContext *pc) &p->data.dir.dir_data); GNUNET_FS_file_information_sync_ (p); } - size = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size; + size = (p->is_directory == GNUNET_YES) ? p->data.dir.dir_size : p->data.file.file_size; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating tree encoder\n"); p->te = GNUNET_FS_tree_encoder_create (pc->h, size, pc, &block_reader, @@ -606,7 +612,7 @@ process_index_start_response (void *cls, const struct GNUNET_MessageHeader *msg) const char *emsg; uint16_t msize; - GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (pc->client); pc->client = NULL; p = pc->fi_pos; if (msg == NULL) @@ -652,7 +658,7 @@ process_index_start_response (void *cls, const struct GNUNET_MessageHeader *msg) * @param res resulting hash, NULL on error */ static void -hash_for_index_cb (void *cls, const GNUNET_HashCode * res) +hash_for_index_cb (void *cls, const struct GNUNET_HashCode * res) { struct GNUNET_FS_PublishContext *pc = cls; struct GNUNET_FS_FileInformation *p; @@ -783,7 +789,7 @@ GNUNET_FS_publish_main_ (void *cls, return; } /* find starting position */ - while ((p->is_directory) && (NULL != p->data.dir.entries) && (NULL == p->emsg) + while ((p->is_directory == GNUNET_YES) && (NULL != p->data.dir.entries) && (NULL == p->emsg) && (NULL == p->data.dir.entries->chk_uri)) { p = p->data.dir.entries; @@ -847,7 +853,7 @@ GNUNET_FS_publish_main_ (void *cls, } return; } - if ((!p->is_directory) && (p->data.file.do_index)) + if ((p->is_directory != GNUNET_YES) && (p->data.file.do_index)) { if (NULL == p->filename) { @@ -942,10 +948,9 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi, pi.status = GNUNET_FS_STATUS_PUBLISH_START; *client_info = GNUNET_FS_publish_make_status_ (&pi, pc, fi, 0); GNUNET_FS_file_information_sync_ (fi); - if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta) - && (fi->dir != NULL)) + if ((fi->is_directory) && (fi->dir != NULL)) { - /* process entries in directory */ + /* We are a directory, and we are not top-level; process entries in directory */ pc->skip_next_fi_callback = GNUNET_YES; GNUNET_FS_file_information_inspect (fi, &fip_signal_start, pc); } @@ -954,41 +959,19 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi, /** - * Signal the FS's progress function that we are suspending + * Actually signal the FS's progress function that we are suspending * 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 bo block options - * @param do_index should we index? - * @param client_info pointer to client context set upon creation (can be modified) - * @return GNUNET_OK to continue (always) + * @param pc the publish context of which a file is being suspended */ -static int -fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, - uint64_t length, struct GNUNET_CONTAINER_MetaData *meta, - struct GNUNET_FS_Uri **uri, - struct GNUNET_FS_BlockOptions *bo, int *do_index, - void **client_info) +static void +suspend_operation (struct GNUNET_FS_FileInformation *fi, + struct GNUNET_FS_PublishContext *pc) { - struct GNUNET_FS_PublishContext *pc = cls; struct GNUNET_FS_ProgressInfo pi; uint64_t off; - if (GNUNET_YES == pc->skip_next_fi_callback) - { - pc->skip_next_fi_callback = GNUNET_NO; - return GNUNET_OK; - } - if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) - { - /* process entries in directory */ - pc->skip_next_fi_callback = GNUNET_YES; - GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); - } if (NULL != pc->ksk_pc) { GNUNET_FS_publish_ksk_cancel (pc->ksk_pc); @@ -1002,10 +985,9 @@ fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending publish operation\n"); GNUNET_free_non_null (fi->serialization); fi->serialization = NULL; - off = (fi->chk_uri == NULL) ? 0 : length; + off = (fi->chk_uri == NULL) ? 0 : (fi->is_directory == GNUNET_YES) ? fi->data.dir.dir_size : fi->data.file.file_size; pi.status = GNUNET_FS_STATUS_PUBLISH_SUSPEND; GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, pc, fi, off)); - *client_info = NULL; if (NULL != pc->qre) { GNUNET_DATASTORE_cancel (pc->qre); @@ -1017,6 +999,45 @@ fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, pc->dsh = NULL; } pc->rid = 0; +} + + +/** + * Signal the FS's progress function that we are suspending + * an upload. Performs the recursion. + * + * @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 bo block options + * @param do_index should we index? + * @param client_info pointer to client context set upon creation (can be modified) + * @return GNUNET_OK to continue (always) + */ +static int +fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, + uint64_t length, struct GNUNET_CONTAINER_MetaData *meta, + struct GNUNET_FS_Uri **uri, + struct GNUNET_FS_BlockOptions *bo, int *do_index, + void **client_info) +{ + struct GNUNET_FS_PublishContext *pc = cls; + + if (GNUNET_YES == pc->skip_next_fi_callback) + { + pc->skip_next_fi_callback = GNUNET_NO; + return GNUNET_OK; + } + if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) + { + /* process entries in directory */ + pc->skip_next_fi_callback = GNUNET_YES; + GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); + } + suspend_operation (fi, pc); + *client_info = NULL; return GNUNET_OK; } @@ -1037,7 +1058,9 @@ GNUNET_FS_publish_signal_suspend_ (void *cls) GNUNET_SCHEDULER_cancel (pc->upload_task); pc->upload_task = GNUNET_SCHEDULER_NO_TASK; } + pc->skip_next_fi_callback = GNUNET_YES; GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_suspend, pc); + suspend_operation (pc->fi, pc); GNUNET_FS_end_top (pc->h, pc->top); pc->top = NULL; publish_cleanup (pc);