gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: NAMESTORE: CLI utility can now parse mul


From: gnunet
Subject: [gnunet] branch master updated: NAMESTORE: CLI utility can now parse multiple records from stdin
Date: Sun, 20 Nov 2022 11:51:36 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 56a3e354d NAMESTORE: CLI utility can now parse multiple records from 
stdin
     new aedaeb128 Merge branch 'master' of git+ssh://git.gnunet.org/gnunet
56a3e354d is described below

commit 56a3e354dba3b348e508359af6b43160f99d7df3
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Sun Nov 20 19:51:03 2022 +0900

    NAMESTORE: CLI utility can now parse multiple records from stdin
---
 src/namestore/gnunet-namestore.c | 864 +++++++++++++++++++++++----------------
 1 file changed, 521 insertions(+), 343 deletions(-)

diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index 36a0a9ba3..46012cf21 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -118,11 +118,6 @@ static struct GNUNET_NAMESTORE_Handle *ns;
  */
 static struct GNUNET_IDENTITY_PrivateKey zone_pkey;
 
-/**
- * Handle to identity lookup.
- */
-static struct GNUNET_IDENTITY_EgoLookup *el;
-
 /**
  * Identity service handle
  */
@@ -168,6 +163,10 @@ static struct MarkedRecord *marked_head;
  */
 static struct MarkedRecord *marked_tail;
 
+/**
+ * Configuration handle
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
  * Ego list
@@ -189,6 +188,11 @@ static int list;
  */
 static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
 
+/**
+ * Run in read from stdin mode.
+ */
+static int read_from_stdin;
+
 /**
  * Desired action is to remove a record.
  */
@@ -239,6 +243,11 @@ static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
  */
 static struct GNUNET_NAMESTORE_QueueEntry *set_qe;
 
+/**
+ * Queue entry for begin/commit
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
 /**
  * Name of the records to add/list/remove.
  */
