diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2022-10-02 18:05:58 +0200 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2022-10-02 18:05:58 +0200 |
commit | 04c7e0bb337dd88dde60293d94d2e192a8fc2ff5 (patch) | |
tree | bff69b52b8d07be2442dde6ca86a3df2776b2e67 /src/extensions/extensions.c | |
parent | 165b85ddd59ce4af9b3f28409b6210d8f688f17d (diff) |
Refactor extensions
- Extensions are now compiled as shared libraries and loaded at runtime
according to the TALER configuration.
- So far, only age restriction is loaded as extension.
- Groundwork for extension auction_brandt started.
Diffstat (limited to 'src/extensions/extensions.c')
-rw-r--r-- | src/extensions/extensions.c | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c index 0df0bae3..95fb8cf0 100644 --- a/src/extensions/extensions.c +++ b/src/extensions/extensions.c @@ -24,21 +24,22 @@ #include "taler_extensions.h" #include "stdint.h" - /* head of the list of all registered extensions */ -static struct TALER_Extension *TE_extensions = NULL; - +static struct TALER_Extensions TE_extensions = { + .next = NULL, + .extension = NULL, +}; -const struct TALER_Extension * +const struct TALER_Extensions * TALER_extensions_get_head () { - return TE_extensions; + return &TE_extensions; } -enum GNUNET_GenericReturnValue -TALER_extensions_add ( - struct TALER_Extension *extension) +static enum GNUNET_GenericReturnValue +add_extension ( + const struct TALER_Extension *extension) { /* Sanity checks */ if ((NULL == extension) || @@ -47,28 +48,30 @@ TALER_extensions_add ( (NULL == extension->disable) || (NULL == extension->test_json_config) || (NULL == extension->load_json_config) || - (NULL == extension->config_to_json) || - (NULL == extension->load_taler_config)) + (NULL == extension->config_to_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "invalid extension\n"); return GNUNET_SYSERR; } - if (NULL == TE_extensions) /* first extension ?*/ - TE_extensions = (struct TALER_Extension *) extension; + if (NULL == TE_extensions.extension) /* first extension ?*/ + TE_extensions.extension = extension; else { - struct TALER_Extension *iter; - struct TALER_Extension *last; + struct TALER_Extensions *iter; + struct TALER_Extensions *last; /* Check for collisions */ - for (iter = TE_extensions; NULL != iter; iter = iter->next) + for (iter = &TE_extensions; + NULL != iter && NULL != iter->extension; + iter = iter->next) { + const struct TALER_Extension *ext = iter->extension; last = iter; - if (extension->type == iter->type || + if (extension->type == ext->type || 0 == strcasecmp (extension->name, - iter->name)) + ext->name)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "extension collision for `%s'\n", @@ -78,7 +81,11 @@ TALER_extensions_add ( } /* No collisions found, so add this extension to the list */ - last->next = extension; + { + struct TALER_Extensions *extn = GNUNET_new (struct TALER_Extensions); + extn->extension = extension; + last->next = extn; + } } return GNUNET_OK; @@ -89,12 +96,12 @@ const struct TALER_Extension * TALER_extensions_get_by_type ( enum TALER_Extension_Type type) { - for (const struct TALER_Extension *it = TE_extensions; - NULL != it; + for (const struct TALER_Extensions *it = &TE_extensions; + NULL != it && NULL != it->extension; it = it->next) { - if (it->type == type) - return it; + if (it->extension->type == type) + return it->extension; } /* No extension found. */ @@ -109,8 +116,7 @@ TALER_extensions_is_enabled_type ( const struct TALER_Extension *ext = TALER_extensions_get_by_type (type); - return (NULL != ext && - TALER_extensions_is_enabled (ext)); + return (NULL != ext && ext->enabled); } @@ -118,14 +124,15 @@ const struct TALER_Extension * TALER_extensions_get_by_name ( const char *name) { - for (const struct TALER_Extension *it = TE_extensions; + for (const struct TALER_Extensions *it = &TE_extensions; NULL != it; it = it->next) { - if (0 == strcasecmp (name, it->name)) - return it; + if (0 == strcasecmp (name, it->extension->name)) + return it->extension; } - /* No extension found. */ + /* No extension found, try to load it. */ + return NULL; } @@ -178,7 +185,8 @@ configure_extension ( { struct LoadConfClosure *col = cls; const char *name; - const struct TALER_Extension *extension; + char *lib_name; + struct TALER_Extension *extension; if (GNUNET_OK != col->error) return; @@ -190,33 +198,49 @@ configure_extension ( name = section + sizeof(TALER_EXTENSION_SECTION_PREFIX) - 1; - if (NULL == - (extension = TALER_extensions_get_by_name (name))) + + /* Load the extension library */ + GNUNET_asprintf (&lib_name, + "libtaler_extension_%s", + name); + extension = GNUNET_PLUGIN_load ( + lib_name, + (void *) col->cfg); + if (NULL == extension) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unsupported extension `%s` (section [%s]).\n", name, + "Couldn't load extension library to `%s` (section [%s]).\n", + name, section); col->error = GNUNET_SYSERR; return; } - if (GNUNET_OK != - extension->load_taler_config ( - (struct TALER_Extension *) extension, - col->cfg)) + + if (GNUNET_OK != add_extension (extension)) { + /* TODO: Ignoring return values here */ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Couldn't parse configuration for extension `%s` (section [%s]).\n", + "Couldn't add extension `%s` (section [%s]).\n", name, section); col->error = GNUNET_SYSERR; + GNUNET_PLUGIN_unload ( + lib_name, + (void *) col->cfg); return; } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "extension library '%s' loaded\n", + lib_name); } +static bool extensions_loaded = false; + enum GNUNET_GenericReturnValue -TALER_extensions_load_taler_config ( +TALER_extensions_load ( const struct GNUNET_CONFIGURATION_Handle *cfg) { struct LoadConfClosure col = { @@ -224,9 +248,16 @@ TALER_extensions_load_taler_config ( .error = GNUNET_OK, }; + if (extensions_loaded) + return GNUNET_OK; + GNUNET_CONFIGURATION_iterate_sections (cfg, &configure_extension, &col); + + if (GNUNET_OK == col.error) + extensions_loaded = true; + return col.error; } @@ -309,28 +340,16 @@ TALER_extensions_load_json_config ( } /* make sure to disable all extensions that weren't mentioned in the json */ - for (const struct TALER_Extension *it = TALER_extensions_get_head (); + for (const struct TALER_Extensions *it = TALER_extensions_get_head (); NULL != it; it = it->next) { - if (NULL == json_object_get (extensions, it->name)) - it->disable ((struct TALER_Extension *) it); + if (NULL == json_object_get (extensions, it->extension->name)) + it->extension->disable ((struct TALER_Extension *) it); } return GNUNET_OK; } -bool -TALER_extensions_age_restriction_is_enabled () -{ - const struct TALER_Extension *age = - TALER_extensions_get_by_type (TALER_Extension_AgeRestriction); - - return (NULL != age && - NULL != age->config_json && - TALER_extensions_age_restriction_is_configured ()); -} - - /* end of extensions.c */ |