* @see http://gnunet.org/encoding
* @author Krista Bennett
* @author Christian Grothoff
- *
- * TODO:
- * - indexing cleanup: unindex on failure (can wait)
- * - datastore reservation support (optimization)
- * - location URIs (publish with anonymity-level zero)
*/
#include "platform.h"
{
struct GNUNET_FS_PublishContext *pc = cls;
+ if (pc->fhc != NULL)
+ {
+ GNUNET_CRYPTO_hash_file_cancel (pc->fhc);
+ pc->fhc = NULL;
+ }
GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL);
if (pc->namespace != NULL)
GNUNET_FS_namespace_delete (pc->namespace, GNUNET_NO);
if (GNUNET_SYSERR == pcc->sc->in_network_wait)
{
/* we were aborted in the meantime, finish shutdown! */
- GNUNET_SCHEDULER_add_continuation (pcc->sc->h->sched,
- &publish_cleanup,
+ GNUNET_SCHEDULER_add_continuation (&publish_cleanup,
pcc->sc,
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
GNUNET_free (pcc);
pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
pi.value.publish.specifics.error.message = pcc->p->emsg;
pcc->p->client_info = GNUNET_FS_publish_make_status_ (&pi, pcc->sc, pcc->p, 0);
+ if ( (pcc->p->is_directory == GNUNET_NO) &&
+ (pcc->p->filename != NULL) &&
+ (pcc->p->data.file.do_index == GNUNET_YES) )
+ {
+ /* run unindex to clean up */
+ GNUNET_FS_unindex_start (pcc->sc->h,
+ pcc->p->filename,
+ NULL);
+ }
}
if (NULL != pcc->cont)
pcc->sc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (pcc->sc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
pcc->cont,
pcc->cont_cls);
GNUNET_free (pcc);
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, sc, p, 0);
+ if ( (p->is_directory == GNUNET_NO) &&
+ (p->filename != NULL) &&
+ (p->data.file.do_index == GNUNET_YES) )
+ {
+ /* run unindex to clean up */
+ GNUNET_FS_unindex_start (sc->h,
+ p->filename,
+ NULL);
+ }
+
}
GNUNET_FS_file_information_sync_ (p);
GNUNET_FS_publish_sync_ (pc);
pc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (pc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
pc);
return;
pc->fi_pos = p->dir;
GNUNET_FS_publish_sync_ (pc);
pc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (pc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
pc);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Finished with tree encoder\n");
#endif
+ /* final progress event */
+ pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
+ pi.value.publish.specifics.progress.data = NULL;
+ pi.value.publish.specifics.progress.offset = GNUNET_FS_uri_chk_get_file_size (p->chk_uri);
+ pi.value.publish.specifics.progress.data_len = 0;
+ pi.value.publish.specifics.progress.depth = 0;
+ p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p,
+ GNUNET_FS_uri_chk_get_file_size (p->chk_uri));
+
/* continue with main */
sc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (sc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
sc);
}
"Waiting for datastore connection\n");
#endif
sc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (sc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
sc);
return;
dpc_cls->p = p;
if ( (! p->is_directory) &&
(GNUNET_YES == p->data.file.do_index) &&
- (type == GNUNET_BLOCK_TYPE_DBLOCK) )
+ (type == GNUNET_BLOCK_TYPE_FS_DBLOCK) )
{
#if DEBUG_PUBLISH
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
odb.offset = GNUNET_htonll (offset);
odb.file_id = p->data.file.file_id;
GNUNET_DATASTORE_put (sc->dsh,
- sc->rid,
+ (p->is_directory) ? 0 : sc->rid,
query,
- sizeof(struct OnDemandBlock),
+ sizeof (struct OnDemandBlock),
&odb,
- GNUNET_BLOCK_TYPE_ONDEMAND,
+ GNUNET_BLOCK_TYPE_FS_ONDEMAND,
p->priority,
p->anonymity,
p->expirationTime,
(unsigned int) block_size);
#endif
GNUNET_DATASTORE_put (sc->dsh,
- sc->rid,
+ (p->is_directory) ? 0 : sc->rid,
query,
block_size,
block,
uint64_t ino;
char *fn;
+ sc->fhc = NULL;
p = sc->fi_pos;
if (NULL == res)
{
p->filename,
GNUNET_h2s (res));
#endif
- client = GNUNET_CLIENT_connect (sc->h->sched,
- "fs",
+ client = GNUNET_CLIENT_connect ("fs",
sc->h->cfg);
if (NULL == client)
{
struct GNUNET_FS_PublishContext *pc = cls;
struct GNUNET_FS_ProgressInfo pi;
struct GNUNET_FS_FileInformation *p;
+ struct GNUNET_FS_Uri *loc;
char *fn;
pc->upload_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"File upload complete, now publishing KSK blocks.\n");
#endif
+ if (0 == p->anonymity)
+ {
+ /* zero anonymity, box CHK URI in LOC URI */
+ loc = GNUNET_FS_uri_loc_create (p->chk_uri,
+ pc->h->cfg,
+ p->expirationTime);
+ GNUNET_FS_uri_destroy (p->chk_uri);
+ p->chk_uri = loc;
+ }
GNUNET_FS_publish_sync_ (pc);
/* upload of "p" complete, publish KBlocks! */
if (p->keywords != NULL)
else
{
p->start_time = GNUNET_TIME_absolute_get ();
- GNUNET_CRYPTO_hash_file (pc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- p->filename,
- HASHING_BLOCKSIZE,
- &hash_for_index_cb,
- pc);
+ pc->fhc = GNUNET_CRYPTO_hash_file (GNUNET_SCHEDULER_PRIORITY_IDLE,
+ p->filename,
+ HASHING_BLOCKSIZE,
+ &hash_for_index_cb,
+ pc);
}
return;
}
{
left = (left + DBLOCK_SIZE - 1) / DBLOCK_SIZE;
sc->reserve_entries += left;
- if (left == 1)
+ if (left <= 1)
break;
left = left * sizeof (struct ContentHashKey);
sc->reserve_space += left;
}
+ sc->reserve_entries++;
/* entries and space for keywords */
if (NULL != *uri)
{
if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task)
{
- GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task);
+ GNUNET_SCHEDULER_cancel (pc->upload_task);
pc->upload_task = GNUNET_SCHEDULER_NO_TASK;
}
GNUNET_FS_file_information_inspect (pc->fi,
}
pc->rid = success;
pc->upload_task
- = GNUNET_SCHEDULER_add_with_priority (pc->h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
pc);
}
struct GNUNET_FS_PublishContext *ret;
struct GNUNET_DATASTORE_Handle *dsh;
+ GNUNET_assert (NULL != h);
if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
{
- dsh = GNUNET_DATASTORE_connect (h->cfg,
- h->sched);
+ dsh = GNUNET_DATASTORE_connect (h->cfg);
if (NULL == dsh)
return NULL;
}
else
{
ret->upload_task
- = GNUNET_SCHEDULER_add_with_priority (h->sched,
- GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
&GNUNET_FS_publish_main_,
ret);
}
}
if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task)
{
- GNUNET_SCHEDULER_cancel (pc->h->sched, pc->upload_task);
+ GNUNET_SCHEDULER_cancel (pc->upload_task);
pc->upload_task = GNUNET_SCHEDULER_NO_TASK;
}
if (pc->serialization != NULL)
GNUNET_free (pkc);
return;
}
- GNUNET_SCHEDULER_add_continuation (pkc->h->sched,
- &publish_ksk_cont,
+ GNUNET_SCHEDULER_add_continuation (&publish_ksk_cont,
pkc,
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
sizeof (struct KBlock) +
pkc->slen,
pkc->cpy,
- GNUNET_BLOCK_TYPE_KBLOCK,
+ GNUNET_BLOCK_TYPE_FS_KBLOCK,
pkc->priority,
pkc->anonymity,
pkc->expirationTime,
char *kbe;
char *sptr;
+ GNUNET_assert (NULL != uri);
pkc = GNUNET_malloc (sizeof (struct PublishKskContext));
pkc->h = h;
pkc->expirationTime = expirationTime;
pkc->cont_cls = cont_cls;
if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
{
- pkc->dsh = GNUNET_DATASTORE_connect (h->cfg,
- h->sched);
+ pkc->dsh = GNUNET_DATASTORE_connect (h->cfg);
if (pkc->dsh == NULL)
{
cont (cont_cls, NULL, _("Could not connect to datastore."));
pkc->slen);
pkc->cpy->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
- GNUNET_SCHEDULER_add_continuation (h->sched,
- &publish_ksk_cont,
+ GNUNET_SCHEDULER_add_continuation (&publish_ksk_cont,
pkc,
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
-/**
- * Context for the SKS publication.
- */
-struct PublishSksContext
-{
-
- /**
- * Global FS context.
- */
- struct GNUNET_FS_Uri *uri;
-
- /**
- * Handle to the datastore.
- */
- struct GNUNET_DATASTORE_Handle *dsh;
-
- /**
- * Function to call once we're done.
- */
- GNUNET_FS_PublishContinuation cont;
-
- /**
- * Closure for cont.
- */
- void *cont_cls;
-
-};
-
-
-/**
- * Function called by the datastore API with
- * the result from the PUT (SBlock) request.
- *
- * @param cls closure of type "struct PublishSksContext*"
- * @param success GNUNET_OK on success
- * @param msg error message (or NULL)
- */
-static void
-sb_put_cont (void *cls,
- int success,
- const char *msg)
-{
- struct PublishSksContext *psc = cls;
-
- if (NULL != psc->dsh)
- {
- GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO);
- psc->dsh = NULL;
- }
- if (GNUNET_OK != success)
- psc->cont (psc->cont_cls,
- NULL,
- msg);
- else
- psc->cont (psc->cont_cls,
- psc->uri,
- NULL);
- GNUNET_FS_uri_destroy (psc->uri);
- GNUNET_free (psc);
-}
-
-
-/**
- * Publish an SBlock on GNUnet.
- *
- * @param h handle to the file sharing subsystem
- * @param namespace namespace to publish in
- * @param identifier identifier to use
- * @param update update identifier to use
- * @param meta metadata to use
- * @param uri URI to refer to in the SBlock
- * @param expirationTime when the SBlock expires
- * @param anonymity anonymity level for the SBlock
- * @param priority priority for the SBlock
- * @param options publication options
- * @param cont continuation
- * @param cont_cls closure for cont
- */
-void
-GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
- struct GNUNET_FS_Namespace *namespace,
- const char *identifier,
- const char *update,
- const struct GNUNET_CONTAINER_MetaData *meta,
- const struct GNUNET_FS_Uri *uri,
- struct GNUNET_TIME_Absolute expirationTime,
- uint32_t anonymity,
- uint32_t priority,
- enum GNUNET_FS_PublishOptions options,
- GNUNET_FS_PublishContinuation cont,
- void *cont_cls)
-{
- struct PublishSksContext *psc;
- struct GNUNET_CRYPTO_AesSessionKey sk;
- struct GNUNET_CRYPTO_AesInitializationVector iv;
- struct GNUNET_FS_Uri *sks_uri;
- char *uris;
- size_t size;
- size_t slen;
- size_t nidlen;
- size_t idlen;
- ssize_t mdsize;
- struct SBlock *sb;
- struct SBlock *sb_enc;
- char *dest;
- struct GNUNET_CONTAINER_MetaData *mmeta;
- GNUNET_HashCode key; /* hash of thisId = key */
- GNUNET_HashCode id; /* hash of hc = identifier */
- GNUNET_HashCode query; /* id ^ nsid = DB query */
-
- if (NULL == meta)
- mmeta = GNUNET_CONTAINER_meta_data_create ();
- else
- mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta);
- uris = GNUNET_FS_uri_to_string (uri);
- slen = strlen (uris) + 1;
- idlen = strlen (identifier);
- if (update == NULL)
- update = "";
- nidlen = strlen (update) + 1;
- mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta);
- size = sizeof (struct SBlock) + slen + nidlen + mdsize;
- if (size > MAX_SBLOCK_SIZE)
- {
- size = MAX_SBLOCK_SIZE;
- mdsize = size - (sizeof (struct SBlock) + slen + nidlen);
- }
- sb = GNUNET_malloc (sizeof (struct SBlock) + size);
- dest = (char *) &sb[1];
- memcpy (dest, update, nidlen);
- dest += nidlen;
- memcpy (dest, uris, slen);
- GNUNET_free (uris);
- dest += slen;
- mdsize = GNUNET_CONTAINER_meta_data_serialize (mmeta,
- &dest,
- mdsize,
- GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
- GNUNET_CONTAINER_meta_data_destroy (mmeta);
- if (mdsize == -1)
- {
- GNUNET_break (0);
- GNUNET_free (sb);
- cont (cont_cls,
- NULL,
- _("Internal error."));
- return;
- }
- size = sizeof (struct SBlock) + mdsize + slen + nidlen;
- sb_enc = GNUNET_malloc (size);
- GNUNET_CRYPTO_hash (identifier, idlen, &key);
- GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &id);
- sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
- sks_uri->type = sks;
- GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &sb_enc->subspace);
- GNUNET_CRYPTO_hash (&sb_enc->subspace,
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &sks_uri->data.sks.namespace);
- sks_uri->data.sks.identifier = GNUNET_strdup (identifier);
- GNUNET_CRYPTO_hash_xor (&id,
- &sks_uri->data.sks.namespace,
- &sb_enc->identifier);
- GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv);
- GNUNET_CRYPTO_aes_encrypt (&sb[1],
- size - sizeof (struct SBlock),
- &sk,
- &iv,
- &sb_enc[1]);
- sb_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK);
- sb_enc->purpose.size = htonl(slen + mdsize + nidlen
- + sizeof(struct SBlock)
- - sizeof(struct GNUNET_CRYPTO_RsaSignature));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_rsa_sign (namespace->key,
- &sb_enc->purpose,
- &sb_enc->signature));
- psc = GNUNET_malloc (sizeof(struct PublishSksContext));
- psc->uri = sks_uri;
- psc->cont = cont;
- psc->cont_cls = cont_cls;
- if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
- {
- GNUNET_free (sb_enc);
- GNUNET_free (sb);
- sb_put_cont (psc,
- GNUNET_OK,
- NULL);
- return;
- }
- psc->dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched);
- if (NULL == psc->dsh)
- {
- GNUNET_free (sb_enc);
- GNUNET_free (sb);
- sb_put_cont (psc,
- GNUNET_NO,
- _("Failed to connect to datastore."));
- return;
- }
- GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace,
- &id,
- &query);
- GNUNET_DATASTORE_put (psc->dsh,
- 0,
- &sb_enc->identifier,
- size,
- sb_enc,
- GNUNET_BLOCK_TYPE_SBLOCK,
- priority,
- anonymity,
- expirationTime,
- -2, 1,
- GNUNET_CONSTANTS_SERVICE_TIMEOUT,
- &sb_put_cont,
- psc);
- GNUNET_free (sb);
- GNUNET_free (sb_enc);
-}
-
/* end of fs_publish.c */