@@ -325,18 +334,217 @@ static struct RecordSetEntry *recordset;
 static struct GNUNET_SCHEDULER_Task *purge_task;
 
 /**
- * Task run on shutdown.  Cleans up everything.
+ * Parse expiration time.
  *
- * @param cls unused
+ * @param expirationstring text to parse
+ * @param[out] etime_is_rel set to #GNUNET_YES if time is relative
+ * @param[out] etime set to expiration time (abs or rel)
+ * @return #GNUNET_OK on success
+ */
+static int
+parse_expiration (const char *expirationstring,
+                  int *etime_is_rel,
+                  uint64_t *etime)
+{
+  struct GNUNET_TIME_Relative etime_rel;
+  struct GNUNET_TIME_Absolute etime_abs;
+
+  if (0 == strcmp (expirationstring, "never"))
+  {
+    *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+    *etime_is_rel = GNUNET_NO;
+    return GNUNET_OK;
+  }
+  if (GNUNET_OK ==
+      GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
+  {
+    *etime_is_rel = GNUNET_YES;
+    *etime = etime_rel.rel_value_us;
+    if (GNUNET_TIME_relative_cmp (etime_rel, <, 
WARN_RELATIVE_EXPIRATION_LIMIT))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Relative expiration times of less than %s are not 
recommended. To improve availability, consider increasing this value.\n",
+                  GNUNET_STRINGS_relative_time_to_string (
+                    WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO));
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Storing record with relative expiration time of %s\n",
+                GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
+    return GNUNET_OK;
+  }
+  if (GNUNET_OK ==
+      GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
+  {
+    *etime_is_rel = GNUNET_NO;
+    *etime = etime_abs.abs_value_us;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Storing record with absolute expiration time of %s\n",
+                GNUNET_STRINGS_absolute_time_to_string (etime_abs));
+    return GNUNET_OK;
+  }
+  return GNUNET_SYSERR;
+}
+
+
+
+/**
+ * Command-line option parser function that allows the user to specify
+ * a complete record as one argument for adding/removing.  A pointer
+ * to the head of the list of record sets must be passed as the "scls"
+ * argument.
+ *
+ * @param ctx command line processor context
+ * @param scls must be of type "struct GNUNET_FS_Uri **"
+ * @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)
+ * @return #GNUNET_OK on success
+ */
+static int
+multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
+                     void *scls,
+                     const char *option,
+                     const char *value)
+{
+  struct RecordSetEntry **head = scls;
+  struct RecordSetEntry *r;
+  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_r (cp, " ", &saveptr);
+  if (NULL == tok)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Empty record line argument is not allowed.\n"));
+    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_r (NULL, " ", &saveptr);
+  if (NULL == tok)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Missing entries in record line `%s'.\n"),
+                value);
+    GNUNET_free (cp);
+    return GNUNET_SYSERR;
+  }
+  record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
+  if (UINT32_MAX == record.record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), 
tok);
+    GNUNET_free (cp);
+    return GNUNET_SYSERR;
+  }
+  tok = strtok_r (NULL, " ", &saveptr);
+  if (NULL == tok)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Missing entries in record line `%s'.\n"),
+                value);
+    GNUNET_free (cp);
+    return GNUNET_SYSERR;
+  }
+  record.flags = GNUNET_GNSRECORD_RF_NONE;
+  if (etime_is_rel)
+    record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
+    record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
+  if (NULL != strchr (tok, (unsigned char) 's'))
+    record.flags |= GNUNET_GNSRECORD_RF_SHADOW;
+  /* find beginning of record value */
+  tok = strchr (&value[tok - cp], (unsigned char) ' ');
+  if (NULL == tok)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Missing entries in record line `%s'.\n"),
+                value);
+    GNUNET_free (cp);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (cp);
+  tok++; /* skip space */
+  if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type,
+                                                     tok,
+                                                     &raw_data,
+                                                     &record.data_size))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Invalid record data for type %s: `%s'.\n"),
+                GNUNET_GNSRECORD_number_to_typename (record.record_type),
+                tok);
+    return GNUNET_SYSERR;
+  }
+
+  r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size);
+  r->next = *head;
+  record.data = &r[1];
+  memcpy (&r[1], raw_data, record.data_size);
+  GNUNET_free (raw_data);
+  r->record = record;
+  *head = r;
+  return GNUNET_OK;
+}
+
+/**
+ * Allow user to specify keywords.
+ *
+ * @param shortName short name of the option
+ * @param name long name of the option
+ * @param argumentHelp help text for the option argument
+ * @param description long help text for the option
+ * @param[out] topKeywords set to the desired value
  */
+struct GNUNET_GETOPT_CommandLineOption
+multirecord_option (char shortName,
+                    const char *name,
+                    const char *argumentHelp,
+                    const char *description,
+                    struct RecordSetEntry **rs)
+{
+  struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
+                                                 .name = name,
+                                                 .argumentHelp = argumentHelp,
+                                                 .description = description,
+                                                 .require_argument = 1,
+                                                 .processor =
+                                                   &multirecord_process,
+                                                 .scls = (void *) rs };
+
+  return clo;
+}
+
 static void
-do_shutdown (void *cls)
+reset_handles (void)
 {
-  struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_tmp;
   struct MarkedRecord *mrec;
   struct MarkedRecord *mrec_tmp;
-  (void) cls;
   if (NULL != ego_name)
   {
     GNUNET_free (ego_name);
@@ -347,16 +555,6 @@ do_shutdown (void *cls)
     GNUNET_SCHEDULER_cancel (purge_task);
     purge_task = NULL;
   }
-  if (NULL != idh)
-  {
-    GNUNET_IDENTITY_disconnect (idh);
-    idh = NULL;
-  }
-  if (NULL != el)
-  {
-    GNUNET_IDENTITY_ego_lookup_cancel (el);
-    el = NULL;
-  }
   for (mrec = marked_head; NULL != mrec;)
   {
     mrec_tmp = mrec;
@@ -364,13 +562,6 @@ do_shutdown (void *cls)
     GNUNET_free (mrec_tmp->name);
     GNUNET_free (mrec_tmp);
   }
-  for (ego_entry = ego_head; NULL != ego_entry;)
-  {
-    ego_tmp = ego_entry;
-    ego_entry = ego_entry->next;
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp);
-  }
   if (NULL != list_it)
   {
     GNUNET_NAMESTORE_zone_iteration_stop (list_it);
@@ -401,10 +592,10 @@ do_shutdown (void *cls)
     GNUNET_NAMESTORE_cancel (del_qe);
     del_qe = NULL;
   }
