gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: diagnostics mode for gnunet-config


From: gnunet
Subject: [gnunet] branch master updated: diagnostics mode for gnunet-config
Date: Wed, 28 Jul 2021 17:38:34 +0200

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

dold pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 7a0caef7a diagnostics mode for gnunet-config
7a0caef7a is described below

commit 7a0caef7a7b1a3fe2949b6a0462125471905540b
Author: Florian Dold <florian@dold.me>
AuthorDate: Wed Jul 28 17:34:44 2021 +0200

    diagnostics mode for gnunet-config
---
 src/include/gnunet_configuration_lib.h |  23 +++
 src/util/configuration.c               | 271 +++++++++++++++++++++++++--------
 src/util/gnunet-config.c               |  49 ++++--
 3 files changed, 273 insertions(+), 70 deletions(-)

diff --git a/src/include/gnunet_configuration_lib.h 
b/src/include/gnunet_configuration_lib.h
index 68ed570a3..7a0dec792 100644
--- a/src/include/gnunet_configuration_lib.h
+++ b/src/include/gnunet_configuration_lib.h
@@ -138,6 +138,19 @@ GNUNET_CONFIGURATION_serialize (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
                                 size_t *size);
 
 
+/**
+ * Serializes the given configuration with diagnostics information.
+ * Diagnostics information will only be available if diagnostics
+ * have been enabled before parsing.
+ *
+ * @param cfg configuration to serialize
+ * @return the memory block where the serialized configuration is
+ *           present. This memory should be freed by the caller
+ */
+char *
+GNUNET_CONFIGURATION_serialize_diagnostics (const struct
+                                            GNUNET_CONFIGURATION_Handle *cfg);
+
 /**
  * De-serializes configuration
  *
@@ -234,6 +247,16 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename,
                                     GNUNET_CONFIGURATION_Callback cb,
                                     void *cb_cls);
 
+/**
+ * Enable extra diagnostics.  Will produce more log output
+ * and allocate more memory.
+ *
+ * @param cfg configuration handle
+ */
+void
+GNUNET_CONFIGURATION_enable_diagnostics (struct
+                                         GNUNET_CONFIGURATION_Handle *cfg);
+
 
 /**
  * Function to iterate over options.
diff --git a/src/util/configuration.c b/src/util/configuration.c
index 06938be67..6178ab68e 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -28,6 +28,7 @@
 #include "gnunet_os_lib.h"
 #include "gnunet_configuration_lib.h"
 #include "gnunet_disk_lib.h"
+#include "gnunet_buffer_lib.h"
 
 #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
@@ -53,6 +54,16 @@ struct ConfigEntry
    * current, committed value
    */
   char *val;
+
+  /**
+   * Diagnostics information for the filename.
+   */
+  char *hint_filename;
+
+  /**
+   * Diagnostics information for the line number.
+   */
+  unsigned int hint_lineno;
 };
 
 
@@ -83,6 +94,21 @@ struct ConfigSection
    * directive, but the referenced file can't be found or accessed.
    */
   bool inaccessible;
+
+  /**
+   * Diagnostics hint for the inaccessible file.
+   */
+  char *hint_secret_filename;
+
+  /**
+   * For secret sections:  Where was this inlined from?
+   */
+  char *hint_inlined_from_filename;
+
+  /**
+   * For secret sections:  Where was this inlined from?
+   */
+  unsigned int hint_inlined_from_line;
 };
 
 
@@ -96,6 +122,11 @@ struct GNUNET_CONFIGURATION_Handle
    */
   struct ConfigSection *sections;
 
