/**@return a backend which gives plugin configuration of the module * which is currently point to. * * @param modules the modules to work with * @param errorKey the key to issue warnings and errors to */ Backend* elektraBackendOpenModules(KeySet *modules, Key *errorKey) { Backend *backend = elektraBackendAllocate(); cursor_t save = ksGetCursor (modules); KeySet *defaultConfig = ksNew(5, keyNew("system/module", KEY_VALUE, "1", KEY_END), keyNew("user/module", KEY_VALUE, "1", KEY_END), KS_END); Key *cur = ksCurrent(modules); elektraKeySetName(errorKey, keyName(cur), KEY_CASCADING_NAME | KEY_EMPTY_NAME); Plugin *plugin = elektraPluginOpen(keyBaseName(cur), modules, defaultConfig, errorKey); if (!plugin) { /* Error already set in plugin */ elektraFree(backend); return 0; } Key *mp = keyNew ("system/elektra/modules", KEY_VALUE, "modules", KEY_END); keyAddBaseName (mp, keyBaseName(cur)); backend->getplugins[0] = plugin; plugin->refcounter = 1; backend->mountpoint = mp; keyIncRef(backend->mountpoint); ksSetCursor (modules, save); return backend; }
/** * Opens a default backend using the plugin named KDB_DEFAULT_RESOLVER * and KDB_DEFAULT_STORAGE. * * @param modules the modules to work with * @param errorKey the key to issue warnings and errors to * @return the fresh allocated default backend or 0 if it failed */ Backend* elektraBackendOpenDefault(KeySet *modules, Key *errorKey) { Backend *backend = elektraBackendAllocate(); KeySet *resolverConfig = ksNew(5, keyNew("system/path", KEY_VALUE, KDB_DB_FILE, KEY_END), KS_END); Plugin *resolver = elektraPluginOpen(KDB_DEFAULT_RESOLVER, modules, resolverConfig, errorKey); if (!resolver) { elektraFree(backend); /* error already set in elektraPluginOpen */ return 0; } backend->getplugins[RESOLVER_PLUGIN] = resolver; backend->setplugins[RESOLVER_PLUGIN] = resolver; backend->setplugins[COMMIT_PLUGIN] = resolver; backend->errorplugins[STORAGE_PLUGIN] = resolver; resolver->refcounter = 4; KeySet *storageConfig = ksNew(5, KS_END); Plugin *storage = elektraPluginOpen(KDB_DEFAULT_STORAGE, modules, storageConfig, errorKey); if (!storage) { elektraPluginClose(resolver, errorKey); elektraFree(backend); /* error already set in elektraPluginOpen */ return 0; } backend->getplugins[STORAGE_PLUGIN] = storage; backend->setplugins[STORAGE_PLUGIN] = storage; storage->refcounter = 2; Key *mp = keyNew ("", KEY_VALUE, "default", KEY_END); backend->mountpoint = mp; keyIncRef(backend->mountpoint); return backend; }
/** * Opens the internal backend that indicates that a backend * is missing at that place. * * @return the fresh allocated backend or 0 if no memory */ Backend* elektraBackendOpenMissing(Key *mp) { Backend *backend = elektraBackendAllocate(); Plugin *plugin = elektraPluginMissing(); if (!plugin) { /* Could not allocate plugin */ elektraFree(backend); return 0; } backend->getplugins[0] = plugin; backend->setplugins[0] = plugin; plugin->refcounter = 2; keySetString (mp, "missing"); backend->mountpoint = mp; keyIncRef(backend->mountpoint); return backend; }
/**Builds a backend out of the configuration supplied * from: * @verbatim system/elektra/mountpoints/<name> @endverbatim * * The root key must be like the above example. You do * not need to rewind the keyset. But every key must be * below the root key. * * The internal consistency will be checked in this * function. If necessary parts are missing, like * no plugins, they cant be loaded or similar 0 * will be returned. * * ksCut() is perfectly suitable for cutting out the * configuration like needed. * * @note The given KeySet will be deleted within the function, * don't use it afterwards. * * @param elektraConfig the configuration to work with. * It is used to build up this backend. * @param modules used to load new modules or get references * to existing one * @return a pointer to a freshly allocated backend * this could be the requested backend or a so called * "missing backend". * @retval 0 if out of memory * @ingroup backend */ Backend* elektraBackendOpen(KeySet *elektraConfig, KeySet *modules, Key *errorKey) { Key * cur; Key * root; KeySet *referencePlugins = 0; KeySet *systemConfig = 0; int failure = 0; referencePlugins = ksNew(0, KS_END); ksRewind(elektraConfig); root = ksNext (elektraConfig); Backend *backend = elektraBackendAllocate(); while ((cur = ksNext(elektraConfig)) != 0) { if (keyRel (root, cur) == 1) { // direct below root key KeySet *cut = ksCut (elektraConfig, cur); if (!strcmp(keyBaseName(cur), "config")) { systemConfig = elektraRenameKeys(cut, "system"); ksDel (cut); } else if (!strcmp(keyBaseName(cur), "getplugins")) { if (elektraProcessPlugins(backend->getplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(13, errorKey, "elektraProcessPlugins for get failed"); failure = 1; } } else if (!strcmp(keyBaseName(cur), "mountpoint")) { backend->mountpoint = keyNew("", KEY_VALUE, keyBaseName(root), KEY_END); elektraKeySetName(backend->mountpoint, keyString(cur), KEY_CASCADING_NAME | KEY_EMPTY_NAME); if (!backend->mountpoint) { if (!failure) ELEKTRA_ADD_WARNINGF(14, errorKey, "Could not create mountpoint with name %s and value %s", keyString(cur), keyBaseName(root)); failure = 1; } keyIncRef(backend->mountpoint); ksDel (cut); } else if (!strcmp(keyBaseName(cur), "setplugins")) { if (elektraProcessPlugins(backend->setplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for set failed"); failure = 1; } } else if (!strcmp(keyBaseName(cur), "errorplugins")) { if (elektraProcessPlugins(backend->errorplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for error failed"); failure = 1; } } else { // no one cares about that config if (!failure) ELEKTRA_ADD_WARNING(16, errorKey, keyBaseName(cur)); ksDel (cut); } } } if (failure) { Backend *tmpBackend = elektraBackendOpenMissing(backend->mountpoint); elektraBackendClose(backend, errorKey); backend = tmpBackend; } ksDel (systemConfig); ksDel (elektraConfig); ksDel (referencePlugins); return backend; }
keyIncRef(backend->mountpoint); ksSetCursor (modules, save); return backend; } /** * Opens the internal version backend. * * @param errorKey the key to issue warnings and errors to * @return the fresh allocated default backend or 0 if it failed */ Backend* elektraBackendOpenVersion(Key * errorKey ELEKTRA_UNUSED) { Backend *backend = elektraBackendAllocate(); Plugin *plugin = elektraPluginVersion(); if (!plugin) { /* Could not allocate plugin */ elektraFree(backend); return 0; } Key *mp = keyNew ("system/elektra/version", KEY_VALUE, "version", KEY_END); backend->getplugins[0] = plugin; backend->setplugins[0] = plugin; plugin->refcounter = 2;
/** * Opens a default backend using the plugin named KDB_DEFAULT_RESOLVER * and KDB_DEFAULT_STORAGE. * * @param modules the modules to work with * @param errorKey the key to issue warnings and errors to * @return the fresh allocated default backend or 0 if it failed */ Backend* elektraBackendOpenDefault(KeySet *modules, const char * file, Key *errorKey) { Backend *backend = elektraBackendAllocate(); KeySet *resolverConfig = ksNew(5, keyNew("system/path", KEY_VALUE, file, KEY_END), KS_END); elektraKeySetName(errorKey, "", KEY_CASCADING_NAME | KEY_EMPTY_NAME); Plugin *resolver = elektraPluginOpen(KDB_DEFAULT_RESOLVER, modules, resolverConfig, errorKey); if (!resolver) { elektraFree(backend); /* error already set in elektraPluginOpen */ return 0; } #if DEBUG && VERBOSE KeySet *tracerConfig = ksNew(5, // does not matter because it is mounted differently in system/elektra/modules: // keyNew("system/logmodule", KEY_VALUE, "1", KEY_END), KS_END); Plugin *tracer = elektraPluginOpen("tracer", modules, tracerConfig, errorKey); if (tracer) { backend->getplugins[RESOLVER_PLUGIN+1] = tracer; backend->setplugins[RESOLVER_PLUGIN+1] = tracer; backend->errorplugins[RESOLVER_PLUGIN+1] = tracer; tracer->refcounter = 3; } #endif backend->getplugins[RESOLVER_PLUGIN] = resolver; backend->setplugins[RESOLVER_PLUGIN] = resolver; backend->setplugins[COMMIT_PLUGIN] = resolver; backend->errorplugins[STORAGE_PLUGIN] = resolver; resolver->refcounter = 4; KeySet *storageConfig = ksNew(5, KS_END); Plugin *storage = elektraPluginOpen(KDB_DEFAULT_STORAGE, modules, storageConfig, errorKey); if (!storage) { elektraPluginClose(resolver, errorKey); elektraFree(backend); /* error already set in elektraPluginOpen */ return 0; } backend->getplugins[STORAGE_PLUGIN] = storage; backend->setplugins[STORAGE_PLUGIN] = storage; storage->refcounter = 2; Key *mp = keyNew ("", KEY_VALUE, "default", KEY_END); backend->mountpoint = mp; keyIncRef(backend->mountpoint); return backend; }
/**Builds a backend out of the configuration supplied * from: * @verbatim system/elektra/mountpoints/<name> @endverbatim * * The root key must be like the above example. You do * not need to rewind the keyset. But every key must be * below the root key. * * The internal consistency will be checked in this * function. If necessary parts are missing, like * no plugins, they cant be loaded or similar 0 * will be returned. * * ksCut() is perfectly suitable for cutting out the * configuration like needed. * * @note The given KeySet will be deleted within the function, * don't use it afterwards. * * @param elektraConfig the configuration to work with. * It is used to build up this backend. * @param modules used to load new modules or get references * to existing one * @param errorKey the key where an error and warnings are added * * @return a pointer to a freshly allocated backend * this could be the requested backend or a so called * "missing backend". * @retval 0 if out of memory * @ingroup backend */ Backend* elektraBackendOpen(KeySet *elektraConfig, KeySet *modules, Key *errorKey) { Key * cur; KeySet *referencePlugins = 0; KeySet *systemConfig = 0; int failure = 0; referencePlugins = ksNew(0, KS_END); ksRewind(elektraConfig); Key * root = ksNext (elektraConfig); Backend *backend = elektraBackendAllocate(); if (elektraBackendSetMountpoint(backend, elektraConfig, errorKey) == -1) { // warning already set failure = 1; } while ((cur = ksNext(elektraConfig)) != 0) { if (keyRel (root, cur) == 1) { // direct below root key KeySet *cut = ksCut (elektraConfig, cur); if (!strcmp(keyBaseName(cur), "config")) { systemConfig = elektraRenameKeys(cut, "system"); ksDel (cut); } else if (!strcmp(keyBaseName(cur), "errorplugins")) { if (elektraProcessPlugins(backend->errorplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for error failed"); failure = 1; } } else if (!strcmp(keyBaseName(cur), "getplugins")) { if (elektraProcessPlugins(backend->getplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(13, errorKey, "elektraProcessPlugins for get failed"); failure = 1; } } else if (!strcmp(keyBaseName(cur), "mountpoint")) { ksDel (cut); // already handled by elektraBackendSetMountpoint continue; } else if (!strcmp(keyBaseName(cur), "setplugins")) { if (elektraProcessPlugins(backend->setplugins, modules, referencePlugins, cut, systemConfig, errorKey) == -1) { if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for set failed"); failure = 1; } } else { // no one cares about that config if (!failure) ELEKTRA_ADD_WARNING(16, errorKey, keyBaseName(cur)); ksDel (cut); } } } if (failure) { Backend *tmpBackend = elektraBackendOpenMissing(backend->mountpoint); elektraBackendClose(backend, errorKey); backend = tmpBackend; } ksDel (systemConfig); ksDel (elektraConfig); ksDel (referencePlugins); return backend; }