-  if (NULL != ns)
+  if (NULL != reverse_qe)
   {
-    GNUNET_NAMESTORE_disconnect (ns);
-    ns = NULL;
+    GNUNET_NAMESTORE_cancel (reverse_qe);
+    reverse_qe = NULL;
   }
   memset (&zone_pkey, 0, sizeof(zone_pkey));
   if (NULL != uri)
@@ -425,25 +616,81 @@ do_shutdown (void *cls)
 }
 
 
+
 /**
- * Check if we are finished, and if so, perform shutdown.
+ * Task run on shutdown.  Cleans up everything.
+ *
+ * @param cls unused
  */
 static void
-test_finished ()
-{
-  if ((NULL == add_qe) && (NULL == add_qe_uri) && (NULL == get_qe) &&
-      (NULL == del_qe) && (NULL == reverse_qe) && (NULL == list_it))
-    GNUNET_SCHEDULER_shutdown ();
-}
-
-
-static void
-add_continuation (void *cls, enum GNUNET_ErrorCode ec)
+do_shutdown (void *cls)
 {
-  struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
+  struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_tmp;
+  (void) cls;
 
-  *qe = NULL;
-  if (GNUNET_EC_NONE != ec)
+  reset_handles ();
+  if (NULL != ns_qe)
+  {
+    GNUNET_NAMESTORE_cancel (ns_qe);
+    ns_qe = NULL;
+  }
+  if (NULL != ns)
+  {
+    GNUNET_NAMESTORE_disconnect (ns);
+    ns = NULL;
+  }
+  if (NULL != idh)
+  {
+    GNUNET_IDENTITY_disconnect (idh);
+    idh = NULL;
+  }
+  for (ego_entry = ego_head; NULL != ego_entry;)
+  {
+    ego_tmp = ego_entry;
+    ego_entry = ego_entry->next;
+    GNUNET_free (ego_tmp->identifier);
+    GNUNET_free (ego_tmp);
+  }
+}
+
+static void
+commit_cb (void *cls, enum GNUNET_ErrorCode ec)
+{
+  ns_qe = NULL;
+  if (GNUNET_EC_NONE != ec)
+  {
+    fprintf (stderr, "Failed to commit to namestore: `%s'\n",
+             GNUNET_ErrorCode_get_hint (ec));
+    ret = 1;
+  }
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+static void
+process_command_stdin ();
+
+
+static void
+finish_command (void)
+{
+  reset_handles ();
+  if (read_from_stdin)
+  {
+    process_command_stdin ();
+    return;
+  }
+  ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
+}
+
+
+static void
+add_continuation (void *cls, enum GNUNET_ErrorCode ec)
+{
+  struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
+
+  *qe = NULL;
+  if (GNUNET_EC_NONE != ec)
   {
     fprintf (stderr,
              _ ("Adding record failed: %s\n"),
@@ -452,7 +699,7 @@ add_continuation (void *cls, enum GNUNET_ErrorCode ec)
       ret = 1;
   }
   ret = 0;
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -467,7 +714,7 @@ del_continuation (void *cls, enum GNUNET_ErrorCode ec)
              _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint (
                ec));
   }
-  test_finished ();
+  finish_command ();
 }
 
 static void
@@ -496,7 +743,7 @@ purge_next_record (void *cls)
   if (NULL == marked_head)
   {
     ret = 0;
-    test_finished ();
+    finish_command ();
     return;
   }
   mrec = marked_head;
@@ -527,7 +774,7 @@ zone_iteration_finished (void *cls)
     return;
   }
   ret = 0;
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -541,7 +788,7 @@ zone_iteration_error_cb (void *cls)
   list_it = NULL;
   fprintf (stderr, "Error iterating over zone\n");
   ret = 1;
-  test_finished ();
+  finish_command ();
 }
 
 static void
