+ }
+ if ((status == GNUNET_SYSERR) && (emsg == NULL))
+ {
+ GNUNET_break (0);
+ emsg = _("Invalid error message received from datastore service");
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Received status %d/%s\n", (int) status, emsg);
+ GNUNET_STATISTICS_update (h->stats,
+ gettext_noop ("# status messages received"), 1,
+ GNUNET_NO);
+ h->retry_time.rel_value = 0;
+ process_queue (h);
+ if (rc.cont != NULL)
+ rc.cont (rc.cont_cls, status,
+ GNUNET_TIME_absolute_ntoh (sm->min_expiration),
+ emsg);
+}
+
+
+/**
+ * Store an item in the datastore. If the item is already present,
+ * the priorities are summed up and the higher expiration time and
+ * lower anonymity level is used.
+ *
+ * @param h handle to the datastore
+ * @param rid reservation ID to use (from "reserve"); use 0 if no
+ * prior reservation was made
+ * @param key key for the value
+ * @param size number of bytes in data
+ * @param data content stored
+ * @param type type of the content
+ * @param priority priority of the content
+ * @param anonymity anonymity-level for the content
+ * @param replication how often should the content be replicated to other peers?
+ * @param expiration expiration time for the content
+ * @param queue_priority ranking of this request in the priority queue
+ * @param max_queue_size at what queue size should this request be dropped
+ * (if other requests of higher priority are in the queue)
+ * @param timeout timeout for the operation
+ * @param cont continuation to call when done
+ * @param cont_cls closure for cont
+ * @return NULL if the entry was not queued, otherwise a handle that can be used to
+ * cancel; note that even if NULL is returned, the callback will be invoked
+ * (or rather, will already have been invoked)
+ */
+struct GNUNET_DATASTORE_QueueEntry *
+GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid,
+ const struct GNUNET_HashCode * key, size_t size,
+ const void *data, enum GNUNET_BLOCK_Type type,
+ uint32_t priority, uint32_t anonymity,
+ uint32_t replication,
+ struct GNUNET_TIME_Absolute expiration,
+ unsigned int queue_priority, unsigned int max_queue_size,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_DATASTORE_ContinuationWithStatus cont,
+ void *cont_cls)
+{
+ struct GNUNET_DATASTORE_QueueEntry *qe;
+ struct DataMessage *dm;
+ size_t msize;
+ union QueueContext qc;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Asked to put %u bytes of data under key `%s' for %llu ms\n", size,
+ GNUNET_h2s (key),
+ GNUNET_TIME_absolute_get_remaining (expiration).rel_value);
+ msize = sizeof (struct DataMessage) + size;
+ GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
+ qc.sc.cont = cont;
+ qc.sc.cont_cls = cont_cls;
+ qe = make_queue_entry (h, msize, queue_priority, max_queue_size, timeout,
+ &process_status_message, &qc);
+ if (qe == NULL)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for PUT\n");
+ return NULL;
+ }
+ GNUNET_STATISTICS_update (h->stats, gettext_noop ("# PUT requests executed"),
+ 1, GNUNET_NO);
+ dm = (struct DataMessage *) &qe[1];
+ dm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_PUT);
+ dm->header.size = htons (msize);
+ dm->rid = htonl (rid);
+ dm->size = htonl ((uint32_t) size);
+ dm->type = htonl (type);
+ dm->priority = htonl (priority);
+ dm->anonymity = htonl (anonymity);
+ dm->replication = htonl (replication);
+ dm->reserved = htonl (0);
+ dm->uid = GNUNET_htonll (0);
+ dm->expiration = GNUNET_TIME_absolute_hton (expiration);
+ dm->key = *key;
+ memcpy (&dm[1], data, size);