/******************************************************************************* * Copyright (C) 2004-2006 Intel Corp. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of Intel Corp. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /** * @author Anas Nashif, Intel Corp. * @author Liang Hou, Intel Corp. */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include "u/libu.h" #include "wsman-xml-api.h" #include "wsman-client-api.h" #include "wsman-soap.h" #include "wsman-xml.h" #include "wsman-faults.h" #include "wsman-soap-envelope.h" #include "wsman-epr.h" char *wsman_epr_selector_by_name(const epr_t *epr, const char* name) { int i; char *value = NULL; key_value_t *ss = epr->refparams.selectorset.selectors; if (ss == NULL) { debug("epr->refparams.selectorset.selectors == NULL\n"); return NULL; } for (i = 0; i < epr->refparams.selectorset.count; i++) { key_value_t *s; s = ss + i; if (strcmp(s->key, name) == 0 && s->type == 0) { value = u_strdup(s->v.text); break; } } return value; } void wsman_epr_selector_cb(const epr_t *epr, selector_callback cb, void *cb_data) { int i; key_value_t *ss = epr->refparams.selectorset.selectors; if (ss == NULL) { debug("epr->refparams.selectorset.selectors == NULL\n"); return; } for (i = 0; i < epr->refparams.selectorset.count; i++) { key_value_t *s; s = ss + i; cb(cb_data, s); } } void wsman_selectorset_cb(SelectorSet *selectorset, selector_callback cb, void *cb_data) { int i; key_value_t *ss = selectorset->selectors; if (ss == NULL) { debug("epr->refparams.selectors == NULL"); return; } for (i = 0; i < selectorset->count; i++) { key_value_t *s; s = ss + i; cb(cb_data, s); } } epr_t *epr_create(const char *uri, hash_t * selectors, const char *address) { epr_t *epr = NULL; epr = u_malloc(sizeof(epr_t)); if (address == NULL) epr->address = u_strdup(WSA_TO_ANONYMOUS); else epr->address = u_strdup(address); epr->refparams.uri = u_strdup(uri); if (selectors) { hnode_t *hn; hscan_t hs; key_value_t *p; key_value_t *entry; epr->refparams.selectorset.count = hash_count(selectors); epr->refparams.selectorset.selectors = u_malloc(sizeof(key_value_t)* epr->refparams.selectorset.count); p = epr->refparams.selectorset.selectors; hash_scan_begin(&hs, selectors); while ((hn = hash_scan_next(&hs))) { entry = (key_value_t *)hnode_get(hn); if (entry->type == 0) { key_value_create((char *)hnode_getkey(hn), entry->v.text, NULL, p); debug("key=%s value=%s", p->key, p->v.text); } else { key_value_create((char *)hnode_getkey(hn), NULL, entry->v.epr, p); debug("key=%s value=%p(nested epr)", p->key, p->v.epr); } p++; } } else { epr->refparams.selectorset.count = 0; epr->refparams.selectorset.selectors = NULL; } return epr; } epr_t *epr_from_string(const char* str) { char *p; char *uri; hash_t *selectors = NULL; hash_t *selectors_new = NULL; hnode_t *hn; hscan_t hs; key_value_t *entry; epr_t *epr; p = strchr(str, '?'); if (p) { uri = u_strndup(str, p - str); selectors = u_parse_query(p + 1); selectors_new = hash_create2(HASHCOUNT_T_MAX, 0, 0); hash_scan_begin(&hs, selectors); while ((hn = hash_scan_next(&hs))) { entry = key_value_create(NULL, (char *)hnode_get(hn), NULL, NULL); hash_alloc_insert(selectors_new, hnode_getkey(hn), entry); } } else { uri = u_strdup(str); } epr = epr_create(uri, selectors_new, NULL); if (selectors_new) { hash_free(selectors_new); hash_free(selectors); } u_free(uri); return epr; } static int epr_add_selector(epr_t *epr, const char *name, const char *text, epr_t *added_epr) { int i; key_value_t *p, *new_p; if (epr == NULL) return 0; p = epr->refparams.selectorset.selectors; for(i = 0; i< epr->refparams.selectorset.count; i++) { if(p->key && ( strcmp(name, p->key) == 0 ) ) { return -1; } p++; } p = epr->refparams.selectorset.selectors; p = u_realloc(p, (epr->refparams.selectorset.count+1) * sizeof(key_value_t)); if (p == NULL) return -1; epr->refparams.selectorset.selectors = p; new_p = key_value_create(name, text, added_epr, &(p[epr->refparams.selectorset.count])); if (new_p == NULL) { return -1; } epr->refparams.selectorset.count++; return 0; } int epr_selector_count(const epr_t *epr) { if(epr == NULL) return 0; return epr->refparams.selectorset.count; } int epr_add_selector_text(epr_t *epr, const char *name, const char *text) { return epr_add_selector(epr, name, text, NULL); } int epr_add_selector_epr(epr_t *epr, const char *name, epr_t *added_epr) { return epr_add_selector(epr, name, NULL, added_epr); } int epr_delete_selector(epr_t *epr, const char *name) { int i,k; int count; key_value_t *selectors; if(epr == NULL || name == NULL) return 0; count = epr->refparams.selectorset.count; selectors = epr->refparams.selectorset.selectors; for(i =0; i < count; i++) { if(strcmp(name, selectors[i].key) == 0) break; } if(i == count) return -1; key_value_destroy(&selectors[i], 1); for(k = i; k < count-1; k++) { memcpy(&selectors[k], &selectors[k+1], sizeof(key_value_t)); } epr->refparams.selectorset.selectors = u_realloc(selectors, (count-1)*sizeof(key_value_t)); epr->refparams.selectorset.count--; return 0; } void epr_destroy(epr_t *epr) { int i; key_value_t *p; if(epr == NULL) return; u_free(epr->address); u_free(epr->refparams.uri); p = epr->refparams.selectorset.selectors; for(i = 0; i< epr->refparams.selectorset.count; i++) { key_value_destroy(p, 1); p++; } u_free(epr->refparams.selectorset.selectors); u_free(epr); } epr_t *epr_copy(const epr_t *epr) { int i; key_value_t *p1; key_value_t *p2; epr_t *cpy_epr = NULL; if(epr == NULL) return cpy_epr; cpy_epr = u_malloc(sizeof(epr_t)); if (epr && epr->address) cpy_epr->address = u_strdup(epr->address); cpy_epr->refparams.uri = u_strdup(epr->refparams.uri); cpy_epr->refparams.selectorset.count = epr->refparams.selectorset.count; cpy_epr->refparams.selectorset.selectors = u_malloc(sizeof(key_value_t)* epr->refparams.selectorset.count); p1 = epr->refparams.selectorset.selectors; p2 = cpy_epr->refparams.selectorset.selectors; for (i = 0; i < epr->refparams.selectorset.count; i++) { key_value_copy(p1, p2); p1++; p2++; } return cpy_epr; } int epr_cmp(const epr_t *epr1, const epr_t *epr2) { int i, j; int matches = 0; key_value_t *p1; key_value_t *p2; assert(epr1 != NULL && epr2 != NULL); //if(strcmp(epr1->address, epr2->address)) return 1; if(strcmp(epr1->refparams.uri, epr2->refparams.uri)) return 1; if(epr1->refparams.selectorset.count != epr2->refparams.selectorset.count) return 1; p1 = epr1->refparams.selectorset.selectors; for(i = 0; i < epr1->refparams.selectorset.count; i++) { p2 = epr1->refparams.selectorset.selectors; for(j = 0; j < epr2->refparams.selectorset.count; j++, p2++) { if(strcmp(p1->key, p2->key)) continue; if(p1->type != p2->type) continue; if(p1->type == 0) { if(strcmp(p1->v.text, p2->v.text)) continue; } else { if (epr_cmp(p1->v.epr, p2->v.epr) == 1) { continue; } } matches++; } p1++; } if (matches == epr1->refparams.selectorset.count) return 0; else return 1; } char *epr_to_string(const epr_t *epr) { int i, len; char *buf, *ptr; key_value_t *p = NULL; if (epr == NULL) return NULL; /* calculate buffer size */ len = strlen(epr->refparams.uri); p = epr->refparams.selectorset.selectors; for(i = 0; i < epr->refparams.selectorset.count; i++) { len += (strlen(p->key) + 1); /* (?|&)key */ if (p->type == 0) len += (strlen(p->v.text) + 1); /* =value */ else { char *value = epr_to_string(p->v.epr); if (value) { len += (strlen(value) + 1); /* =value */ u_free(value); } } p++; } buf = u_malloc(len + 1); strcpy(buf, epr->refparams.uri); ptr = buf + strlen(buf); p = epr->refparams.selectorset.selectors; for(i = 0; i < epr->refparams.selectorset.count; i++) { if (i == 0) *ptr++ = '?'; else *ptr++ = '&'; strcpy(ptr, p->key); ptr += strlen(p->key); *ptr++ = '='; if (p->type == 0) { strcpy(ptr, p->v.text); ptr += strlen(p->v.text); } else { char *value = epr_to_string(p->v.epr); if (value) { strcpy(ptr, value); ptr += strlen(value); u_free(value); } } p++; } *ptr++ = 0; return buf; } char *epr_to_txt(const epr_t *epr, const char *ns, const char*epr_node_name) { char *buf = NULL; int len; WsXmlDocH doc2; WsXmlDocH doc = ws_xml_create_doc(ns, epr_node_name); WsXmlNodeH rootNode = ws_xml_get_doc_root(doc); epr_serialize(rootNode, NULL, NULL, epr, 1); doc2 = ws_xml_create_doc_by_import( rootNode); ws_xml_dump_memory_node_tree(ws_xml_get_doc_root(doc), &buf, &len); ws_xml_destroy_doc(doc);; ws_xml_destroy_doc(doc2); return buf; } char *epr_get_resource_uri(const epr_t *epr) { if (epr) return epr->refparams.uri; else return NULL; } int epr_serialize(WsXmlNodeH node, const char *ns, const char *epr_node_name, const epr_t *epr, int embedded) { int i; WsXmlNodeH eprnode = NULL; WsXmlNodeH refparamnode = NULL; WsXmlNodeH selectorsetnode = NULL; key_value_t *p = NULL; if(epr == NULL) return 0; if(epr_node_name) { eprnode = ws_xml_add_child(node, ns, epr_node_name, NULL); } else eprnode = node; if(embedded) ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_ADDRESS, epr->address); else ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_TO, epr->address); if(embedded) refparamnode = ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS, NULL); else refparamnode = node; ws_xml_add_child(refparamnode, XML_NS_WS_MAN, WSM_RESOURCE_URI, epr->refparams.uri); selectorsetnode = ws_xml_add_child(refparamnode, XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL); p = epr->refparams.selectorset.selectors; for(i = 0; i < epr->refparams.selectorset.count; i++) { WsXmlNodeH temp = NULL; if(p->type == 0) temp = ws_xml_add_child(selectorsetnode, XML_NS_WS_MAN, WSM_SELECTOR, p->v.text); else { temp = ws_xml_add_child(selectorsetnode, XML_NS_WS_MAN, WSM_SELECTOR, NULL); epr_serialize(temp, XML_NS_ADDRESSING, WSA_EPR, p->v.epr, 1); } ws_xml_add_node_attr(temp, NULL, WSM_NAME, p->key); p++; } return 0; } epr_t *epr_deserialize(WsXmlNodeH node, const char *ns, const char *epr_node_name, int embedded) { int i; epr_t *epr = u_malloc(sizeof(epr_t)); WsXmlNodeH eprnode = NULL; WsXmlNodeH refparamnode = NULL; WsXmlNodeH temp = NULL; WsXmlNodeH selectorsetnode = NULL; WsXmlAttrH attr = NULL; key_value_t *p = NULL; if(epr_node_name) { eprnode = ws_xml_get_child(node, 0, ns, epr_node_name); if(eprnode == NULL) goto CLEANUP; } else { eprnode = node; } if(embedded) { temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_ADDRESS); } else { temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_TO); } if(temp == NULL) goto CLEANUP; epr->address = u_strdup(ws_xml_get_node_text(temp)); if(embedded) { refparamnode = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS); } else { refparamnode = node; } if(refparamnode == NULL) goto CLEANUP; temp = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI); if(temp == NULL) goto CLEANUP; epr->refparams.uri = u_strdup(ws_xml_get_node_text(temp)); selectorsetnode = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET); epr->refparams.selectorset.count = ws_xml_get_child_count(selectorsetnode); epr->refparams.selectorset.selectors = u_malloc(epr->refparams.selectorset.count * sizeof(key_value_t)); p = epr->refparams.selectorset.selectors; for(i = 0; i < epr->refparams.selectorset.count; i++) { temp = ws_xml_get_child(selectorsetnode, i, XML_NS_WS_MAN, WSM_SELECTOR); attr = ws_xml_find_node_attr(temp, NULL, "Name"); if(attr) { p->key = u_strdup(ws_xml_get_attr_value(attr)); } if(ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_EPR)) { p->type = 1; p->v.epr = epr_deserialize(temp, XML_NS_ADDRESSING, WSA_EPR, 1); } else { p->type = 0; p->v.text = u_strdup(ws_xml_get_node_text(temp)); } p++; } return epr; CLEANUP: u_free(epr); return NULL; } char *get_cimnamespace_from_selectorset(SelectorSet *selectorset) { int i = 0; while(i < selectorset->count) { if(strcmp(selectorset->selectors[i].key, CIM_NAMESPACE_SELECTOR) == 0) return selectorset->selectors[i].v.text; i++; } return NULL; }