[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: diagnostics mode for gnunet-config,
gnunet <=