| /******************************************************************************* |
| * 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 <wsman_config.h> |
| #endif |
| |
| #define _GNU_SOURCE |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <ctype.h> |
| #include <assert.h> |
| |
| #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; |
| new_p = key_value_create(name, text, added_epr, &(p[epr->refparams.selectorset.count])); |
| |
| epr->refparams.selectorset.selectors = p; |
| 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; |
| } |
| |