Exemple #1
0
/**
 * nmp_get_node_attr_value: get value of an attribute
 *
 * @xml_buf:    input, pointer of xml text buffer
 * @xml_len:    input, xml text buffer length
 * @xpath:      input, addressing parts of an XML document
 * @attribute:  input, attribute
 * @attr_value: output, attribute value
 * @return:     succeed 0, else -1
 */
int
nmp_get_node_attr_value(
    const char  *xml_buff,
    int         xml_len,
    xmlChar     *xpath, 
    xmlChar     *attribute,
    xmlChar     *attr_value
)
{
    ASSERT((xml_buff != NULL) && (xpath!=NULL) && 
            (attribute != NULL) && (attr_value != NULL));
    xmlDocPtr doc; 
    char *cmd;
    xmlXPathObjectPtr app_result;
    int i;
    
    doc = xmlParseMemory(xml_buff, xml_len);    //doc = xmlParseDoc(&xml_buff); 
    if (doc == NULL ) 
    {    
        xml_error("Document not parsed successfully. \n");  
        return -1;
    }
    
    app_result = nmp_get_node(doc, (const xmlChar *)xpath);
    if (app_result == NULL)
      goto end;
    
    if (app_result)
    {
        xmlNodeSetPtr nodeset = app_result->nodesetval;
        //*value_num = nodeset->nodeNr;
        xml_debug(" nodeset->nodeNr=%d\n", nodeset->nodeNr);
        for (i=0; i < nodeset->nodeNr; i++)
        {
            cmd = (char *)xmlGetProp(nodeset->nodeTab[i], (const xmlChar *)attribute);
            xml_debug("cmd type =%s\n",cmd);
            memcpy(attr_value,cmd,strlen(cmd));
            xml_debug("attr_value type =%s\n",attr_value);
            xmlFree(cmd);
        }
        xmlXPathFreeObject(app_result);
    }  
    
    end: 
    xmlFreeDoc(doc);
    
    return 0;
}
Exemple #2
0
/*
 * Process command. When we get here, we've processed "<!-"
 */
xml_token_type_t
xml_skip_comment(xml_reader_t *xr)
{
	int match = 0, cc;

	if (xml_getc(xr) != '-') {
		xml_parse_error(xr, "Unexpected <!-...> element");
		return None;
	}

	while ((cc = xml_getc(xr)) != EOF) {
		if (cc == '-') {
			match++;
		} else {
			if (cc == '>' && match >= 2) {
#ifdef XMLDEBUG_PARSER
				xml_debug("Processed comment\n");
#endif
				return Comment;
			}
			match = 0;
		}
	}

	xml_parse_error(xr, "Unexpected end of file while parsing comment");
	return None;
}
Exemple #3
0
static void handleElement(struct XMLstate *state)
{
	DM_RESULT res;

	xml_debug("handling data: %s\n", state->text ? : "NOTHING");

	res = dm_string2value(state->element, state->text, flags & DS_USERCONFIG, state->value);
#ifdef XML_DEBUG
	if (res != DM_OK)
		xml_debug("dm_string2value returned %d (DM_RESULT)\n", res);
#endif
}
Exemple #4
0
/**
 * nmp_add_new_node: add a new node 
 *
 * @xml_in:     input, pointer of xml text buffer
 * @len_in:     iutput, xml text buffer length
 * @xml_out:    output, pointer of buffer block, containing xml text 
 *              after deleting a node
 * @len_out:    output, indicate buffer length of xml_out
 * @xpath:      addressing parts of an XML document
 * @node_name:  node name
 * @node_cont:  node content
 * @return:     succeed 0, else -1
 */
