first step to remove plibc
[oweals/gnunet.git] / src / util / program.c
index 9e3037b8b0eeb76fc5e072dfea55ab5cba96c43c..77f4ea3ae2e539fe4d81aec364e8e2b243324246 100644 (file)
@@ -2,20 +2,20 @@
      This file is part of GNUnet.
      Copyright (C) 2009-2013 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 PURPROSE.  See the GNU
-     General Public License for more details.
+     Affero 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.
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
 #include "speedup.h"
 #include <gcrypt.h>
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util-program", __VA_ARGS__)
+#define LOG(kind, ...) GNUNET_log_from (kind, "util-program", __VA_ARGS__)
 
-#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-program", syscall, filename)
+#define LOG_STRERROR_FILE(kind, syscall, filename) \
+  GNUNET_log_from_strerror_file (kind, "util-program", syscall, filename)
 
 /**
  * Context for the command.
@@ -64,7 +65,6 @@ struct CommandContext
    * Configuration to use.
    */
   const struct GNUNET_CONFIGURATION_Handle *cfg;
-
 };
 
 
@@ -88,7 +88,7 @@ program_main (void *cls)
 {
   struct CommandContext *cc = cls;
 
-  GNUNET_SPEEDUP_start_(cc->cfg);
+  GNUNET_SPEEDUP_start_ (cc->cfg);
   GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
   GNUNET_RESOLVER_connect (cc->cfg);
   cc->task (cc->task_cls, cc->args, cc->cfgfile, cc->cfg);
@@ -138,10 +138,13 @@ cmd_sorter (const void *a1, const void *a2)
  * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  */
 int
-GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
+GNUNET_PROGRAM_run2 (int argc,
+                     char *const *argv,
+                     const char *binaryName,
                      const char *binaryHelp,
                      const struct GNUNET_GETOPT_CommandLineOption *options,
-                     GNUNET_PROGRAM_Main task, void *task_cls,
+                     GNUNET_PROGRAM_Main task,
+                     void *task_cls,
                      int run_without_scheduler)
 {
   struct CommandContext cc;
@@ -158,14 +161,13 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
   unsigned long long skew_variance;
   long long clock_offset;
   struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  struct GNUNET_GETOPT_CommandLineOption defoptions[] = {
-    GNUNET_GETOPT_option_cfgfile (&cc.cfgfile),
-    GNUNET_GETOPT_option_help (binaryHelp),
-    GNUNET_GETOPT_option_loglevel (&loglev),
-    GNUNET_GETOPT_option_logfile (&logfile),
-    GNUNET_GETOPT_option_version (PACKAGE_VERSION " " VCS_VERSION)
-  };
+  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
+  struct GNUNET_GETOPT_CommandLineOption defoptions[] =
+    {GNUNET_GETOPT_option_cfgfile (&cc.cfgfile),
+     GNUNET_GETOPT_option_help (binaryHelp),
+     GNUNET_GETOPT_option_loglevel (&loglev),
+     GNUNET_GETOPT_option_logfile (&logfile),
+     GNUNET_GETOPT_option_version (pd->version)};
   struct GNUNET_GETOPT_CommandLineOption *allopts;
   const char *gargs;
   char *lpfx;
@@ -177,16 +179,14 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
   {
     char **gargv;
     unsigned int gargc;
-    int i;
-    char *tok;
     char *cargs;
 
     gargv = NULL;
     gargc = 0;
-    for (i = 0; i < argc; i++)
+    for (int i = 0; i < argc; i++)
       GNUNET_array_append (gargv, gargc, GNUNET_strdup (argv[i]));
     cargs = GNUNET_strdup (gargs);
-    for (tok = strtok (cargs, " "); NULL != tok; tok = strtok (NULL, " "))
+    for (char *tok = strtok (cargs, " "); NULL != tok; tok = strtok (NULL, " "))
       GNUNET_array_append (gargv, gargc, GNUNET_strdup (tok));
     GNUNET_free (cargs);
     GNUNET_array_append (gargv, gargc, NULL);
@@ -200,29 +200,35 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
   cc.cfg = cfg = GNUNET_CONFIGURATION_create ();
   /* prepare */
 #if ENABLE_NLS
-  setlocale (LC_ALL, "");
-  path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR);
-  if (NULL != path)
+  if (NULL != pd->gettext_domain)
   {
-    BINDTEXTDOMAIN ("GNUnet", path);
-    GNUNET_free (path);
+    setlocale (LC_ALL, "");
+    path = (NULL == pd->gettext_path)
+             ? GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR)
+             : GNUNET_strdup (pd->gettext_path);
+    if (NULL != path)
+    {
+      bindtextdomain (pd->gettext_domain, path);
+      GNUNET_free (path);
+    }
+    textdomain (pd->gettext_domain);
   }
-  textdomain ("GNUnet");
 #endif
   cnt = 0;
   while (NULL != options[cnt].name)
     cnt++;
   allopts =
-      GNUNET_malloc ((cnt +
-                      1) * sizeof (struct GNUNET_GETOPT_CommandLineOption) +
-                     sizeof (defoptions));
+    GNUNET_malloc ((cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption) +
+                   sizeof (defoptions));
   GNUNET_memcpy (allopts, defoptions, sizeof (defoptions));
-  GNUNET_memcpy (&allopts
-          [sizeof (defoptions) /
-           sizeof (struct GNUNET_GETOPT_CommandLineOption)], options,
-          (cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption));
+  GNUNET_memcpy (&allopts[sizeof (defoptions) /
+                          sizeof (struct GNUNET_GETOPT_CommandLineOption)],
+                 options,
+                 (cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption));
   cnt += sizeof (defoptions) / sizeof (struct GNUNET_GETOPT_CommandLineOption);
-  qsort (allopts, cnt, sizeof (struct GNUNET_GETOPT_CommandLineOption),
+  qsort (allopts,
+         cnt,
+         sizeof (struct GNUNET_GETOPT_CommandLineOption),
          &cmd_sorter);
   loglev = NULL;
   xdg = getenv ("XDG_CONFIG_HOME");
@@ -231,9 +237,9 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
                      "%s%s%s",
                      xdg,
                      DIR_SEPARATOR_STR,
-                     GNUNET_OS_project_data_get ()->config_file);
+                     pd->config_file);
   else
