You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
* @file gnunet-namestore.c
*/
static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
+/**
+ * Queue entry for the 'set/replace' operation.
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *set_qe;
+
/**
* Name of the records to add/list/remove.
*/
static size_t data_size;
/**
- * Expirationstring converted to relative time.
- */
-static struct GNUNET_TIME_Relative etime_rel;
-
-/**
- * Expirationstring converted to absolute time.
+ * Expiration string converted to numeric value.
*/
-static struct GNUNET_TIME_Absolute etime_abs;
+static uint64_t etime;
/**
* Is expiration time relative or absolute time?
GNUNET_NAMESTORE_cancel (add_qe);
add_qe = NULL;
}
+ if (NULL != set_qe)
+ {
+ GNUNET_NAMESTORE_cancel (set_qe);
+ set_qe = NULL;
+ }
if (NULL != add_qe_uri)
{
GNUNET_NAMESTORE_cancel (add_qe_uri);
unsigned int rd_len,
const struct GNUNET_GNSRECORD_Data *rd)
{
+ (void) cls;
+ (void) zone_key;
get_qe = NULL;
display_record (rname,
rd_len,
rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
if (1 != is_public)
rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
+ rde->expiration_time = etime;
if (GNUNET_YES == etime_is_rel)
- {
- rde->expiration_time = etime_rel.rel_value_us;
rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
- }
- else if (GNUNET_NO == etime_is_rel)
- rde->expiration_time = etime_abs.abs_value_us;
- else
+ else if (GNUNET_NO != etime_is_rel)
rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
GNUNET_assert (NULL != name);
add_qe = GNUNET_NAMESTORE_records_store (ns,
}
-#if 0
-/* globals? */
-unsigned int rd_count;
-struct GNUNET_GNSRECORD_Data *rd;
-
-
-rd_count = 0;
-for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
- rd_count++;
-rd = GNUNET_new_array (rd_count,
- struct GNUNET_GNSRECORD_Data);
-rd_count = 0;
-for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
+/**
+ * Function called when namestore is done with the replace
+ * operation.
+ *
+ * @param cls NULL
+ * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ * #GNUNET_NO if content was already there or not found
+ * #GNUNET_YES (or other positive value) on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+static void
+replace_cont (void *cls,
+ int success,
+ const char *emsg)
{
- rd[rd_count] = e->record;
- rd_count++;
+ (void) cls;
+
+ set_qe = NULL;
+ if (GNUNET_OK != success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Failed to replace records: %s\n"),
+ emsg);
+ ret = 1; /* fail from 'main' */
+ }
+ GNUNET_SCHEDULER_shutdown ();
}
-/* if add: */
-qe = GNUNET_NAMESTORE_records_store (...,
- rd_count,
- rd,
- &my_cont
- ..);
-
-in 'my_cont' and/or shutdown:
-
-qe = NULL;
-GNUNET_free (rd);
-
-in shutdown:
-
-if NULL != qe NAMESTORE_cancel (qe);
-GNUNET_free (rd);
-
-#endif
-
/**
* Callback invoked from identity service with ego information.
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct GNUNET_CRYPTO_EcdsaPublicKey pub;
struct GNUNET_GNSRECORD_Data rd;
- uint64_t etime;
el = NULL;
if (NULL == ego)
GNUNET_free_non_null (ego_name);
ego_name = NULL;
- if (! (add|del|list|(NULL != nickstring)|(NULL != uri)|(NULL != reverse_pkey)) )
+ if (! (add|del|list|(NULL != nickstring)|(NULL != uri)|(NULL != reverse_pkey)|(NULL != recordset)) )
{
/* nothing more to be done */
fprintf (stderr,
return;
}
GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey,
- &pub);
-
+ &pub);
ns = GNUNET_NAMESTORE_connect (cfg);
if (NULL == ns)
{
_("Failed to connect to namestore\n"));
return;
}
+
+ if (NULL != recordset)
+ {
+ /* replace entire record set */
+ unsigned int rd_count;
+ struct GNUNET_GNSRECORD_Data *rd;
+
+ if (NULL == name)
+ {
+ fprintf (stderr,
+ _("Missing option `%s' for operation `%s'\n"),
+ "-R", _("replace"));
+ GNUNET_SCHEDULER_shutdown ();
+ ret = 1;
+ return;
+ }
+ rd_count = 0;
+ for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
+ rd_count++;
+ rd = GNUNET_new_array (rd_count,
+ struct GNUNET_GNSRECORD_Data);
+ rd_count = 0;
+ for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
+ {
+ rd[rd_count] = e->record;
+ rd_count++;
+ }
+ set_qe = GNUNET_NAMESTORE_records_store (ns,
+ &zone_pkey,
+ name,
+ rd_count,
+ rd,
+ &replace_cont,
+ NULL);
+ GNUNET_free (rd);
+ return;
+ }
+
if (add)
{
if (NULL == name)
(void) cls;
(void) args;
(void) cfgfile;
+ if (NULL != args[0])
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Superfluous command line arguments (starting with `%s') ignored\n"),
+ args[0]);
if ( (NULL != args[0]) &&
(NULL == uri) )
uri = GNUNET_strdup (args[0]);
* @param option name of the option (typically 'R')
* @param value command line argument given; format is
* "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs),
+ * always given in seconds (without the unit),
* TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or
* a combination of 's' (shadow) and 'p' (public) and VALUE is the
* value (in human-readable format)
struct GNUNET_GNSRECORD_Data record;
char *cp;
char *tok;
+ char *saveptr;
int etime_is_rel;
void *raw_data;
+ (void) ctx;
+ (void) option;
cp = GNUNET_strdup (value);
- tok = strtok (cp, " ");
+ tok = strtok_r (cp, " ", &saveptr);
if (NULL == tok)
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Empty record line argument is not allowed.\n"));
GNUNET_free (cp);
return GNUNET_SYSERR;
}
- if (GNUNET_OK !=
- parse_expiration (tok,
- &etime_is_rel,
- &record.expiration_time))
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- _("Invalid expiration time `%s'\n"),
- tok);
- GNUNET_free (cp);
- return GNUNET_SYSERR;
+ char *etime_in_s;
+
+ GNUNET_asprintf (&etime_in_s,
+ "%s s",
+ tok);
+ if (GNUNET_OK !=
+ parse_expiration (etime_in_s,
+ &etime_is_rel,
+ &record.expiration_time))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Invalid expiration time `%s' (must be without unit)\n"),
+ tok);
+ GNUNET_free (cp);
+ GNUNET_free (etime_in_s);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (etime_in_s);
}
- tok = strtok (NULL, " ");
+ tok = strtok_r (NULL, " ", &saveptr);
if (NULL == tok)
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Missing entries in record line `%s'.\n"),
value);
GNUNET_free (cp);
record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
if (UINT32_MAX == record.record_type)
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Unknown record type `%s'\n"),
tok);
GNUNET_free (cp);
return GNUNET_SYSERR;
}
- tok = strtok (NULL, " ");
+ tok = strtok_r (NULL, " ", &saveptr);
if (NULL == tok)
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Missing entries in record line `%s'.\n"),
value);
GNUNET_free (cp);
tok = strchr (&value[tok - cp], (unsigned char) ' ');
if (NULL == tok)
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Missing entries in record line `%s'.\n"),
value);
GNUNET_free (cp);
&raw_data,
&record.data_size))
{
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Invalid record data for type %s: `%s'.\n"),
GNUNET_GNSRECORD_number_to_typename (record.record_type),
tok);
gettext_noop ("determine our name for the given PKEY"),
&reverse_pkey),
multirecord_option ('R',
- "record",
+ "replace",
"RECORDLINE",
- gettext_noop ("complete record on one line to add/delete/display; can be specified multiple times"),
+ gettext_noop ("set record set to values given by (possibly multiple) RECORDLINES; can be specified multiple times"),
&recordset),
GNUNET_GETOPT_option_string ('t',
"type",