+  /**
+   * Enable diagnostics.
+   */
+  bool diagnostics;
+
   /**
    * Modification indication since last save
    * #GNUNET_NO if clean, #GNUNET_YES if dirty,
@@ -122,6 +153,14 @@ struct DiffHandle
 };
 
 
+void
+GNUNET_CONFIGURATION_enable_diagnostics (struct
+                                         GNUNET_CONFIGURATION_Handle *cfg)
+{
+  cfg->diagnostics = true;
+}
+
+
 struct GNUNET_CONFIGURATION_Handle *
 GNUNET_CONFIGURATION_create ()
 {
@@ -300,27 +339,6 @@ find_section (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
 }
 
 
-static void
-set_section_inaccessible (struct GNUNET_CONFIGURATION_Handle *cfg,
-                          const char *section)
-{
-  struct ConfigSection *sec;
-
-  sec = find_section (cfg, section);
-
-  if (NULL == sec)
-  {
-    sec = GNUNET_new (struct ConfigSection);
-    sec->name = GNUNET_strdup (section);
-    sec->next = cfg->sections;
-    cfg->sections = sec;
-    sec->entries = NULL;
-  }
-
-  sec->inaccessible = true;
-}
-
-
 /**
  * Handle an inline directive.
  *
@@ -331,7 +349,8 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg,
                const char *path_or_glob,
                bool path_is_glob,
                const char *restrict_section,
-               const char *source_filename)
+               const char *source_filename,
+               unsigned int source_lineno)
 {
   char *inline_path;
 
@@ -399,9 +418,30 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg,
 
     fret = GNUNET_DISK_file_test_read (inline_path);
 
+    cs = find_section (cfg, restrict_section);
+
+    if (NULL == cs)
+    {
+      cs = GNUNET_new (struct ConfigSection);
+      cs->name = GNUNET_strdup (restrict_section);
+      cs->next = cfg->sections;
+      cfg->sections = cs;
+      cs->entries = NULL;
+    }
+    if (cfg->diagnostics)
+    {
+      if (NULL != inline_path)
+        cs->hint_secret_filename = GNUNET_strdup (inline_path);
+      if (source_filename)
+      {
+        cs->hint_inlined_from_filename = GNUNET_strdup (source_filename);
+        cs->hint_inlined_from_line = source_lineno;
+      }
+    }
+
     if (GNUNET_OK != fret)
     {
-      set_section_inaccessible (cfg, restrict_section);
+      cs->inaccessible = true;
       GNUNET_free (inline_path);
       return GNUNET_OK;
     }
@@ -447,6 +487,67 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg,
 }
 
 
+/**
+ * Find an entry from a configuration.
+ *
+ * @param cfg handle to the configuration
+ * @param section section the option is in
+ * @param key the option
+ * @return matching entry, NULL if not found
+ */
+static struct ConfigEntry *
+find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg,
+            const char *section,
+            const char *key)
+{
+  struct ConfigSection *sec;
+  struct ConfigEntry *pos;
+
+  if (NULL == (sec = find_section (cfg, section)))
+    return NULL;
+  if (sec->inaccessible)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Section '%s' is marked as inaccessible, because the configuration "
+         " file that contains the section can't be read.  Attempts to use "
+         "option '%s' will fail.\n",
+         section,
+         key);
+    return NULL;
+  }
+  pos = sec->entries;
+  while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
+    pos = pos->next;
+  return pos;
+}
+
+
+/**
+ * Set a configuration hint.
+ *
+ * @param cfg configuration handle
+ * @param section section
+ * @param option config option
+ * @param hint_filename
+ * @param hint_line
+ */
+static void
+set_entry_hint (struct GNUNET_CONFIGURATION_Handle *cfg,
+                const char *section,
+                const char *option,
+                const char *hint_filename,
+                unsigned int hint_line)
+{
+  struct ConfigEntry *e = find_entry (cfg, section, option);
+  if (! cfg->diagnostics)
+    return;
+  if (! e)
+    return;
+  e->hint_filename = GNUNET_strdup (hint_filename);
+  e->hint_lineno = hint_line;
+}
+
+
 enum GNUNET_GenericReturnValue
 GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
                                   const char *mem,
