Пример #1
0
/**
 * Print an entry in a directory.
 *
 * @param cls closure (not used)
 * @param filename name of the file in the directory
 * @param uri URI of the file
 * @param meta metadata for the file; metadata for
 *        the directory if everything else is NULL/zero
 * @param length length of the available data for the file
 *           (of type size_t since data must certainly fit
 *            into memory; if files are larger than size_t
 *            permits, then they will certainly not be
 *            embedded with the directory itself).
 * @param data data available for the file (length bytes)
 */
static void
print_entry (void *cls, const char *filename, const struct GNUNET_FS_Uri *uri,
             const struct GNUNET_CONTAINER_MetaData *meta, size_t length,
             const void *data)
{
  char *string;
  char *name;

  name =
      GNUNET_CONTAINER_meta_data_get_by_type (meta,
                                              EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
  if (uri == NULL)
  {
    printf (_("Directory `%s' meta data:\n"), name);
    GNUNET_CONTAINER_meta_data_iterate (meta, &item_printer, NULL);
    printf ("\n");
    printf (_("Directory `%s' contents:\n"), name);
    GNUNET_free (name);
    return;
  }
  string = GNUNET_FS_uri_to_string (uri);
  printf ("%s (%s):\n", name, string);
  GNUNET_free (string);
  GNUNET_CONTAINER_meta_data_iterate (meta, &item_printer, NULL);
  printf ("\n");
  GNUNET_free (name);
}
Пример #2
0
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;
}
Пример #3
0
/**
 * Publish a UBlock.
 *
 * @param h handle to the file sharing subsystem
 * @param dsh datastore handle to use for storage operation
 * @param label identifier to use
 * @param ulabel update label to use, may be an empty string for none
 * @param ns namespace to publish in
 * @param meta metadata to use
 * @param uri URI to refer to in the UBlock
 * @param bo per-block options
 * @param options publication options
 * @param cont continuation
 * @param cont_cls closure for @a cont
 * @return NULL on error (@a cont will still be called)
 */
