XMLNODE *XMLParse(XSLTGLOBALDATA *gctx, char *document) { info("XMLParse:: document"); return xml_parse_string(gctx, document, 0); }
/* Check if the response is an error, redirect response * or it includes a warning * @param response - the LoST response body * @param resp_type - the response type: ERROR, REDIRECT, WARNING or OK * @returns the root node of the parsed xml body */ xmlNode* get_LoST_resp_type(str response, lost_resp_type * resp_type, str * reason){ xmlNode * root, * node, * child; reason->s = NULL; reason->len = 0; root = xml_parse_string(response); if(!root) return root; #ifdef LOST_DEBUG print_element_names(root); #endif if(strcmp((char*)root->name, LOST_ERR_NODE_NAME) == 0){ DEBUG_LOG("LoST response has an error response\n"); node = child_node(root); if(node){ DEBUG_LOG("reason %s\n", node->name); reason->s = (char*)node->name; reason->len = strlen(reason->s); #ifdef LOST_DEBUG print_attr(node, LOST_MSG_ATTR_NAME); #endif }else { DEBUG_LOG("the message has no reason\n"); } *resp_type = LOST_ERR; } else if(strcmp((char*)root->name, LOST_REDIR_NODE_NAME) == 0){ DEBUG_LOG("LoST response has a redirect response\n"); #ifdef LOST_DEBUG print_attr(root, LOST_TGT_ATTR_NAME); #endif *resp_type = LOST_REDIR; } else if(strcmp((char*)root->name, LOST_FINDSRESP_NODE_NAME) != 0){ ERROR_LOG("invalid LoST response\n"); *resp_type = LOST_ERR; } else { node = child_named_node(root, LOST_WRNG_NODE_NAME); if(node){ DEBUG_LOG("LoST response has a response with warning\n"); if((child = child_node(node))){ DEBUG_LOG("reason %s\n", child->name); reason->s = (char*)child->name; reason->len = strlen(reason->s); #ifdef LOST_DEBUG print_attr(node, LOST_MSG_ATTR_NAME); #endif }else { DEBUG_LOG("warning without reason\n"); } *resp_type = LOST_WRNG; }else *resp_type = LOST_OK; } return root; }
/*! Send internal netconf rpc from client to backend * @param[in] h CLICON handle * @param[in] msg Encoded message. Deallocate woth free * @param[out] xret Return value from backend as xml tree. Free w xml_free * @param[inout] sock0 If pointer exists, do not close socket to backend on success * and return it here. For keeping a notify socket open * @note sock0 is if connection should be persistent, like a notification/subscribe api * @note xret is populated with yangspec according to standard handle yangspec */ int clicon_rpc_msg(clicon_handle h, struct clicon_msg *msg, cxobj **xret0, int *sock0) { int retval = -1; char *sock; int port; char *retdata = NULL; cxobj *xret = NULL; yang_stmt *yspec; #ifdef RPC_USERNAME_ASSERT assert(strstr(msg->op_body, "username")!=NULL); /* XXX */ #endif clicon_debug(1, "%s request:%s", __FUNCTION__, msg->op_body); if ((sock = clicon_sock(h)) == NULL){ clicon_err(OE_FATAL, 0, "CLICON_SOCK option not set"); goto done; } /* What to do if inet socket? */ switch (clicon_sock_family(h)){ case AF_UNIX: if (clicon_rpc_connect_unix(msg, sock, &retdata, sock0) < 0){ #if 0 if (errno == ESHUTDOWN) /* Maybe could reconnect on a higher layer, but lets fail loud and proud */ cligen_exiting_set(cli_cligen(h), 1); #endif goto done; } break; case AF_INET: if ((port = clicon_sock_port(h)) < 0){ clicon_err(OE_FATAL, 0, "CLICON_SOCK option not set"); goto done; } if (port < 0){ clicon_err(OE_FATAL, 0, "CLICON_SOCK_PORT not set"); goto done; } if (clicon_rpc_connect_inet(msg, sock, port, &retdata, sock0) < 0) goto done; break; } clicon_debug(1, "%s retdata:%s", __FUNCTION__, retdata); if (retdata){ yspec = clicon_dbspec_yang(h); if (xml_parse_string(retdata, yspec, &xret) < 0) goto done; } if (xret0){ *xret0 = xret; xret = NULL; } retval = 0; done: if (retdata) free(retdata); if (xret) xml_free(xret); return retval; }