@@ -797,7 +1044,7 @@ display_record_lookup (void *cls,
   (void) zone_key;
   get_qe = NULL;
   display_record (zone_key, rname, rd_len, rd);
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -838,7 +1085,7 @@ lookup_error_cb (void *cls)
   (void) cls;
   get_qe = NULL;
   fprintf (stderr, "%s", "Failed to lookup record.\n");
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -852,7 +1099,7 @@ add_error_cb (void *cls)
   add_qe = NULL;
   GNUNET_break (0);
   ret = 1;
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -883,7 +1130,7 @@ get_existing_record (void *cls,
   {
     GNUNET_break (0);
     ret = 1;
-    test_finished ();
+    finish_command ();
     return;
   }
 
@@ -904,7 +1151,7 @@ get_existing_record (void *cls,
             "A SOA record exists already under `%s', cannot add a second SOA 
to the same zone.\n"),
           rec_name);
         ret = 1;
-        test_finished ();
+        finish_command ();
         return;
       }
       break;
@@ -974,7 +1221,7 @@ handle_reverse_lookup (void *cls,
     fprintf (stdout, "%s\n", reverse_pkey);
   else
     fprintf (stdout, "%s.%s\n", label, ego_name);
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -988,7 +1235,7 @@ del_lookup_error_cb (void *cls)
   del_qe = NULL;
   GNUNET_break (0);
   ret = 1;
-  test_finished ();
+  finish_command ();
 }
 
 
@@ -1025,7 +1272,7 @@ del_monitor (void *cls,
                "There are no records under label `%s' that could be 
deleted.\n"),
              label);
     ret = 1;
-    test_finished ();
+    finish_command ();
     return;
   }
   if ((NULL == value) && (NULL == typestring))
@@ -1067,7 +1314,7 @@ del_monitor (void *cls,
       _ (
         "There are no records under label `%s' that match the request for 
deletion.\n"),
       label);
-    test_finished ();
+    finish_command ();
     return;
   }
   /* delete everything but what we copied to 'rdx' */
@@ -1081,59 +1328,6 @@ del_monitor (void *cls,
 }
 
 
-/**
- * Parse expiration time.
- *
- * @param expirationstring text to parse
- * @param[out] etime_is_rel set to #GNUNET_YES if time is relative
- * @param[out] etime set to expiration time (abs or rel)
- * @return #GNUNET_OK on success
- */
-static int
-parse_expiration (const char *expirationstring,
-                  int *etime_is_rel,
-                  uint64_t *etime)
-{
-  struct GNUNET_TIME_Relative etime_rel;
-  struct GNUNET_TIME_Absolute etime_abs;
-
-  if (0 == strcmp (expirationstring, "never"))
-  {
-    *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
-    *etime_is_rel = GNUNET_NO;
-    return GNUNET_OK;
-  }
-  if (GNUNET_OK ==
-      GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
-  {
-    *etime_is_rel = GNUNET_YES;
-    *etime = etime_rel.rel_value_us;
-    if (GNUNET_TIME_relative_cmp (etime_rel, <, 
WARN_RELATIVE_EXPIRATION_LIMIT))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "Relative expiration times of less than %s are not 
recommended. To improve availability, consider increasing this value.\n",
-                  GNUNET_STRINGS_relative_time_to_string (
-                    WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO));
-    }
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Storing record with relative expiration time of %s\n",
-                GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
-    return GNUNET_OK;
-  }
-  if (GNUNET_OK ==
-      GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
-  {
-    *etime_is_rel = GNUNET_NO;
-    *etime = etime_abs.abs_value_us;
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Storing record with absolute expiration time of %s\n",
-                GNUNET_STRINGS_absolute_time_to_string (etime_abs));
-    return GNUNET_OK;
-  }
-  return GNUNET_SYSERR;
-}
-
-
 static void
 replace_cont (void *cls, enum GNUNET_ErrorCode ec)
 {
@@ -1147,7 +1341,7 @@ replace_cont (void *cls, enum GNUNET_ErrorCode ec)
                 GNUNET_ErrorCode_get_hint (ec));
     ret = 1;   /* fail from 'main' */
   }