struct GNUNET_FS_PublishUblockContext *
GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
			   struct GNUNET_DATASTORE_Handle *dsh,
			   const char *label,
			   const char *ulabel,
			   const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns,
			   const struct GNUNET_CONTAINER_MetaData *meta,
			   const struct GNUNET_FS_Uri *uri,
			   const struct GNUNET_FS_BlockOptions *bo,
			   enum GNUNET_FS_PublishOptions options,
			   GNUNET_FS_UBlockContinuation cont, void *cont_cls)
{
  struct GNUNET_FS_PublishUblockContext *uc;
  struct GNUNET_HashCode query;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct GNUNET_CRYPTO_SymmetricSessionKey skey;
  struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd;
  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
  char *uris;
  size_t size;
  char *kbe;
  char *sptr;
  ssize_t mdsize;
  size_t slen;
  size_t ulen;
  struct UBlock *ub_plain;
  struct UBlock *ub_enc;

  /* compute ublock to publish */
  if (NULL == meta)
    mdsize = 0;
  else
    mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
  GNUNET_assert (mdsize >= 0);
  uris = GNUNET_FS_uri_to_string (uri);
  slen = strlen (uris) + 1;
  if (NULL == ulabel)
    ulen = 1;
  else
    ulen = strlen (ulabel) + 1;
  size = mdsize + sizeof (struct UBlock) + slen + ulen;
  if (size > MAX_UBLOCK_SIZE)
  {
    size = MAX_UBLOCK_SIZE;
    mdsize = size - sizeof (struct UBlock) - (slen + ulen);
  }
  ub_plain = GNUNET_malloc (size);
  kbe = (char *) &ub_plain[1];
  if (NULL != ulabel)
    memcpy (kbe, ulabel, ulen);
  kbe += ulen;
  memcpy (kbe, uris, slen);
  kbe += slen;
  GNUNET_free (uris);
  sptr = kbe;
  if (NULL != meta)
    mdsize =
      GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize,
					    GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
  if (-1 == mdsize)
  {
    GNUNET_break (0);
    GNUNET_free (ub_plain);
    cont (cont_cls, _("Internal error."));
    return NULL;
  }
  size = sizeof (struct UBlock) + slen + mdsize + ulen;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Publishing under identifier `%s'\n",
              label);
  /* get public key of the namespace */
  GNUNET_CRYPTO_ecdsa_key_get_public (ns,
				    &pub);
  derive_ublock_encryption_key (&skey, &iv,
				label, &pub);

  /* encrypt ublock */
  ub_enc = GNUNET_malloc (size);
  GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1],
			     ulen + slen + mdsize,
			     &skey, &iv,
                             &ub_enc[1]);
  GNUNET_free (ub_plain);
  ub_enc->purpose.size = htonl (ulen + slen + mdsize +
				sizeof (struct UBlock)
				- sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
  ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);

  /* derive signing-key from 'label' and public key of the namespace */
  nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock");
  GNUNET_CRYPTO_ecdsa_key_get_public (nsd,
				    &ub_enc->verification_key);
  GNUNET_assert (GNUNET_OK ==
		 GNUNET_CRYPTO_ecdsa_sign (nsd,
					 &ub_enc->purpose,
					 &ub_enc->signature));
  GNUNET_CRYPTO_hash (&ub_enc->verification_key,
		      sizeof (ub_enc->verification_key),
		      &query);
  GNUNET_free (nsd);

  uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext);
  uc->cont = cont;
  uc->cont_cls = cont_cls;
  uc->qre =
    GNUNET_DATASTORE_put (dsh, 0, &query,
			  ulen + slen + mdsize + sizeof (struct UBlock),
			  ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK,
			  bo->content_priority, bo->anonymity_level,
			  bo->replication_level, bo->expiration_time,
			  -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
			  &ublock_put_cont, uc);
  return uc;
}
Пример #4
0
static int
testLocation ()
{
  struct GNUNET_FS_Uri *uri;
  char *uric;
  struct GNUNET_FS_Uri *uri2;
  struct GNUNET_FS_Uri *baseURI;
  char *emsg;
  struct GNUNET_CRYPTO_EddsaPrivateKey *pk;

  baseURI =
      GNUNET_FS_uri_parse
      ("gnunet://fs/chk/4QZP479A9SKGFNMQ2ZBCYE71YV2QMTVGWTVPB6A10ASVCKXDHB05DKPSC7ZF6E9P9W1VE47394EQY7NXA47Q6R35M7P1MJPGP59D1Z8.D54QD1K5XCG5878T6YZ19AM60MQ6FC0YNVK7QY08KK0KM0FJJ3KQWYG112FN5T07KN7J0X35DF6WVBT9B8ZMZ3X2BXJ22X3KFQ6MV2G.15999",
       &emsg);
  GNUNET_assert (baseURI != NULL);
  GNUNET_assert (emsg == NULL);
  pk = GNUNET_CRYPTO_eddsa_key_create ();
  uri = GNUNET_FS_uri_loc_create (baseURI,
                                  pk,
                                  GNUNET_TIME_absolute_get ());
  GNUNET_free (pk);
  if (NULL == uri)
  {
    GNUNET_break (0);
    GNUNET_FS_uri_destroy (baseURI);
    return 1;
  }
  if (! GNUNET_FS_uri_test_loc (uri))
  {
    GNUNET_break (0);
    GNUNET_FS_uri_destroy (uri);
    GNUNET_FS_uri_destroy (baseURI);
    return 1;
  }
  uri2 = GNUNET_FS_uri_loc_get_uri (uri);
  if (! GNUNET_FS_uri_test_equal (baseURI, uri2))
  {
    GNUNET_break (0);
    GNUNET_FS_uri_destroy (uri);
    GNUNET_FS_uri_destroy (uri2);
    GNUNET_FS_uri_destroy (baseURI);
    return 1;
  }
  GNUNET_FS_uri_destroy (uri2);
  GNUNET_FS_uri_destroy (baseURI);
  uric = GNUNET_FS_uri_to_string (uri);
#if 0
  /* not for the faint of heart: */
  printf ("URI: `%s'\n", uric);
#endif
  uri2 = GNUNET_FS_uri_parse (uric, &emsg);
  GNUNET_free (uric);
  if (uri2 == NULL)
  {
    fprintf (stderr, "URI parsing failed: %s\n", emsg);
    GNUNET_break (0);
    GNUNET_FS_uri_destroy (uri);
    GNUNET_free (emsg);
    return 1;
  }
  GNUNET_assert (NULL == emsg);
  if (GNUNET_YES != GNUNET_FS_uri_test_equal (uri, uri2))
  {
    GNUNET_break (0);
    GNUNET_FS_uri_destroy (uri);
    GNUNET_FS_uri_destroy (uri2);
    return 1;
  }
  GNUNET_FS_uri_destroy (uri2);
  GNUNET_FS_uri_destroy (uri);
  return 0;
}
Пример #5
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;
}
Пример #6
0
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;
}
Пример #7
0
/**
 * Publish a CHK under various keywords on GNUnet.
 *
 * @param h handle to the file sharing subsystem
 * @param ksk_uri keywords to use
 * @param meta metadata to use
 * @param uri URI to refer to in the KBlock
 * @param bo per-block options
 * @param options publication options
 * @param cont continuation
 * @param cont_cls closure for cont
 * @return NULL on error ('cont' will still be called)
 */
