static void elektraAddUname (KeySet * returned, Key * parentKey) { Key * dir; Key * key = keyDup (parentKey); ksAppendKey (returned, key); struct utsname buf; uname (&buf); // TODO: handle error dir = keyDup (parentKey); keyAddBaseName (dir, "sysname"); keySetString (dir, buf.sysname); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "nodename"); keySetString (dir, buf.nodename); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "release"); keySetString (dir, buf.release); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "version"); keySetString (dir, buf.version); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "machine"); keySetString (dir, buf.machine); ksAppendKey (returned, dir); }
static void writeLineComments(Key *key, FILE *fp) { // TODO: this is really inefficient KeySet *metaKeys = elektraKeyGetMetaKeySet(key); Key *commentParent = keyNew("comment", KEY_META_NAME, KEY_END); KeySet *comments = elektraArrayGet(commentParent, metaKeys); keyDel(commentParent); ksRewind(comments); Key *current; while ((current = ksNext (comments))) { if (strcmp (keyName (current), "comment/#0")) { Key *spaceKey = keyDup (current); keyAddBaseName (spaceKey, "space"); Key *startKey = keyDup (current); keyAddBaseName (startKey, "start"); const char *spaces = getMetaValue (key, keyName (spaceKey)); const char *start = getMetaValue (key, keyName (startKey)); const char *comment = getMetaValue (key, keyName (current)); keyDel (spaceKey); keyDel (startKey); writeComment (spaces, start, comment, fp); fprintf (fp, "\n"); } } ksDel(metaKeys); ksDel(comments); }
int main () { // clang-format off { //! [set base basic] Key * k = keyNew ("user/my/long/name", KEY_END); keySetBaseName (k, "myname"); printf ("%s\n", keyName (k)); // will print user/my/long/myname keyDel (k); //! [set base basic] } { //! [add base basic] Key * k = keyNew ("user/my/long", KEY_END); keyAddBaseName (k, "myname"); printf ("%s\n", keyName (k)); // will print user/my/long/myname keyDel (k); //! [add base basic] } { //! [add base escaped] Key * k = keyNew ("user/my/long", KEY_END); keyAddBaseName (k, "myname"); printf ("%s\n", keyName (k)); // will print user/my/long/myname keyDel (k); //! [add base escaped] } }
/** * @internal * Read placement list from plugin. * * The returned string needs to be freed. * * @param plugin Plugin * @return Space separated list of placement names */ static char * getPluginPlacementList (Plugin * plugin) { ELEKTRA_NOT_NULL (plugin); // Get placements from plugin Key * pluginInfo = keyNew ("system/elektra/modules/", KEY_END); keyAddBaseName (pluginInfo, plugin->name); KeySet * ksResult = ksNew (0, KS_END); plugin->kdbGet (plugin, ksResult, pluginInfo); Key * placementsKey = keyDup (pluginInfo); keyAddBaseName (placementsKey, "infos"); keyAddBaseName (placementsKey, "placements"); Key * placements = ksLookup (ksResult, placementsKey, 0); if (placements == NULL) { ELEKTRA_LOG_WARNING ("could not read placements from plugin"); return 0; } char * placementList = elektraStrDup (keyString (placements)); keyDel (pluginInfo); keyDel (placementsKey); ksDel (ksResult); return placementList; }
void kdbGetByName(KDB *kdb, KeySet *conf, Key *parentKey, char *where) { keySetName(parentKey, "system"); keyAddBaseName(parentKey, where); kdbGet(kdb, conf, parentKey); keySetName(parentKey, "user"); keyAddBaseName(parentKey, where); kdbGet(kdb, conf, parentKey); }
static KeySet * nextPackage (FILE * fp, Key * parentKey) { char * line = elektraMalloc (DPKG_LINE_MAX); KeySet * package = ksNew (500, KS_END); Key * lastKey = NULL; Key * baseKey = NULL; int notDone = 0; while (fgets (line, DPKG_LINE_MAX, fp) != NULL) { if (*line == '\n') break; if (*line == ' ') { if (strchr (line, '\n')) notDone = 0; else notDone = 1; appendToKey (lastKey, line); } else if (notDone) { if (strchr (line, '\n')) notDone = 0; appendToKey (lastKey, line); } else { if (!strchr (line, '\n')) notDone = 1; char * section = line; char * data = strchr (line, ':'); if (data) *data = '\0'; ++data; // skip : ++data; // skip whitespace strtok (data, "\n"); // remove newline if (!strcmp (section, "Package")) { baseKey = keyDup (parentKey); keyAddBaseName (baseKey, data); lastKey = baseKey; ksAppendKey (package, baseKey); } else { Key * key = keyDup (baseKey); keyAddBaseName (key, section); keySetString (key, data); lastKey = key; ksAppendKey (package, key); } } memset (line, 0, DPKG_LINE_MAX); } elektraFree (line); return package; }
static Key * prefToKey (Key * parentKey, PrefType type, const char * pref) { Key * key = keyNew (keyName (parentKey), KEY_END); keyAddBaseName (key, prefix[type]); char * localString = elektraStrDup (pref); char * cPtr = strstr (localString, ","); *cPtr = '\0'; char * sPtr = localString; ++sPtr; *sPtr++ = '\0'; char * ePtr = cPtr - 1; elektraRstrip (sPtr, &ePtr); size_t keyLen = ePtr - sPtr; char * prefKey = elektraMalloc (keyLen + 1); snprintf (prefKey, keyLen + 1, "%s", sPtr); char * tPtr = strtok (prefKey, "."); if (tPtr) keyAddBaseName (key, tPtr); while ((tPtr = strtok (NULL, ".")) != NULL) { keyAddBaseName (key, tPtr); } elektraFree (prefKey); sPtr = cPtr + 1; sPtr = elektraLskip (sPtr); ePtr = strrchr (sPtr, ')'); *ePtr-- = '\0'; elektraRstrip (sPtr, &ePtr); size_t argLen = ePtr - sPtr + 1; char * prefArg = elektraMalloc (argLen + 1); snprintf (prefArg, argLen + 1, "%s", sPtr); if (!strcmp (prefArg, "true") || !(strcmp (prefArg, "false"))) { keySetMeta (key, "type", "boolean"); keySetString (key, prefArg); } else if (prefArg[0] == '"' && prefArg[strlen (prefArg) - 1] == '"') { // TODO: else if list keySetMeta (key, "type", "string"); *prefArg = '\0'; *(prefArg + (strlen (prefArg + 1))) = '\0'; keySetString (key, (prefArg + 1)); } else { keySetMeta (key, "type", "integer"); keySetString (key, prefArg); } elektraFree (prefArg); elektraFree (localString); return key; }
static void test_us () { printf ("Test mounting of user and system backends\n"); KDB * kdb = kdb_new (); KeySet * modules = ksNew (0, KS_END); elektraModulesInit (modules, 0); Key * mp; KeySet * config = set_us (); ksAppendKey (config, keyNew ("system/elektra/mountpoints", KEY_END)); succeed_if (mountOpen (kdb, config, modules, 0) == 0, "could not open mount"); succeed_if (mountDefault (kdb, modules, 1, 0) == 0, "could not mount default backend"); succeed_if (kdb->split->size == 5, "size of split not correct"); mp = keyNew ("system", KEY_VALUE, "system", KEY_END); compare_key (mp, kdb->split->parents[0]); keySetName (mp, "user"); keySetString (mp, "user"); compare_key (mp, kdb->split->parents[1]); keySetName (mp, "system/elektra"); keySetString (mp, "default"); compare_key (mp, kdb->split->parents[4]); keyDel (mp); Key * key = keyNew ("user/anywhere/backend/simple", KEY_END); Backend * backend = trieLookup (kdb->trie, key); keyAddBaseName (key, "somewhere"); keyAddBaseName (key, "deep"); keyAddBaseName (key, "below"); Backend * backend2 = trieLookup (kdb->trie, key); succeed_if (backend == backend2, "should be same backend"); succeed_if ((mp = backend->mountpoint) != 0, "no mountpoint found"); succeed_if_same_string (keyName (mp), "user"); succeed_if_same_string (keyString (mp), "user"); keySetName (key, "system/anywhere/tests/backend/two"); Backend * two = trieLookup (kdb->trie, key); succeed_if (two != backend, "should be differnt backend"); succeed_if ((mp = two->mountpoint) != 0, "no mountpoint found"); succeed_if_same_string (keyName (mp), "system"); succeed_if_same_string (keyString (mp), "system"); keyDel (key); kdb_del (kdb); elektraModulesClose (modules, 0); ksDel (modules); }
static void addAddressHierarchy (Key * key, char * fieldbuffer) { /* determine whether this is an ipv4 or ipv6 entry */ int family = getAddressFamily (fieldbuffer); /* in case of an error default to ipv4 */ switch (family) { case AF_INET6: keyAddBaseName (key, "ipv6"); break; default: keyAddBaseName (key, "ipv4"); } }
static KeySet * pwentToKS (struct passwd * pwd, Key * parentKey, SortBy index) { KeySet * ks = ksNew (0, KS_END); Key * append = keyNew (keyName (parentKey), KEY_END); char id[ID_MAX_CHARACTERS]; if (index == UID) { snprintf (id, sizeof (id), "%u", pwd->pw_uid); keyAddBaseName (append, id); keySetBinary (append, 0, 0); ksAppendKey (ks, keyDup (append)); keyAddBaseName (append, "name"); keySetString (append, pwd->pw_name); } else { keyAddBaseName (append, pwd->pw_name); keySetBinary (append, 0, 0); ksAppendKey (ks, keyDup (append)); snprintf (id, sizeof (id), "%u", pwd->pw_uid); keyAddBaseName (append, "uid"); keySetString (append, id); } ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "shell"); keySetString (append, pwd->pw_shell); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "home"); keySetString (append, pwd->pw_dir); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "gid"); snprintf (id, sizeof (id), "%u", pwd->pw_gid); keySetString (append, id); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "passwd"); keySetString (append, pwd->pw_passwd); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "gecos"); keySetString (append, pwd->pw_gecos); ksAppendKey (ks, keyDup (append)); keyDel (append); return ks; }
/** * @brief Remove ___empty_map if thats the only thing which would be * returned. * * @param returned to remove the key from */ static void elektraYajlParseSuppressEmpty (KeySet * returned, Key * parentKey) { if (ksGetSize (returned) == 2) { Key * lookupKey = keyDup (parentKey); keyAddBaseName (lookupKey, "___empty_map"); Key * toRemove = ksLookup (returned, lookupKey, KDB_O_POP); #ifdef ELEKTRA_YAJL_VERBOSE if (toRemove) { printf ("remove %s\n", keyName (toRemove)); } else { ksRewind (returned); Key * cur; while ((cur = ksNext (returned)) != 0) { printf ("key %s has value %s\n", keyName (cur), keyString (cur)); } printf ("did not find %s\n", keyName (lookupKey)); ksRewind (returned); } #endif if (toRemove) { keyDel (toRemove); } keyDel (lookupKey); } }
static char * parseCanonicalName (Key * result, char * line) { char * fieldBuffer; char * tokenPointer = line; /* read the ip address (if any) */ int sret = elektraParseToken (&fieldBuffer, line); if (sret == 0) return 0; tokenPointer += sret; /* determine whether this is an ipv4 or ipv6 entry */ addAddressHierarchy (result, fieldBuffer); /* store the ip address */ keySetString (result, fieldBuffer); elektraFree (fieldBuffer); /* read the canonical name */ sret = elektraParseToken (&fieldBuffer, tokenPointer); if (sret == 0) return 0; tokenPointer += sret; keyAddBaseName (result, fieldBuffer); elektraFree (fieldBuffer); return tokenPointer; }
/**@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); 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; }
char * elektraMetaArrayToString (Key * key, const char * metaName, const char * delim) { char * result = NULL; Key * lookupElem = keyDup (keyGetMeta (key, metaName)); keyAddBaseName (lookupElem, "#0"); Key * elem = (Key *)keyGetMeta (key, keyName (lookupElem)); if (elem != NULL) { elektraRealloc ((void **)&result, keyGetValueSize (elem)); snprintf (result, keyGetValueSize (elem), "%s", keyString (elem)); } elektraArrayIncName (lookupElem); elem = (Key *)keyGetMeta (key, keyName (lookupElem)); while (elem != NULL) { elektraRealloc ((void **)&result, elektraStrLen (result) + keyGetValueSize (elem) + 1); // String (incl. +2 times \0) + delimiter + whitespace strcat (result, delim); strcat (result, keyString (elem)); elektraArrayIncName (lookupElem); elem = (Key *)keyGetMeta (key, keyName (lookupElem)); } keyDel (lookupElem); return result; }
/** * @brief sets mountpoint * * @param backend where the mountpoint should be set * @param elektraConfig the config where the mountpoint can be found * @param [out] errorKey the name also has the mountpoint set * * @pre ksCurrent() is root key * @post ksCurrent() is root key * * @retval -1 if no mountpoint is found or memory allocation problem * @retval 0 on success */ int elektraBackendSetMountpoint(Backend *backend, KeySet *elektraConfig, Key *errorKey) { Key * root = ksCurrent(elektraConfig); Key * searchMountpoint = keyDup(root); keyAddBaseName(searchMountpoint, "mountpoint"); Key * foundMountpoint = ksLookup(elektraConfig, searchMountpoint, 0); keyDel (searchMountpoint); ksLookup(elektraConfig, root, 0); // reset ksCurrent() if (!foundMountpoint) { ELEKTRA_ADD_WARNINGF(14, errorKey, "Could not find mountpoint within root %s", keyName(root)); return -1; } backend->mountpoint = keyNew("", KEY_VALUE, keyBaseName(root), KEY_END); elektraKeySetName(backend->mountpoint, keyString(foundMountpoint), KEY_CASCADING_NAME | KEY_EMPTY_NAME); keySetName(errorKey, keyName(backend->mountpoint)); if (!backend->mountpoint) { ELEKTRA_ADD_WARNINGF(14, errorKey, "Could not create mountpoint with name %s and value %s", keyString(foundMountpoint), keyBaseName(root)); return -1; } keyIncRef(backend->mountpoint); return 0; }
static Key *createUnescapedKey(Key *key, const char *name) { char *localString = strdup(name); char *newBaseName = strtok(localString, "/"); if (newBaseName != NULL) keyAddBaseName(key, newBaseName); while (newBaseName != NULL) { newBaseName = strtok(NULL, "/"); if (newBaseName != NULL) { keyAddBaseName(key, newBaseName); } } elektraFree (localString); return key; }
static int iniKeyToElektraKey (void *vconfig, const char *section, const char *name, const char *value) { Configuration *config = (Configuration *)vconfig; Key *appendKey = keyDup (config->parentKey); if (section) { keyAddBaseName(appendKey, section); } keyAddBaseName (appendKey, name); writeCommentToMeta (config, appendKey); keySetString (appendKey, value); ksAppendKey (config->result, appendKey); return 1; }
/** * @internal * Remove plugin at all placements from list plugin configuration and apply it. * * @param list List plugin * @param plugin Plugin to remove * @retval 0 on error * @retval 1 on success */ static int listRemovePlugin (Plugin * list, Plugin * plugin) { ELEKTRA_NOT_NULL (list); ELEKTRA_NOT_NULL (plugin); KeySet * newConfig = ksDup (list->config); Key * configBase = keyNew ("user/plugins", KEY_END); KeySet * array = elektraArrayGet (configBase, newConfig); // Find the plugin with our handle Key * current; ksRewind (array); while ((current = ksNext (array)) != NULL) { Key * handleLookup = keyDup (current); keyAddBaseName (handleLookup, "handle"); Key * handle = ksLookup (newConfig, handleLookup, 0); keyDel (handleLookup); if (handle) { Plugin * handleValue = (*(Plugin **) keyValue (handle)); if (handleValue == plugin) { // Remove plugin configuration KeySet * cut = ksCut (newConfig, current); ksDel (cut); } } } ksDel (array); // Renumber array items KeySet * sourceArray = elektraArrayGet (configBase, newConfig); Key * renumberBase = keyNew ("user/plugins/#", KEY_END); ksRewind (sourceArray); while ((current = ksNext (sourceArray)) != NULL) { // Create new array item base name e.g. "user/plugins/#0" elektraArrayIncName (renumberBase); moveKeysRecursive (keyName (current), keyName (renumberBase), newConfig); } keyDel (configBase); keyDel (renumberBase); ksDel (sourceArray); ksDel (list->config); // Apply new configuration list->config = newConfig; list->kdbOpen (list, NULL); return 1; }
void elektraMetaArrayAdd (Key * key, const char * metaName, const char * value) { const Key * meta = keyGetMeta (key, metaName); Key * arrayKey; if (!meta) { keySetMeta (key, metaName, "#0"); arrayKey = keyDup (keyGetMeta (key, metaName)); keySetString (arrayKey, 0); keyAddBaseName (arrayKey, "#"); } else { arrayKey = keyDup (meta); keyAddBaseName (arrayKey, keyString (meta)); } elektraArrayIncName (arrayKey); keySetMeta (key, keyName (arrayKey), value); keySetMeta (key, metaName, keyBaseName (arrayKey)); keyDel (arrayKey); }
static int iniSectionToElektraKey (void *vconfig, const char *section) { Configuration *config = (Configuration *)vconfig; Key *appendKey = keyDup (config->parentKey); keyAddBaseName(appendKey, section); writeCommentToMeta (config, appendKey); keySetDir(appendKey); ksAppendKey(config->result, appendKey); return 1; }
void test_checkfile () { printf ("Check file\n"); KeySet * modules = ksNew (0, KS_END); elektraModulesInit (modules, 0); Plugin * plugin = elektraPluginOpen ("resolver", modules, set_pluginconf (), 0); exit_if_fail (plugin, "did not find a resolver"); Key * root = keyNew ("system/elektra/modules", KEY_END); keyAddBaseName (root, plugin->name); KeySet * contract = ksNew (5, KS_END); plugin->kdbGet (plugin, contract, root); keyAddName (root, "/exports/checkfile"); Key * found = ksLookup (contract, root, 0); exit_if_fail (found, "did not find checkfile symbol"); typedef int (*func_t) (const char *); union { func_t f; void * v; } conversation; succeed_if (keyGetBinary (found, &conversation.v, sizeof (conversation)) == sizeof (conversation), "could not get binary"); func_t checkFile = conversation.f; succeed_if (checkFile ("valid") == 1, "valid file not recognised"); succeed_if (checkFile ("/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("/absolute/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("../valid") == -1, "invalid file not recognised"); succeed_if (checkFile ("valid/..") == -1, "invalid file not recognised"); succeed_if (checkFile ("/../valid") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("/valid/..") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("very..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("/") == -1, "invalid absolute file not recognised"); succeed_if (checkFile (".") == -1, "invalid file not recognised"); succeed_if (checkFile ("..") == -1, "invalid file not recognised"); ksDel (contract); keyDel (root); elektraPluginClose (plugin, 0); elektraModulesClose (modules, 0); ksDel (modules); }
static const char * getGlobFlags (KeySet * keys, Key * globKey) { Key * flagKey = keyDup (globKey); keyAddBaseName (flagKey, "flags"); Key * flagResult = ksLookup (keys, flagKey, KDB_O_NONE); keyDel (flagKey); if (flagResult) { return keyString (flagResult); } return 0; }
/**Create a root key for a backend. * * @return a allocated root key */ Key * create_root_key (const char *backendName) { Key *root = keyNew ("user/tests", KEY_END); /*Make mount point beneath root, and do all tests here*/ /* Not needed anymore: keySetDir(root); keySetUID(root, nbUid); keySetGID(root, nbGid); keySetComment (root, "backend root key for tests"); */ keyAddBaseName (root, backendName); keySetString (root, backendName); keySetString (root, backendName); return root; }
static int elektraYajlParseStartMap (void * ctx) { KeySet * ks = (KeySet *)ctx; elektraYajlIncrementArrayEntry (ks); Key * currentKey = ksCurrent (ks); Key * newKey = keyNew (keyName (currentKey), KEY_END); // add a pseudo element for empty map keyAddBaseName (newKey, "___empty_map"); ksAppendKey (ks, newKey); #ifdef ELEKTRA_YAJL_VERBOSE printf ("elektraYajlParseStartMap with new key %s\n", keyName (newKey)); #endif return 1; }
static void test_readFormat (const char * format, const char * fileContent, int numKeys, const char ** keys, const char ** values) { const char * tmpFile = elektraFilename (); FILE * fh = fopen (tmpFile, "w"); if (fh) { fputs (fileContent, fh); fclose (fh); } Key * parentKey = keyNew ("user/tests/simpleini", KEY_VALUE, tmpFile, KEY_END); KeySet * conf = 0; if (format) { conf = ksNew (1, keyNew ("system/format", KEY_VALUE, format, KEY_END), KS_END); } else { conf = ksNew (0, KS_END); } PLUGIN_OPEN ("simpleini"); KeySet * ks = ksNew (numKeys, KS_END); Key * key = 0; succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); Key * lookup = 0; for (int i = 0; i < numKeys; i++) { lookup = keyNew ("user/tests/simpleini", KEY_END); keyAddBaseName (lookup, keys[i]); printf ("testing key '%s'\n", keyBaseName (lookup)); succeed_if ((key = ksLookup (ks, lookup, 0)) != NULL, "key not found"); succeed_if (strcmp (values[i], keyString (key)) == 0, "value of key did not match"); keyDel (lookup); } keyDel (key); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); }
static char * parseAlias (KeySet * append, const Key * hostParent, char * tokenPointer) { char * fieldBuffer; int sret = 0; sret = elektraParseToken (&fieldBuffer, tokenPointer); if (sret == 0) return 0; Key * alias = keyDup (hostParent); keyAddBaseName (alias, fieldBuffer); elektraFree (fieldBuffer); /* only add the alias if it does not exist already */ if (ksLookup (append, alias, KDB_O_NONE)) { keyDel (alias); } else { ksAppendKey (append, alias); } return tokenPointer + sret; }
static int iniKeyToElektraKey (void *vhandle, const char *section, const char *name, const char *value, unsigned short lineContinuation) { CallbackHandle *handle = (CallbackHandle *)vhandle; Key *appendKey = keyDup (handle->parentKey); keySetMeta(appendKey, "ini/lastSection", 0); if (!section || *section == '\0') { section = INTERNAL_ROOT_SECTION; } appendKey = createUnescapedKey(appendKey, section); short mergeSections = 0; Key *existingKey = NULL; if ((existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE))) { if (keyGetMeta(existingKey, "ini/duplicate")) { mergeSections = 1; } } setSectionNumber(handle->parentKey, appendKey, handle->result); appendKey = createUnescapedKey(appendKey, name); existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE); if (existingKey) { //a key with the same name already exists if (handle->array) { //array support is turned on keySetMeta(appendKey, "ini/section", 0); if (keyGetMeta(existingKey, "ini/array")) { //array already exists, appending new key const char *lastIndex = keyString(keyGetMeta(existingKey, "ini/array")); keyAddBaseName(appendKey, lastIndex); keySetMeta(appendKey, "order/parent", 0); keySetMeta(appendKey, "ini/array", 0); keySetMeta(appendKey, "order", 0); if (elektraArrayIncName(appendKey) == 1) { return -1; } keySetString(appendKey, value); keySetMeta(appendKey, "ini/key", 0); ksAppendKey(handle->result, appendKey); keySetMeta(existingKey, "ini/array", keyBaseName(appendKey)); ksAppendKey(handle->result, existingKey); } else { //creating a new array Key *sectionKey = keyDup(appendKey); keyAddName(sectionKey, ".."); char *origVal = strdup(keyString(existingKey)); keySetString(appendKey, ""); keySetMeta(appendKey, "ini/array", "#1"); keySetMeta(appendKey, "order/parent", keyName(sectionKey)); setSectionNumber(handle->parentKey, appendKey, handle->result); setOrderNumber(handle->parentKey, appendKey); keySetMeta(appendKey, "ini/key", ""); ksAppendKey(handle->result, keyDup(appendKey)); keySetMeta(appendKey, "ini/key", 0); keySetMeta(appendKey, "ini/array", 0); keySetMeta(appendKey, "parent", 0); keyAddName(appendKey, "#"); keySetMeta(appendKey, "order", 0); if (elektraArrayIncName(appendKey) == -1) { free(origVal); return -1; } keySetString(appendKey, origVal); ksAppendKey(handle->result, keyDup(appendKey)); free(origVal); if (elektraArrayIncName(appendKey) == -1) { return -1; } keySetMeta(appendKey, "parent", 0); keySetString(appendKey, value); ksAppendKey(handle->result, keyDup(appendKey)); keyDel(appendKey); keyDel(sectionKey); } return 1; } else if(!lineContinuation) { ELEKTRA_SET_ERRORF(141, handle->parentKey, "Key: %s\n", name); return -1; } } setSectionNumber(handle->parentKey, appendKey, handle->result); if (value == NULL) keySetMeta(appendKey, "ini/empty", ""); if (!lineContinuation) { flushCollectedComment (handle, appendKey); keySetString (appendKey, value); keySetMeta(appendKey, "ini/key", ""); ksAppendKey (handle->result, appendKey); if (mergeSections) { keySetMeta(appendKey, "order", 0); insertNewKeyIntoExistendOrder(appendKey, handle->result); } else { setOrderNumber(handle->parentKey, appendKey); } } else { existingKey = ksLookup (handle->result, appendKey, KDB_O_NONE); keyDel (appendKey); /* something went wrong before because this key should exist */ if (!existingKey) return -1; elektraKeyAppendLine(existingKey, value); } return 1; }
int main() { KeySet *ks=ksNew(0); Key *key=0; printf ("Generate some keys..."); ksAppendKey(ks,keyNew("user/sw",KEY_END)); /* a simple key */ ksAppendKey(ks,keyNew(0)); /* an empty key */ ksAppendKey(ks,keyNew("system/sw", KEY_END)); ksAppendKey(ks,keyNew("user/tmp/ex1", KEY_VALUE,"some data", /* with a simple value */ KEY_END)); /* end of args */ ksAppendKey(ks,keyNew("user/tmp/ex2", KEY_VALUE,"some data", /* with a simple value */ KEY_MODE,0777, /* permissions */ KEY_END)); /* end of args */ ksAppendKey(ks,keyNew("user/tmp/ex4", KEY_BINARY, KEY_COMMENT,"value is truncated", KEY_SIZE, 7, KEY_VALUE,"some data", /* value that will be truncated to 7 bytes */ KEY_UID,0, /* root uid */ KEY_END)); /* end of args */ ksAppendKey(ks,keyNew("user/tmp/ex5", KEY_VALUE,"some data", /* value */ KEY_OWNER,"root", /* owner (not uid) is root */ KEY_COMMENT,"some comment", /* a comment */ KEY_END)); /* end of args */ ksAppendKey(ks,keyNew("user/env/alias/ls", /* a key we know we have */ KEY_END)); /* do nothing more */ ksAppendKey(ks,keyNew("user/env/alias/ls", /* same key, to compare in output */ KEY_OWNER,"root", /* set new owner (not uid) as root */ KEY_COMMENT,"new comment", /* set new comment */ KEY_END)); /* end of args */ key=keyNew("user/test//", KEY_END); /* we are providing a lot of '/' to see it being removed */ keySetName(key,"system"); keySetName(key,"user"); keySetName(key,"user:aviram"); keySetName(key,"user///abc//////def///"); keySetName(key,"user:root///aaa//////bbb///"); keyAddBaseName(key,"tmp"); keyAddBaseName(key,"////ex6///exx7///"); keySetBaseName(key,"ex8"); keySetBaseName(key,"ex9"); keyAddBaseName(key,"///exxx9///ex10///ex\\/11///"); keySetBaseName(key,"ex12"); keySetBaseName(key,"ex13///"); ksAppendKey(ks,key); ksDel(ks); printf ("finished\n"); return 0; }
static void test_modules() { printf ("Test mounting with modules\n"); KDB *kdb = kdb_new(); Key *errorKey = keyNew(0); KeySet *modules = modules_config(); succeed_if (elektraMountOpen(kdb, root_config(), modules, errorKey) == 0, "could not buildup mount"); succeed_if (elektraMountDefault(kdb, modules, errorKey) == 0, "could not mount default backend"); succeed_if (elektraMountModules(kdb, modules, errorKey) == 0, "could not mount modules"); succeed_if(output_warnings (errorKey), "warnings found"); succeed_if(output_error (errorKey), "error found"); succeed_if (kdb->split->size == 8, "size of split not correct"); Key *mp = keyNew("spec", KEY_VALUE, "root", KEY_END); compare_key(mp, kdb->split->parents[0]); keySetName(mp, "dir"); keySetString (mp, "root"); compare_key(mp, kdb->split->parents[1]); keySetName(mp, "user"); keySetString (mp, "root"); compare_key(mp, kdb->split->parents[2]); keySetName(mp, "system"); keySetString (mp, "root"); compare_key(mp, kdb->split->parents[3]); /* we cannot exactly know where resolver+dump is located *(depending on alphabet) keySetName(mp, "system/elektra/modules/"KDB_DEFAULT_RESOLVER); keySetString (mp, "modules"); compare_key(mp, kdb->split->parents[4]); */ keySetName(mp, "system/elektra"); keySetString (mp, "default"); compare_key(mp, kdb->split->parents[5]); keySetName(mp, "user/tests/simple"); keySetString (mp, "simple"); compare_key(mp, kdb->split->parents[4]); exit_if_fail (kdb->trie, "trie was not build up successfully"); // output_trie (kdb->trie); Key *searchKey = keyNew("", KEY_END); Key *rmp = keyNew("", KEY_VALUE, "root", KEY_END); elektraKeySetName(rmp, "/", KEY_CASCADING_NAME); Backend *b2 = 0; keySetName (searchKey, "user"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); compare_key(b2->mountpoint, rmp); Backend *backend = 0; keySetName(searchKey, "user/tests/simple"); backend = elektraTrieLookup(kdb->trie, searchKey); succeed_if (backend, "there should be a backend"); compare_key(backend->mountpoint, mp); keySetName(searchKey, "user/tests/simple/below"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); succeed_if (backend == b2, "should be same backend"); compare_key(b2->mountpoint, mp); keySetName(searchKey, "user/tests/simple/deep/below"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); succeed_if (backend == b2, "should be same backend"); compare_key(b2->mountpoint, mp); Key *dmp = keyNew ("", KEY_VALUE, "default", KEY_END); keySetName(searchKey, "system/elektra"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); succeed_if (b2 == kdb->defaultBackend, "should be the default backend"); compare_key(b2->mountpoint, dmp); keySetName(searchKey, "system/elektra/below"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); succeed_if (b2 == kdb->defaultBackend, "should be the default backend"); compare_key(b2->mountpoint, dmp); Key *mmp = keyNew ("system/elektra/modules", KEY_VALUE, "modules", KEY_END); keyAddBaseName (mmp, "default"); /* keySetName(searchKey, "system/elektra/modules/default"); b2 = elektraTrieLookup(kdb->trie, searchKey); succeed_if (b2, "there should be a backend"); succeed_if (b2 != kdb->defaultBackend, "should not be the default backend"); compare_key(b2->mountpoint, mmp); */ keyDel (mmp); keyDel (dmp); keyDel (mp); keyDel (rmp); keyDel (searchKey); kdb_del (kdb); keyDel (errorKey); ksDel (modules); }
static int csvRead(KeySet *returned, Key *parentKey, char delim, short useHeader, unsigned long fixColumnCount, const char **colNames) { const char *fileName; fileName = keyString(parentKey); FILE *fp = NULL; fp = fopen(fileName, "rb"); if(!fp) { ELEKTRA_SET_ERRORF(116, parentKey, "couldn't open file %s\n", fileName); return -1; } unsigned long length = 0; length = getLineLength(fp); if(length == 0) { ELEKTRA_ADD_WARNING(118, parentKey, "Empty file"); fclose(fp); return -2; } char *lineBuffer; lineBuffer = elektraMalloc((length * sizeof(char))+1); if(!lineBuffer) { ELEKTRA_SET_ERROR(87, parentKey, "Out of memory"); return -1; } if(!fgets(lineBuffer, length, fp)) { ELEKTRA_SET_ERROR(116, parentKey, "Cant read from file"); return -1; } unsigned long columns = 0; columns = getColumnCount(lineBuffer, delim); if(fixColumnCount) { if(columns != fixColumnCount) { ELEKTRA_SET_ERROR(117, parentKey, "illegal number of columns in Header line"); elektraFree(lineBuffer); fclose(fp); return -1; } } unsigned long colCounter = 0; unsigned long lineCounter = 0; unsigned long offset = 0; char *col; char buf[INTSTR_MAX]; int nr_keys = 1; KeySet *header = ksNew(0, KS_END); Key *key; if(useHeader == 1) { colCounter = 0; offset = 0; while((col = parseLine(lineBuffer, delim, offset, parentKey, lineCounter)) != NULL) { offset += elektraStrLen(col); key = keyDup(parentKey); if(colNames && (colNames+colCounter)) { keyAddBaseName(key, colNames[colCounter]); } else { keyAddBaseName(key, col); } keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1)); ksAppendKey(header, key); ++colCounter; } fseek(fp, 0, SEEK_SET); } else { colCounter = 0; //if no headerline exists name the columns 0..N where N is the number of columns key = keyDup(parentKey); keyAddName(key, "#"); while(colCounter < columns) { if(elektraArrayIncName(key) == -1) { elektraFree(lineBuffer); keyDel(key); ksDel(header); fclose(fp); return -1; } keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1)); if(colNames && (colNames+colCounter)) keySetBaseName(key, colNames[colCounter]); ksAppendKey(header, keyDup(key)); ++colCounter; } keyDel(key); if(useHeader == 0) fseek(fp, 0, SEEK_SET); } Key *dirKey; Key *cur; dirKey = keyDup(parentKey); keyAddName(dirKey, "#"); while(!feof(fp)) { length = getLineLength(fp); if(length == 0) break; if(elektraRealloc((void **)&lineBuffer, (length * sizeof(char))+1) < 0) { fclose(fp); elektraFree(lineBuffer); ksDel(header); keyDel(dirKey); ELEKTRA_SET_ERROR(87, parentKey, "Out of memory"); return -1; } fgets(lineBuffer, length, fp); if(elektraArrayIncName(dirKey) == -1) { elektraFree(lineBuffer); keyDel(dirKey); ksDel(header); fclose(fp); return -1; } ++nr_keys; offset = 0; colCounter = 0; char *lastIndex = "#0"; while((col = parseLine(lineBuffer, delim, offset, parentKey, lineCounter)) != NULL) { cur = getKeyByOrderNr(header, colCounter); offset += elektraStrLen(col); key = keyDup(dirKey); keyAddBaseName(key, keyBaseName(cur)); keySetString(key, col); keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1)); ksAppendKey(returned, key); lastIndex = (char *)keyBaseName(key); ++nr_keys; ++colCounter; } keySetString(dirKey, lastIndex); ksAppendKey(returned, keyDup(dirKey)); if(colCounter != columns) { if(fixColumnCount) { ELEKTRA_SET_ERRORF(117, parentKey, "illegal number of columns in line %lu", lineCounter); elektraFree(lineBuffer); fclose(fp); keyDel(dirKey); ksDel(header); return -1; } ELEKTRA_ADD_WARNINGF(118, parentKey, "illegal number of columns in line %lu", lineCounter); } ++lineCounter; } key = keyDup(parentKey); keySetString(key, keyBaseName(dirKey)); ksAppendKey(returned, key); keyDel(dirKey); fclose(fp); elektraFree(lineBuffer); ksDel(header); return 1; }