static int testKeyword () { char *uri; struct GNUNET_FS_Uri *ret; char *emsg; if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/++", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/foo+bar", &emsg); if (NULL == ret) { GNUNET_free (emsg); GNUNET_assert (0); } if (! GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } if ((2 != ret->data.ksk.keywordCount) || (0 != strcmp (" foo", ret->data.ksk.keywords[0])) || (0 != strcmp (" bar", ret->data.ksk.keywords[1]))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); if (0 != strcmp (uri, "gnunet://fs/ksk/foo+bar")) { GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; }
/** * 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 int testNamespace (int i) { char *uri; struct GNUNET_FS_Uri *ret; char *emsg; struct GNUNET_CRYPTO_EcdsaPrivateKey *ph; struct GNUNET_CRYPTO_EcdsaPublicKey id; char buf[1024]; char ubuf[1024]; char *sret; if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/D1KJS9H2A82Q65VKQ0ML3RFU6U1D3VUK", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/XQHH4R288W26EBV369F6RCE0PJVJTX2Y74Q2FJPMPGA31HJX2JG/this", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/test", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); ph = GNUNET_CRYPTO_ecdsa_key_create (); GNUNET_CRYPTO_ecdsa_key_get_public (ph, &id); sret = GNUNET_STRINGS_data_to_string (&id, sizeof (id), ubuf, sizeof (ubuf) - 1); GNUNET_assert (NULL != sret); sret[0] = '\0'; GNUNET_snprintf (buf, sizeof (buf), "gnunet://fs/sks/%s/test", ubuf); ret = GNUNET_FS_uri_parse (buf, &emsg); if (NULL == ret) { GNUNET_free (emsg); GNUNET_assert (0); } if (GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } if (!GNUNET_FS_uri_test_sks (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); if (0 != strcmp (uri, buf)) { GNUNET_FS_uri_destroy (ret); GNUNET_free (uri); GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; }
static int testFile (int i) { char *uri; struct GNUNET_FS_Uri *ret; char *emsg; if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/chk/C282GG70GKK41O4551011DO413KFBVTVMQG1OG30I0K4045N0G41HAPB82G680A02JRVVFO8URVRU2F159011DO41000000022RG820.RNVVVVOOLCLK065B5D04HTNVNSIB2AI022RG8200HSLK1CO1000ATQ98824DMA2032LIMG50CG0K057NVUVG200000H00000440000.42", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/chk/C282GG70GKK41O4551011DO413KFBVTVMQG1OG30I0K4045N0G41HAPB82G680A02JRVVFO8URVRU2F159011DO41000000022RG820.RNVVVVOOLCLK065B5D04HTNVNSIB2AI022RG8200HSLK1CO1000ATQ98824DMA2032LIMG50CG0K057NVUVG200000H000004400000", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/chk/C282GG70GKK41O4551011DO413KFBVTVMQG1OG30I0K4045N0G41HAPB82G680A02JRVVFO8URVRU2F159011DO41000000022RG820.RNVVVVOOLCLK065B5D04HTNVNSIB2AI022RG8200HSLK1CO1000ATQ98824DMA2032LIMG50CG0K057NVUVG200000H000004400000.FGH", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); ret = GNUNET_FS_uri_parse ("gnunet://fs/chk/4QZP479A9SKGFNMQ2ZBCYE71YV2QMTVGWTVPB6A10ASVCKXDHB05DKPSC7ZF6E9P9W1VE47394EQY7NXA47Q6R35M7P1MJPGP59D1Z8.D54QD1K5XCG5878T6YZ19AM60MQ6FC0YNVK7QY08KK0KM0FJJ3KQWYG112FN5T07KN7J0X35DF6WVBT9B8ZMZ3X2BXJ22X3KFQ6MV2G.42", &emsg); if (ret == NULL) { GNUNET_free (emsg); GNUNET_assert (0); } if (GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } if (GNUNET_FS_uri_test_sks (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } if (GNUNET_ntohll (ret->data.chk.file_length) != 42) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); if (0 != strcmp (uri, "gnunet://fs/chk/4QZP479A9SKGFNMQ2ZBCYE71YV2QMTVGWTVPB6A10ASVCKXDHB05DKPSC7ZF6E9P9W1VE47394EQY7NXA47Q6R35M7P1MJPGP59D1Z8.D54QD1K5XCG5878T6YZ19AM60MQ6FC0YNVK7QY08KK0KM0FJJ3KQWYG112FN5T07KN7J0X35DF6WVBT9B8ZMZ3X2BXJ22X3KFQ6MV2G.42")) { GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; }
/** * 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++; }