-    cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
+    cfg_fn = GNUNET_strdup (pd->user_config_file);
   lpfx = GNUNET_strdup (binaryName);
   if (NULL != (spc = strstr (lpfx, " ")))
     *spc = '\0';
@@ -245,15 +251,14 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
     GNUNET_free (lpfx);
     goto cleanup;
   }
-  if (NULL == cc.cfgfile)
-    cc.cfgfile = GNUNET_strdup (cfg_fn);
-  if (GNUNET_YES ==
-      GNUNET_DISK_file_test (cc.cfgfile))
+  if (NULL != cc.cfgfile)
   {
-    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile))
+    if ((GNUNET_YES != GNUNET_DISK_file_test (cc.cfgfile)) ||
+        (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile)))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Malformed configuration file `%s', exit ...\n"),
+                  _ (
+                    "Unreadable or malformed configuration file `%s', exit ...\n"),
                   cc.cfgfile);
       ret = GNUNET_SYSERR;
       GNUNET_free (allopts);
@@ -263,28 +268,46 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
   }
   else
   {
-    if (0 != strcmp (cc.cfgfile, cfg_fn))
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Could not access configuration file `%s'\n"),
-                 cc.cfgfile);
-    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
+    if (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Malformed configuration, exit ...\n"));
-      ret = GNUNET_SYSERR;
-      GNUNET_free (allopts);
-      GNUNET_free (lpfx);
-      goto cleanup;
+      if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn))
+      {
+        GNUNET_log (
+          GNUNET_ERROR_TYPE_ERROR,
+          _ (
+            "Unreadable or malformed default configuration file `%s', exit ...\n"),
+          cfg_fn);
+        ret = GNUNET_SYSERR;
+        GNUNET_free (allopts);
+        GNUNET_free (lpfx);
+        goto cleanup;
+      }
+    }
+    else
+    {
+      GNUNET_free (cfg_fn);
+      cfg_fn = NULL;
+      if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, NULL))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    _ ("Unreadable or malformed configuration, exit ...\n"));
+        ret = GNUNET_SYSERR;
+        GNUNET_free (allopts);
+        GNUNET_free (lpfx);
+        goto cleanup;
+      }
     }
   }
   GNUNET_free (allopts);
   GNUNET_free (lpfx);
