glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / util / gnunet-config.c
index 4e03d8ee2d0a1f07507f2e33046bdde666dfec2c..81e09fdbf83fc62b0cc667dd93d24f092049bf44 100644 (file)
@@ -1,21 +1,16 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2012 GNUnet e.V.
 
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     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
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     Affero General Public License for more details.
 */
 
 /**
@@ -57,6 +52,11 @@ static int list_sections;
  */
 static int ret;
 
+/**
+ * Should we generate a configuration file that is clean and
+ * only contains the deltas to the defaults?
+ */
+static int rewrite;
 
 /**
  * Print each option in a given section.
@@ -67,12 +67,17 @@ static int ret;
  * @param value value of the option
  */
 static void
-print_option (void *cls, const char *section,
+print_option (void *cls,
+             const char *section,
              const char *option,
              const char *value)
 {
+  (void) cls;
+  (void) section;
   fprintf (stdout,
-          "%s = %s\n", option, value);
+          "%s = %s\n",
+          option,
+          value);
 }
 
 
@@ -86,7 +91,10 @@ static void
 print_section_name (void *cls,
                     const char *section)
 {
-  fprintf (stdout, "%s\n", section);
+  (void) cls;
+  fprintf (stdout,
+          "%s\n",
+          section);
 }
 
 
@@ -99,41 +107,72 @@ print_section_name (void *cls,
  * @param cfg configuration
  */
 static void
-run (void *cls, char *const *args, const char *cfgfile,
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  struct GNUNET_CONFIGURATION_Handle *out;
+  struct GNUNET_CONFIGURATION_Handle *out = NULL;
+  struct GNUNET_CONFIGURATION_Handle *diff = NULL;
 
-  if (NULL == section || list_sections)
+  (void) cls;
+  (void) args;
+  if (rewrite)
+  {
+    struct GNUNET_CONFIGURATION_Handle *def;
+
+    def = GNUNET_CONFIGURATION_create ();
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_load (def, NULL))
+    {
+      fprintf (stderr,
+               _("failed to load configuration defaults"));
+      ret = 1;
+      return;
+    }
+    diff = GNUNET_CONFIGURATION_get_diff (def,
+                                          cfg);
+    cfg = diff;
+  }
+  if ( ((! rewrite) && (NULL == section)) || list_sections)
   {
     if (! list_sections)
     {
-      fprintf (stderr, _("--section argument is required\n"));
+      fprintf (stderr,
+               _("--section argument is required\n"));
     }
-    fprintf (stderr, _("The following sections are available:\n"));
-    GNUNET_CONFIGURATION_iterate_sections (cfg, &print_section_name, NULL);
+    fprintf (stderr,
+             _("The following sections are available:\n"));
+    GNUNET_CONFIGURATION_iterate_sections (cfg,
+                                           &print_section_name,
+                                           NULL);
     ret = 1;
-    return;
+    goto cleanup;
   }
 
-  if (NULL == value)
+  if ( (NULL != section) && (NULL == value) )
   {
     if (NULL == option)
     {
-      GNUNET_CONFIGURATION_iterate_section_values (cfg, section,
-                                                  &print_option, NULL);
+      GNUNET_CONFIGURATION_iterate_section_values (cfg,
+                                                   section,
+                                                  &print_option,
+                                                   NULL);
     }
     else
     {
       if (is_filename)
       {
        if (GNUNET_OK !=
-           GNUNET_CONFIGURATION_get_value_filename (cfg, section, option, &value))
+           GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                                     section,
+                                                     option,
+                                                     &value))
        {
          GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                     section, option);
          ret = 3;
-         return;
+          goto cleanup;
        }
       }
       else
@@ -144,28 +183,38 @@ run (void *cls, char *const *args, const char *cfgfile,
          GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                     section, option);
          ret = 3;
-         return;
+          goto cleanup;
        }
       }
       fprintf (stdout, "%s\n", value);
     }
   }
-  else
+  else if (NULL != section)
   {
     if (NULL == option)
     {
       fprintf (stderr, _("--option argument required to set value\n"));
       ret = 1;
-      return;
+      goto cleanup;
     }
     out = GNUNET_CONFIGURATION_dup (cfg);
-    GNUNET_CONFIGURATION_set_value_string (out, section, option, value);
+    GNUNET_CONFIGURATION_set_value_string (out,
+                                           section,
+                                           option,
+                                           value);
+  }
+  if ( (NULL != diff) || (NULL != out) )
+  {
     if (GNUNET_OK !=
-       GNUNET_CONFIGURATION_write (out, cfgfile))
+       GNUNET_CONFIGURATION_write ((NULL == out) ? diff : out,
+                                    cfgfile))
       ret = 2;
-    GNUNET_CONFIGURATION_destroy (out);
-    return;
   }
+  if (NULL != out)
+    GNUNET_CONFIGURATION_destroy (out);
+ cleanup:
+  if (NULL != diff)
+    GNUNET_CONFIGURATION_destroy (diff);
 }
 
 
@@ -177,33 +226,51 @@ run (void *cls, char *const *args, const char *cfgfile,
  * @return 0 ok, 1 on error
  */
 int
-main (int argc, char *const *argv)
+main (int argc,
+      char *const *argv)
 {
-  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
-    { 'f', "filename", NULL,
-      gettext_noop ("obtain option of value as a filename (with $-expansion)"),
-      0, &GNUNET_GETOPT_set_one, &is_filename },
-    { 's', "section", "SECTION",
-      gettext_noop ("name of the section to access"),
-      1, &GNUNET_GETOPT_set_string, &section },
-    { 'o', "option", "OPTION",
-      gettext_noop ("name of the option to access"),
-      1, &GNUNET_GETOPT_set_string, &option },
-    { 'V', "value", "VALUE",
-      gettext_noop ("value to set"),
-      1, &GNUNET_GETOPT_set_string, &value },
-    { 'S', "list-sections", NULL,
-      gettext_noop ("print available configuration sections"),
-      0, &GNUNET_GETOPT_set_one, &list_sections },
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_flag ('f',
+                              "filename",
+                              gettext_noop ("obtain option of value as a filename (with $-expansion)"),
+                              &is_filename),
+    GNUNET_GETOPT_option_string ('s',
+                                "section",
+                                "SECTION",
+                                gettext_noop ("name of the section to access"),
+                                &section),
+    GNUNET_GETOPT_option_string ('o',
+                                "option",
+                                "OPTION",
+                                gettext_noop ("name of the option to access"),
+                                &option),
+    GNUNET_GETOPT_option_string ('V',
+                                "value",
+                                "VALUE",
+                                gettext_noop ("value to set"),
+                                &value),
+    GNUNET_GETOPT_option_flag ('S',
+                              "list-sections",
+                              gettext_noop ("print available configuration sections"),
+                              &list_sections),
+    GNUNET_GETOPT_option_flag ('w',
+                              "rewrite",
+                              gettext_noop ("write configuration file that only contains delta to defaults"),
+                              &rewrite),
     GNUNET_GETOPT_OPTION_END
   };
-  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_get_utf8_args (argc, argv,
+                                    &argc, &argv))
     return 2;
 
   ret = (GNUNET_OK ==
-        GNUNET_PROGRAM_run (argc, argv, "gnunet-config [OPTIONS]",
+        GNUNET_PROGRAM_run (argc,
+                             argv,
+                             "gnunet-config [OPTIONS]",
                             gettext_noop ("Manipulate GNUnet configuration files"),
-                            options, &run, NULL)) ? 0 : ret;
+                            options,
+                             &run, NULL)) ? 0 : ret;
   GNUNET_free ((void*) argv);
   return ret;
 }