/** * Create an entry for an empty directory in a publish-structure. * This function should be used by applications for which the * use of "GNUNET_FS_file_information_create_from_directory" * is not appropriate. * * @param h handle to the file sharing subsystem * @param client_info initial value for the client-info value for this entry * @param meta metadata for the directory * @param keywords under which keywords should this directory be available * directly; can be NULL * @param bo block options * @param filename name of the directory; can be NULL * @return publish structure entry for the directory , NULL on error */ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_empty_directory (struct GNUNET_FS_Handle *h, void *client_info, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_BlockOptions *bo, const char *filename) { struct GNUNET_FS_FileInformation *ret; ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation)); ret->h = h; ret->client_info = client_info; ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); ret->keywords = GNUNET_FS_uri_dup (keywords); ret->bo = *bo; ret->is_directory = GNUNET_YES; if (filename != NULL) ret->filename = GNUNET_strdup (filename); return ret; }
/** * Create an entry for a file in a publish-structure. * * @param h handle to the file sharing subsystem * @param client_info initial value for the client-info value for this entry * @param length length of the file * @param reader function that can be used to obtain the data for the file * @param reader_cls closure for "reader" * @param keywords under which keywords should this file be available * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation * @param bo block options * @return publish structure entry for the file */ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_reader (struct GNUNET_FS_Handle *h, void *client_info, uint64_t length, GNUNET_FS_DataReader reader, void *reader_cls, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, const struct GNUNET_FS_BlockOptions *bo) { struct GNUNET_FS_FileInformation *ret; if ((GNUNET_YES == do_index) && (reader != &GNUNET_FS_data_reader_file_)) { GNUNET_break (0); return NULL; } ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation)); ret->h = h; ret->client_info = client_info; ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); if (ret->meta == NULL) ret->meta = GNUNET_CONTAINER_meta_data_create (); ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords); ret->data.file.reader = reader; ret->data.file.reader_cls = reader_cls; ret->data.file.do_index = do_index; ret->data.file.file_size = length; ret->bo = *bo; return ret; }
/** * Create a directory builder. * * @param mdir metadata for the directory */ struct GNUNET_FS_DirectoryBuilder * GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir) { struct GNUNET_FS_DirectoryBuilder *ret; ret = GNUNET_malloc (sizeof (struct GNUNET_FS_DirectoryBuilder)); if (mdir != NULL) ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir); else ret->meta = GNUNET_CONTAINER_meta_data_create (); GNUNET_FS_meta_data_make_directory (ret->meta); return ret; }
/** * Start download probes for the given search result. * * @param h file-sharing handle to use for the operation * @param uri URI to probe * @param meta meta data associated with the URI * @param client_info client info pointer to use for associated events * @param anonymity anonymity level to use for the probes * @return the search result handle to access the probe activity */ struct GNUNET_FS_SearchResult * GNUNET_FS_probe (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta, void *client_info, uint32_t anonymity) { struct GNUNET_FS_SearchResult *sr; GNUNET_assert (NULL != h); sr = GNUNET_new (struct GNUNET_FS_SearchResult); sr->h = h; sr->uri = GNUNET_FS_uri_dup (uri); sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); sr->client_info = client_info; sr->anonymity = anonymity; GNUNET_FS_search_start_probe_ (sr); return sr; }
/** * We have received a KSK result. Check how it fits in with the * overall query and notify the client accordingly. * * @param sc context for the overall query * @param ent entry for the specific keyword * @param uri the URI that was found * @param meta metadata associated with the URI * under the @a ent keyword */ static void process_ksk_result (struct GNUNET_FS_SearchContext *sc, struct SearchRequestEntry *ent, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta) { struct GNUNET_HashCode key; struct GNUNET_FS_SearchResult *sr; struct GetResultContext grc; int is_new; unsigned int koff; /* check if new */ GNUNET_assert (NULL != sc); GNUNET_FS_uri_to_key (uri, &key); if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_get_multiple (ent->results, &key, &test_result_present, (void *) uri)) return; /* duplicate result */ /* try to find search result in master map */ grc.sr = NULL; grc.uri = uri; GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map, &key, &get_result_present, &grc); sr = grc.sr; is_new = (NULL == sr) || (sr->mandatory_missing > 0); if (NULL == sr) { sr = GNUNET_new (struct GNUNET_FS_SearchResult); sr->h = sc->h; sr->sc = sc; sr->anonymity = sc->anonymity; sr->uri = GNUNET_FS_uri_dup (uri); sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); sr->mandatory_missing = sc->mandatory_count; sr->key = key; sr->keyword_bitmap = GNUNET_malloc ((sc->uri->data.ksk.keywordCount + 7) / 8); /* round up, count bits */ GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &key, sr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); }
/** * Join a chat room. * * @param cfg configuration * @param nick_name nickname of the user joining (used to * determine which public key to use); * the nickname should probably also * be used in the member_info (as "EXTRACTOR_TITLE") * @param member_info information about the joining member * @param room_name name of the room * @param msg_options message options of the joining user * @param joinCallback function to call on successful join * @param join_cls closure for joinCallback * @param messageCallback which function to call if a message has * been received? * @param message_cls argument to callback * @param memberCallback which function to call for join/leave notifications * @param member_cls argument to callback * @param confirmationCallback which function to call for confirmations (maybe NULL) * @param confirmation_cls argument to callback * @param me member ID (pseudonym) * @return NULL on error */ struct GNUNET_CHAT_Room * GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *nick_name, struct GNUNET_CONTAINER_MetaData *member_info, const char *room_name, enum GNUNET_CHAT_MsgOptions msg_options, GNUNET_CHAT_JoinCallback joinCallback, void *join_cls, GNUNET_CHAT_MessageCallback messageCallback, void *message_cls, GNUNET_CHAT_MemberListCallback memberCallback, void *member_cls, GNUNET_CHAT_MessageConfirmation confirmationCallback, void *confirmation_cls, GNUNET_HashCode * me) { struct GNUNET_CHAT_Room *chat_room; struct GNUNET_CRYPTO_RsaPrivateKey *priv_key; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub_key; struct GNUNET_CLIENT_Connection *client; #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Joining the room '%s'\n", room_name); #endif priv_key = init_private_key (cfg, nick_name); if (NULL == priv_key) return NULL; GNUNET_CRYPTO_rsa_key_get_public (priv_key, &pub_key); GNUNET_CRYPTO_hash (&pub_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), me); GNUNET_PSEUDONYM_add (cfg, me, member_info); client = GNUNET_CLIENT_connect ("chat", cfg); if (NULL == client) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to the chat service\n")); return NULL; } if (NULL == joinCallback) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Undefined mandatory parameter: joinCallback\n")); return NULL; } if (NULL == messageCallback) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Undefined mandatory parameter: messageCallback\n")); return NULL; } if (NULL == memberCallback) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Undefined mandatory parameter: memberCallback\n")); return NULL; } chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); chat_room->msg_options = msg_options; chat_room->room_name = GNUNET_strdup (room_name); chat_room->member_info = GNUNET_CONTAINER_meta_data_duplicate (member_info); chat_room->my_private_key = priv_key; chat_room->is_joined = GNUNET_NO; chat_room->join_callback = joinCallback; chat_room->join_callback_cls = join_cls; chat_room->message_callback = messageCallback; chat_room->message_callback_cls = message_cls; chat_room->member_list_callback = memberCallback; chat_room->member_list_callback_cls = member_cls; chat_room->confirmation_callback = confirmationCallback; chat_room->confirmation_cls = confirmation_cls; chat_room->cfg = cfg; chat_room->client = client; chat_room->members = NULL; if (GNUNET_SYSERR == rejoin_room (chat_room)) { GNUNET_CHAT_leave_room (chat_room); return NULL; } return chat_room; }
/** * 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++; }