/** * Extract metadata from files. * * @param item entry we are processing * @return GNUNET_OK on success, GNUNET_SYSERR on fatal errors */ static int extract_files (struct ScanTreeNode *item) { struct GNUNET_CONTAINER_MetaData *meta; ssize_t size; size_t slen; if (GNUNET_YES == item->is_directory) { /* for directories, we simply only descent, no extraction, no progress reporting */ struct ScanTreeNode *pos; for (pos = item->children_head; NULL != pos; pos = pos->next) if (GNUNET_OK != extract_files (pos)) return GNUNET_SYSERR; return GNUNET_OK; } /* this is the expensive operation, *afterwards* we'll check for aborts */ meta = GNUNET_CONTAINER_meta_data_create (); if (NULL != plugins) EXTRACTOR_extract (plugins, item->filename, NULL, 0, &add_to_md, meta); slen = strlen (item->filename) + 1; size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); if (-1 == size) { /* no meta data */ GNUNET_CONTAINER_meta_data_destroy (meta); if (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA, item->filename, slen)) return GNUNET_SYSERR; return GNUNET_OK; } { char buf[size + slen]; char *dst = &buf[slen]; memcpy (buf, item->filename, slen); size = GNUNET_CONTAINER_meta_data_serialize (meta, &dst, size, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); if (size < 0) { GNUNET_break (0); size = 0; } GNUNET_CONTAINER_meta_data_destroy (meta); if (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA, buf, slen + size)) return GNUNET_SYSERR; } return GNUNET_OK; }
static void testNamespace () { struct GNUNET_CRYPTO_EcdsaPrivateKey *ns; struct GNUNET_FS_BlockOptions bo; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *ksk_uri; struct GNUNET_FS_Uri *sks_uri; ns = GNUNET_CRYPTO_ecdsa_key_create (); meta = GNUNET_CONTAINER_meta_data_create (); ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL); bo.content_priority = 1; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root"); GNUNET_FS_publish_ksk (fs, ksk_uri, meta, sks_uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &adv_cont, NULL); GNUNET_FS_uri_destroy (sks_uri); kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout, NULL); GNUNET_FS_uri_destroy (ksk_uri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_free (ns); }
static void sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *ksk_uri; char *msg; struct GNUNET_FS_BlockOptions bo; if (NULL == uri) { fprintf (stderr, "Error publishing: %s\n", emsg); err = 1; GNUNET_FS_stop (fs); return; } meta = GNUNET_CONTAINER_meta_data_create (); msg = NULL; ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg); GNUNET_assert (NULL == msg); ksk_expect_uri = GNUNET_FS_uri_dup (uri); bo.content_priority = 1; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL); GNUNET_FS_uri_destroy (ksk_uri); GNUNET_CONTAINER_meta_data_destroy (meta); }
static void adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_CRYPTO_EcdsaPrivateKey *ns; struct GNUNET_FS_BlockOptions bo; if (NULL != emsg) { FPRINTF (stderr, "Error publishing: %s\n", emsg); err = 1; GNUNET_FS_stop (fs); return; } ns = GNUNET_CRYPTO_ecdsa_key_create (); meta = GNUNET_CONTAINER_meta_data_create (); sks_expect_uri = GNUNET_FS_uri_dup (uri); bo.content_priority = 1; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); GNUNET_CRYPTO_ecdsa_key_get_public (ns, &nsid); GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_free (ns); }
/** * Add a pseudonym to the set of known pseudonyms. * For all pseudonym advertisements that we discover * FS should automatically call this function. * * @param cfg overall configuration * @param id the pseudonym identifier * @param meta metadata for the pseudonym */ void GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * id, const struct GNUNET_CONTAINER_MetaData *meta) { char *name; int32_t ranking; struct GNUNET_CONTAINER_MetaData *old; char *fn; struct stat sbuf; ranking = 0; fn = get_data_filename (cfg, PS_METADATA_DIR, id); GNUNET_assert (fn != NULL); if ((0 == STAT (fn, &sbuf)) && (GNUNET_OK == read_info (cfg, id, &old, &ranking, &name))) { GNUNET_CONTAINER_meta_data_merge (old, meta); write_pseudonym_info (cfg, id, old, ranking, name); GNUNET_CONTAINER_meta_data_destroy (old); GNUNET_free_non_null (name); } else { write_pseudonym_info (cfg, id, meta, ranking, NULL); } GNUNET_free (fn); internal_notify (id, meta, ranking); }
/** * Destroy publish-structure. Clients should never destroy publish * structures that were passed to #GNUNET_FS_publish_start already. * * @param fi structure to destroy * @param cleaner function to call on each entry in the structure * (useful to clean up client_info); can be NULL; return * values are ignored * @param cleaner_cls closure for @a cleaner */ void GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, GNUNET_FS_FileInformationProcessor cleaner, void *cleaner_cls) { struct GNUNET_FS_FileInformation *pos; int no; no = GNUNET_NO; if (GNUNET_YES == fi->is_directory) { /* clean up directory */ while (NULL != (pos = fi->data.dir.entries)) { fi->data.dir.entries = pos->next; GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls); } /* clean up client-info */ if (NULL != cleaner) cleaner (cleaner_cls, fi, fi->data.dir.dir_size, fi->meta, &fi->keywords, &fi->bo, &no, &fi->client_info); GNUNET_free_non_null (fi->data.dir.dir_data); } else { /* call clean-up function of the reader */ if (NULL != fi->data.file.reader) { (void) fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL); fi->data.file.reader = NULL; } /* clean up client-info */ if (NULL != cleaner) cleaner (cleaner_cls, fi, fi->data.file.file_size, fi->meta, &fi->keywords, &fi->bo, &fi->data.file.do_index, &fi->client_info); } GNUNET_free_non_null (fi->filename); GNUNET_free_non_null (fi->emsg); if (NULL != fi->sks_uri) GNUNET_FS_uri_destroy (fi->sks_uri); if (NULL != fi->chk_uri) GNUNET_FS_uri_destroy (fi->chk_uri); /* clean up serialization */ if ((NULL != fi->serialization) && (0 != UNLINK (fi->serialization))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fi->serialization); if (NULL != fi->keywords) GNUNET_FS_uri_destroy (fi->keywords); if (NULL != fi->meta) GNUNET_CONTAINER_meta_data_destroy (fi->meta); GNUNET_free_non_null (fi->serialization); if (NULL != fi->te) { GNUNET_FS_tree_encoder_finish (fi->te, NULL); fi->te = NULL; } GNUNET_free (fi); }
static int test_normal_rw () { char *msg; int64_t testNum; char *readResultString; char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); struct GNUNET_BIO_WriteHandle *fileW; struct GNUNET_BIO_ReadHandle *fileR; struct GNUNET_CONTAINER_MetaData *metaDataW; struct GNUNET_CONTAINER_MetaData *metaDataR; metaDataW = GNUNET_CONTAINER_meta_data_create (); metaDataR = NULL; GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW); fileW = GNUNET_BIO_write_open (fileName); GNUNET_assert (NULL != fileW); GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING)); GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_meta_data (fileW, metaDataW)); GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int64 (fileW, TESTNUMBER64)); GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); fileR = GNUNET_BIO_read_open (fileName); GNUNET_assert (NULL != fileR); readResultString = NULL; GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_string (fileR, "Read string error", &readResultString, 200)); GNUNET_assert (NULL != readResultString); GNUNET_assert (0 == strcmp (TESTSTRING, readResultString)); GNUNET_free (readResultString); GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_meta_data (fileR, "Read meta error", &metaDataR)); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_meta_data_test_equal (metaDataR, metaDataW)); GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_int64 (fileR, &testNum)); GNUNET_BIO_read_close (fileR, &msg); GNUNET_CONTAINER_meta_data_destroy (metaDataW); GNUNET_CONTAINER_meta_data_destroy (metaDataR); GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); GNUNET_free (fileName); return 0; }
/** * read the pseudonym infomation from a file * @param cfg configuration to use * @param nsid hash code of a pseudonym * @param meta meta data to be read from a file * @param ranking ranking of a pseudonym * @param ns_name name of a pseudonym */ static int read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **meta, int32_t * ranking, char **ns_name) { char *fn; char *emsg; struct GNUNET_BIO_ReadHandle *fileR; fn = get_data_filename (cfg, PS_METADATA_DIR, nsid); GNUNET_assert (fn != NULL); if (GNUNET_YES != GNUNET_DISK_file_test (fn)) { GNUNET_free (fn); return GNUNET_SYSERR; } fileR = GNUNET_BIO_read_open (fn); if (fileR == NULL) { GNUNET_free (fn); return GNUNET_SYSERR; } emsg = NULL; *ns_name = NULL; if ((GNUNET_OK != GNUNET_BIO_read_int32 (fileR, ranking)) || (GNUNET_OK != GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) || (GNUNET_OK != GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta))) { (void) GNUNET_BIO_read_close (fileR, &emsg); GNUNET_free_non_null (emsg); GNUNET_free_non_null (*ns_name); *ns_name = NULL; GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); GNUNET_free (fn); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to parse metadata about pseudonym from file `%s': %s\n"), fn, emsg); GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); GNUNET_CONTAINER_meta_data_destroy (*meta); *meta = NULL; GNUNET_free_non_null (*ns_name); *ns_name = NULL; GNUNET_free_non_null (emsg); GNUNET_free (fn); return GNUNET_SYSERR; } GNUNET_free (fn); return GNUNET_OK; }
/** * the help function to list all available pseudonyms * @param cls point to a struct ListPseudonymClosure * @param fullname name of pseudonym */ static int list_pseudonym_helper (void *cls, const char *fullname) { struct ListPseudonymClosure *c = cls; int ret; struct GNUNET_HashCode id; int32_t rating; struct GNUNET_CONTAINER_MetaData *meta; const char *fn; char *str; char *name_unique; if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) return GNUNET_OK; fn = &fullname[strlen (fullname) + 1 - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)]; if (fn[-1] != DIR_SEPARATOR) return GNUNET_OK; ret = GNUNET_OK; if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id)) return GNUNET_OK; /* invalid name */ str = NULL; if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating, &str, NULL)) { /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason * to ignore it... So yeah, it will have placeholders instead of name, * empty metadata container and a default rank == -1, so what? We know * its nsid - that's all we really need. Right? */ GNUNET_free (str); GNUNET_CONTAINER_meta_data_destroy (meta); return GNUNET_OK; } name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL); if (c->iterator != NULL) ret = c->iterator (c->closure, &id, str, name_unique, meta, rating); GNUNET_free_non_null (str); GNUNET_free_non_null (name_unique); GNUNET_CONTAINER_meta_data_destroy (meta); return ret; }
static void do_shutdown () { if (uri_this != NULL) GNUNET_FS_uri_destroy (uri_this); if (uri_next != NULL) GNUNET_FS_uri_destroy (uri_next); if (ns != NULL) GNUNET_FS_namespace_delete (ns, GNUNET_NO); if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); }
static void do_shutdown () { if (uri_this != NULL) GNUNET_FS_uri_destroy (uri_this); if (uri_next != NULL) GNUNET_FS_uri_destroy (uri_next); if (ns != NULL) GNUNET_free (ns); if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); }
/** * Leave a chat room. */ void GNUNET_CHAT_leave_room (struct GNUNET_CHAT_Room *chat_room) { struct MemberList *pos; #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Leaving the room '%s'\n", chat_room->room_name); #endif GNUNET_CLIENT_disconnect (chat_room->client); GNUNET_free (chat_room->room_name); GNUNET_CONTAINER_meta_data_destroy (chat_room->member_info); GNUNET_CRYPTO_rsa_key_free (chat_room->my_private_key); while (NULL != chat_room->members) { pos = chat_room->members; chat_room->members = pos->next; GNUNET_CONTAINER_meta_data_destroy (pos->meta); GNUNET_free (pos); } GNUNET_free (chat_room); }
/** * Stop probe activity. Must ONLY be used on values * returned from #GNUNET_FS_probe. * * @param sr search result to stop probing for (freed) * @return the value of the 'client_info' pointer */ void * GNUNET_FS_probe_stop (struct GNUNET_FS_SearchResult *sr) { void *client_info; GNUNET_assert (NULL == sr->sc); GNUNET_FS_search_stop_probe_ (sr); GNUNET_FS_uri_destroy (sr->uri); GNUNET_CONTAINER_meta_data_destroy (sr->meta); client_info = sr->client_info; GNUNET_free (sr); return client_info; }
static int test_fullfile_rw () { #ifdef LINUX /* /dev/full only seems to exist on Linux */ char *msg; int64_t testNum; char *readResultString; char readResult[200]; struct GNUNET_BIO_WriteHandle *fileW; struct GNUNET_BIO_ReadHandle *fileR; struct GNUNET_CONTAINER_MetaData *metaDataW; struct GNUNET_CONTAINER_MetaData *metaDataR; metaDataW = GNUNET_CONTAINER_meta_data_create (); GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW); fileW = GNUNET_BIO_write_open ("/dev/full"); GNUNET_assert (NULL != fileW); (void) GNUNET_BIO_write (fileW, TESTSTRING, strlen (TESTSTRING)); (void) GNUNET_BIO_write_string (fileW, TESTSTRING); (void) GNUNET_BIO_write_meta_data (fileW, metaDataW); GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW)); GNUNET_CONTAINER_meta_data_destroy (metaDataW); fileW = GNUNET_BIO_write_open ("/dev/full"); GNUNET_assert (NULL != fileW); GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW)); fileR = GNUNET_BIO_read_open ("/dev/null"); GNUNET_assert (NULL != fileR); GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read (fileR, "Read error", readResult, sizeof (readResult))); readResultString = NULL; GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_string (fileR, "Read string error", &readResultString, 200)); GNUNET_assert (NULL == readResultString); GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_int64 (fileR, &testNum)); metaDataR = NULL; GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_meta_data (fileR, "Read meta error", &metaDataR)); msg = NULL; GNUNET_BIO_read_close (fileR, &msg); GNUNET_free (msg); GNUNET_assert (NULL == metaDataR); #endif return 0; }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", "down_bar" }; char *buf; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *kuri; struct GNUNET_FS_BlockOptions bo; struct GNUNET_FS_FileInformation *fi; size_t i; size_t j; fs = GNUNET_FS_start (cfg, "test-fs-search", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); processed_files = 0; for(j = 0; j < NUM_FILES; j++){ buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); meta = GNUNET_CONTAINER_meta_data_create (); kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords); bo.content_priority = 42; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME); fi = GNUNET_FS_file_information_create_from_data (fs, "publish-context", FILESIZE, buf, kuri, meta, GNUNET_NO, &bo); GNUNET_FS_uri_destroy (kuri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_assert (NULL != fi); start = GNUNET_TIME_absolute_get (); publish = GNUNET_FS_publish_start (fs, fi, NULL, NULL, NULL, GNUNET_FS_PUBLISH_OPTION_NONE); GNUNET_assert (publish != NULL); } timeout_task = GNUNET_SCHEDULER_add_delayed (LIFETIME, &abort_error, NULL); }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", "down_bar", }; char *buf; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *kuri; struct GNUNET_FS_FileInformation *fi; size_t i; struct GNUNET_FS_BlockOptions bo; cfg = c; fn = GNUNET_DISK_mktemp ("gnunet-unindex-test-dst"); fs = GNUNET_FS_start (cfg, "test-fs-unindex-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); GNUNET_assert (FILESIZE == GNUNET_DISK_fn_write (fn, buf, FILESIZE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)); GNUNET_free (buf); meta = GNUNET_CONTAINER_meta_data_create (); kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords); bo.content_priority = 42; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME); fi = GNUNET_FS_file_information_create_from_file (fs, "publish-context", fn, kuri, meta, GNUNET_YES, &bo); GNUNET_FS_uri_destroy (kuri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_assert (NULL != fi); start = GNUNET_TIME_absolute_get (); publish = GNUNET_FS_publish_start (fs, fi, NULL, NULL, NULL, GNUNET_FS_PUBLISH_OPTION_NONE); GNUNET_assert (publish != NULL); }
/** * Release memory of a share item tree. * * @param toplevel toplevel of the tree to be freed */ void GNUNET_FS_share_tree_free (struct GNUNET_FS_ShareTreeItem *toplevel) { struct GNUNET_FS_ShareTreeItem *pos; while (NULL != (pos = toplevel->children_head)) GNUNET_FS_share_tree_free (pos); if (NULL != toplevel->parent) GNUNET_CONTAINER_DLL_remove (toplevel->parent->children_head, toplevel->parent->children_tail, toplevel); if (NULL != toplevel->meta) GNUNET_CONTAINER_meta_data_destroy (toplevel->meta); if (NULL != toplevel->ksk_uri) GNUNET_FS_uri_destroy (toplevel->ksk_uri); GNUNET_free_non_null (toplevel->filename); GNUNET_free_non_null (toplevel->short_filename); GNUNET_free (toplevel); }
/** * Change the ranking of a pseudonym. * * @param cfg overall configuration * @param nsid id of the pseudonym * @param delta by how much should the rating be * changed? * @return new rating of the pseudonym */ int GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, int delta) { struct GNUNET_CONTAINER_MetaData *meta; int ret; int32_t ranking; char *name; name = NULL; ret = read_info (cfg, nsid, &meta, &ranking, &name); if (ret == GNUNET_SYSERR) { ranking = 0; meta = GNUNET_CONTAINER_meta_data_create (); } ranking += delta; write_pseudonym_info (cfg, nsid, meta, ranking, name); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_free_non_null (name); return ranking; }
/** * Finish building the directory. Frees the * builder context and returns the directory * in-memory. * * @param bld directory to finish * @param rsize set to the number of bytes needed * @param rdata set to the encoded directory * @return GNUNET_OK on success */ int GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, size_t * rsize, void **rdata) { char *data; char *sptr; size_t *sizes; unsigned int *perm; unsigned int i; unsigned int j; struct BuilderEntry *pos; struct BuilderEntry **bes; size_t size; size_t psize; size_t off; ssize_t ret; uint32_t big; size = strlen (GNUNET_DIRECTORY_MAGIC) + sizeof (uint32_t); size += GNUNET_CONTAINER_meta_data_get_serialized_size (bld->meta); sizes = NULL; perm = NULL; bes = NULL; if (0 < bld->count) { sizes = GNUNET_malloc (bld->count * sizeof (size_t)); perm = GNUNET_malloc (bld->count * sizeof (unsigned int)); bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *)); pos = bld->head; for (i = 0; i < bld->count; i++) { perm[i] = i; bes[i] = pos; sizes[i] = pos->len; pos = pos->next; } block_align (size, bld->count, sizes, perm); /* compute final size with alignment */ for (i = 0; i < bld->count; i++) { psize = size; size += sizes[perm[i]]; size = do_align (psize, size); } } *rsize = size; data = GNUNET_malloc_large (size); if (data == NULL) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc"); *rsize = 0; *rdata = NULL; GNUNET_free_non_null (sizes); GNUNET_free_non_null (perm); GNUNET_free_non_null (bes); return GNUNET_SYSERR; } *rdata = data; memcpy (data, GNUNET_DIRECTORY_MAGIC, strlen (GNUNET_DIRECTORY_MAGIC)); off = strlen (GNUNET_DIRECTORY_MAGIC); sptr = &data[off + sizeof (uint32_t)]; ret = GNUNET_CONTAINER_meta_data_serialize (bld->meta, &sptr, size - off - sizeof (uint32_t), GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); GNUNET_assert (ret != -1); big = htonl (ret); memcpy (&data[off], &big, sizeof (uint32_t)); off += sizeof (uint32_t) + ret; for (j = 0; j < bld->count; j++) { i = perm[j]; psize = off; off += sizes[i]; off = do_align (psize, off); memcpy (&data[off - sizes[i]], &(bes[i])[1], sizes[i]); GNUNET_free (bes[i]); } GNUNET_free_non_null (sizes); GNUNET_free_non_null (perm); GNUNET_free_non_null (bes); GNUNET_assert (off == size); GNUNET_CONTAINER_meta_data_destroy (bld->meta); GNUNET_free (bld); return GNUNET_OK; }
int main (int argc, char *argv[]) { int ok; struct GNUNET_HashCode rid1; struct GNUNET_HashCode id2; struct GNUNET_HashCode rid2; struct GNUNET_HashCode fid; struct GNUNET_HashCode id3; int old; int newVal; struct GNUNET_CONFIGURATION_Handle *cfg; char *name1; char *name2; char *name3; char *name1_unique; char *name2_unique; char *noname; int noname_is_a_dup; int notiCount, fakenotiCount; int count; static char m[1024 * 1024 * 10]; memset (m, 'b', sizeof (m)); m[sizeof (m) - 1] = '\0'; GNUNET_log_setup ("test-pseudonym", "WARNING", NULL); ok = GNUNET_YES; GNUNET_CRYPTO_random_disable_entropy_gathering (); (void) GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test"); cfg = GNUNET_CONFIGURATION_create (); if (-1 == GNUNET_CONFIGURATION_parse (cfg, "test_pseudonym_data.conf")) { GNUNET_CONFIGURATION_destroy (cfg); GNUNET_break (0); return -1; } notiCount = 0; fakenotiCount = 0; count = 0; GNUNET_PSEUDONYM_discovery_callback_register (cfg, &fake_noti_callback, &fakenotiCount); GNUNET_PSEUDONYM_discovery_callback_register (cfg, ¬i_callback, ¬iCount); GNUNET_PSEUDONYM_discovery_callback_unregister (&false_callback, &count); GNUNET_PSEUDONYM_discovery_callback_unregister (&fake_noti_callback, &fakenotiCount); /* ACTUAL TEST CODE */ old = GNUNET_PSEUDONYM_list_all (cfg, NULL, NULL); meta = GNUNET_CONTAINER_meta_data_create (); GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_TITLE, EXTRACTOR_METAFORMAT_UTF8, "text/plain", "test", strlen ("test") + 1); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id1); GNUNET_PSEUDONYM_add (cfg, &id1, meta); CHECK (notiCount == 1); GNUNET_PSEUDONYM_add (cfg, &id1, meta); CHECK (notiCount == 2); newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok); CHECK (old < newVal); old = newVal; GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id2); GNUNET_PSEUDONYM_add (cfg, &id2, meta); CHECK (notiCount == 3); newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok); CHECK (old < newVal); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_COMMENT, EXTRACTOR_METAFORMAT_UTF8, "text/plain", m, strlen (m) + 1)); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3); GNUNET_PSEUDONYM_add (cfg, &id3, meta); GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL); CHECK (name3 != NULL); GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL); CHECK (name2 != NULL); GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL); CHECK (name1 != NULL); CHECK (0 == strcmp (name1, name2)); name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL); name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL); CHECK (0 != strcmp (name1_unique, name2_unique)); CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2)); CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2)); CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1)); CHECK (0 == memcmp (&id1, &rid1, sizeof (struct GNUNET_HashCode))); CHECK (0 == memcmp (&id2, &rid2, sizeof (struct GNUNET_HashCode))); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &fid); GNUNET_log_skip (1, GNUNET_NO); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0)); GNUNET_log_skip (0, GNUNET_YES); CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL, &noname, &noname_is_a_dup)); CHECK (noname != NULL); CHECK (noname_is_a_dup == GNUNET_YES); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0)); CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10)); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); GNUNET_free (name1); GNUNET_free (name2); GNUNET_free (name1_unique); GNUNET_free (name2_unique); GNUNET_free (name3); GNUNET_free (noname); /* END OF TEST CODE */ FAILURE: GNUNET_PSEUDONYM_discovery_callback_unregister (¬i_callback, ¬iCount); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_CONFIGURATION_destroy (cfg); GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test")); return (ok == GNUNET_YES) ? 0 : 1; }
/** * Get namespace name, metadata and rank * This is a wrapper around internal read_info() call, and ensures that * returned data is not invalid (not NULL). * * @param cfg configuration * @param nsid cryptographic ID of the namespace * @param ret_meta a location to store metadata pointer. NULL, if metadata * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). * @param ret_rank a location to store rank. NULL, if rank not needed. * @param ret_name a location to store human-readable name. Name is not unique. * NULL, if name is not needed. Free with GNUNET_free(). * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with * a duplicate of a "no-name" placeholder * @return GNUNET_OK on success. GNUENT_SYSERR if the data was * unobtainable (in that case ret_* are filled with placeholders - * empty metadata container, rank -1 and a "no-name" name). */ int GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, int32_t *ret_rank, char **ret_name, int *name_is_a_dup) { struct GNUNET_CONTAINER_MetaData *meta; char *name; int32_t rank = -1; meta = NULL; name = NULL; if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name)) { if ((meta != NULL) && (name == NULL)) name = GNUNET_CONTAINER_meta_data_get_first_by_types (meta, EXTRACTOR_METATYPE_TITLE, EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METATYPE_FILENAME, EXTRACTOR_METATYPE_DESCRIPTION, EXTRACTOR_METATYPE_SUBJECT, EXTRACTOR_METATYPE_PUBLISHER, EXTRACTOR_METATYPE_AUTHOR_NAME, EXTRACTOR_METATYPE_COMMENT, EXTRACTOR_METATYPE_SUMMARY, -1); if (ret_name != NULL) { if (name == NULL) { name = GNUNET_strdup (_("no-name")); if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_YES; } else if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_NO; *ret_name = name; } else if (name != NULL) GNUNET_free (name); if (ret_meta != NULL) { if (meta == NULL) meta = GNUNET_CONTAINER_meta_data_create (); *ret_meta = meta; } else if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); if (ret_rank != NULL) *ret_rank = rank; return GNUNET_OK; } if (ret_name != NULL) *ret_name = GNUNET_strdup (_("no-name")); if (ret_meta != NULL) *ret_meta = GNUNET_CONTAINER_meta_data_create (); if (ret_rank != NULL) *ret_rank = -1; if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_YES; return GNUNET_SYSERR; }
/** * Iterate over all entries in a directory. Note that directories * are structured such that it is possible to iterate over the * individual blocks as well as over the entire directory. Thus * a client can call this function on the buffer in the * GNUNET_FS_ProgressCallback. Also, directories can optionally * include the contents of (small) files embedded in the directory * itself; for those files, the processor may be given the * contents of the file directly by this function. * <p> * * Note that this function maybe called on parts of directories. Thus * parser errors should not be reported _at all_ (with GNUNET_break). * Still, if some entries can be recovered despite these parsing * errors, the function should try to do this. * * @param size number of bytes in data * @param data pointer to the beginning of the directory * @param offset offset of data in the directory * @param dep function to call on each entry * @param dep_cls closure for dep * @return GNUNET_OK if this could be a block in a directory, * GNUNET_NO if this could be part of a directory (but not 100% OK) * GNUNET_SYSERR if 'data' does not represent a directory */ int GNUNET_FS_directory_list_contents (size_t size, const void *data, uint64_t offset, GNUNET_FS_DirectoryEntryProcessor dep, void *dep_cls) { struct GetFullDataClosure full_data; const char *cdata = data; char *emsg; uint64_t pos; uint64_t align; uint32_t mdSize; uint64_t epos; struct GNUNET_FS_Uri *uri; struct GNUNET_CONTAINER_MetaData *md; char *filename; if ((offset == 0) && ((size < 8 + sizeof (uint32_t)) || (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8)))) return GNUNET_SYSERR; pos = offset; if (offset == 0) { GNUNET_memcpy (&mdSize, &cdata[8], sizeof (uint32_t)); mdSize = ntohl (mdSize); if (mdSize > size - 8 - sizeof (uint32_t)) { /* invalid size */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("MAGIC mismatch. This is not a GNUnet directory.\n")); return GNUNET_SYSERR; } md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + sizeof (uint32_t)], mdSize); if (md == NULL) { GNUNET_break (0); return GNUNET_SYSERR; /* malformed ! */ } dep (dep_cls, NULL, NULL, md, 0, NULL); GNUNET_CONTAINER_meta_data_destroy (md); pos = 8 + sizeof (uint32_t) + mdSize; } while (pos < size) { /* find end of URI */ if (cdata[pos] == '\0') { /* URI is never empty, must be end of block, * skip to next alignment */ align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; if (align == pos) { /* if we were already aligned, still skip a block! */ align += DBLOCK_SIZE; } pos = align; if (pos >= size) { /* malformed - or partial download... */ break; } } epos = pos; while ((epos < size) && (cdata[epos] != '\0')) epos++; if (epos >= size) return GNUNET_NO; /* malformed - or partial download */ uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg); pos = epos + 1; if (uri == NULL) { GNUNET_free (emsg); pos--; /* go back to '\0' to force going to next alignment */ continue; } if (GNUNET_FS_uri_test_ksk (uri)) { GNUNET_FS_uri_destroy (uri); GNUNET_break (0); return GNUNET_NO; /* illegal in directory! */ } GNUNET_memcpy (&mdSize, &cdata[pos], sizeof (uint32_t)); mdSize = ntohl (mdSize); pos += sizeof (uint32_t); if (pos + mdSize > size) { GNUNET_FS_uri_destroy (uri); return GNUNET_NO; /* malformed - or partial download */ } md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize); if (md == NULL) { GNUNET_FS_uri_destroy (uri); GNUNET_break (0); return GNUNET_NO; /* malformed ! */ } pos += mdSize; filename = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); full_data.size = 0; full_data.data = NULL; GNUNET_CONTAINER_meta_data_iterate (md, &find_full_data, &full_data); if (dep != NULL) { dep (dep_cls, filename, uri, md, full_data.size, full_data.data); } GNUNET_free_non_null (full_data.data); GNUNET_free_non_null (filename); GNUNET_CONTAINER_meta_data_destroy (md); GNUNET_FS_uri_destroy (uri); } return GNUNET_OK; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { const char *keywords[] = { "down_foo", "down_bar", }; char *buf; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *kuri; struct GNUNET_FS_FileInformation *fi1; struct GNUNET_FS_FileInformation *fi2; struct GNUNET_FS_FileInformation *fidir; size_t i; struct GNUNET_FS_BlockOptions bo; cfg = c; setup_peer (&p1, "test_fs_publish_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-publish-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); fn1 = GNUNET_DISK_mktemp ("gnunet-publish-test-dst"); buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); GNUNET_assert (FILESIZE == GNUNET_DISK_fn_write (fn1, buf, FILESIZE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)); GNUNET_free (buf); fn2 = GNUNET_DISK_mktemp ("gnunet-publish-test-dst"); buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); GNUNET_assert (FILESIZE == GNUNET_DISK_fn_write (fn2, buf, FILESIZE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)); GNUNET_free (buf); meta = GNUNET_CONTAINER_meta_data_create (); kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords); bo.content_priority = 42; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME); fi1 = GNUNET_FS_file_information_create_from_file (fs, "publish-context1", fn1, kuri, meta, GNUNET_YES, &bo); GNUNET_assert (NULL != fi1); bo.anonymity_level = 2; fi2 = GNUNET_FS_file_information_create_from_file (fs, "publish-context2", fn2, kuri, meta, GNUNET_YES, &bo); GNUNET_assert (NULL != fi2); bo.anonymity_level = 3; fidir = GNUNET_FS_file_information_create_empty_directory (fs, "publish-context-dir", kuri, meta, &bo, NULL); GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi1)); GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi2)); GNUNET_FS_uri_destroy (kuri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_assert (NULL != fidir); start = GNUNET_TIME_absolute_get (); GNUNET_FS_publish_start (fs, fidir, NULL, NULL, NULL, GNUNET_FS_PUBLISH_OPTION_NONE); GNUNET_assert (publish != NULL); }
static int testDirectory (unsigned int i) { struct GNUNET_FS_DirectoryBuilder *db; char *data; size_t dlen; struct GNUNET_FS_Uri **uris; struct GNUNET_CONTAINER_MetaData **mds; struct GNUNET_CONTAINER_MetaData *meta; struct PCLS cls; char *emsg; int p; int q; char uri[512]; char txt[128]; int ret = 0; struct GNUNET_TIME_Absolute start; const char *s; cls.max = i; uris = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri *) * i); mds = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MetaData *) * i); meta = GNUNET_CONTAINER_meta_data_create (); GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_TITLE, EXTRACTOR_METAFORMAT_UTF8, "text/plain", "A title", strlen ("A title") + 1); GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_AUTHOR_NAME, EXTRACTOR_METAFORMAT_UTF8, "text/plain", "An author", strlen ("An author") + 1); for (p = 0; p < i; p++) { mds[p] = GNUNET_CONTAINER_meta_data_create (); for (q = 0; q <= p; q++) { GNUNET_snprintf (txt, sizeof (txt), "%u -- %u\n", p, q); GNUNET_CONTAINER_meta_data_insert (mds[p], "<test>", #if HAVE_EXTRACTOR_H q % EXTRACTOR_metatype_get_max (), #else q % 128, #endif EXTRACTOR_METAFORMAT_UTF8, "text/plain", txt, strlen (txt) + 1); } GNUNET_snprintf (uri, sizeof (uri), "gnunet://fs/chk/C282GG70GKK41O4551011DO413KFBVTVMQG1OG30I0K4045N0G41HAPB82G680A02JRVVFO8URVRU2F159011DO41000000022RG820.RNVVVVOOLCLK065B5D04HTNVNSIB2AI022RG8200HSLK1CO1000ATQ98824DMA2032LIMG50CG0K057NVUVG200000H000004400000.%u", p); emsg = NULL; uris[p] = GNUNET_FS_uri_parse (uri, &emsg); if (uris[p] == NULL) { GNUNET_CONTAINER_meta_data_destroy (mds[p]); while (--p > 0) { GNUNET_CONTAINER_meta_data_destroy (mds[p]); GNUNET_FS_uri_destroy (uris[p]); } GNUNET_free (mds); GNUNET_free (uris); GNUNET_free (emsg); GNUNET_CONTAINER_meta_data_destroy (meta); ABORT (); /* error in testcase */ } GNUNET_assert (emsg == NULL); } start = GNUNET_TIME_absolute_get (); db = GNUNET_FS_directory_builder_create (meta); for (p = 0; p < i; p++) GNUNET_FS_directory_builder_add (db, uris[p], mds[p], NULL); GNUNET_FS_directory_builder_finish (db, &dlen, (void **) &data); s = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES); FPRINTF (stdout, "Creating directory with %u entires and total size %llu took %s\n", i, (unsigned long long) dlen, s); if (i < 100) { cls.pos = 0; cls.uri = uris; cls.md = mds; GNUNET_FS_directory_list_contents (dlen, data, 0, &processor, &cls); GNUNET_assert (cls.pos == i); } GNUNET_free (data); GNUNET_CONTAINER_meta_data_destroy (meta); for (p = 0; p < i; p++) { GNUNET_CONTAINER_meta_data_destroy (mds[p]); GNUNET_FS_uri_destroy (uris[p]); } GNUNET_free (uris); GNUNET_free (mds); return ret; }
/** * Add an entry to a directory. * * @param bld directory to extend * @param uri uri of the entry (must not be a KSK) * @param md metadata of the entry * @param data raw data of the entry, can be NULL, otherwise * data must point to exactly the number of bytes specified * by the uri which must be of type LOC or CHK */ void GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *md, const void *data) { struct GNUNET_FS_Uri *curi; struct BuilderEntry *e; uint64_t fsize; uint32_t big; ssize_t ret; size_t mds; size_t mdxs; char *uris; char *ser; char *sptr; size_t slen; struct GNUNET_CONTAINER_MetaData *meta; const struct GNUNET_CONTAINER_MetaData *meta_use; GNUNET_assert (!GNUNET_FS_uri_test_ksk (uri)); if (NULL != data) { GNUNET_assert (!GNUNET_FS_uri_test_sks (uri)); if (GNUNET_FS_uri_test_chk (uri)) { fsize = GNUNET_FS_uri_chk_get_file_size (uri); } else { curi = GNUNET_FS_uri_loc_get_uri (uri); GNUNET_assert (NULL != curi); fsize = GNUNET_FS_uri_chk_get_file_size (curi); GNUNET_FS_uri_destroy (curi); } } else { fsize = 0; /* not given */ } if (fsize > MAX_INLINE_SIZE) fsize = 0; /* too large */ uris = GNUNET_FS_uri_to_string (uri); slen = strlen (uris) + 1; mds = GNUNET_CONTAINER_meta_data_get_serialized_size (md); meta_use = md; meta = NULL; if (fsize > 0) { meta = GNUNET_CONTAINER_meta_data_duplicate (md); GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", EXTRACTOR_METATYPE_GNUNET_FULL_DATA, EXTRACTOR_METAFORMAT_BINARY, NULL, data, fsize); mdxs = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); if ((slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE == (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE) { /* adding full data would not cause us to cross * additional blocks, so add it! */ meta_use = meta; mds = mdxs; } } if (mds > GNUNET_MAX_MALLOC_CHECKED / 2) mds = GNUNET_MAX_MALLOC_CHECKED / 2; e = GNUNET_malloc (sizeof (struct BuilderEntry) + slen + mds + sizeof (uint32_t)); ser = (char *) &e[1]; memcpy (ser, uris, slen); GNUNET_free (uris); sptr = &ser[slen + sizeof (uint32_t)]; ret = GNUNET_CONTAINER_meta_data_serialize (meta_use, &sptr, mds, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); if (NULL != meta) GNUNET_CONTAINER_meta_data_destroy (meta); if (ret == -1) mds = 0; else mds = ret; big = htonl (mds); memcpy (&ser[slen], &big, sizeof (uint32_t)); e->len = slen + sizeof (uint32_t) + mds; e->next = bld->head; bld->head = e; bld->count++; }
/** * Handles messages received from the service. Calls the proper client * callback. */ static void process_result (struct GNUNET_CHAT_Room *room, const struct GNUNET_MessageHeader *reply) { struct LeaveNotificationMessage *leave_msg; struct JoinNotificationMessage *join_msg; struct ReceiveNotificationMessage *received_msg; struct ConfirmationReceiptMessage *receipt; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; GNUNET_HashCode id; const GNUNET_HashCode *sender; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_CHAT_SendReceiptContext *src; struct MemberList *pos; struct MemberList *prev; struct GNUNET_CRYPTO_AesSessionKey key; char decrypted_msg[MAX_MESSAGE_LENGTH]; uint16_t size; uint16_t meta_len; uint16_t msg_len; char *message_content; size = ntohs (reply->size); switch (ntohs (reply->type)) { case GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION: #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a join notification\n"); #endif if (size < sizeof (struct JoinNotificationMessage)) { GNUNET_break (0); return; } join_msg = (struct JoinNotificationMessage *) reply; meta_len = size - sizeof (struct JoinNotificationMessage); meta = GNUNET_CONTAINER_meta_data_deserialize ((const char *) &join_msg[1], meta_len); if (NULL == meta) { GNUNET_break (0); return; } pos = GNUNET_malloc (sizeof (struct MemberList)); pos->meta = meta; GNUNET_CRYPTO_hash (&join_msg->public_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pos->id); GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta); pos->next = room->members; room->members = pos; if (GNUNET_NO == room->is_joined) { GNUNET_CRYPTO_rsa_key_get_public (room->my_private_key, &pkey); if (0 == memcmp (&join_msg->public_key, &pkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) { room->join_callback (room->join_callback_cls); room->is_joined = GNUNET_YES; } else { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("The current user must be the the first one joined\n")); GNUNET_break (0); return; } } else room->member_list_callback (room->member_list_callback_cls, meta, &join_msg->public_key, ntohl (join_msg->msg_options)); break; case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION: #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a leave notification\n"); #endif if (size < sizeof (struct LeaveNotificationMessage)) { GNUNET_break (0); return; } leave_msg = (struct LeaveNotificationMessage *) reply; room->member_list_callback (room->member_list_callback_cls, NULL, &leave_msg->user, GNUNET_CHAT_MSG_OPTION_NONE); GNUNET_CRYPTO_hash (&leave_msg->user, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &id); prev = NULL; pos = room->members; while ((NULL != pos) && (0 != memcmp (&pos->id, &id, sizeof (GNUNET_HashCode)))) { prev = pos; pos = pos->next; } GNUNET_assert (NULL != pos); if (NULL == prev) room->members = pos->next; else prev->next = pos->next; GNUNET_CONTAINER_meta_data_destroy (pos->meta); GNUNET_free (pos); break; case GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION: #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a message notification\n"); #endif if (size <= sizeof (struct ReceiveNotificationMessage)) { GNUNET_break (0); return; } received_msg = (struct ReceiveNotificationMessage *) reply; if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ACKNOWLEDGED)) { src = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendReceiptContext)); src->chat_room = room; src->received_msg = GNUNET_memdup (received_msg, size); GNUNET_CLIENT_notify_transmit_ready (room->client, sizeof (struct ConfirmationReceiptMessage), GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_YES, &transmit_acknowledge_request, src); } msg_len = size - sizeof (struct ReceiveNotificationMessage); if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_PRIVATE)) { if (-1 == GNUNET_CRYPTO_rsa_decrypt (room->my_private_key, &received_msg->encrypted_key, &key, sizeof (struct GNUNET_CRYPTO_AesSessionKey))) { GNUNET_break (0); return; } msg_len = GNUNET_CRYPTO_aes_decrypt (&received_msg[1], msg_len, &key, (const struct GNUNET_CRYPTO_AesInitializationVector *) INITVALUE, decrypted_msg); message_content = decrypted_msg; } else { message_content = GNUNET_malloc (msg_len + 1); memcpy (message_content, &received_msg[1], msg_len); } message_content[msg_len] = '\0'; if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)) { sender = NULL; meta = NULL; } else { pos = room->members; while ((NULL != pos) && (0 != memcmp (&pos->id, &received_msg->sender, sizeof (GNUNET_HashCode)))) pos = pos->next; GNUNET_assert (NULL != pos); sender = &received_msg->sender; meta = pos->meta; } room->message_callback (room->message_callback_cls, room, sender, meta, message_content, GNUNET_TIME_absolute_ntoh (received_msg->timestamp), ntohl (received_msg->msg_options)); if (message_content != decrypted_msg) GNUNET_free (message_content); break; case GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION: #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a confirmation receipt\n"); #endif if (size < sizeof (struct ConfirmationReceiptMessage)) { GNUNET_break (0); return; } receipt = (struct ConfirmationReceiptMessage *) reply; if (NULL != room->confirmation_callback) room->confirmation_callback (room->confirmation_cls, room, ntohl (receipt->sequence_number), GNUNET_TIME_absolute_ntoh (receipt->timestamp), &receipt->target); break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unknown message type: '%u'\n"), ntohs (reply->type)); GNUNET_break_op (0); break; } }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { const char *keywords[] = { "down_foo", "down_bar", }; char *fn1; char *fn2; char *buf; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *kuri; struct GNUNET_FS_FileInformation *fi1; struct GNUNET_FS_FileInformation *fi2; struct GNUNET_FS_FileInformation *fidir; struct GNUNET_FS_Handle *fs; size_t i; struct GNUNET_FS_BlockOptions bo; fs = GNUNET_FS_start (cfg, "test-fs-file-information", NULL, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); fn1 = GNUNET_DISK_mktemp ("gnunet-file_information-test-dst"); buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); GNUNET_assert (FILESIZE == GNUNET_DISK_fn_write (fn1, buf, FILESIZE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)); GNUNET_free (buf); fn2 = GNUNET_DISK_mktemp ("gnunet-file_information-test-dst"); buf = GNUNET_malloc (FILESIZE); for (i = 0; i < FILESIZE; i++) buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); GNUNET_assert (FILESIZE == GNUNET_DISK_fn_write (fn2, buf, FILESIZE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)); GNUNET_free (buf); meta = GNUNET_CONTAINER_meta_data_create (); kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords); bo.content_priority = 42; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME); fi1 = GNUNET_FS_file_information_create_from_file (fs, "file_information-context1", fn1, kuri, meta, GNUNET_YES, &bo); GNUNET_assert (fi1 != NULL); fi2 = GNUNET_FS_file_information_create_from_file (fs, "file_information-context2", fn2, kuri, meta, GNUNET_YES, &bo); GNUNET_assert (fi2 != NULL); fidir = GNUNET_FS_file_information_create_empty_directory (fs, "file_information-context-dir", kuri, meta, &bo, NULL); GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi1)); GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi2)); GNUNET_FS_uri_destroy (kuri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_assert (NULL != fidir); /* FIXME: test more of API! */ GNUNET_FS_file_information_destroy (fidir, &mycleaner, NULL); GNUNET_DISK_directory_remove (fn1); GNUNET_DISK_directory_remove (fn2); GNUNET_free_non_null (fn1); GNUNET_free_non_null (fn2); GNUNET_FS_stop (fs); }