static void
check_value (void *cls, const GNUNET_HashCode * key, size_t size,
             const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
             uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
             uint64_t uid)
{
  struct CpsRunContext *crc = cls;
  int i;

  if (NULL == key)
  {
    crc->phase = RP_GET_FAIL;
    GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    return;
  }
  i = crc->i;
  GNUNET_assert (size == get_size (i));
  GNUNET_assert (0 == memcmp (data, get_data (i), size));
  GNUNET_assert (type == get_type (i));
  GNUNET_assert (priority == get_priority (i));
  GNUNET_assert (anonymity == get_anonymity (i));
  GNUNET_assert (expiration.abs_value == get_expiration (i).abs_value);
  crc->offset++;
  crc->i--;
  if (crc->i == 0)
    crc->phase = RP_DONE;
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
static void
list_indexed_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{

  GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
static void
check_success (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration,  const char *msg)
{
  struct CpsRunContext *crc = cls;

  if (GNUNET_OK != success)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Check success failed: `%s'\n", msg);
    crc->phase = RP_ERROR;
    GNUNET_SCHEDULER_add_now (&run_continuation, crc);
    return;
  }
#if REPORT_ID
  FPRINTF (stderr, "%s",  "I");
#endif
  stored_bytes += crc->size;
  stored_ops++;
  stored_entries++;
  crc->j++;
  if (crc->j >= PUT_10)
  {
    crc->j = 0;
    crc->i++;
    if (crc->i == ITERATIONS)
      crc->phase = RP_DONE;
    else
      crc->phase = RP_CUT;
  }
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
Beispiel #4
0
/**
 * Transmit DROP message to datastore service.
 *
 * @param cls the 'struct GNUNET_DATASTORE_Handle'
 * @param size number of bytes that can be copied to buf
 * @param buf where to copy the drop message
 * @return number of bytes written to buf
 */
static size_t
transmit_drop (void *cls, size_t size, void *buf)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_MessageHeader *hdr;

  if (buf == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         _("Failed to transmit request to drop database.\n"));
    GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h,
				       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    return 0;
  }
  GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
  hdr = buf;
  hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
  hdr->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_DROP);
  GNUNET_SCHEDULER_add_continuation (&disconnect_after_drop, h,
				     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
  return sizeof (struct GNUNET_MessageHeader);
}
static void
check_success (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg)
{
  struct CpsRunContext *crc = cls;

  if (GNUNET_OK != success)
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", msg);
  GNUNET_assert (GNUNET_OK == success);
  GNUNET_free_non_null (crc->data);
  crc->data = NULL;
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
static void
check_nothing (void *cls, const GNUNET_HashCode * key, size_t size,
               const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority,
               uint32_t anonymity, struct GNUNET_TIME_Absolute expiration,
               uint64_t uid)
{
  struct CpsRunContext *crc = cls;

  GNUNET_assert (key == NULL);
  if (0 == --crc->i)
    crc->phase = RP_DONE;
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
static void
run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg)
{
  struct CpsRunContext *crc = cls;

  if (success != GNUNET_YES)
  {
    FPRINTF (stderr,
             "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n",
             msg);
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    return;
  }
  GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
Beispiel #8
0
/**
 * Receive confirmation from test, service is up.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_CLIENT_Connection *client = cls;

  /* We may want to consider looking at the reply in more
   * detail in the future, for example, is this the
   * correct service? FIXME! */
  if (NULL != msg)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received confirmation that service is running.\n");
    GNUNET_SCHEDULER_add_continuation (client->test_cb, client->test_cb_cls,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
  }
  else
  {
    service_test_error (client->test_cb, client->test_cb_cls);
  }
  GNUNET_CLIENT_disconnect (client);
}
Beispiel #9
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)
{
  const char *s;

  switch (info->status)
  {
  case GNUNET_FS_STATUS_UNINDEX_START:
    break;
  case GNUNET_FS_STATUS_UNINDEX_PROGRESS:
    if (verbose)
    {
      s = GNUNET_STRINGS_relative_time_to_string (info->value.unindex.eta, GNUNET_YES);
      FPRINTF (stdout, _("Unindexing at %llu/%llu (%s remaining)\n"),
               (unsigned long long) info->value.unindex.completed,
               (unsigned long long) info->value.unindex.size, s);
    }
    break;
  case GNUNET_FS_STATUS_UNINDEX_ERROR:
    FPRINTF (stderr, _("Error unindexing: %s.\n"),
             info->value.unindex.specifics.error.message);
    GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_UNINDEX_COMPLETED:
    FPRINTF (stdout, "%s",  _("Unindexing done.\n"));
    GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_UNINDEX_STOPPED:
    GNUNET_SCHEDULER_add_continuation (&cleanup_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  default:
    FPRINTF (stderr, _("Unexpected status: %d\n"), info->status);
    break;
  }
  return NULL;
}
Beispiel #10
0
/**
 * Test if the service is running.  If we are given a UNIXPATH or a local address,
 * we do this NOT by trying to connect to the service, but by trying to BIND to
 * the same port.  If the BIND fails, we know the service is running.
 *
 * @param service name of the service to wait for
 * @param cfg configuration to use
 * @param timeout how long to wait at most
 * @param task task to run if service is running
 *        (reason will be "PREREQ_DONE" (service running)
 *         or "TIMEOUT" (service not known to be running))
 * @param task_cls closure for task
 */
void
GNUNET_CLIENT_service_test (const char *service,
                            const struct GNUNET_CONFIGURATION_Handle *cfg,
                            struct GNUNET_TIME_Relative timeout,
                            GNUNET_SCHEDULER_Task task, void *task_cls)
{
  char *hostname;
  unsigned long long port;
  struct GNUNET_NETWORK_Handle *sock;
  struct GNUNET_CLIENT_Connection *client;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n",
       service);
#ifdef AF_UNIX
  {
    /* probe UNIX support */
    struct sockaddr_un s_un;
    size_t slen;
    char *unixpath;

    unixpath = NULL;
    if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath)))  /* We have a non-NULL unixpath, does that mean it's valid? */
    {
      if (strlen (unixpath) >= sizeof (s_un.sun_path))
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
             (unsigned long long) sizeof (s_un.sun_path));
	unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
        LOG (GNUNET_ERROR_TYPE_INFO,
             _("Using `%s' instead\n"), unixpath);
      }
    }
    if (NULL != unixpath)
    {
      sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
      if (NULL != sock)
      {
	memset (&s_un, 0, sizeof (s_un));
	s_un.sun_family = AF_UNIX;
	slen = strlen (unixpath) + 1;
	if (slen >= sizeof (s_un.sun_path))
	  slen = sizeof (s_un.sun_path) - 1;
	memcpy (s_un.sun_path, unixpath, slen);
	s_un.sun_path[slen] = '\0';
	slen = sizeof (struct sockaddr_un);
#if LINUX
	s_un.sun_path[0] = '\0';
#endif
#if HAVE_SOCKADDR_IN_SIN_LEN
	s_un.sun_len = (u_char) slen;
#endif
	if (GNUNET_OK !=
	    GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un,
					slen))
        {
	  /* failed to bind => service must be running */
	  GNUNET_free (unixpath);
	  (void) GNUNET_NETWORK_socket_close (sock);
	  GNUNET_SCHEDULER_add_continuation (task, task_cls,
					     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
	  return;
	}
	(void) GNUNET_NETWORK_socket_close (sock);        
        /* let's try IP */
      }
    }
    GNUNET_free_non_null (unixpath);
  }