-  GNUNET_SCHEDULER_shutdown ();
+  finish_command ();
 }
 
 
@@ -1173,14 +1367,7 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
   {
     /* nothing more to be done */
     fprintf (stderr, _ ("No options given\n"));
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  ns = GNUNET_NAMESTORE_connect (cfg);
-  if (NULL == ns)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Failed to connect to namestore\n"));
+    finish_command ();
     return;
   }
 
@@ -1196,8 +1383,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("replace"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == name)
@@ -1206,8 +1393,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-R",
                _ ("replace"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     rd_count = 0;
@@ -1235,8 +1422,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
     if (0 == strlen (nickstring))
     {
       fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     add = 1;
@@ -1258,8 +1445,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("add"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == name)
@@ -1268,8 +1455,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-n",
                _ ("add"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == typestring)
@@ -1278,16 +1465,16 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-t",
                _ ("add"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     type = GNUNET_GNSRECORD_typename_to_number (typestring);
     if (UINT32_MAX == type)
     {
       fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if ((GNUNET_DNSPARSER_TYPE_SRV == type) ||
@@ -1297,8 +1484,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
       fprintf (stderr,
                _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'"));
       fprintf (stderr, ", please use a `BOX' record instead\n");
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == value)
@@ -1308,7 +1495,7 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                "-V",
                _ ("add"));
       ret = 1;
-      GNUNET_SCHEDULER_shutdown ();
+      finish_command ();
       return;
     }
     if (GNUNET_OK !=
@@ -1318,8 +1505,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Value `%s' invalid for record type `%s'\n"),
                value,
                typestring);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == expirationstring)
@@ -1328,15 +1515,15 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-e",
                _ ("add"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, 
&etime))
     {
       fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     add_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1355,8 +1542,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("del"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == name)
@@ -1365,8 +1552,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-n",
                _ ("del"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     del_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1398,8 +1585,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("purge-zone"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns,
@@ -1423,8 +1610,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                  _ ("Missing option `%s' for operation `%s'\n"),
                  "-z",
                  _ ("list"));
-        GNUNET_SCHEDULER_shutdown ();
         ret = 1;
+        finish_command ();
         return;
       }
       get_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1457,8 +1644,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("reverse-pkey"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (GNUNET_OK !=
@@ -1468,7 +1655,9 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
       fprintf (stderr,
                _ ("Invalid public key for reverse lookup `%s'\n"),
                reverse_pkey);
-      GNUNET_SCHEDULER_shutdown ();
+      ret = 1;
+      finish_command ();
+      return;
     }
     reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns,
                                                 &zone_pkey,
@@ -1489,8 +1678,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-z",
                _ ("uri"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
 
@@ -1502,8 +1691,8 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
          GNUNET_IDENTITY_public_key_from_string (sh, &pkey)))
     {
       fprintf (stderr, _ ("Invalid URI `%s'\n"), uri);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (NULL == expirationstring)
@@ -1512,15 +1701,15 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
                _ ("Missing option `%s' for operation `%s'\n"),
                "-e",
                _ ("add"));
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, 
&etime))
     {
       fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
-      GNUNET_SCHEDULER_shutdown ();
       ret = 1;
+      finish_command ();
       return;
     }
     memset (&rd, 0, sizeof(rd));
@@ -1556,34 +1745,182 @@ run_with_zone_pkey (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
   }
 }
 
+#define MAX_LINE_LEN 4086
+
+#define MAX_ARGS 20
 
-/**
- * Callback invoked from identity service with ego information.
- * An @a ego of NULL means the ego was not found.
- *
- * @param cls closure with the configuration
- * @param ego an ego known to identity service, or NULL
- */
 static void
-identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
+process_command_stdin ()
 {
-  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+  struct EgoEntry *ego_entry;
+  char buf[MAX_LINE_LEN];
+  char *tmp_argv[MAX_ARGS];
+  unsigned int tmp_argc = 0;
+  char *tmp;
+  struct GNUNET_GETOPT_CommandLineOption options[] =
+  { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
+    GNUNET_GETOPT_option_flag ('d',
+                               "delete",
+                               gettext_noop ("delete record"),
+                               &del),
+    GNUNET_GETOPT_option_flag ('D',
+                               "display",
+                               gettext_noop ("display records"),
+                               &list),
+    GNUNET_GETOPT_option_flag ('S',
+                               "from-stdin",
+                               gettext_noop ("read commands from stdin"),
+                               &read_from_stdin),
+    GNUNET_GETOPT_option_string (
+      'e',
+      "expiration",
+      "TIME",
+      gettext_noop (
+        "expiration time for record to use (for adding only), \"never\" is 
possible"),
+      &expirationstring),
+    GNUNET_GETOPT_option_string ('i',
+                                 "nick",
+                                 "NICKNAME",
+                                 gettext_noop (
+                                   "set the desired nick name for the zone"),
+                                 &nickstring),
+    GNUNET_GETOPT_option_flag ('m',
+                               "monitor",
+                               gettext_noop (
+                                 "monitor changes in the namestore"),
+                               &monitor),
+    GNUNET_GETOPT_option_string ('n',
+                                 "name",
+                                 "NAME",
+                                 gettext_noop (
+                                   "name of the record to add/delete/display"),
+                                 &name),
+    GNUNET_GETOPT_option_string ('r',
+                                 "reverse",
+                                 "PKEY",
+                                 gettext_noop (
+                                   "determine our name for the given PKEY"),
+                                 &reverse_pkey),
+    multirecord_option (
+      'R',
+      "replace",
+      "RECORDLINE",
+      gettext_noop (
+        "set record set to values given by (possibly multiple) RECORDLINES; 
can be specified multiple times"),
+      &recordset),
+    GNUNET_GETOPT_option_string ('t',
+                                 "type",
+                                 "TYPE",
+                                 gettext_noop (
+                                   "type of the record to add/delete/display"),
+                                 &typestring),
+    GNUNET_GETOPT_option_string ('u',
+                                 "uri",
+                                 "URI",
+                                 gettext_noop ("URI to import into our zone"),
+                                 &uri),
+    GNUNET_GETOPT_option_string ('V',
+                                 "value",
+                                 "VALUE",
+                                 gettext_noop (
+                                   "value of the record to add/delete"),
+                                 &value),
+    GNUNET_GETOPT_option_flag ('p',
+                               "public",
+                               gettext_noop ("create or list public record"),
+                               &is_public),
+    GNUNET_GETOPT_option_flag ('o',
+                               "omit-private",
+                               gettext_noop ("omit private records"),
+                               &omit_private),
+    GNUNET_GETOPT_option_flag ('T',
+                               "include-maintenance",
+                               gettext_noop (
+                                 "do not filter maintenance records"),
+                               &include_maintenance),
+    GNUNET_GETOPT_option_flag ('P',
+                               "purge-orphans",
+                               gettext_noop (
+                                 "purge namestore of all orphans"),
+                               &purge_orphaned),
+    GNUNET_GETOPT_option_flag ('O',
+                               "list-orphans",
+                               gettext_noop (
+                                 "show private key for orphaned records for 
recovery using `gnunet-identity -C -P <key>'. Use in combination with 
--display"),
+                               &list_orphaned),
+    GNUNET_GETOPT_option_flag ('X',
+                               "purge-zone-records",
+                               gettext_noop (
+                                 "delete all records in specified zone"),
+                               &purge_zone),
+    GNUNET_GETOPT_option_flag (
+      's',
+      "shadow",
+      gettext_noop (
+        "create shadow record (only valid if all other records of the same 
type have expired"),
+      &is_shadow),
+    GNUNET_GETOPT_option_string ('z',
+                                 "zone",
+                                 "EGO",
+                                 gettext_noop (
+                                   "name of the ego controlling the zone"),
+                                 &ego_name),
+    GNUNET_GETOPT_OPTION_END };
 
-  el = NULL;
 
-  if (NULL == ego)
+  if (NULL == fgets (buf, sizeof (buf), stdin))
   {
-    if (NULL != ego_name)
-    {
-      fprintf (stderr,
-               _ ("Ego `%s' not known to identity service\n"),
-               ego_name);
-    }
+    ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
+    return;
+  }
+  if (buf[strlen (buf) - 1] == '\n')
+    buf[strlen (buf) - 1] = '\0';
+  /* We need to build a char *const *argv here */
+  /* I guess strtok on space */
+  tmp = strtok (buf, " ");
+  if (NULL == tmp)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error parsing line %s\n", buf);
     GNUNET_SCHEDULER_shutdown ();
-    ret = -1;
     return;
   }
-  zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
+  tmp_argv[0] = tmp;
+  tmp_argc = 1;
+  while (NULL != (tmp = strtok (NULL, " ")))
+  {
+    tmp_argv[tmp_argc] = tmp;
+    tmp_argc++;
+  }
+  GNUNET_GETOPT_run ("gnunet-namestore", options, tmp_argc, tmp_argv);
+  for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
+  {
+    if (0 != strcmp (ego_entry->identifier, ego_name))
+      continue;
+    zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+    break;
+  }
+  run_with_zone_pkey (cfg);
+}
+
+
+static void
+begin_cb (void *cls, enum GNUNET_ErrorCode ec)
+{
+  ns_qe = NULL;
+  if (GNUNET_EC_NONE != ec)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to start transaction: %s\n",
+                GNUNET_ErrorCode_get_hint (ec));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (read_from_stdin)
+  {
+    process_command_stdin ();
+    return;
+  }
   run_with_zone_pkey (cfg);
 }
 