struct GNUNET_FS_PublishKskContext *
GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
                       const struct GNUNET_FS_Uri *ksk_uri,
                       const struct GNUNET_CONTAINER_MetaData *meta,
                       const struct GNUNET_FS_Uri *uri,
                       const struct GNUNET_FS_BlockOptions *bo,
                       enum GNUNET_FS_PublishOptions options,
                       GNUNET_FS_PublishContinuation cont, void *cont_cls)
{
  struct GNUNET_FS_PublishKskContext *pkc;
  char *uris;
  size_t size;
  char *kbe;
  char *sptr;

  GNUNET_assert (NULL != uri);
  pkc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishKskContext));
  pkc->h = h;
  pkc->bo = *bo;
  pkc->cont = cont;
  pkc->cont_cls = cont_cls;
  if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
  {
    pkc->dsh = GNUNET_DATASTORE_connect (h->cfg);
    if (NULL == pkc->dsh)
    {
      cont (cont_cls, NULL, _("Could not connect to datastore."));
      GNUNET_free (pkc);
      return NULL;
    }
  }
  if (meta == NULL)
    pkc->mdsize = 0;
  else
    pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
  GNUNET_assert (pkc->mdsize >= 0);
  uris = GNUNET_FS_uri_to_string (uri);
  pkc->slen = strlen (uris) + 1;
  size = pkc->mdsize + sizeof (struct KBlock) + pkc->slen;
  if (size > MAX_KBLOCK_SIZE)
  {
    size = MAX_KBLOCK_SIZE;
    pkc->mdsize = size - sizeof (struct KBlock) - pkc->slen;
  }
  pkc->kb = GNUNET_malloc (size);
  kbe = (char *) &pkc->kb[1];
  memcpy (kbe, uris, pkc->slen);
  GNUNET_free (uris);
  sptr = &kbe[pkc->slen];
  if (meta != NULL)
    pkc->mdsize =
        GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize,
                                              GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
  if (-1 == pkc->mdsize)
  {
    GNUNET_break (0);
    GNUNET_free (pkc->kb);
    if (pkc->dsh != NULL)
    {
      GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
      pkc->dsh = NULL;
    }
    GNUNET_free (pkc);
    cont (cont_cls, NULL, _("Internal error."));
    return NULL;
  }
  size = sizeof (struct KBlock) + pkc->slen + pkc->mdsize;

  pkc->cpy = GNUNET_malloc (size);
  pkc->cpy->purpose.size =
      htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
             sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
             pkc->mdsize + pkc->slen);
  pkc->cpy->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
  pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
  pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc);
  return pkc;
}
Пример #8
0
/**
 * Called by FS client to give information about the progress of an
 * operation.
 *
 * @param cls closure
 * @param info details about the event, specifying the event type
 *        and various bits about the event
 * @return client-context (for the next progress call
 *         for this operation; should be set to NULL for
 *         SUSPEND and STOPPED events).  The value returned
 *         will be passed to future callbacks in the respective
 *         field in the GNUNET_FS_ProgressInfo struct.
 */
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
{
  static unsigned int cnt;
  int is_directory;
  char *uri;
  char *filename;

  switch (info->status)
  {
  case GNUNET_FS_STATUS_SEARCH_START:
    break;
  case GNUNET_FS_STATUS_SEARCH_RESULT:
    if (db != NULL)
      GNUNET_FS_directory_builder_add (db,
                                       info->value.search.specifics.result.uri,
                                       info->value.search.specifics.result.meta,
                                       NULL);
    uri = GNUNET_FS_uri_to_string (info->value.search.specifics.result.uri);
    printf ("#%u:\n", cnt++);
    filename =
        GNUNET_CONTAINER_meta_data_get_by_type (info->value.search.
                                                specifics.result.meta,
                                                EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
    is_directory =
        GNUNET_FS_meta_data_test_for_directory (info->value.search.
                                                specifics.result.meta);
    if (filename != NULL)
    {
      GNUNET_DISK_filename_canonicalize (filename);
      if (GNUNET_YES == is_directory)
        printf ("gnunet-download -o \"%s%s\" -R %s\n", filename, GNUNET_FS_DIRECTORY_EXT, uri);
      else
        printf ("gnunet-download -o \"%s\" %s\n", filename, uri);
    }
    else if (GNUNET_YES == is_directory)
      printf ("gnunet-download -o \"collection%s\" -R %s\n", GNUNET_FS_DIRECTORY_EXT, uri);
    else
      printf ("gnunet-download %s\n", uri);
    if (verbose)
      GNUNET_CONTAINER_meta_data_iterate (info->value.search.specifics.
                                          result.meta, &item_printer, NULL);
    printf ("\n");
    fflush (stdout);
    GNUNET_free_non_null (filename);
    GNUNET_free (uri);
    results++;
    if ((results_limit > 0) && (results >= results_limit))
      GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_SEARCH_UPDATE:
    break;
  case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
    /* ignore */
    break;
  case GNUNET_FS_STATUS_SEARCH_ERROR:
    FPRINTF (stderr, _("Error searching: %s.\n"),
             info->value.search.specifics.error.message);
    GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_SEARCH_STOPPED:
    GNUNET_SCHEDULER_add_now (&clean_task, NULL);
    break;
  default:
    FPRINTF (stderr, _("Unexpected status: %d\n"), info->status);
    break;
  }
  return NULL;
}
Пример #9
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++;
}