@@ -553,7 +654,8 @@ GNUNET_CONFIGURATION_deserialize (struct 
GNUNET_CONFIGURATION_Handle *cfg,
                                        path,
                                        false,
                                        NULL,
-                                       source_filename);
+                                       source_filename,
+                                       nr);
       }
       else if (0 == strcasecmp (directive, "INLINE-MATCHING"))
       {
@@ -567,7 +669,8 @@ GNUNET_CONFIGURATION_deserialize (struct 
GNUNET_CONFIGURATION_Handle *cfg,
                                        path,
                                        true,
                                        NULL,
-                                       source_filename);
+                                       source_filename,
+                                       nr);
       }
       else if (0 == strcasecmp (directive, "INLINE-SECRET"))
       {
@@ -600,7 +703,8 @@ GNUNET_CONFIGURATION_deserialize (struct 
GNUNET_CONFIGURATION_Handle *cfg,
                                        path,
                                        false,
                                        secname,
-                                       source_filename);
+                                       source_filename,
+                                       nr);
       }
       else
       {
@@ -660,6 +764,14 @@ GNUNET_CONFIGURATION_deserialize (struct 
GNUNET_CONFIGURATION_Handle *cfg,
         value++;
       }
       GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]);
+      if (cfg->diagnostics)
+      {
+        set_entry_hint (cfg,
+                        section,
+                        tag,
+                        source_filename ? source_filename : "<input>",
+                        nr);
+      }
       GNUNET_free (tag);
       continue;
     }
@@ -799,6 +911,8 @@ GNUNET_CONFIGURATION_serialize (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
        NULL != sec;
        sec = sec->next)
   {
+    if (sec->inaccessible)
+      continue;
     /* For each section we need to add 3 characters: {'[',']','\n'} */
     m_size += strlen (sec->name) + 3;
     for (struct ConfigEntry *ent = sec->entries;
@@ -877,6 +991,73 @@ GNUNET_CONFIGURATION_serialize (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
   return mem;
 }
 
+char *
+GNUNET_CONFIGURATION_serialize_diagnostics (const struct
+                                            GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_Buffer buf = { 0 };
+
+  for (struct ConfigSection *sec = cfg->sections;
+       NULL != sec;
+       sec = sec->next)
+  {
+    if (sec->hint_secret_filename)
+      GNUNET_buffer_write_fstr (&buf,
+                                "# secret section from %s\n",
+                                sec->hint_secret_filename);
+    if (sec->hint_inlined_from_filename)
+    {
+      GNUNET_buffer_write_fstr (&buf,
+                                "# inlined from %s:%u\n",
+                                sec->hint_inlined_from_filename,
+                                sec->hint_inlined_from_line);
+    }
+    GNUNET_buffer_write_fstr (&buf,
+                              "[%s]\n",
+                              sec->name);
+    if (sec->inaccessible)
+    {
+      GNUNET_buffer_write_fstr (&buf,
+                                "# <section contents inaccessible>\n\n");
+      continue;
+    }
+    for (struct ConfigEntry *ent = sec->entries;
+         NULL != ent;
+         ent = ent->next)
+    {
+      if (do_skip (sec->name,
+                   ent->key))
+        continue;
+      if (NULL != ent->val)
+      {
+        char *pos;
+        char *val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
+        strcpy (val, ent->val);
+        while (NULL != (pos = strstr (val, "\n")))
+        {
+          memmove (&pos[2], &pos[1], strlen (&pos[1]));
+          pos[0] = '\\';
+          pos[1] = 'n';
+        }
+        if (NULL != ent->hint_filename)
+        {
+          GNUNET_buffer_write_fstr (&buf,
+                                    "# %s:%u\n",
+                                    ent->hint_filename,
+                                    ent->hint_lineno);
+        }
+        GNUNET_buffer_write_fstr (&buf,
+                                  "%s = %s\n",
+                                  ent->key,
+                                  val);
+        GNUNET_free (val);
+      }
+      GNUNET_buffer_write_str (&buf, "\n");
+    }
+    GNUNET_buffer_write_str (&buf, "\n");
+  }
+  return GNUNET_buffer_reap_str (&buf);
+}
 
 enum GNUNET_GenericReturnValue
 GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -1028,10 +1209,13 @@ GNUNET_CONFIGURATION_remove_section (struct 
GNUNET_CONFIGURATION_Handle *cfg,
         spos->entries = ent->next;
         GNUNET_free (ent->key);
         GNUNET_free (ent->val);
+        GNUNET_free (ent->hint_filename);
         GNUNET_free (ent);
         cfg->dirty = GNUNET_YES;
       }
       GNUNET_free (spos->name);
+      GNUNET_free (spos->hint_secret_filename);
+      GNUNET_free (spos->hint_inlined_from_filename);
       GNUNET_free (spos);
       return;
     }
@@ -1073,41 +1257,6 @@ GNUNET_CONFIGURATION_dup (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
 }
 
 
-/**
- * Find an entry from a configuration.
- *
- * @param cfg handle to the configuration
- * @param section section the option is in
- * @param key the option
- * @return matching entry, NULL if not found
- */
-static struct ConfigEntry *
-find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg,
-            const char *section,
-            const char *key)
-{
-  struct ConfigSection *sec;
-  struct ConfigEntry *pos;
-
-  if (NULL == (sec = find_section (cfg, section)))
-    return NULL;
-  if (sec->inaccessible)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         "Section '%s' is marked as inaccessible, because the configuration "
-         " file that contains the section can't be read.  Attempts to use "
-         "option '%s' will fail.\n",
-         section,
-         key);
-    return NULL;
-  }
-  pos = sec->entries;
-  while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
-    pos = pos->next;
-  return pos;
-}
-
-
 /**
  * A callback function, compares entries from two configurations
  * (default against a new configuration) and write the diffs in a
diff --git a/src/util/gnunet-config.c b/src/util/gnunet-config.c
index 3932ff1bf..20fd44c65 100644
--- a/src/util/gnunet-config.c
+++ b/src/util/gnunet-config.c
@@ -69,6 +69,12 @@ static int global_ret;
  */
 static int rewrite;
 
