/******************************************************************** * FUNCTION xml_rd_open_file * * Read the value for the specified obj from an open FILE in XML format * * INPUTS: * fp == open FILE control block * obj == object template for the output value * val == address of value for output * * RETURNS: * status *********************************************************************/ status_t xml_rd_open_file (FILE *fp, obj_template_t *obj, val_value_t **val) { xml_node_t top; status_t res; /* get a dummy session control block */ ses_cb_t *scb = ses_new_dummy_scb(); if (!scb) { return ERR_INTERNAL_MEM; } scb->fp = fp; res = xml_get_reader_for_session(my_ses_read_cb, NULL, scb/*context*/, &scb->reader); if(res != NO_ERR) { return res; } /* parse */ *val = val_new_value(); if(*val == NULL) { return ERR_INTERNAL_MEM; } xml_init_node(&top); res = xml_consume_node(scb->reader, &top, TRUE, TRUE); if (res != NO_ERR) { return res; } res = val_parse(scb, obj, &top, *val); scb->fp = NULL; /* skip fclose inside ses_free_scb */ ses_free_scb(scb); xml_clean_node(&top); return res; } /* xml_rd_open_file */
/******************************************************************** * FUNCTION mgr_xml_skip_subtree * * Already encountered an error, so advance nodes until the * matching start-node is reached or a terminating error occurs * - end of input * - start depth level reached * * INPUTS: * reader == XmlReader already initialized from File, Memory, * or whatever * startnode == xml_node_t of the start node of the sub-tree to skip * RETURNS: * status of the operation * SIDE EFFECTS: * the xmlreader state is advanced until the current node is the * end node of the specified start node or a fatal error occurs *********************************************************************/ status_t mgr_xml_skip_subtree (xmlTextReaderPtr reader, const xml_node_t *startnode) { xml_node_t node; const xmlChar *qname, *badns; uint32 len; int ret, depth, nodetyp; xmlns_id_t nsid; boolean done, justone; status_t res; #ifdef DEBUG if (!reader || !startnode) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif justone = FALSE; switch (startnode->nodetyp) { case XML_NT_START: break; case XML_NT_EMPTY: return NO_ERR; case XML_NT_STRING: justone = TRUE; break; case XML_NT_END: return NO_ERR; default: return SET_ERROR(ERR_INTERNAL_VAL); } xml_init_node(&node); res = mgr_xml_consume_node_noadv(reader, &node); if (res == NO_ERR) { res = xml_endnode_match(startnode, &node); if (res == NO_ERR) { xml_clean_node(&node); return NO_ERR; } } xml_clean_node(&node); if (justone) { return NO_ERR; } done = FALSE; while (!done) { /* advance the node pointer */ ret = xmlTextReaderRead(reader); if (ret != 1) { /* fatal error */ return ERR_XML_READER_EOF; } /* get the node depth to match the end node correctly */ depth = xmlTextReaderDepth(reader); if (depth == -1) { /* not sure if this can happen, treat as fatal error */ return ERR_XML_READER_INTERNAL; } else if (depth <= startnode->depth) { /* this depth override will cause errors to be ignored * - wrong namespace in matching end node * - unknown namespace in matching end node * - wrong name in 'matching' end node */ done = TRUE; } /* get the internal nodetype, check it and convert it */ nodetyp = xmlTextReaderNodeType(reader); /* get the element QName */ qname = xmlTextReaderConstName(reader); if (qname) { /* check for namespace prefix in the name * only error is 'unregistered namespace ID' * which doesn't matter in this case */ nsid = 0; (void)xml_check_ns(reader, qname, &nsid, &len, &badns); } else { qname = (const xmlChar *)""; } /* check the normal case to see if the search is done */ if (depth == startnode->depth && !xml_strcmp(qname, startnode->qname) && nodetyp == XML_ELEMENT_DECL) { done = TRUE; } #ifdef XML_UTIL_DEBUG log_debug3("\nxml_skip: %s L:%d T:%s", qname, depth, xml_get_node_name(nodetyp)); #endif } return NO_ERR; } /* mgr_xml_skip_subtree */
/******************************************************************** * FUNCTION agt_top_dispatch_msg * * Find the appropriate top node handler and call it * called by the transport manager (through the session manager) * when a new message is detected * * INPUTS: * scb == session control block containing the xmlreader * set at the start of an incoming message. * * RETURNS: * none *********************************************************************/ void agt_top_dispatch_msg (ses_cb_t **ppscb) { ses_total_stats_t *myagttotals; agt_profile_t *profile; xml_node_t top; status_t res; top_handler_t handler; ses_cb_t *scb = *ppscb; #ifdef DEBUG if (!scb) { SET_ERROR(ERR_INTERNAL_PTR); return; } #endif myagttotals = ses_get_total_stats(); profile = agt_get_profile(); xml_init_node(&top); /* get the first node */ res = agt_xml_consume_node(scb, &top, NCX_LAYER_TRANSPORT, NULL); if (res != NO_ERR) { scb->stats.inBadRpcs++; myagttotals->stats.inBadRpcs++; myagttotals->droppedSessions++; if (LOGINFO) { log_info("\nagt_top: bad msg for session %d (%s)", scb->sid, get_error_string(res)); } xml_clean_node(&top); agt_ses_free_session(scb); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; return; } log_debug3("\nagt_top: got node"); if (LOGDEBUG4 && scb->state != SES_ST_INIT) { xml_dump_node(&top); } /* check node type and if handler exists, then call it */ if (top.nodetyp==XML_NT_START || top.nodetyp==XML_NT_EMPTY) { /* find the owner, elname tuple in the topQ */ handler = top_find_handler(top.module, top.elname); if (handler) { /* call the handler */ (*handler)(scb, &top); } else { res = ERR_NCX_DEF_NOT_FOUND; } } else { res = ERR_NCX_WRONG_NODETYP; } /* check any error trying to invoke the top handler */ if (res != NO_ERR) { scb->stats.inBadRpcs++; myagttotals->stats.inBadRpcs++; myagttotals->droppedSessions++; if (LOGINFO) { log_info("\nagt_top: bad msg for session %d (%s)", scb->sid, get_error_string(res)); } agt_ses_free_session(scb); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; } else if (profile->agt_stream_output && scb->state == SES_ST_SHUTDOWN_REQ) { /* session was closed */ agt_ses_kill_session(scb, scb->killedbysid, scb->termreason); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; } xml_clean_node(&top); } /* agt_top_dispatch_msg */