int
nmp_add_new_node(
    const char  *xml_in,
    int         len_in,
    xmlChar     *xml_out,
    int         *len_out,
    xmlChar     *xpath,
    xmlChar     *node_name,
    xmlChar     *node_cont
)
{
    ASSERT(xml_in != NULL && xml_out!= NULL && xpath != NULL);
    xmlDocPtr doc; 
    xmlNodePtr node;
    xmlXPathObjectPtr app_result;
    int node_num;;
    xmlChar *xml_buffer;
    
    doc = xmlParseMemory(xml_in, len_in);   //doc = xmlParseDoc(&xml_buff); 
    if (doc == NULL ) 
    {    
        xml_error("Document not parsed successfully. \n");  
        return -1;
    }
    
    app_result = nmp_get_node(doc, (const xmlChar *)xpath);
    if (app_result == NULL)
      goto end;
    
    if (app_result)
    {
        xmlNodeSetPtr nodeset = app_result->nodesetval;
        node_num = nodeset->nodeNr - 1;
        node = xmlNewNode(NULL, BAD_CAST node_name);    
        xmlNodeSetContent(node, (const xmlChar *)node_cont);
        xmlAddNextSibling ( nodeset->nodeTab[node_num],node);
        xmlSaveFormatFileEnc("-", doc, ECODE_UFT8, 1);
        xmlDocDumpMemoryEnc(doc, &xml_buffer, len_out,ECODE_UFT8); 
        xml_debug("xml_buffer=%s\n", xml_buffer);        
        memcpy(xml_out,xml_buffer,*len_out);       
        xmlFree(xml_buffer);
        xmlXPathFreeObject(app_result);
    }
    
    end:
    xmlFreeDoc(doc);
    
    
    return 0;
}
Exemple #5
0
/**
 * nmp_modify_attr_value: modify attribute's value in XML document
 *
 * @xml_in:     input, pointer of xml text buffer
 * @len_in:     iutput, xml text buffer length
 * @xml_out:    output, pointer of buffer block, containing xml text 
 *              after modifying attribute value
 * @len_out:    output, indicate buffer length of xml_out
 * @xpath:      addressing parts of an XML document
 * @attribute:  XML element attribute
 * @attr_value: value of a specific attribute in XML document
 * @return:     succeed 0, else -1
 */