+/**
+ * Should we give extra diagnostics?
+ */
+static int diagnostics;
+
+
 /**
  * Should the generated configuration file contain the whole configuration?
  */
@@ -162,6 +168,18 @@ run (void *cls,
     GNUNET_free (name);
     return;
   }
+
+  if (diagnostics)
+  {
+    struct GNUNET_CONFIGURATION_Handle *ncfg;
+    /* Re-parse the configuration with diagnostics enabled. */
+    GNUNET_assert (NULL != cfgfile);
+    ncfg = GNUNET_CONFIGURATION_create ();
+    GNUNET_CONFIGURATION_enable_diagnostics (ncfg);
+    GNUNET_CONFIGURATION_load (ncfg, cfgfile);
+    cfg = ncfg;
+  }
+
   if (full)
     rewrite = GNUNET_YES;
   if (list_sections)
@@ -176,16 +194,23 @@ run (void *cls,
   if ( (! rewrite) &&
        (NULL == section) )
   {
-    fprintf (stderr,
-             _ ("%s or %s argument is required\n"),
-             "--section",
-             "--list-sections");
-    global_ret = 1;
-    return;
+    char *ser;
+    if (! diagnostics)
+    {
+      fprintf (stderr,
+               _ ("%s, %s or %s argument is required\n"),
+               "--section",
+               "--list-sections",
+               "--diagnostics");
+      global_ret = 1;
+      return;
+    }
+    ser = GNUNET_CONFIGURATION_serialize_diagnostics (cfg);
+    printf ("%s", ser);
+    GNUNET_free (ser);
   }
-
-  if ( (NULL != section) &&
-       (NULL == value) )
+  else if ( (NULL != section) &&
+            (NULL == value) )
   {
     if (NULL == option)
     {
@@ -348,6 +373,12 @@ main (int argc, char *const *argv)
       gettext_noop (
         "rewrite the configuration file, even if nothing changed"),
       &rewrite),
+    GNUNET_GETOPT_option_flag (
+      'd',
+      "diagnostics",
+      gettext_noop (
+        "output extra diagnostics"),
+      &diagnostics),
     GNUNET_GETOPT_option_flag ('S',
                                "list-sections",
                                gettext_noop (

-- 
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]