#endif

  hostname = NULL;
  if ((GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) ||
      (port > 65535) ||
      (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
                                              &hostname)))
  {
    /* UNIXPATH failed (if possible) AND IP failed => error */
    service_test_error (task, task_cls);
    return;
  }

  if (0 == strcmp ("localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in s_in;

    memset (&s_in, 0, sizeof (s_in));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in.sin_len = sizeof (struct sockaddr_in);
#endif
    s_in.sin_family = AF_INET;
    s_in.sin_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in,
                                      sizeof (s_in)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        GNUNET_SCHEDULER_add_continuation (task, task_cls,
                                           GNUNET_SCHEDULER_REASON_PREREQ_DONE);
        return;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (0 == strcmp ("ip6-localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in6 s_in6;

    memset (&s_in6, 0, sizeof (s_in6));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in6.sin6_len = sizeof (struct sockaddr_in6);
#endif
    s_in6.sin6_family = AF_INET6;
    s_in6.sin6_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6,
                                      sizeof (s_in6)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        GNUNET_SCHEDULER_add_continuation (task, task_cls,
                                           GNUNET_SCHEDULER_REASON_PREREQ_DONE);
        return;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (((0 == strcmp ("localhost", hostname)) ||
       (0 == strcmp ("ip6-localhost", hostname)))
#if !LINUX
      && 0
#endif
      )
  {
    /* all binds succeeded => claim service not running right now */
    GNUNET_free_non_null (hostname);
    service_test_error (task, task_cls);
    return;
  }
  GNUNET_free_non_null (hostname);

  /* non-localhost, try 'connect' method */
  client = GNUNET_CLIENT_connect (service, cfg);
  if (NULL == client)
  {
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Could not connect to service `%s', must not be running.\n"),
         service);
    service_test_error (task, task_cls);
    return;
  }
  client->test_cb = task;
  client->test_cb_cls = task_cls;
  client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
  if (NULL == GNUNET_CLIENT_notify_transmit_ready (client,
						   sizeof (struct GNUNET_MessageHeader),
						   timeout, GNUNET_YES, &write_test,
						   client))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         _("Failure to transmit request to service `%s'\n"), service);
    service_test_error (task, task_cls);
    GNUNET_CLIENT_disconnect (client);
    return;
  }
}
Beispiel #11
0
/**
 * Report service unavailable.
 */
static void
service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls)
{
  GNUNET_SCHEDULER_add_continuation (task, task_cls,
                                     GNUNET_SCHEDULER_REASON_TIMEOUT);
}
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
{
  void *ret;

  ret = NULL;
  switch (event->status)
  {
  case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
    ret = event->value.publish.cctx;
    printf ("Publish complete,  %llu kbps.\n",
            (unsigned long long) (FILESIZE * 1000 /
                                  (1 +
                                   GNUNET_TIME_absolute_get_duration
                                   (start).rel_value) / 1024));
    if (0 == strcmp ("list_indexed-context-dir", event->value.publish.cctx))
      GNUNET_SCHEDULER_add_continuation (&list_indexed_task, NULL,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);

    break;
  case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
    ret = event->value.publish.cctx;
    GNUNET_assert (publish == event->value.publish.pc);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Publish is progressing (%llu/%llu at level %u off %llu)...\n",
		(unsigned long long) event->value.publish.completed,
		(unsigned long long) event->value.publish.size,
		event->value.publish.specifics.progress.depth,
		(unsigned long long) event->value.publish.specifics.
		progress.offset);
    break;
  case GNUNET_FS_STATUS_PUBLISH_ERROR:
    ret = event->value.publish.cctx;
    FPRINTF (stderr, "Error publishing file: %s\n",
             event->value.publish.specifics.error.message);
    err = 1;
    if (0 == strcmp ("list_indexed-context-dir", event->value.publish.cctx))
      GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_PUBLISH_START:
    ret = event->value.publish.cctx;
    if (0 == strcmp ("list_indexed-context1", event->value.publish.cctx))
    {
      GNUNET_assert (0 ==
                     strcmp ("list_indexed-context-dir",
                             event->value.publish.pctx));
      GNUNET_assert (FILESIZE == event->value.publish.size);
      GNUNET_assert (0 == event->value.publish.completed);
      GNUNET_assert (1 == event->value.publish.anonymity);
    }
    else if (0 == strcmp ("list_indexed-context2", event->value.publish.cctx))
    {
      GNUNET_assert (0 ==
                     strcmp ("list_indexed-context-dir",
                             event->value.publish.pctx));
      GNUNET_assert (FILESIZE == event->value.publish.size);
      GNUNET_assert (0 == event->value.publish.completed);
      GNUNET_assert (2 == event->value.publish.anonymity);
    }
    else if (0 ==
             strcmp ("list_indexed-context-dir", event->value.publish.cctx))
    {
      GNUNET_assert (0 == event->value.publish.completed);
      GNUNET_assert (3 == event->value.publish.anonymity);
    }
    else
      GNUNET_assert (0);
    break;
  case GNUNET_FS_STATUS_PUBLISH_STOPPED:
    if (0 == strcmp ("list_indexed-context-dir", event->value.publish.cctx))
    {
      GNUNET_assert (publish == event->value.publish.pc);
      publish = NULL;
    }
    break;
  default:
    printf ("Unexpected event: %d\n", event->status);
    break;
  }
  return ret;
}
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
{
  const char *keywords[] = {
    "down_foo"
  };
  struct GNUNET_FS_Uri *kuri;

  switch (event->status)
  {
  case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Publish is progressing (%llu/%llu at level %u off %llu)...\n",
		(unsigned long long) event->value.publish.completed,
		(unsigned long long) event->value.publish.size,
		event->value.publish.specifics.progress.depth,
		(unsigned long long) event->value.publish.specifics.
		progress.offset);
    break;
  case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
    kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords);
    start = GNUNET_TIME_absolute_get ();
    GNUNET_FS_search_start (fs, kuri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
                            "search");
    GNUNET_FS_uri_destroy (kuri);
    GNUNET_assert (search != NULL);
    break;
  case GNUNET_FS_STATUS_PUBLISH_SUSPEND:
    if (event->value.publish.pc == publish)
      publish = NULL;
    break;
  case GNUNET_FS_STATUS_PUBLISH_RESUME:
    if (NULL == publish)
      publish = event->value.publish.pc;
    break;
  case GNUNET_FS_STATUS_SEARCH_RESULT:
    /* FIXME: consider_restart (event->status); cannot be tested with
     * search result since we exit here after the first one... */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Search complete.\n");
    GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_PUBLISH_ERROR:
    FPRINTF (stderr, "Error publishing file: %s\n",
             event->value.publish.specifics.error.message);
    GNUNET_break (0);
    GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_SEARCH_ERROR:
    FPRINTF (stderr, "Error searching file: %s\n",
             event->value.search.specifics.error.message);
    GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_SEARCH_SUSPEND:
    if (event->value.search.sc == search)
      search = NULL;
    break;
  case GNUNET_FS_STATUS_SEARCH_RESUME:
    if (NULL == search)
    {
      search = event->value.search.sc;
      return "search";
    }
    break;
  case GNUNET_FS_STATUS_PUBLISH_START:
    GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx));
    GNUNET_assert (NULL == event->value.publish.pctx);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (0 == event->value.publish.completed);
    GNUNET_assert (1 == event->value.publish.anonymity);
    break;
  case GNUNET_FS_STATUS_PUBLISH_STOPPED:
    GNUNET_assert (publish == event->value.publish.pc);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (1 == event->value.publish.anonymity);
    GNUNET_FS_stop (fs);
    fs = NULL;
    break;
  case GNUNET_FS_STATUS_SEARCH_START:
    consider_restart (event->status);
    GNUNET_assert (search == NULL);
    search = event->value.search.sc;
    GNUNET_assert (0 == strcmp ("search", event->value.search.cctx));
    GNUNET_assert (1 == event->value.search.anonymity);
    break;
  case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
    break;
  case GNUNET_FS_STATUS_SEARCH_STOPPED:
    GNUNET_assert (search == event->value.search.sc);
    GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    search = NULL;
    break;
  default:
    FPRINTF (stderr, "Unexpected event: %d\n", event->status);
    break;
  }
  return NULL;
}
static void
run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct CpsRunContext *crc = cls;
  size_t size;
  static struct GNUNET_HashCode key;
  static char data[65536];
  int i;
  int k;
  char gstr[128];

  ok = (int) crc->phase;
  switch (crc->phase)
  {
  case RP_PUT:
    memset (&key, 256 - crc->i, sizeof (struct GNUNET_HashCode));
    i = crc->j;
    k = crc->i;
    /* most content is 32k */
    size = 32 * 1024;
    if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16) == 0) /* but some of it is less! */
      size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024);
    crc->size = size = size - (size & 7);       /* always multiple of 8 */
    GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &key);
    memset (data, i, size);
    if (i > 255)
      memset (data, i - 255, size / 2);
    data[0] = k;
    GNUNET_assert (NULL !=
                   GNUNET_DATASTORE_put (datastore, 0, &key, size, data, i + 1,
                                         GNUNET_CRYPTO_random_u32
                                         (GNUNET_CRYPTO_QUALITY_WEAK, 100), i,
                                         0,
                                         GNUNET_TIME_relative_to_absolute
                                         (GNUNET_TIME_relative_multiply
                                          (GNUNET_TIME_UNIT_SECONDS,
                                           GNUNET_CRYPTO_random_u32
                                           (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
                                         1, 1, TIMEOUT, &check_success, crc));
    break;
  case RP_CUT:
    /* trim down below MAX_SIZE again */
    GNUNET_assert (NULL !=
                   GNUNET_DATASTORE_get_for_replication (datastore, 1, 1,
                                                         TIMEOUT, &delete_value,
                                                         crc));
    break;
  case RP_REPORT:
    printf (
#if REPORT_ID
             "\n"
#endif
             "Stored %llu kB / %lluk ops / %llu ops/s\n", stored_bytes / 1024,  /* used size in k */
             stored_ops / 1024, /* total operations (in k) */
             1000 * stored_ops / (1 +
                                  GNUNET_TIME_absolute_get_duration
                                  (start_time).rel_value));
    crc->phase = RP_PUT;
    crc->j = 0;
    GNUNET_SCHEDULER_add_continuation (&run_continuation, crc,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case RP_DONE:
    GNUNET_snprintf (gstr, sizeof (gstr), "DATASTORE-%s", plugin_name);
    if ((crc->i == ITERATIONS) && (stored_ops > 0))
      GAUGER (gstr, "PUT operation duration",
              GNUNET_TIME_absolute_get_duration (start_time).rel_value /
              stored_ops, "ms/operation");
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    ok = 0;
    break;
  case RP_ERROR:
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    ok = 1;
    break;
  default:
    GNUNET_assert (0);
  }
}
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
{

  switch (event->status)
  {
  case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
#if VERBOSE
    printf ("Publish is progressing (%llu/%llu at level %u off %llu)...\n",
            (unsigned long long) event->value.publish.completed,
            (unsigned long long) event->value.publish.size,
            event->value.publish.specifics.progress.depth,
            (unsigned long long) event->value.publish.specifics.
            progress.offset);
#endif
    break;
  case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
    printf ("Publishing complete, %llu kbps.\n",
            (unsigned long long) (FILESIZE * 1000 /
                                  (1 +
                                   GNUNET_TIME_absolute_get_duration
                                   (start).rel_value) / 1024));
    start = GNUNET_TIME_absolute_get ();
    unindex = GNUNET_FS_unindex_start (fs, fn, "unindex");
    GNUNET_assert (unindex != NULL);
    break;
  case GNUNET_FS_STATUS_UNINDEX_COMPLETED:
    printf ("Unindex complete,  %llu kbps.\n",
            (unsigned long long) (FILESIZE * 1000 /
                                  (1 +
                                   GNUNET_TIME_absolute_get_duration
                                   (start).rel_value) / 1024));
    GNUNET_SCHEDULER_add_continuation (&abort_unindex_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_UNINDEX_PROGRESS:
    GNUNET_assert (unindex == event->value.unindex.uc);
#if VERBOSE
    printf ("Unindex is progressing (%llu/%llu at level %u off %llu)...\n",
            (unsigned long long) event->value.unindex.completed,
            (unsigned long long) event->value.unindex.size,
            event->value.unindex.specifics.progress.depth,
            (unsigned long long) event->value.unindex.specifics.
            progress.offset);
#endif
    break;
  case GNUNET_FS_STATUS_PUBLISH_ERROR:
    FPRINTF (stderr, "Error publishing file: %s\n",
             event->value.publish.specifics.error.message);
    GNUNET_break (0);
    GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_UNINDEX_ERROR:
    FPRINTF (stderr, "Error unindexing file: %s\n",
             event->value.unindex.specifics.error.message);
    GNUNET_SCHEDULER_add_continuation (&abort_unindex_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  case GNUNET_FS_STATUS_PUBLISH_START:
    GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx));
    GNUNET_assert (NULL == event->value.publish.pctx);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (0 == event->value.publish.completed);
    GNUNET_assert (1 == event->value.publish.anonymity);
    break;
  case GNUNET_FS_STATUS_PUBLISH_STOPPED:
    GNUNET_assert (publish == event->value.publish.pc);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (1 == event->value.publish.anonymity);
    GNUNET_FS_stop (fs);
    fs = NULL;
    break;
  case GNUNET_FS_STATUS_UNINDEX_START:
    GNUNET_assert (unindex == NULL);
    GNUNET_assert (0 == strcmp ("unindex", event->value.unindex.cctx));
    GNUNET_assert (0 == strcmp (fn, event->value.unindex.filename));
    GNUNET_assert (FILESIZE == event->value.unindex.size);
    GNUNET_assert (0 == event->value.unindex.completed);
    break;
  case GNUNET_FS_STATUS_UNINDEX_STOPPED:
    GNUNET_assert (unindex == event->value.unindex.uc);
    GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
                                       GNUNET_SCHEDULER_REASON_PREREQ_DONE);
    break;
  default:
    printf ("Unexpected event: %d\n", event->status);
    break;
  }
  return NULL;
}