@@ -1606,7 +1943,6 @@ id_connect_cb (void *cls,
                void **ctx,
                const char *name)
 {
-  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_IDENTITY_PublicKey pk;
   struct EgoEntry *ego_entry;
 
@@ -1621,17 +1957,20 @@ id_connect_cb (void *cls,
     GNUNET_CONTAINER_DLL_insert_tail (ego_head,
                                       ego_tail,
                                       ego_entry);
+    if ((NULL != ego_name) &&
+        (0 == strcmp (name, ego_name)))
+      zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
     return;
   }
   if (NULL != ego)
     return;
-  if (NULL == ego_name)
-    run_with_zone_pkey (cfg);
-  else
-    el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) 
cfg);
+  ns_qe = GNUNET_NAMESTORE_transaction_begin (ns, &begin_cb, (void *) cfg);
 }
 
 
+
+
+
 /**
  * Main function that will be run.
  *
@@ -1644,202 +1983,36 @@ static void
 run (void *cls,
      char *const *args,
      const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *cfg)
+     const struct GNUNET_CONFIGURATION_Handle *_cfg)
 {
-  const char *pkey_str;
-
   (void) cls;
   (void) args;
   (void) cfgfile;
+  cfg = _cfg;
   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]);
 
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg);
-  pkey_str = getenv ("GNUNET_NAMESTORE_EGO_PRIVATE_KEY");
-  if (NULL != pkey_str)
+  ns = GNUNET_NAMESTORE_connect (cfg);
+  if (NULL == ns)
   {
-    if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pkey_str,
-                                                    strlen (pkey_str),
-                                                    &zone_pkey,
-                                                    sizeof(zone_pkey)))
-    {
-      fprintf (stderr,
-               "Malformed private key `%s' in $%s\n",
-               pkey_str,
-               "GNUNET_NAMESTORE_EGO_PRIVATE_KEY");
-      ret = 1;
-      GNUNET_SCHEDULER_shutdown ();
-      return;
-    }
-    run_with_zone_pkey (cfg);
+    fprintf (stderr, _ ("Failed to connect to namestore\n"));
+    GNUNET_SCHEDULER_shutdown ();
     return;
   }
   idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg);
   if (NULL == idh)
-    fprintf (stderr, _ ("Cannot connect to identity service\n"));
-  ret = -1;
-}
-
-
-/**
- * Command-line option parser function that allows the user to specify
- * a complete record as one argument for adding/removing.  A pointer
- * to the head of the list of record sets must be passed as the "scls"
- * argument.
- *
- * @param ctx command line processor context
- * @param scls must be of type "struct GNUNET_FS_Uri **"
- * @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)
- * @return #GNUNET_OK on success
- */
-static int
-multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
-                     void *scls,
-                     const char *option,
-                     const char *value)
-{
-  struct RecordSetEntry **head = scls;
-  struct RecordSetEntry *r;
-  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_r (cp, " ", &saveptr);
-  if (NULL == tok)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Empty record line argument is not allowed.\n"));
-    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_r (NULL, " ", &saveptr);
-  if (NULL == tok)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Missing entries in record line `%s'.\n"),
-                value);
-    GNUNET_free (cp);
-    return GNUNET_SYSERR;
-  }
-  record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
-  if (UINT32_MAX == record.record_type)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), 
tok);
-    GNUNET_free (cp);
-    return GNUNET_SYSERR;
-  }
-  tok = strtok_r (NULL, " ", &saveptr);
-  if (NULL == tok)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Missing entries in record line `%s'.\n"),
-                value);
-    GNUNET_free (cp);
-    return GNUNET_SYSERR;
-  }
-  record.flags = GNUNET_GNSRECORD_RF_NONE;
-  if (etime_is_rel)
-    record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
-  if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
-    record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
-  if (NULL != strchr (tok, (unsigned char) 's'))
-    record.flags |= GNUNET_GNSRECORD_RF_SHADOW;
-  /* find beginning of record value */
-  tok = strchr (&value[tok - cp], (unsigned char) ' ');
-  if (NULL == tok)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Missing entries in record line `%s'.\n"),
-                value);
-    GNUNET_free (cp);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (cp);
-  tok++; /* skip space */
-  if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type,
-                                                     tok,
-                                                     &raw_data,
-                                                     &record.data_size))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Invalid record data for type %s: `%s'.\n"),
-                GNUNET_GNSRECORD_number_to_typename (record.record_type),
-                tok);
-    return GNUNET_SYSERR;
+    ret = -1;
+    fprintf (stderr, _ ("Cannot connect to identity service\n"));
+    GNUNET_SCHEDULER_shutdown ();
   }
