Пример #1
0
static const char* NodeTypeStr
(
    le_cfg_IteratorRef_t iterRef
)
{
    switch (le_cfg_GetNodeType(iterRef, ""))
    {
        case LE_CFG_TYPE_STRING:
            return "string";

        case LE_CFG_TYPE_EMPTY:
            return "empty";

        case LE_CFG_TYPE_BOOL:
            return "bool";

        case LE_CFG_TYPE_INT:
            return "int";

        case LE_CFG_TYPE_FLOAT:
            return "float";

        case LE_CFG_TYPE_STEM:
            return "stem";

        case LE_CFG_TYPE_DOESNT_EXIST:
            return "**DOESN'T EXIST**";
    }

    return "unknown";
}
Пример #2
0
// -------------------------------------------------------------------------------------------------
static json_t* CreateJsonNodeFromIterator
(
    le_cfg_IteratorRef_t iterRef  ///< The iterator to read from.
)
// -------------------------------------------------------------------------------------------------
{
    char nodeName[LE_CFG_NAME_LEN_BYTES] = "";

    le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");
    le_cfg_GetNodeName(iterRef, "", nodeName, sizeof(nodeName));

    json_t* nodePtr = CreateJsonNode(nodeName, NodeTypeStr(type));

    switch (type)
    {
        case LE_CFG_TYPE_EMPTY:
            json_object_set_new(nodePtr,
                                JSON_FIELD_TYPE,
                                json_string(NodeTypeStr(LE_CFG_TYPE_STEM)));
            json_object_set_new(nodePtr, JSON_FIELD_CHILDREN, json_array());
            break;

        case LE_CFG_TYPE_BOOL:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_boolean(le_cfg_GetBool(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_STRING:
            {
                char strBuffer[LE_CFG_STR_LEN_BYTES] = "";
                le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, "");
                json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_string(strBuffer));
            }
            break;

        case LE_CFG_TYPE_INT:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_integer(le_cfg_GetInt(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_FLOAT:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_real(le_cfg_GetFloat(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_STEM:
        default:
            // Unknown type, nothing to do
            json_decref(nodePtr);
            nodePtr = NULL;
            break;
    }

    return nodePtr;
}
Пример #3
0
// -------------------------------------------------------------------------------------------------
static void DumpTreeJSON
(
    le_cfg_IteratorRef_t iterRef,  ///< Read the tree data from this iterator.
    json_t* jsonObject             ///< JSON object to hold the tree data.
)
// -------------------------------------------------------------------------------------------------
{
    // Note that because this is a recursive function, the buffer here is static in order to save on
    // stack space.  The implication here is that we then have to be careful how it is later
    // accessed.  Also, this makes the function not thread safe.  But this trade off was made as
    // this was not intended to be a multi-threaded program.
    static char strBuffer[LE_CFG_STR_LEN_BYTES] = "";

    // Build up the child array.
    json_t* childArrayPtr = json_array();

    do
    {
        // Simply grab the name and the type of the current node.
        le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer));
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            // It's a stem object, so mark this item as being a stem and recurse into the stem's
            // sub-items.
            case LE_CFG_TYPE_STEM:
                {
                    json_t* nodePtr = CreateJsonNode(strBuffer, NodeTypeStr(type));

                    le_cfg_GoToFirstChild(iterRef);
                    DumpTreeJSON(iterRef, nodePtr);
                    le_cfg_GoToParent(iterRef);
                    json_array_append(childArrayPtr, nodePtr);
                }
                break;

            default:
                {
                    json_t* nodePtr = CreateJsonNodeFromIterator(iterRef);
                    if (nodePtr != NULL)
                    {
                        json_array_append(childArrayPtr, nodePtr);
                    }
                }
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);

    // Set children into the JSON document.
    json_object_set_new(jsonObject, JSON_FIELD_CHILDREN, childArrayPtr);
}
Пример #4
0
//--------------------------------------------------------------------------------------------------
static int GetCfgResourceLimit
(
    le_cfg_IteratorRef_t limitCfg,  // The iterator to use to read the configured limit.  This
                                    // iterator is owned by the caller and should not be deleted
                                    // in this function.
    const char* nodeName,           // The name of the node in the config tree that holds the value.
    int defaultValue                // The default value to use if the config value is invalid.
)
{
    int limitValue = le_cfg_GetInt(limitCfg, nodeName, defaultValue);

    if (!le_cfg_NodeExists(limitCfg, nodeName))
    {
        LE_INFO("Configured resource limit %s is not available.  Using the default value %d.",
                 nodeName, defaultValue);

        return defaultValue;
    }

    if (le_cfg_IsEmpty(limitCfg, nodeName))
    {
        LE_WARN("Configured resource limit %s is empty.  Using the default value %d.",
                 nodeName, defaultValue);

        return defaultValue;
    }

    if (le_cfg_GetNodeType(limitCfg, nodeName) != LE_CFG_TYPE_INT)
    {
        LE_ERROR("Configured resource limit %s is the wrong type.  Using the default value %d.",
                 nodeName, defaultValue);

        return defaultValue;
    }

    if (limitValue < 0)
    {
        LE_ERROR("Configured resource limit %s is negative.  Using the default value %d.",
                 nodeName, defaultValue);

        return defaultValue;
    }

    return limitValue;
}
Пример #5
0
// -------------------------------------------------------------------------------------------------
static int HandleGetUserFriendly
(
    const char* nodePathPtr  ///< Path to the node in the tree.
)
// -------------------------------------------------------------------------------------------------
{
    // Start a read transaction at the specified node path.  Then dump the value, (if any.)
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr);

    switch (le_cfg_GetNodeType(iterRef, ""))
    {
        case LE_CFG_TYPE_EMPTY:
            // Nothing to do here.
            break;

        case LE_CFG_TYPE_STEM:
            DumpTree(iterRef, 0);
            break;

        case LE_CFG_TYPE_BOOL:
            if (le_cfg_GetBool(iterRef, "", false))
            {
                printf("true\n");
            }
            else
            {
                printf("false\n");
            }
            break;

        default:
            {
                char nodeValue[LE_CFG_STR_LEN_BYTES] = "";

                le_cfg_GetString(iterRef, "", nodeValue, LE_CFG_STR_LEN_BYTES, "");
                printf("%s\n", nodeValue);
            }
            break;
    }

    le_cfg_CancelTxn(iterRef);

    return EXIT_SUCCESS;
}
Пример #6
0
static void DumpTree(le_cfg_IteratorRef_t iterRef, size_t indent)
{
    if (le_arg_NumArgs() == 1)
    {
        return;
    }

    static char strBuffer[STR_SIZE] = { 0 };

    do
    {
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        le_cfg_GetNodeName(iterRef, "", strBuffer, STR_SIZE);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);
                break;

            case LE_CFG_TYPE_EMPTY:
                printf("%s~~\n", strBuffer);
                break;

            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(iterRef));
                le_cfg_GetString(iterRef, "", strBuffer, STR_SIZE, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}
Пример #7
0
// -------------------------------------------------------------------------------------------------
static int HandleSet
(
    void
)
// -------------------------------------------------------------------------------------------------
{
    // Looks like we're trying to write a value to a node.  Get the node's current type and then
    // write the requested value to that node.
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(NodePath);

    le_cfg_nodeType_t originalType = le_cfg_GetNodeType(iterRef, "");
    le_cfg_nodeType_t newType = DataType;

    if (   (newType != originalType)
        && (originalType != LE_CFG_TYPE_DOESNT_EXIST))
    {
        printf("Converting node '%s' type from %s to %s.\n",
               NodePath,
               NodeTypeStr(originalType),
               NodeTypeStr(newType));
    }

    int result = EXIT_SUCCESS;

    switch (newType)
    {
        case LE_CFG_TYPE_STRING:
            le_cfg_SetString(iterRef, "", NodeValue);
            break;

        case LE_CFG_TYPE_BOOL:
            if (strcmp(NodeValue, "false") == 0)
            {
                le_cfg_SetBool(iterRef, "", false);
            }
            else if (strcmp(NodeValue, "true") == 0)
            {
                le_cfg_SetBool(iterRef, "", true);
            }
            else
            {
                fprintf(stderr, "Bad boolean value '%s'.\n", NodeValue);
            }
            break;

        case LE_CFG_TYPE_INT:
            {
                char *endIntp;

                errno = 0;
                int32_t value = strtol(NodeValue, &endIntp, 10);

                if (errno != 0)
                {
                    fprintf(stderr, "Integer '%s' out of range\n", NodeValue);
                    result = EXIT_FAILURE;
                }
                else if (*endIntp != '\0')
                {
                    fprintf(stderr, "Invalid character in integer '%s'\n", NodeValue);
                    result = EXIT_FAILURE;
                }
                else
                {
                    le_cfg_SetInt(iterRef, "", value);
                }
                break;
            }

        case LE_CFG_TYPE_FLOAT:
            {
                char *endFloatp;

                errno = 0;
                double floatVal = strtod(NodeValue, &endFloatp);

                if (errno != 0)
                {
                    fprintf(stderr, "Float value '%s' out of range\n", NodeValue);
                    result = EXIT_FAILURE;
                }
                else if (*endFloatp != '\0')
                {
                    fprintf(stderr, "Invalid character in float value '%s'\n", NodeValue);
                    result = EXIT_FAILURE;
                }
                else
                {
                    le_cfg_SetFloat(iterRef, "", floatVal);
                }
                break;
            }

        case LE_CFG_TYPE_DOESNT_EXIST:
            result = EXIT_FAILURE;
            break;

        default:
            fprintf(stderr, "Unexpected node type specified, %s.\n", NodeTypeStr(newType));
            result = EXIT_FAILURE;
            break;
    }

    // Finally, commit the value update, if the set was successful.
    if (result != EXIT_FAILURE)
    {
        le_cfg_CommitTxn(iterRef);
    }
    else
    {
        le_cfg_CancelTxn(iterRef);
    }

    return result;
}
Пример #8
0
// -------------------------------------------------------------------------------------------------
static le_result_t HandleImportJSONIteration
(
    le_cfg_IteratorRef_t iterRef,  ///< Dump the JSON data into this iterator.
    json_t* nodePtr                ///< From this JSON object.
)
// -------------------------------------------------------------------------------------------------
{
    // Get value
    json_t* value = json_object_get(nodePtr, JSON_FIELD_VALUE);

    // Check type
    const char* typeStr = json_string_value(json_object_get(nodePtr, JSON_FIELD_TYPE));
    le_cfg_nodeType_t type = GetNodeTypeFromString(typeStr);

    switch (type)
    {
        case LE_CFG_TYPE_BOOL:
            le_cfg_SetBool(iterRef, "", json_is_true(value));
            break;

        case LE_CFG_TYPE_STRING:
            le_cfg_SetString(iterRef, "", json_string_value(value));
            break;

        case LE_CFG_TYPE_INT:
            le_cfg_SetInt(iterRef, "", json_integer_value(value));
            break;

        case LE_CFG_TYPE_FLOAT:
            le_cfg_SetFloat(iterRef, "", json_real_value(value));
            break;

        case LE_CFG_TYPE_STEM:
            {
                // Iterate on children
                json_t* childrenPtr = json_object_get(nodePtr, JSON_FIELD_CHILDREN);
                json_t* childPtr;
                int i;

                json_array_foreach(childrenPtr, i, childPtr)
                {
                    // Get name
                    const char* name = json_string_value(json_object_get(childPtr,
                                                                         JSON_FIELD_NAME));

                    // Is node exist with this name?
                    le_cfg_nodeType_t existingType = le_cfg_GetNodeType(iterRef, name);
                    switch (existingType)
                    {
                        case LE_CFG_TYPE_DOESNT_EXIST:
                        case LE_CFG_TYPE_STEM:
                        case LE_CFG_TYPE_EMPTY:
                            // Not existing, already a stem or empty node, nothing to do
                        break;

                        default:
                            // Issue with node creation
                            fprintf(stderr, "Node conflict when importing, at node %s", name);
                            return LE_NOT_POSSIBLE;
                        break;
                    }

                    // Iterate to this child
                    le_cfg_GoToNode(iterRef, name);

                    // Iterate
                    le_result_t subResult = HandleImportJSONIteration(iterRef, childPtr);
                    if (subResult != LE_OK)
                    {
                        // Something went wrong
                        return subResult;
                    }

                    // Go back to parent
                    le_cfg_GoToParent(iterRef);
                }
            }
            break;

        default:
            return LE_FAULT;
    }

    return LE_OK;
}
Пример #9
0
// -------------------------------------------------------------------------------------------------
static int HandleGetJSON
(
    const char* nodePathPtr,  ///< Path to the node in the configTree.
    const char* filePathPtr   ///< Path to the file in the file system.  If NULL STDOUT is used
                              ///< instead of a file.
)
// -------------------------------------------------------------------------------------------------
{
    json_t* nodePtr = NULL;

    // Get the node path from our command line arguments.
    if (strcmp("*", nodePathPtr) == 0)
    {
        // Dump all trees
        // Create JSON root item
        json_t* rootPtr = CreateJsonNode("root", "root");
        json_t* treeListPtr = json_array();

        // Loop through the trees in the system.
        le_cfgAdmin_IteratorRef_t iteratorRef = le_cfgAdmin_CreateTreeIterator();
        while (le_cfgAdmin_NextTree(iteratorRef) == LE_OK)
        {
            // Allocate space for the tree name, plus space for a trailing :/ used when we create a
            // transaction for that tree.
            char treeName[MAX_TREE_NAME_BYTES + 2] = "";

            if (le_cfgAdmin_GetTreeName(iteratorRef, treeName, MAX_TREE_NAME_BYTES) != LE_OK)
            {
                continue;
            }

            // JSON node for the tree.
            json_t* treeNodePtr = CreateJsonNode(treeName, "tree");
            strcat(treeName, ":/");

            // Start a read transaction at the specified node path.  Then dump the value, (if any.)
            le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(treeName);
            le_cfg_GoToFirstChild(iterRef);

            // Dump tree to JSON
            DumpTreeJSON(iterRef, treeNodePtr);
            le_cfg_CancelTxn(iterRef);

            json_array_append(treeListPtr, treeNodePtr);
        }
        le_cfgAdmin_ReleaseTreeIterator(iteratorRef);

        // Finalize root object...
        json_object_set_new(rootPtr, "trees", treeListPtr);
        nodePtr = rootPtr;
    }
    else
    {
        // Start a read transaction at the specified node path.  Then dump the value, (if any.)
        le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr);

        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");
        switch (type)
        {
            case LE_CFG_TYPE_STEM:
                {
                    char strBuffer[LE_CFG_STR_LEN_BYTES] = "";
                    char nodeType[LE_CFG_STR_LEN_BYTES] = "";
                    le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer));

                    // If no name, we are dumping a complete tree.
                    if (strlen(strBuffer) == 0)
                    {
                        strcpy(nodeType, "tree");
                    }
                    else
                    {
                        strcpy(nodeType, NodeTypeStr(type));
                    }

                    nodePtr = CreateJsonNode(strBuffer, nodeType);
                    le_cfg_GoToFirstChild(iterRef);
                    DumpTreeJSON(iterRef, nodePtr);
                    le_cfg_GoToParent(iterRef);
                }
                break;

            default:
                nodePtr = CreateJsonNodeFromIterator(iterRef);
                break;
        }

        le_cfg_CancelTxn(iterRef);
    }

    if (nodePtr == NULL)
    {
        // Empty node
        nodePtr = json_object();
    }

    // Dump Json content
    // stdout mode?

    int result = EXIT_SUCCESS;

    if (filePathPtr == NULL)
    {
        printf("%s\n", json_dumps(nodePtr, JSON_COMPACT));
    }
    else if (json_dump_file(nodePtr, filePathPtr, JSON_COMPACT) != 0)
    {
        result = EXIT_FAILURE;
    }

    json_decref(nodePtr);
    return result;
}
Пример #10
0
// -------------------------------------------------------------------------------------------------
static void DumpTree
(
    le_cfg_IteratorRef_t iterRef,  ///< Write out the tree pointed to by this iterator.
    size_t indent                  ///< The amount of indentation to use for this item.
)
// -------------------------------------------------------------------------------------------------
{
    // Note that because this is a recursive function, the buffer here is static in order to save on
    // stack space.  The implication here is that we then have to be careful how it is later
    // accessed.  Also, this makes the function not thread safe.  But this trade off was made as
    // this was not intended to be a multi-threaded program.
    static char strBuffer[LE_CFG_STR_LEN_BYTES] = "";

    do
    {
        // Quick and dirty way to indent the tree item.
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        // Simply grab the name and the type of the current node.
        le_cfg_GetNodeName(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            // It's a stem object, so mark this item as being a stem and recurse into the stem's
            // sub-items.
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);

                // If we got back up to where we started then don't iterate the "root" node's
                // siblings.
                if (indent == 0)
                {
                    return;
                }
                break;

            // The node is empty, so simply mark it as such.
            case LE_CFG_TYPE_EMPTY:
                printf("%s<empty>\n", strBuffer);
                break;

            case LE_CFG_TYPE_BOOL:
                {
                    char* value = NULL;

                    if (le_cfg_GetBool(iterRef, "", false))
                    {
                        value = "true";
                    }
                    else
                    {
                        value = "false";
                    }

                    printf("%s<bool> == %s\n", strBuffer, value);
                }
                break;

            // The node has a different type.  So write out the name and the type.  Then print the
            // value.
            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(le_cfg_GetNodeType(iterRef, "")));
                le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}