static int elektraYajlParseMapKey (void * ctx, const unsigned char * stringVal, yajl_size_type stringLen) { KeySet * ks = (KeySet *)ctx; elektraYajlIncrementArrayEntry (ks); Key * currentKey = keyNew (keyName (ksCurrent (ks)), KEY_END); keySetString (currentKey, 0); unsigned char delim = stringVal[stringLen]; char * stringValue = (char *)stringVal; stringValue[stringLen] = '\0'; #ifdef ELEKTRA_YAJL_VERBOSE printf ("elektraYajlParseMapKey stringValue: %s currentKey: %s\n", stringValue, keyName (currentKey)); #endif if (currentKey && !strcmp (keyBaseName (currentKey), "___empty_map")) { // remove old key keyDel (ksLookup (ks, currentKey, KDB_O_POP)); // now we know the name of the object keySetBaseName (currentKey, stringValue); } else { // we entered a new pair (inside the previous object) keySetBaseName (currentKey, stringValue); } ksAppendKey (ks, currentKey); // restore old character in buffer stringValue[stringLen] = delim; return 1; }
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; }
static void validateWildcardSubs (KeySet * ks, Key * key, Key * specKey) { const Key * requiredMeta = keyGetMeta (specKey, "required"); if (!requiredMeta) return; Key * tmpParent = keyDup (key); keySetBaseName (tmpParent, 0); Key * parent = ksLookup (ks, tmpParent, KDB_O_NONE); keyDel (tmpParent); if (parent == NULL) return; KeySet * ksCopy = ksDup (ks); KeySet * subKeys = ksCut (ksCopy, parent); Key * cur; long subCount = 0; while ((cur = ksNext (subKeys)) != NULL) { if (keyIsDirectBelow (parent, cur)) ++subCount; } long required = atol (keyString (requiredMeta)); if (required != subCount) { char buffer[MAX_CHARS_IN_LONG + 1]; snprintf (buffer, sizeof (buffer), "%ld", subCount); keySetMeta (parent, "conflict/invalid/subcount", buffer); } ksDel (subKeys); ksDel (ksCopy); }
/** @retval 0 if ksCurrent does not hold an array entry @retval 1 if the array entry will be used because its the first @retval 2 if a new array entry was created @retval -1 error in snprintf */ static int elektraYajlIncrementArrayEntry (KeySet * ks) { Key * current = ksCurrent (ks); const char * baseName = keyBaseName (current); if (baseName && *baseName == '#') { current = keyNew (keyName (current), KEY_END); if (!strcmp (baseName, "###empty_array")) { // get rid of previous key keyDel (ksLookup (ks, current, KDB_O_POP)); // we have a new array entry keySetBaseName (current, 0); keyAddName (current, "#0"); ksAppendKey (ks, current); return 1; } else { // we are in an array elektraArrayIncName (current); ksAppendKey (ks, current); return 2; } } else { // previous entry indicates this is not an array return 0; } }
static int elektraYajlParseEnd (void * ctx) { KeySet * ks = (KeySet *)ctx; Key * currentKey = ksCurrent (ks); Key * lookupKey = keyNew (keyName (currentKey), KEY_END); keySetBaseName (lookupKey, 0); // remove current baseName // lets point current to the correct place Key * foundKey = ksLookup (ks, lookupKey, 0); #ifdef ELEKTRA_YAJL_VERBOSE if (foundKey) { printf ("elektraYajlParseEnd %s\n", keyName (foundKey)); } else { printf ("elektraYajlParseEnd did not find key!\n"); } #else (void)foundKey; // foundKey is not used, but lookup is needed #endif keyDel (lookupKey); return 1; }
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] } }
static void flushConvertedKeys (Key * target, KeySet * converted, KeySet * orig) { if (ksGetSize (converted) == 0) return; ksRewind (converted); Key * current; Key * appendTarget; while ((current = ksNext (converted))) { appendTarget = target; const char * metaName = keyString (keyGetMeta (current, CONVERT_METANAME)); Key * currentDup = keyDup (current); Key * targetDup = keyDup (appendTarget); keySetBaseName (currentDup, 0); keySetBaseName (targetDup, 0); /* the convert key request to be converted to a key * on the same level, but the target is below or above */ if (keyGetMeta (current, CONVERT_APPEND_SAMELEVEL) && keyCmp (currentDup, targetDup)) { appendTarget = 0; } keyDel (currentDup); keyDel (targetDup); /* no target key was found of the target * was discarded for some reason. Revert to the parent */ if (!appendTarget) { appendTarget = findNearestParent (current, orig); } elektraKeyAppendMetaLine (appendTarget, metaName, keyString (current)); removeKeyFromResult (current, target, orig); } ksClear (converted); }
// keyRel2 helper, returns how many levels check is below key, or 0 if check isn't below int keyGetLevelsBelow (const Key * key, const Key * check) { if (!keyIsBelow (key, check)) return 0; if (keyGetNamespace (key) != keyGetNamespace (check)) return 0; Key * toCheck = keyDup (check); int levels = 0; while (strcmp (keyName (key), keyName (toCheck))) { keySetBaseName (toCheck, 0); if (keyName (toCheck)[0] == '\0') keySetName (toCheck, "/"); ++levels; } keyDel (toCheck); return levels; }
static int handleErrors (Key * parentKey, KeySet * ks, Key * key, Key * specKey, ConflictHandling * ch, Direction dir) { cursor_t cursor = ksGetCursor (ks); int ret = 0; ConflictHandling * localCh = elektraMalloc (sizeof (ConflictHandling)); memcpy (localCh, ch, sizeof (ConflictHandling)); parseLocalConfig (specKey, localCh, dir); Key * parentLookup = keyDup (key); keySetBaseName (parentLookup, 0); Key * parent = ksLookup (ks, parentLookup, KDB_O_NONE); keyDel (parentLookup); keyRewindMeta (parent); Conflict conflict; Key * meta; while (keyNextMeta (parent) != NULL) { meta = (Key *) keyCurrentMeta (parent); conflict = getConflict (meta); if (conflict != NAC) { ret |= handleError (parentKey, parent, specKey, meta, conflict, localCh); keySetMeta (parent, keyName (meta), 0); } else if (!strncmp (keyName (meta), "conflict/#", 10) || !strncmp (keyName (meta), "conflict/invalid/hasmember/#", 28)) { keySetMeta (parent, keyName (meta), 0); } } keyRewindMeta (key); while (keyNextMeta (key) != NULL) { meta = (Key *) keyCurrentMeta (key); conflict = getConflict (meta); if (conflict != NAC) { ret |= handleError (parentKey, key, specKey, meta, conflict, localCh); keySetMeta (key, keyName (meta), 0); } else if (!strncmp (keyName (meta), "conflict/#", 10) || !strncmp (keyName (meta), "conflict/invalid/hasmember/#", 28)) { keySetMeta (key, keyName (meta), 0); } } elektraFree (localCh); ksSetCursor (ks, cursor); return ret; }
static int isValidArrayKey (Key * key) { Key * copy = keyDup (key); do { if (keyBaseName (copy)[0] == '#') { if (elektraArrayValidateName (copy) == -1) { keyDel (copy); return 0; } } } while (keySetBaseName (copy, 0) != -1); keyDel (copy); return 1; }
/** * @brief Increment the name of the key by one * * Alphabetical order will remain * * e.g. user/abc/\#9 will be changed to * user/abc/\#_10 * * For the start: * user/abc/\# * will be changed to * user/abc/\#0 * * @param key which base name will be incremented * * @retval -1 on error (e.g. too large array, not validated array) * @retval 0 on success */ int elektraArrayIncName(Key *key) { const char * baseName = keyBaseName(key); int arrayElement = elektraArrayValidateName(key); if (arrayElement == -1) { return -1; } ++baseName; // jump over # while(*baseName == '_') // jump over all _ { ++baseName; } kdb_long_long_t oldIndex = 0; if (!arrayElement) { // we have a start element oldIndex = -1; } else { if (elektraReadArrayNumber(baseName, &oldIndex) == -1) { return -1; } } kdb_long_long_t newIndex = oldIndex+1; // we increment by one char newName[ELEKTRA_MAX_ARRAY_SIZE]; elektraWriteArrayNumber(newName, newIndex); keySetBaseName(key, newName); return 0; }
static void validateArray (KeySet * ks, Key * arrayKey, Key * specKey) { Key * tmpArrayParent = keyDup (arrayKey); keySetBaseName (tmpArrayParent, 0); Key * arrayParent = ksLookup (ks, tmpArrayParent, KDB_O_NONE); keyDel (tmpArrayParent); if (arrayParent == NULL) return; KeySet * ksCopy = ksDup (ks); KeySet * subKeys = ksCut (ksCopy, arrayParent); Key * cur; long validCount = 0; while ((cur = ksNext (subKeys)) != NULL) { if (!keyIsDirectBelow (arrayParent, cur)) continue; if (keyBaseName (cur)[0] == '#') { if (elektraArrayValidateName (cur) == 1) { ++validCount; keySetMeta (cur, "spec/internal/valid", ""); } else { KeySet * invalidCutKS = ksCut (subKeys, cur); Key * toMark; while ((toMark = ksNext (invalidCutKS)) != NULL) { if (strcmp (keyName (cur), keyName (toMark))) keySetMeta (toMark, "conflict/invalid", ""); elektraMetaArrayAdd (arrayParent, "conflict/invalid/hasmember", keyName (toMark)); } ksDel (invalidCutKS); } } } ksDel (subKeys); ksDel (ksCopy); validateArrayRange (arrayParent, validCount, specKey); }
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; }
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_array (void) { printf ("Test array\n"); Key * k = keyNew ("user/array/#0", KEY_END); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#1"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#2"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#3"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#4"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#5"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#6"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#7"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#8"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#9"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_10"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_11"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_12"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_13"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_14"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_15"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_16"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_17"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_18"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_19"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_20"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_21"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_22"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_23"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_24"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_25"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_26"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_27"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_28"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_29"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); for (int i = 30; i < 99; ++i) { succeed_if (!elektraArrayIncName (k), "increment array entry in loop returned error"); } succeed_if_same_string (keyName (k), "user/array/#_99"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#__100"); for (int i = 101; i < 1000; ++i) { succeed_if (!elektraArrayIncName (k), "increment array entry in loop returned error"); } succeed_if_same_string (keyName (k), "user/array/#__999"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#___1000"); keySetBaseName (k, "#_________4000000000"); succeed_if (!elektraArrayIncName (k), "increment array entry name returned error"); succeed_if_same_string (keyName (k), "user/array/#_________4000000001"); keyDel (k); }
static int listParseConfiguration (Placements * placements, KeySet * config) { Key * cur; Key * key = ksLookupByName (config, "/plugins", 0); KeySet * cutKS = ksCut (config, key); ksRewind (cutKS); if (ksGetSize (cutKS) < 2) return 0; int rc = 0; while ((cur = ksNext (cutKS)) != NULL) { if (keyRel (key, cur) != 1) { continue; } if (keyBaseName (cur)[0] == '#') { if (strcmp (lastIndex, keyBaseName (cur)) < 0) { snprintf (lastIndex, ELEKTRA_MAX_ARRAY_SIZE, "%s", keyBaseName (cur)); } } Key * sub; Key * lookup = keyDup (cur); keyAddBaseName (lookup, "placements"); keyAddBaseName (lookup, "set"); sub = ksLookup (cutKS, lookup, 0); if (sub) { const char * setString = keyString (sub); const char * setStrings[] = { "presetstorage", "presetcleanup", "precommit", "postcommit" }; SetPlacements setPlacement = preSetStorage; while (setPlacement != setEnd) { if (strstr (setString, setStrings[setPlacement])) { rc = 1; ksAppendKey (placements->setKS[setPlacement], keyDup (cur)); } ++setPlacement; } } keySetBaseName (lookup, "get"); sub = ksLookup (cutKS, lookup, 0); if (sub) { const char * getString = keyString (sub); const char * getStrings[] = { "pregetstorage", "postgetstorage", "postgetcleanup" }; GetPlacements getPlacement = preGetStorage; while (getPlacement != getEnd) { if (strstr (getString, getStrings[getPlacement])) { rc = 1; ksAppendKey (placements->getKS[getPlacement], keyDup (cur)); } ++getPlacement; } } keySetBaseName (lookup, "error"); sub = ksLookup (cutKS, lookup, 0); if (sub) { const char * errString = keyString (sub); const char * errStrings[] = { "prerollback", "postrollback" }; ErrPlacements errPlacement = preRollback; while (errPlacement != errEnd) { if (strstr (errString, errStrings[errPlacement])) { rc = 1; ksAppendKey (placements->errKS[errPlacement], keyDup (cur)); } ++errPlacement; } } keyDel (lookup); } ksDel (cutKS); return rc; }
int keyRel2 (const Key * key, const Key * check, KeyRelType which) { if (!key || !check) return -1; if (!key->key || !check->key) return -1; Key * cKey = keyAsCascading (key); Key * cCheck = keyAsCascading (check); Key * cKeyParent = keyDup (cKey); keySetBaseName (cKeyParent, 0); if (keyName (cKeyParent)[0] == '\0') keySetName (cKeyParent, "/"); int isBelow = 0; int isSilblingNephew = 0; isBelow = keyGetLevelsBelow (cKey, cCheck); if (!isBelow) isSilblingNephew = keyGetLevelsBelow (cKeyParent, cCheck); elektraNamespace keyNamespace = keyGetNamespace (key); elektraNamespace checkNamespace = keyGetNamespace (check); int retVal = 0; int bits = 0; for (KeyRelType type = 1; type != 0; type <<= 1) { if (type & which) ++bits; } if (bits != 1) return -1; switch (which) { case ELEKTRA_REL_BELOW_SAME_NS: if (isBelow && (keyNamespace == checkNamespace)) retVal = isBelow; break; case ELEKTRA_REL_BELOW_IGNORE_NS: if (isBelow) retVal = isBelow; break; case ELEKTRA_REL_BELOW_CASCADING_NS: if (isBelow && ((checkNamespace == KEY_NS_CASCADING) || (keyNamespace == KEY_NS_CASCADING))) retVal = isBelow; break; case ELEKTRA_REL_DIRECT_BELOW_SAME_NS: if ((isBelow == 1) && (keyNamespace == checkNamespace)) retVal = 1; break; case ELEKTRA_REL_DIRECT_BELOW_IGNORE_NS: if (isBelow == 1) retVal = 1; break; case ELEKTRA_REL_DIRECT_BELOW_CASCADING_NS: if ((isBelow == 1) && ((checkNamespace == KEY_NS_CASCADING) || (keyNamespace == KEY_NS_CASCADING))) retVal = 1; break; case ELEKTRA_REL_SILBLING_SAME_NS: if ((isSilblingNephew == 1) && (keyNamespace == checkNamespace)) retVal = 1; break; case ELEKTRA_REL_SILBLING_IGNORE_NS: if (isSilblingNephew == 1) retVal = 1; break; case ELEKTRA_REL_SILBLING_CASCADING_NS: if ((isSilblingNephew == 1) && ((checkNamespace == KEY_NS_CASCADING) || (keyNamespace == KEY_NS_CASCADING))) retVal = 1; break; case ELEKTRA_REL_NEPHEW_SAME_NS: if ((isSilblingNephew > 1) && (keyNamespace == checkNamespace)) retVal = isSilblingNephew - 1; break; case ELEKTRA_REL_NEPHEW_IGNORE_NS: if (isSilblingNephew > 1) retVal = isSilblingNephew - 1; break; case ELEKTRA_REL_NEPHEW_CASCADING_NS: if ((isSilblingNephew > 1) && ((checkNamespace == KEY_NS_CASCADING) || (keyNamespace == KEY_NS_CASCADING))) retVal = isSilblingNephew - 1; break; default: retVal = -1; break; } keyDel (cKey); keyDel (cCheck); keyDel (cKeyParent); return retVal; }