diff --git a/config/plugins/ccsais/config.c b/config/plugins/ccsais/config.c index 4db379b53..d1e9fa652 100644 --- a/config/plugins/ccsais/config.c +++ b/config/plugins/ccsais/config.c @@ -1,216 +1,216 @@ #include #include #include #include #include #include #include "list.h" #include "cnxman-socket.h" #include "cnxman-private.h" #include #include #include #include "libccscompat.h" #include "logging.h" #define CONFIG_VERSION_PATH "/cluster/@config_version" #define CONFIG_NAME_PATH "/cluster/@name" static int ccs_readconfig(struct objdb_iface_ver0 *objdb, char **error_string); static int init_config(struct objdb_iface_ver0 *objdb, char *error_string); static char error_reason[1024]; /* * Exports the interface for the service */ static struct config_iface_ver0 ccsconfig_iface_ver0 = { .config_readconfig = ccs_readconfig }; static struct lcr_iface ifaces_ver0[2] = { { .name = "ccsconfig", .version = 0, .versions_replace = 0, .versions_replace_count = 0, .dependencies = 0, .dependency_count = 0, .constructor = NULL, .destructor = NULL, .interfaces = NULL, } }; static struct lcr_comp ccs_comp_ver0 = { .iface_count = 1, .ifaces = ifaces_ver0, }; __attribute__ ((constructor)) static void ccs_comp_register(void) { lcr_interfaces_set(&ifaces_ver0[0], &ccsconfig_iface_ver0); lcr_component_register(&ccs_comp_ver0); }; static int should_alloc(int ccs_fd, char *key) { int keyerror, childerr; char path[256]; char *str = NULL; sprintf(path, "%s/@*", key); keyerror = ccs_get_list(ccs_fd, path, &str); if(str) { free(str); str = NULL; } sprintf(path, "%s/child::*", key); childerr = ccs_get_list(ccs_fd, path, &str); if(str) free(str); if (childerr && keyerror) return 0; return 1; } static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned int parent, char *object, char *key, int always_create) { int error; char *str; unsigned int object_handle = 0; char path[256]; int gotcount = 0; char *subkeys[52]; int subkeycount = 0; int i; if (should_alloc(ccs_fd, key) || always_create) objdb->object_create(parent, &object_handle, object, strlen(object)); sprintf(path, "%s/@*", key); /* Get the keys */ for (;;) { char *equal; error = ccs_get_list(ccs_fd, path, &str); if (error || !str) break; equal = strchr(str, '='); if (equal) { *equal = 0; objdb->object_key_create(object_handle, str, strlen(str), equal+1, strlen(equal+1)+1); gotcount++; } free(str); } /* Now look for sub-objects. CCS can't cope with recursive queries so we have to store the result of the subkey search */ memset(subkeys, 0, sizeof(subkeys)); sprintf(path, "%s/child::*", key); for (;;) { char *equal; error = ccs_get_list(ccs_fd, path, &str); if (error || !str) break; /* CCS returns duplicate values for the numbered entries we use below. eg. if there are 4 entries it will return clusternode= clusternode= clusternode= clusternode= which is not helpful to us cos we retrieve them as clusternode[1] clusternode[2] clusternode[3] clusternode[4] so we just store unique keys. */ equal = strchr(str, '='); if (equal) *equal = 0; if (subkeycount > 0 && strcmp(str, subkeys[subkeycount-1]) == 0) { free(str); - break; + continue; } subkeys[subkeycount++] = str; } for (i=0; i #include #include #include #include #include #include #include #include #include #include #include "logging.h" static int xml_readconfig(struct objdb_iface_ver0 *objdb, char **error_string); static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, char **error_string); static int init_config(struct objdb_iface_ver0 *objdb, char *configfile, char *error_string); static char error_reason[1024]; static int xmllistindex = 0; static char previous_query[PATH_MAX]; #define DEFAULT_CONFIG DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE /* * Exports the interface for the service */ static struct config_iface_ver0 xmlconfig_iface_ver0 = { .config_readconfig = xml_readconfig, .config_reloadconfig = xml_reloadconfig }; static struct lcr_iface ifaces_ver0[2] = { { .name = "xmlconfig", .version = 0, .versions_replace = 0, .versions_replace_count = 0, .dependencies = 0, .dependency_count = 0, .constructor = NULL, .destructor = NULL, .interfaces = NULL, } }; static struct lcr_comp xml_comp_ver0 = { .iface_count = 1, .ifaces = ifaces_ver0, }; __attribute__ ((constructor)) static void xml_comp_register(void) { lcr_interfaces_set(&ifaces_ver0[0], &xmlconfig_iface_ver0); lcr_component_register(&xml_comp_ver0); }; static char *do_xml_query(xmlXPathContextPtr ctx, char *query, int list) { xmlXPathObjectPtr obj = NULL; xmlNodePtr node = NULL; char *rtn = NULL; int size = 0, nnv = 0, child = 0; if (list && !strcmp(query, previous_query)) xmllistindex++; else { memset(previous_query, 0, PATH_MAX); xmllistindex = 0; } obj = xmlXPathEvalExpression((xmlChar *)query, ctx); if (obj && obj->nodesetval && (obj->nodesetval->nodeNr > 0)) { if (xmllistindex >= obj->nodesetval->nodeNr) { memset(previous_query, 0, PATH_MAX); xmllistindex = 0; goto fail; } node = obj->nodesetval->nodeTab[xmllistindex]; if (!node) goto fail; if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) || ((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))) { if (node->children && node->children->content) { size = strlen((char *)node->children->content) + strlen((char *)node->name)+2; child = 1; } else size = strlen((char *)node->name)+2; nnv = 1; } else { if (node->children && node->children->content) size = strlen((char *)node->children->content)+1; else goto fail; } rtn = malloc(size); if (!rtn) goto fail; memset(rtn, 0, size); if (nnv) { if (child) sprintf(rtn, "%s=%s", node->name, (char *)node->children->content); else sprintf(rtn, "%s=", node->name); } else sprintf(rtn, "%s", node->children ? node->children->content : node->name); if(list) strncpy(previous_query, query, PATH_MAX-1); } fail: if (obj) xmlXPathFreeObject(obj); return rtn; } static int should_alloc(xmlXPathContextPtr ctx, char *key) { int keyerror = 1, childerr = 1; char path[256]; char *str = NULL; sprintf(path, "%s/@*", key); str = do_xml_query(ctx, path, 1); if (str) { keyerror = 0; free(str); str = NULL; } sprintf(path, "%s/child::*", key); str = do_xml_query(ctx, path, 1); if(str) { childerr = 0; free(str); str = NULL; } if (childerr && keyerror) return 0; return 1; } static int read_config_for(xmlXPathContextPtr ctx, struct objdb_iface_ver0 *objdb, unsigned int parent, char *object, char *key, int always_create) { char *str; unsigned int object_handle = 0; char path[256]; int gotcount = 0; char *subkeys[52]; int subkeycount = 0; int i; if (should_alloc(ctx, key) || always_create) { objdb->object_create(parent, &object_handle, object, strlen(object)); } memset(previous_query, 0, PATH_MAX); sprintf(path, "%s/@*", key); /* Get the keys */ for (;;) { char *equal; str = do_xml_query(ctx, path, 1); if (!str) break; equal = strchr(str, '='); if (equal) { *equal = 0; objdb->object_key_create(object_handle, str, strlen(str), equal+1, strlen(equal+1)+1); gotcount++; } free(str); } /* Now look for sub-objects. CCS can't cope with recursive queries so we have to store the result of the subkey search */ memset(previous_query, 0, PATH_MAX); memset(subkeys, 0, sizeof(subkeys)); sprintf(path, "%s/child::*", key); for (;;) { char *equal; str = do_xml_query(ctx, path, 1); if (!str) break; /* CCS returns duplicate values for the numbered entries we use below. eg. if there are 4 entries it will return clusternode= clusternode= clusternode= clusternode= which is not helpful to us cos we retrieve them as clusternode[1] clusternode[2] clusternode[3] clusternode[4] so we just store unique keys. */ equal = strchr(str, '='); if (equal) *equal = 0; if (subkeycount > 0 && strcmp(str, subkeys[subkeycount-1]) == 0) { free(str); - break; + continue; } subkeys[subkeycount++] = str; } for (i=0; i