-  if (GNUNET_OK ==
-      GNUNET_CONFIGURATION_get_value_number (cc.cfg, "testing", "skew_offset",
-                                             &skew_offset) &&
-      (GNUNET_OK ==
-       GNUNET_CONFIGURATION_get_value_number (cc.cfg, "testing",
-                                              "skew_variance", &skew_variance)))
+  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cc.cfg,
+                                                          "testing",
+                                                          "skew_offset",
+                                                          &skew_offset) &&
+      (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cc.cfg,
+                                                           "testing",
+                                                           "skew_variance",
+                                                           &skew_variance)))
   {
     clock_offset = skew_offset - skew_variance;
     GNUNET_TIME_set_offset (clock_offset);
@@ -295,18 +318,18 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
      in "cfg".  This is typically really only having an effect if we
      are running code in src/arm/, as obviously the rest of the code
      has little business with ARM-specific options. */
-  if (GNUNET_YES !=
-      GNUNET_CONFIGURATION_have_value (cfg,
-                                       "arm",
-                                       "CONFIG"))
+  if (GNUNET_YES != GNUNET_CONFIGURATION_have_value (cfg, "arm", "CONFIG"))
   {
-    GNUNET_CONFIGURATION_set_value_string (cfg,
-                                           "arm", "CONFIG",
-                                           cc.cfgfile);
+    if (NULL != cc.cfgfile)
+      GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", cc.cfgfile);
+    else if (NULL != cfg_fn)
+      GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", cfg_fn);
   }
 
   /* run */
   cc.args = &argv[ret];
+  if ((NULL == cc.cfgfile) && (NULL != cfg_fn))
+    cc.cfgfile = GNUNET_strdup (cfg_fn);
   if (GNUNET_NO == run_without_scheduler)
   {
     GNUNET_SCHEDULER_run (&program_main, &cc);
@@ -317,15 +340,16 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
     cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg);
   }
   ret = GNUNET_OK;
- cleanup:
+cleanup:
   GNUNET_CONFIGURATION_destroy (cfg);
   GNUNET_free_non_null (cc.cfgfile);
-  GNUNET_free (cfg_fn);
+  GNUNET_free_non_null (cfg_fn);
   GNUNET_free_non_null (loglev);
   GNUNET_free_non_null (logfile);
   return ret;
 }
 
+
 /**
  * Run a standard GNUnet command startup sequence (initialize loggers
  * and configuration, parse options).
@@ -340,17 +364,21 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName,
  * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  */
 int
-GNUNET_PROGRAM_run (int argc, char *const *argv,
+GNUNET_PROGRAM_run (int argc,
+                    char *const *argv,
                     const char *binaryName,
                     const char *binaryHelp,
                     const struct GNUNET_GETOPT_CommandLineOption *options,
                     GNUNET_PROGRAM_Main task,
                     void *task_cls)
 {
-  return GNUNET_PROGRAM_run2 (argc, argv,
-                              binaryName, binaryHelp,
+  return GNUNET_PROGRAM_run2 (argc,
+                              argv,
+                              binaryName,
+                              binaryHelp,
                               options,
-                              task, task_cls,
+                              task,
+                              task_cls,
                               GNUNET_NO);
 }