-
-  r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size);
-  r->next = *head;
-  record.data = &r[1];
-  memcpy (&r[1], raw_data, record.data_size);
-  GNUNET_free (raw_data);
-  r->record = record;
-  *head = r;
-  return GNUNET_OK;
 }
 
 
-/**
- * Allow user to specify keywords.
- *
- * @param shortName short name of the option
- * @param name long name of the option
- * @param argumentHelp help text for the option argument
- * @param description long help text for the option
- * @param[out] topKeywords set to the desired value
- */
-struct GNUNET_GETOPT_CommandLineOption
-multirecord_option (char shortName,
-                    const char *name,
-                    const char *argumentHelp,
-                    const char *description,
-                    struct RecordSetEntry **rs)
-{
-  struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
-                                                 .name = name,
-                                                 .argumentHelp = argumentHelp,
-                                                 .description = description,
-                                                 .require_argument = 1,
-                                                 .processor =
-                                                   &multirecord_process,
-                                                 .scls = (void *) rs };
-
-  return clo;
-}
-
 
 /**
  * The main function for gnunet-namestore.
@@ -1851,6 +2024,7 @@ multirecord_option (char shortName,
 int
 main (int argc, char *const *argv)
 {
+  int lret;
   struct GNUNET_GETOPT_CommandLineOption options[] =
   { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
     GNUNET_GETOPT_option_flag ('d',
@@ -1861,6 +2035,10 @@ main (int argc, char *const *argv)
                                "display",
                                gettext_noop ("display records"),
                                &list),
+    GNUNET_GETOPT_option_flag ('S',
+                               "from-stdin",
+                               gettext_noop ("read commands from stdin"),
+                               &read_from_stdin),
     GNUNET_GETOPT_option_string (
       'e',
       "expiration",
@@ -1956,7 +2134,7 @@ main (int argc, char *const *argv)
                                    "name of the ego controlling the zone"),
                                  &ego_name),
     GNUNET_GETOPT_OPTION_END };
-  int lret;
+
 
   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
     return 2;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]