Exemplo n.º 1
0
static
rc_t XML_ValidateNode(FSNode* parent, const KXMLNode* n, SRAConfigFlags flags, char* errmsg)
{
    rc_t rc = 0;
    const char* name = NULL;
    FSNode* fsn = NULL;
    bool children_allowed = false, should_have_children = false, ignore_children = false;

    if( (rc = KXMLNodeElementName(n, &name)) != 0 ) {
        return rc;
    }
    DEBUG_MSG(8, ("Node: %s\n", name));
    if( name == NULL ) {
        return RC(rcExe, rcDoc, rcValidating, rcDirEntry, rcNull);
    }

    if( strcmp(name, "Directory") == 0 ) {
        rc = DirectoryNode_Make(n, &fsn, errmsg, g_start_dir, g_xml_mtime, g_xml_validate);
        children_allowed = true;
    } else if( strcmp(name, "File") == 0 ) {
        rc = FileNode_Make(n, &fsn, errmsg, g_start_dir, g_xml_validate);
    } else if( strcmp(name, "SRA") == 0 ) {
        if( (rc = SRAListNode_Make(n, parent, flags, errmsg, g_start_dir, g_xml_validate)) == 0 ) {
            fsn = parent;
        }
    } else if( strcmp(name, "TAR") == 0 ) {
        /* tar nodes do not validate on creation */
        rc = TarNode_MakeXML(n, &fsn, errmsg, g_start_dir);
        children_allowed = true;
        ignore_children = true;
    } else if( strcmp(name, "SRAConfig") == 0 ) {
        if( (rc = SRAConfigParse(n, &flags, errmsg)) == 0 ) {
            fsn = parent;
            children_allowed = true;
            should_have_children = true;
        }
    } else {
        strcpy(errmsg, name);
        rc = RC(rcExe, rcDoc, rcValidating, rcTag, rcUnknown);
    }
    if( rc == 0 ) {
        strcpy(errmsg, name);
        if( fsn == parent || (rc = FSNode_AddChild(parent, fsn)) == 0 ) {
            uint32_t count = 0;
            if( (rc = KXMLNodeCountChildNodes(n, &count)) == 0 && count > 0 ) {
                if( !children_allowed ) {
                    if( fsn != NULL ) {
                        FSNode_GetName(fsn, &name);
                    }
                    rc = RC(rcExe, rcDoc, rcValidating, rcDirEntry, rcInvalid);
                    strcpy(errmsg, name);
                } else if( !ignore_children ) {
                    uint32_t i = 0;
                    const KXMLNode* ch = NULL;
                    while( rc == 0 && i < count ) {
                        if( (rc = KXMLNodeGetNodeRead(n, &ch, i++)) == 0 ) {
                            rc = XML_ValidateNode(fsn, ch, flags, errmsg);
                            ReleaseComplain(KXMLNodeRelease, ch);
                        }
                    }
                }
            } else if( count == 0 && should_have_children ) {
                PLOGMSG(klogWarn, (klogWarn, "$(n) may have children", PLOG_S(n), name));
            }
        }
    }
    return rc;
}
Exemplo n.º 2
0
static
rc_t TarNode_MakeFileList(const KXMLNode* xml_node, const TarFileList** files, char* errmsg, const char* rel_path, const char* name)
{
    rc_t rc = 0;
    time_t now = time(NULL);
    uint32_t count = 0;

    *files = NULL;
    if( (rc = KXMLNodeCountChildNodes(xml_node, &count)) == 0 ) {
        if( count == 0 ) {
            rc = RC(rcExe, rcDoc, rcValidating, rcData, rcEmpty);
        } else if( (rc = TarFileList_Make(files, count, name)) == 0 ) {
            uint32_t i = 0;
            while(rc == 0 && i < count) {
                const KXMLNode* n = NULL;
                const char* n_name;
                if( (rc = KXMLNodeGetNodeRead(xml_node, &n, i++)) == 0 && (rc = KXMLNodeElementName(n, &n_name)) == 0 ) {
                    if( strcmp(n_name, "Item") != 0 ) {
                        rc = RC(rcExe, rcDoc, rcValidating, rcNode, rcUnexpected);
                        strcpy(errmsg, n_name);
                    } else {
                        size_t sz_read;
                        char path[4096], name[4096];
                        KTime_t ts = now;
                        uint64_t fsz = 0;
                        bool exec = false;

                        if( (rc = KXMLNodeReadAttrCString(n, "path", name, sizeof(name), &sz_read)) == 0 ) {
                            if( name[0] == '\0' ) {
                                rc = RC(rcExe, rcDoc, rcValidating, rcAttr, rcEmpty);
                            } else if( name[0] == '/' ) {
                                memmove(path, name, sz_read + 1);
                            } else {
                                KDirectory* dir = NULL;
                                if( (rc = KDirectoryNativeDir(&dir)) == 0 &&
                                    (rc = KDirectoryResolvePath(dir, true, path, sizeof(path), "%s/%s", rel_path, name)) == 0 ) {
                                    DEBUG_LINE(8, "%s/%s resolved to %s", rel_path, name, path);
                                }
                                KDirectoryRelease(dir);
                            }
                            if( rc != 0 ) {
                                strcpy(errmsg, "TAR/Item/@path");
                            }
                        }
                        if( rc == 0 && (rc = XML_ParseTimestamp(n, "timestamp", &ts, true)) != 0 ) {
                            strcpy(errmsg, "TAR/Item/@timestamp");
                        }
                        if( rc == 0 && (rc = XML_ParseBool(n, "executable", &exec, true)) != 0 ) {
                            strcpy(errmsg, "TAR/Item/@executable");
                        }
                        if( rc == 0 && (rc = KXMLNodeReadAttrAsU64(n, "size", &fsz)) != 0 ) {
                            strcpy(errmsg, "TAR/Item/@size");
                        }
                        if( rc == 0 ) {
                            name[0] = '\0';
                            rc = KXMLNodeReadAttrCString(n, "name", name, sizeof(name), &sz_read);
                            if( (GetRCObject(rc) == (enum RCObject)rcAttr && GetRCState(rc) == rcNotFound) || name[0] == '\0' ) {
                                char* x = strrchr(path, '/');
                                strcpy(name, x ? x + 1 : path);
                                rc = 0;
                            } else if( rc == 0 && name[0] == '/' ) {
                                strcat(errmsg, "Item/@name cannot be absolute");
                                rc = RC(rcExe, rcDoc, rcValidating, rcName, rcInvalid);
                            } else if( rc != 0 ) {
                                strcpy(errmsg, "Item/@name");
                            }
                        }
                        if( rc == 0 ) {
                            const KNamelist* attr = NULL;
                            if( (rc = KXMLNodeListAttr(n, &attr)) == 0 ) {
                                uint32_t j = 0, count = 0;
                                if( (rc = KNamelistCount(attr, &count)) == 0 && count > 0 ) {
                                    while( rc == 0 && j < count ) {
                                        const char *attr_nm = NULL;
                                        if( (rc = KNamelistGet(attr, j++, &attr_nm)) != 0 ) {
                                            break;
                                        }
                                        if( strcmp("path", attr_nm) == 0 || strcmp("name", attr_nm) == 0 ||
                                            strcmp("timestamp", attr_nm) == 0 || strcmp("size", attr_nm) == 0 ||
                                            strcmp("executable", attr_nm) == 0 ) {
                                            continue;
                                        }
                                        rc = RC(rcExe, rcDoc, rcValidating, rcDirEntry, rcInvalid);
                                        strcpy(errmsg, "unknown attribute TAR/Item/@");
                                        strcat(errmsg, attr_nm);
                                    }
                                }
                                ReleaseComplain(KNamelistRelease, attr);
                            }
                        }
                        if( rc == 0 && (rc = TarFileList_Add(*files, path, name, fsz, ts, exec)) != 0 ) {
                            strcpy(errmsg, "adding to TAR");
                        }
                    }
                    ReleaseComplain(KXMLNodeRelease, n);
                }
            }
            if( rc != 0 ) {
                TarFileList_Release(*files);
                *files = NULL;
            }
        }
    }
    return rc;
}
Exemplo n.º 3
0
static
rc_t ProcessNode(const KXMLNode* node,
    const char* parentName, uint32_t idx,
    struct XTocEntry* xSelf, struct XTocEntry* xContainer)
{
    rc_t rc = 0;
    uint32_t count = 0;
    uint32_t i = 0;
    struct XTocEntry* xEntry = NULL;
    bool isContainer = false;
    NodeData data;

