/* This file is part of GNUnet. Copyright (C) 2006, 2007, 2008, 2009, 2013, 2020, 2021 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later */ /** * @file src/util/configuration_helper.c * @brief helper logic for gnunet-config * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" /** * Print each option in a given section as a filename. * * @param cls closure * @param section name of the section * @param option name of the option * @param value value of the option */ static void print_filename_option (void *cls, const char *section, const char *option, const char *value) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; char *value_fn; char *fn; GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, section, option, &value_fn)); fn = GNUNET_STRINGS_filename_expand (value_fn); if (NULL == fn) fn = value_fn; else GNUNET_free (value_fn); fprintf (stdout, "%s = %s\n", option, fn); GNUNET_free (fn); } /** * Print each option in a given section. * * @param cls closure * @param section name of the section * @param option name of the option * @param value value of the option */ static void print_option (void *cls, const char *section, const char *option, const char *value) { (void) cls; (void) section; fprintf (stdout, "%s = %s\n", option, value); } /** * Print out given section name. * * @param cls unused * @param section a section in the configuration file */ static void print_section_name (void *cls, const char *section) { (void) cls; fprintf (stdout, "%s\n", section); } void GNUNET_CONFIGURATION_config_tool_run ( void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls; struct GNUNET_CONFIGURATION_Handle *out = NULL; struct GNUNET_CONFIGURATION_Handle *ncfg = NULL; (void) args; if (cs->diagnostics) { /* Re-parse the configuration with diagnostics enabled. */ ncfg = GNUNET_CONFIGURATION_create (); GNUNET_CONFIGURATION_enable_diagnostics (ncfg); GNUNET_CONFIGURATION_load (ncfg, cfgfile); cfg = ncfg; } if (cs->full) cs->rewrite = GNUNET_YES; if (cs->list_sections) { fprintf (stderr, _ ("The following sections are available:\n")); GNUNET_CONFIGURATION_iterate_sections (cfg, &print_section_name, NULL); return; } if ( (! cs->rewrite) && (NULL == cs->section) ) { char *serialization; if (! cs->diagnostics) { fprintf (stderr, _ ("%s, %s or %s argument is required\n"), "--section", "--list-sections", "--diagnostics"); cs->global_ret = EXIT_INVALIDARGUMENT; return; } serialization = GNUNET_CONFIGURATION_serialize_diagnostics (cfg); fprintf (stdout, "%s", serialization); GNUNET_free (serialization); } else if ( (NULL != cs->section) && (NULL == cs->value) ) { if (NULL == cs->option) { GNUNET_CONFIGURATION_iterate_section_values ( cfg, cs->section, cs->is_filename ? &print_filename_option : &print_option, (void *) cfg); } else { char *value; if (cs->is_filename) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, cs->section, cs->option, &value)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, cs->section, cs->option); cs->global_ret = EXIT_NOTCONFIGURED; return; } } else { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, cs->section, cs->option, &value)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, cs->section, cs->option); cs->global_ret = EXIT_NOTCONFIGURED; return; } } fprintf (stdout, "%s\n", value); GNUNET_free (value); } } else if (NULL != cs->section) { if (NULL == cs->option) { fprintf (stderr, _ ("--option argument required to set value\n")); cs->global_ret = EXIT_INVALIDARGUMENT; return; } out = GNUNET_CONFIGURATION_dup (cfg); GNUNET_CONFIGURATION_set_value_string (out, cs->section, cs->option, cs->value); cs->rewrite = GNUNET_YES; } if (cs->rewrite) { char *cfg_fn = NULL; if (NULL == out) out = GNUNET_CONFIGURATION_dup (cfg); if (NULL == cfgfile) { const char *xdg = getenv ("XDG_CONFIG_HOME"); if (NULL != xdg) GNUNET_asprintf (&cfg_fn, "%s%s%s", xdg, DIR_SEPARATOR_STR, GNUNET_OS_project_data_get ()->config_file); else cfg_fn = GNUNET_strdup ( GNUNET_OS_project_data_get ()->user_config_file); cfgfile = cfg_fn; } if (! cs->full) { struct GNUNET_CONFIGURATION_Handle *def; def = GNUNET_CONFIGURATION_create (); if (GNUNET_OK != GNUNET_CONFIGURATION_load (def, NULL)) { fprintf (stderr, _ ("failed to load configuration defaults")); cs->global_ret = 1; GNUNET_CONFIGURATION_destroy (def); GNUNET_CONFIGURATION_destroy (out); GNUNET_free (cfg_fn); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_write_diffs (def, out, cfgfile)) cs->global_ret = 2; GNUNET_CONFIGURATION_destroy (def); } else { if (GNUNET_OK != GNUNET_CONFIGURATION_write (out, cfgfile)) cs->global_ret = 2; } GNUNET_free (cfg_fn); } if (NULL != out) GNUNET_CONFIGURATION_destroy (out); if (NULL != ncfg) GNUNET_CONFIGURATION_destroy (ncfg); } void GNUNET_CONFIGURATION_config_settings_free ( struct GNUNET_CONFIGURATION_ConfigSettings *cs) { GNUNET_free (cs->option); GNUNET_free (cs->section); GNUNET_free (cs->value); } /* end of configuration_helper.c */