Hello, as the subject line says, the attached patch allows applications to omit (set to NULL) some fields in the ProjectData structure. This change is mostly meant for clients, as services don't really gain anything from omitting fields.
Consider the following simple example use case: I'm writing a wget-style tool which takes a peer P from the command line and optionally a port Q, connects to to P through CADET (eventually using port Q) and dumps the received data to stdout, closing the connection afterwards. Because I'm specifiying new options, I want to use gettext to localize the new help strings, so I specify this ProjectData structure (with some macros from autoconf): static struct GNUNET_OS_ProjectData pd = { .project_dirname = PACKAGE, .binary_name = "cget", .bug_email = PACKAGE_BUGREPORT, .homepage = "myhomepage.tld/cget", .version = PACKAGE_VERSION, .is_gnu = 0, .gettext_domain = PACKAGE, .gettext_path = LOCALEDIR, .agpl_url = "myhomepage.tld/cget/source", }; I don't provide a library, since it's just a self-contained client tool, and the only configuration needed is GNUnet's and the values taken from the command line, so I don't specify any environment variable or a configuration file. GNUnet's configuration can be obtained with `GNUNET_CONFIGURATION_default'. Despite compiling just fine, when ran the program fails immediately at startup: not specifying a configuration file (either using NULL or an empty string) terminates the program either aborting (NULL value) or stating that the configuration file is missing or malformed (empty string.) With the attached patch, clients like this hypotetical "cget" tool can be used even without installing an empty configuration file in `GNUNET_OS_IPK_DATADIR'. Thanks, A.V.
>From 67adc95a802f0c88ba048af75b96a082cd90c129 Mon Sep 17 00:00:00 2001 From: Alessio Vanni <vanni...@firemail.cc> Date: Sat, 10 Oct 2020 17:19:53 +0200 Subject: [PATCH] Allow applications to change ProjectData with only some fields Some simple applications (e.g. thin clients) might want to change the ProjectData structure (e.g. for gettext), but might not meet all the requirements needed to fill it out completely. A thin client might not provide any library, making the `libname' field useless. More importantly, not every application requires a configuration: some of them, especially clients, might simply use command line options to drive their behaviour. --- src/util/configuration_loader.c | 3 ++- src/util/os_installation.c | 2 ++ src/util/program.c | 25 +++++++++++++++---------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/util/configuration_loader.c b/src/util/configuration_loader.c index b9e5cb67f..51af24a9f 100644 --- a/src/util/configuration_loader.c +++ b/src/util/configuration_loader.c @@ -47,7 +47,8 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname; - if (NULL != (baseconfig = getenv (base_config_varname))) + if (NULL != base_config_varname + && NULL != (baseconfig = getenv (base_config_varname))) { baseconfig = GNUNET_strdup (baseconfig); } diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 34b88d761..1f2dd2e5b 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -150,6 +150,8 @@ get_path_from_proc_maps () FILE *f; char *lgu; + if (NULL == current_pd->libname) + return NULL; GNUNET_snprintf (fn, sizeof(fn), "/proc/%u/maps", getpid ()); if (NULL == (f = fopen (fn, "r"))) return NULL; diff --git a/src/util/program.c b/src/util/program.c index 8bda34b4f..b5484855c 100644 --- a/src/util/program.c +++ b/src/util/program.c @@ -232,15 +232,20 @@ GNUNET_PROGRAM_run2 (int argc, sizeof(struct GNUNET_GETOPT_CommandLineOption), &cmd_sorter); loglev = NULL; - xdg = getenv ("XDG_CONFIG_HOME"); - if (NULL != xdg) - GNUNET_asprintf (&cfg_fn, - "%s%s%s", - xdg, - DIR_SEPARATOR_STR, - pd->config_file); + if (NULL != pd->config_file && NULL != pd->user_config_file) + { + xdg = getenv ("XDG_CONFIG_HOME"); + if (NULL != xdg) + GNUNET_asprintf (&cfg_fn, + "%s%s%s", + xdg, + DIR_SEPARATOR_STR, + pd->config_file); + else + cfg_fn = GNUNET_strdup (pd->user_config_file); + } else - cfg_fn = GNUNET_strdup (pd->user_config_file); + cfg_fn = NULL; lpfx = GNUNET_strdup (binaryName); if (NULL != (spc = strstr (lpfx, " "))) *spc = '\0'; @@ -269,7 +274,7 @@ GNUNET_PROGRAM_run2 (int argc, } else { - if (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn)) + if (NULL != cfg_fn && GNUNET_YES == GNUNET_DISK_file_test (cfg_fn)) { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn)) { @@ -284,7 +289,7 @@ GNUNET_PROGRAM_run2 (int argc, goto cleanup; } } - else + else if (NULL != cfg_fn) { GNUNET_free (cfg_fn); cfg_fn = NULL; -- 2.26.2