Exemplo n.º 1
0
//--------------------------------------------------------------------------------------------------
tdb_NodeRef_t ni_GetNode
(
    ni_IteratorRef_t iteratorRef,  ///< The iterator object to access.
    const char* subPathPtr         ///< Optional, can be used to specify a node relative to the
                                   ///<   current one.
)
//--------------------------------------------------------------------------------------------------
{
    // Check to see if we have a current node.  If we do, then attempt to traverse from our current
    // node, to the requested sub-node.  If the new path is NULL or empty, then we'll just end up
    // getting our current node.
    if (iteratorRef->currentNodeRef != NULL)
    {
        le_pathIter_Ref_t newPathRef = le_pathIter_CreateForUnix(subPathPtr);
        tdb_NodeRef_t nodeRef = tdb_GetNode(iteratorRef->currentNodeRef, newPathRef);

        le_pathIter_Delete(newPathRef);

        return nodeRef;
    }

    // Ok, the iterator doesn't have a current node.  So, copy iterator's existing path, and append
    // the new sub path to the existing path.  Once that's done, attempt to find the requested node
    // in the tree.  If the node still can not be found, return NULL.
    le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
    tdb_NodeRef_t nodeRef = NULL;
    le_result_t result = LE_OK;

    if (subPathPtr != NULL)
    {
        result = le_pathIter_Append(newPathRef, subPathPtr);
    }

    // Make sure that the append was successful.  If it is, get the node.
    if (result == LE_OVERFLOW)
    {
        tu_TerminateClient(iteratorRef->sessionRef, "Specified path too large.");
    }
    else if (result == LE_UNDERFLOW)
    {
        tu_TerminateClient(iteratorRef->sessionRef,
                           "Specified path attempts to iterate below root.");
    }
    else
    {
        nodeRef = tdb_GetNode(tdb_GetRootNode(iteratorRef->treeRef), newPathRef);
    }

    le_pathIter_Delete(newPathRef);

    return nodeRef;
}
Exemplo n.º 2
0
//--------------------------------------------------------------------------------------------------
static le_result_t CloneAndAppendPath
(
    ni_IteratorRef_t iteratorRef,         ///< [IN]  The iterator to read.
    const char* subPathPtr,               ///< [IN]  Optionally, a sub-path to traverse to.
    le_pathIter_Ref_t* newPathIterRefPtr  ///< [OUT] Pointer to a to-be newly created ref.  Must be
                                          ///<       NULL on entry!
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(*newPathIterRefPtr == NULL);


    le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
    le_result_t result = LE_OK;

    if (subPathPtr != NULL)
    {
        result = le_pathIter_Append(newPathRef, subPathPtr);
    }

    if (result != LE_OK)
    {
        char* terminateMessage;

        switch (result)
        {
            case LE_OVERFLOW:
                terminateMessage = "Specified path too large.";
                break;

            case LE_UNDERFLOW:
                terminateMessage = "Specified path attempts to iterate below root.";
                break;

            default:
                terminateMessage = "Unexpected error while appending path.";
                break;
        }

        iteratorRef->isTerminated = true;
        tu_TerminateConfigClient(iteratorRef->sessionRef, terminateMessage);

        le_pathIter_Delete(newPathRef);
        return result;
    }

    *newPathIterRefPtr = newPathRef;
    return result;
}
Exemplo n.º 3
0
//--------------------------------------------------------------------------------------------------
le_result_t ni_GetPathForNode
(
    ni_IteratorRef_t iteratorRef,  ///< The iterator object to access.
    const char* subPathPtr,        ///< Optional, can be used to specify a node relative to the
                                   ///<   current one.
    char* destBufferPtr,           ///< The buffer to copy string data into.
    size_t bufferMax               ///< The maximum size of the string buffer.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(iteratorRef != NULL);
    LE_ASSERT(destBufferPtr != NULL);
    LE_ASSERT(bufferMax > 0);

    // Check to see if they're looking for a path to a node relative to the current one.
    if (   (subPathPtr != NULL)
        && (strcmp(subPathPtr, "") != 0))
    {
        // Build up a new path based on the existing path.
        le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
        le_result_t result = le_pathIter_Append(newPathRef, subPathPtr);

        if (result == LE_OVERFLOW)
        {
            tu_TerminateClient(iteratorRef->sessionRef, "Specified path too large.");
        }
        else if (result == LE_UNDERFLOW)
        {
            tu_TerminateClient(iteratorRef->sessionRef,
                               "Specified path attempts to iterate below root.");
        }
        else
        {
            result = le_pathIter_GetPath(newPathRef, destBufferPtr, bufferMax);
        }

        le_pathIter_Delete(newPathRef);
        return result;
    }

    // Simply return the current path.
    return le_pathIter_GetPath(iteratorRef->pathIterRef, destBufferPtr, bufferMax);
}
Exemplo n.º 4
0
//--------------------------------------------------------------------------------------------------
le_result_t ni_SetNodeName
(
    ni_IteratorRef_t iteratorRef,  ///< [IN] The iterator object to access.
    const char* pathPtr,           ///< [IN] Optional path to another node in the tree.
    const char* namePtr            ///< [IN] The new name to use.
)
//--------------------------------------------------------------------------------------------------
{
    // Try to get or create the requested node.  If the optional sub-path results in a new path that
    // overflows, then the node get will fail.
    tdb_NodeRef_t nodeRef = ni_TryCreateNode(iteratorRef, pathPtr);
    le_result_t result = LE_OK;

    if (nodeRef)
    {
        // Ok, the existing path is ok.  Cache the existing node name, in case we have to revert it
        // later, then set the new name.  We may have to revert the name later, because, while the
        // new name itself may be ok.  The name may actually be too long for the path limit.
        char oldName[LE_CFG_NAME_LEN_BYTES] = "";
        LE_ASSERT(tdb_GetNodeName(nodeRef, oldName, sizeof(oldName)) == LE_OK);

        result = tdb_SetNodeName(nodeRef, namePtr);

        if (result == LE_OK)
        {
            // The new name passed validation, now we have to make sure that the full path to the
            // node is still ok.  So, first we have to check, was a relative path used.
            if (strcmp(pathPtr, "") == 0)
            {
                // Looks like the caller was using the iterator's current node.  So, remove the old
                // name from the end of the iterator's current path, and append the new name.  If
                // this fails, it's because the new absolute path is too long, so name change fails,
                // and we have to revert the changes.
                LE_ASSERT(le_pathIter_Append(iteratorRef->pathIterRef, "..") == LE_OK);
                result = le_pathIter_Append(iteratorRef->pathIterRef, namePtr);

                if (result != LE_OK)
                {
                    LE_ASSERT(le_pathIter_Append(iteratorRef->pathIterRef, oldName) == LE_OK);
                }
            }
            else
            {
                // The user is accessing a node relative to the iterator's current node.  So, we
                // need too build up a new path and validate that the new name still fits within our
                // limits.  The new path ref is for validation only and can be safely discarded once
                // the check is complete.
                le_pathIter_Ref_t newPathRef = le_pathIter_Clone(iteratorRef->pathIterRef);
                result = le_pathIter_Append(newPathRef, pathPtr);

                if (result == LE_OK)
                {
                    LE_ASSERT(le_pathIter_Append(newPathRef, "..") == LE_OK);
                    result = le_pathIter_Append(newPathRef, namePtr);
                }

                le_pathIter_Delete(newPathRef);
            }

            // If we got to this point and everything is ok, then we know that the name set was ok,
            // and that the resultant path with the new name is also ok.  So, make sure that this
            // node exists in the next commit.  Otherwise, revert the node to it's old name and
            // report the error to the caller.
            if (result == LE_OK)
            {
                tdb_EnsureExists(nodeRef);
            }
            else
            {
                LE_ASSERT(tdb_SetNodeName(nodeRef, oldName) == LE_OK);
            }
        }
    }

    return result;
}