int
nmp_modify_attr_value(
    const char  *xml_in,
    int         len_in,
    xmlChar     *xml_out,
    int         *len_out,
    xmlChar     *xpath,
    xmlChar     *attribute,
    xmlChar     *attr_value
)
{
    ASSERT(xml_out != NULL && attribute!=NULL && attr_value!= NULL);
    xmlDocPtr doc; 
    xmlXPathObjectPtr app_result;
    int node_num;;
    xmlChar *xml_buffer;
    
    doc = xmlParseMemory(xml_in, len_in);   //doc = xmlParseDoc(&xml_buff); 
    if (doc == NULL ) 
    {    
        xml_error("Document not parsed successfully. \n");  
        return -1;
    }
    
    app_result = nmp_get_node(doc, (const xmlChar *)xpath);
    if (app_result == NULL)
    {
        goto end;
    }
    
    if (app_result)
    {
        xmlNodeSetPtr nodeset = app_result->nodesetval;
        //*value_num = nodeset->nodeNr;
        xml_debug(" nodeset->nodeNr=%d\n", nodeset->nodeNr);
        node_num = nodeset->nodeNr - 1;
        xmlSetProp(nodeset->nodeTab[0], BAD_CAST attribute, BAD_CAST attr_value);
        xmlSaveFormatFileEnc("-", doc, ECODE_UFT8, 1);
        xmlDocDumpMemoryEnc(doc, &xml_buffer, len_out,ECODE_UFT8); 
        memcpy(xml_out, xml_buffer, *len_out);
        xmlFree(xml_buffer);
        xmlXPathFreeObject(app_result);
    }
   end: 
    xmlFreeDoc(doc);

    return 0;
}
Exemple #6
0
xml_token_type_t
xml_get_tag_attributes(xml_reader_t *xr, xml_node_t *node)
{
	ni_stringbuf_t tokenValue, attrName, attrValue;
	xml_token_type_t token;

	ni_stringbuf_init(&tokenValue);
	ni_stringbuf_init(&attrName);
	ni_stringbuf_init(&attrValue);

	token = xml_get_token(xr, &tokenValue);
	while (1) {
		if (token == RightAngle || token == RightAngleQ || token == RightAngleSlash)
			break;

		if (token != Identifier) {
			xml_parse_error(xr, "Unexpected token in tag attributes");
			token = None;
			break;
		}

		ni_stringbuf_move(&attrName, &tokenValue);

		token = xml_get_token(xr, &tokenValue);
		if (token != Equals) {
			xml_node_add_attr(node, attrName.string, NULL);
			continue;
		}

		token = xml_get_token(xr, &tokenValue);
		if (token != QuotedString) {
			xml_parse_error(xr, "Attribute value not a quoted string!");
			token = None;
			break;
		}

		xml_debug("  attr %s=%s\n", attrName.string, tokenValue.string);
		xml_node_add_attr(node, attrName.string, tokenValue.string);

		token = xml_get_token(xr, &tokenValue);
	}

	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&attrName);
	ni_stringbuf_destroy(&attrValue);
	return token;
}
Exemple #7
0
ni_bool_t
xml_process_element_nested(xml_reader_t *xr, xml_node_t *cur, unsigned int nesting)
{
	ni_stringbuf_t tokenValue, identifier;
	xml_token_type_t token;
	xml_node_t *child;

	ni_stringbuf_init(&tokenValue);
	ni_stringbuf_init(&identifier);

	while (1) {
		token = xml_get_token(xr, &tokenValue);

		switch (token) {
		case CData:
			/* process element content */
			xml_node_set_cdata(cur, tokenValue.string);
			break;

		case LeftAngleExclam:
			/* Most likely <!DOCTYPE ...> */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open <! not followed by identifier");
				goto error;
			}

			if (strcmp(identifier.string, "DOCTYPE")) {
				xml_parse_error(xr, "Unexpected element: <!%s ...> not supported", identifier.string);
				goto error;
			}

			while (1) {
				token = xml_get_token(xr, &identifier);
				if (token == RightAngle)
					break;
				if (token == Identifier && !xr->doctype)
					ni_string_dup(&xr->doctype, identifier.string);
				if (token != Identifier && token != QuotedString) {
					xml_parse_error(xr, "Error parsing <!DOCTYPE ...> attributes");
					goto error;
				}
			}
			break;

		case LeftAngle:
			/* New element start */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open < not followed by identifier");
				goto error;
			}

			child = xml_node_new(identifier.string, cur);
			if (xr->shared_location)
				child->location = xml_location_new(xr->shared_location, xr->lineCount);

			token = xml_get_tag_attributes(xr, child);
			if (token == None) {
				xml_parse_error(xr, "Error parsing <%s ...> tag attributes", child->name);
				goto error;
			} else
			if (token == RightAngle) {
				/* Handle <foo>...</foo> */
				xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name);
				if (!xml_process_element_nested(xr, child, nesting + 2))
					goto error;
			} else if (token == RightAngleSlash) {
				/* We parsed a "<foo/>" element - nothing left to do, we're done */
				xml_debug("%*.*s<%s/>\n", nesting, nesting, "", child->name);
			} else {
				xml_parse_error(xr, "Unexpected token %s at end of <%s ...",
						xml_token_name(token), child->name);
				goto error;
			}

			break;

		case LeftAngleSlash:
			/* Element end */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: end tag open </ not followed by identifier");
				goto error;
			}

			if (xml_get_token(xr, &tokenValue) != RightAngle) {
				xml_parse_error(xr, "Bad element: </%s - missing tag close", identifier.string);
				goto error;
			}

			if (cur->parent == NULL) {
				xml_parse_error(xr, "Unexpected </%s> tag", identifier.string);
				goto error;
			}
			if (strcmp(cur->name, identifier.string)) {
				xml_parse_error(xr, "Closing tag </%s> does not match <%s>",
						identifier.string, cur->name);
				goto error;
			}

			xml_debug("%*.*s</%s>\n", nesting, nesting, "", cur->name);
			goto success;

		case LeftAngleQ:
			/* New PI node starts here */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open <? not followed by identifier");
				goto error;
			}

			child = xml_node_new(identifier.string, NULL);
			if (xr->shared_location)
				child->location = xml_location_new(xr->shared_location, xr->lineCount);

			token = xml_get_tag_attributes(xr, child);
			if (token == None) {
				xml_parse_error(xr, "Error parsing <?%s ...?> tag attributes", child->name);
				xml_node_free(child);
				goto error;
			} else
			if (token == RightAngleQ) {
				xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name);
				xml_process_pi_node(xr, child);
				xml_node_free(child);
			} else {
				xml_parse_error(xr, "Unexpected token %s at end of <?%s ...",
						xml_token_name(token), child->name);
				xml_node_free(child);
				goto error;
			}

			break;

		case EndOfDocument:
			if (cur->parent) {
				xml_parse_error(xr, "End of document while processing element <%s>", cur->name);
				goto error;
			}
			goto success;

		case None:
			/* parser error */
			goto error;

		default:
			xml_parse_error(xr, "Unexpected token %s", xml_token_name(token));
			goto error;
		}
	}

success:
	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&identifier);
	return TRUE;