    assert(node && parentName);

    if (rc == 0) {
        rc = NodeDataInit(&data, node, parentName, idx);
    }

    if (rc == 0) {
        DBGMSG(DBG_APP,DBG_COND_1,
            ("%s[%i] = %s\n", parentName, idx, data.nodeName));
        rc = NodeDataAddToXToc(&data, xSelf, xContainer, &xEntry, &isContainer);
        if (isContainer) {
            xContainer = xEntry;
        }
    }

    if (rc == 0) {
        rc = KXMLNodeCountChildNodes(node, &count);
        if (rc != 0) {
/*          PLOGERR(klogErr, (klogErr, rc,
                "while calling KXMLNodeCountChildNodes($(parent)[$(i)])",
                "parent=%s,i=%d", parentName, idx));*/
        }
        else {
/*          DBGMSG(DBG_APP,DBG_COND_1,
                ("KXMLNodeCountChildNodes(%s) = %i\n", data.nodeName, count));*/
        }
    }

    for (i = 0; i < count && rc == 0; ++i) {
        const KXMLNode* child = NULL;

        rc = KXMLNodeGetNodeRead(node, &child, i);
        if (rc != 0) {
/*          PLOGERR(klogErr, (klogErr, rc,
                "while calling KXMLNodeCountChildNodes($(parent)[$(i)][$(j)]",
                "parent=%s,i=%d,j=%d", parentName, idx, i));*/
        }
        else {
/*          DBGMSG(DBG_APP,DBG_COND_1,
                ("KXMLNodeGetNodeRead(%s[%i])\n", data.nodeName, idx, i));*/
            ProcessNode(child, data.nodeName, i, xEntry, xContainer);
        }

        {
            rc_t rc2 = KXMLNodeRelease(child);
            if (rc == 0)
            {   rc = rc2; }
            child = NULL;
        }
    }

    NodeDataDestroy(&data);

    return rc;
}