error:
	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&identifier);
	return FALSE;
}
Exemple #8
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
	const struct dm_element *kw = NULL;
	DM_VALUE *val = NULL;

	struct XMLstate **state = userData;

	const char *base = (*state)->base;
	int valid = ((*state)->flags & XML_VALID) == XML_VALID;
	int is_root = ((*state)->flags & XML_ROOT) == XML_ROOT;
	const struct dm_element *element = (*state)->element;
	DM_VALUE *value = (*state)->value;

	int xid = 0;
	int ntfy = 0;
	dm_id id;

	for (int i = 0; atts[i]; i += 2) {
		if (strcasecmp("instance", atts[i]) == 0) {
			xml_debug("%s: instance: %s\n", name, atts[i + 1]);
			xid = atoi(atts[i + 1]);
			break;
		}
		else if (strcasecmp("notify", atts[i]) == 0) {
			xml_debug("%s: notify: %s\n", name, atts[i + 1]);
			ntfy = dm_enum2int( &notify_attr, atts[i + 1]);
		}
		else if (strcasecmp("encoding", atts[i]) == 0) {
			xml_debug("%s: encoding: %s\n", name, atts[i + 1]);
			if (strcasecmp(atts[i+1], "escaped") == 0)
				(*state)->flags |= XML_ESCAPED;
		}
		else if (strcasecmp("version", atts[i]) == 0) {
			xml_debug("%s: config version: %s\n", name, atts[i + 1]);
			dm_set_cfg_version(atoi(atts[i + 1]));
		}
	}

	(*state)++;

	if (is_root) {
		if (flags & DS_VERSIONCHECK &&
		    dm_get_cfg_version() != CFG_VERSION) {
			(*state)->flags |= XML_UPGRADE;

			lua_pushinteger(lua_environment, CFG_VERSION);
			lua_pushinteger(lua_environment, dm_get_cfg_version());
			if (fp_Lua_function("fncPreVersionCheck", 2))
				debug("(): Error during Lua function execution");
		}
	} else {
		memset(*state, 0, sizeof(struct XMLstate));

		if (xid != 0)
			asprintf(&(*state)->base, "%s.%s.%d", base, name, xid);
		else
			asprintf(&(*state)->base, "%s.%s", base, name);

		if (valid) {
			const struct dm_table *table = element->u.t.table;

			id = dm_get_element_id_by_name(name, strlen(name), table);
			if (id != DM_ERR) {
				kw = &(table->table[id - 1]);
				val = dm_get_value_ref_by_id(DM_TABLE(*value), id);
				(*state)->flags |= XML_VALID;
			} else {
				printf("Element '%s' not found in table '%s'\n", name, element->key);
				valid = 0;
			}
		}

		if (!valid || !((*state)->flags & XML_VALID)) {
			debug("enter invalid: %s\n", (*state)->base);
			return;
		}

		xml_debug("enter: %s = %p, (%p, %p)\n", name, *state, kw, val);

		(*state)->element = kw;
		if (kw->type == T_OBJECT) {
			struct dm_instance *inst = DM_INSTANCE(*val);
			struct dm_instance_node *node = NULL;

			/** FIXME: this should be easier */
			if (xid > 0)
				node = dm_get_instance_node_by_id(inst, xid);
			if (!node) {
				dm_selector basesel;

				dm_selcpy(basesel, DM_TABLE(*value)->id);
				dm_selcat(basesel, id);

				node = dm_add_instance(kw, inst, basesel, xid);
				dm_assert(node);

				if (flags & DS_USERCONFIG) {
					val->flags |= DV_UPDATED;
					DM_parity_update(*val);
					node->table.flags |= DV_UPDATED;
					DM_parity_update(node->table);
				}
			}

			val = &node->table;

			(*state)->inst = inst;
			(*state)->node = node;

		} else if (kw->type == T_TOKEN) {
			if (DM_TABLE(*val) == NULL) {
				set_DM_TABLE(*val, dm_alloc_table(kw->u.t.table, DM_TABLE(*value)->id, id));

				if (flags & DS_USERCONFIG)
					val->flags |= DV_UPDATED;
				xml_debug("adding table for token \"%s\" with %d elements: %p\n", name,
					  kw->u.t.table->size, DM_TABLE(*val));
				DM_parity_update(*val);
			}
		}
		(*state)->value = val;
		if (ntfy >= 0)
			set_notify_single_slot_element(kw, (*state)->value, 0, ntfy);
	}
}