13 #include <sys/types.h>
17 #include <libxml/tree.h>
47 pcmk__new_nvpair(
const char *
name,
const char *value)
56 nvpair->
name = strdup(name);
57 nvpair->
value = value? strdup(value) : NULL;
68 pcmk__free_nvpair(gpointer
data)
93 return g_slist_prepend(nvpairs, pcmk__new_nvpair(name, value));
104 g_slist_free_full(nvpairs, pcmk__free_nvpair);
117 pcmk__compare_nvpair(gconstpointer a, gconstpointer b)
129 rc = strcmp(pair_a->
name, pair_b->
name);
148 return g_slist_sort(list, pcmk__compare_nvpair);
163 GSList *result = NULL;
165 for (xmlAttrPtr iter = pcmk__first_xml_attr(xml); iter != NULL;
169 (
const char *) iter->name,
170 (
const char *) pcmk__xml_attr_value(iter));
186 pcmk__nvpair_add_xml_attr(gpointer data, gpointer user_data)
189 xmlNode *parent = user_data;
203 g_slist_foreach(list, pcmk__nvpair_add_xml_attr, xml);
225 if (sscanf(input,
"%m[^=]=%m[^\n]", name, value) <= 0) {
233 sep = strstr(optarg,
"=");
238 *name =
strndup(input, sep-input);
247 if (*(sep+1) !=
'\0') {
248 *value = strdup(sep+1);
250 if (*value == NULL) {
256 if (*name != NULL && *value != NULL) {
258 }
else if (*name != NULL || *value != NULL) {
319 xmlAttr *attr = NULL;
327 #if XML_PARANOIA_CHECKS
329 const char *old_value = NULL;
335 crm_err(
"Cannot reset %s with crm_xml_add(%s)", name, value);
343 if (old == NULL || value == NULL || strcmp(old, value) != 0) {
349 crm_trace(
"Cannot add %s=%s to %s", name, value, node->name);
358 CRM_CHECK(attr && attr->children && attr->children->content,
return NULL);
359 return (
char *)attr->children->content;
376 xmlAttr *attr = NULL;
377 const char *old_value = NULL;
380 CRM_CHECK(name != NULL && name[0] != 0,
return NULL);
385 CRM_CHECK(old_value != value,
return value);
389 crm_trace(
"Cannot replace %s=%s to %s", name, value, node->name);
392 }
else if (old_value && !value) {
398 if (!old_value || !value || !strcmp(old_value, value)) {
407 CRM_CHECK(attr && attr->children && attr->children->content,
return NULL);
408 return (
char *) attr->children->content;
426 char *number = crm_itoa(value);
427 const char *added =
crm_xml_add(node, name, number);
449 const char *added =
crm_xml_add(node, name, number);
499 const struct timeval *value)
501 const char *added = NULL;
503 if (xml && name_sec && value) {
505 if (added && name_usec) {
524 xmlAttr *attr = NULL;
527 crm_err(
"Couldn't find %s in NULL", name ? name :
"<null>");
531 }
else if (name == NULL) {
532 crm_err(
"Couldn't find NULL in %s", crm_element_name(data));
539 attr = xmlHasProp((xmlNode *) data, (
pcmkXmlStr) name);
540 if (!attr || !attr->children) {
543 return (
const char *) attr->children->content;
560 const char *value = NULL;
588 const char *value = NULL;
616 const char *value = NULL;
629 if ((errno != 0) || (value_ll < 0) || (value_ll > G_MAXUINT)) {
633 *dest = (guint) value_ll;
651 long long value_ll = 0;
660 *dest = (time_t) value_ll;
679 const char *name_usec,
struct timeval *dest)
681 long long value_i = 0;
702 dest->tv_sec = (time_t) value_i;
708 dest->tv_usec = (suseconds_t) value_i;
727 char *value_copy = NULL;
731 value_copy = strdup(value);
752 const char *name = key;
753 const char *s_value = value;
755 xmlNode *xml_node = user_data;
757 if (isdigit(name[0])) {
765 crm_trace(
"dumped: %s=%s", name, s_value);
768 crm_trace(
"duplicate: %s=%s", name, s_value);
786 const char *name = key;
787 const char *s_value = value;
789 xmlNode *xml_node = user_data;
795 crm_trace(
"duplicate: %s=%s", name, s_value);
814 char *crm_name = NULL;
816 if (key == NULL || value == NULL) {
823 for (crm_name = key; *crm_name; ++crm_name) {
824 if ((*crm_name ==
'#') || (*crm_name ==
':')) {
863 const char *parent_id =
ID(parent);
887 const char *name = key;
888 const char *s_value = value;
889 xmlNode *xml_node = user_data;
892 crm_trace(
"dumped: name=%s value=%s", name, s_value);
912 xmlNode *child = NULL;
913 xmlAttrPtr pIter = NULL;
914 xmlNode *nvpair_list = NULL;
915 GHashTable *nvpair_hash = crm_str_table_new();
917 CRM_CHECK(parent != NULL,
return nvpair_hash);
920 if (nvpair_list == NULL) {
921 crm_trace(
"No attributes in %s", crm_element_name(parent));
927 for (pIter = pcmk__first_xml_attr(nvpair_list); pIter != NULL;
928 pIter = pIter->next) {
930 const char *p_name = (
const char *)pIter->name;
931 const char *p_value = pcmk__xml_attr_value(pIter);
933 crm_trace(
"Added %s=%s", p_name, p_value);
935 g_hash_table_insert(nvpair_hash, strdup(p_name), strdup(p_value));
938 for (child = __xml_first_child(nvpair_list); child != NULL;
939 child = __xml_next(child)) {
946 if (key != NULL && value != NULL) {
947 g_hash_table_insert(nvpair_hash, strdup(key), strdup(value));
#define CRM_CHECK(expr, failure_action)
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
GSList * pcmk_sort_nvpairs(GSList *list)
Sort a list of name/value pairs.
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs.
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value.
G_GNUC_INTERNAL void pcmk__mark_xml_attr_dirty(xmlAttr *a)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
#define XML_NVPAIR_ATTR_NAME
#define CRM_LOG_ASSERT(expr)
GSList * pcmk_prepend_nvpair(GSList *nvpairs, const char *name, const char *value)
Prepend a name/value pair to a list.
int pcmk_scan_nvpair(const char *input, char **name, char **value)
Extract the name and value from an input string formatted as "name=value". If unable to extract them...
#define XML_CIB_TAG_NVPAIR
char * pcmk_format_nvpair(const char *name, const char *value, const char *units)
int crm_element_value_ll(const xmlNode *data, const char *name, long long *dest)
Retrieve the long long integer value of an XML attribute.
GSList * pcmk_xml_attrs2nvpairs(xmlNode *xml)
Create a list of name/value pairs from an XML node's attributes.
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Add hash table entry to XML as (possibly legacy) name/value.
char * strndup(const char *str, size_t len)
char * crm_meta_name(const char *field)
void hash2nvpair(gpointer key, gpointer value, gpointer user_data)
Add XML nvpair element based on hash table entry.
char * pcmk_format_named_time(const char *name, time_t epoch_time)
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
int crm_element_value_timeval(const xmlNode *data, const char *name_sec, const char *name_usec, struct timeval *dest)
Retrieve the value of XML second/microsecond attributes as time.
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Replace an XML attribute with specified name and (possibly NULL) value.
#define crm_trace(fmt, args...)
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
const char * pcmk__epoch2str(time_t *when)
const char * crm_xml_add_timeval(xmlNode *xml, const char *name_sec, const char *name_usec, const struct timeval *value)
Create XML attributes for seconds and microseconds.
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
const xmlChar * pcmkXmlStr
long long crm_parse_ll(const char *text, const char *default_text)
Parse a long long integer value from a string.
#define crm_err(fmt, args...)
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
void xml_remove_prop(xmlNode *obj, const char *name)
#define XML_NVPAIR_ATTR_VALUE
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
GHashTable * xml2list(xmlNode *parent)
Retrieve XML attributes as a hash table.
void pcmk_nvpairs2xml_attrs(GSList *list, xmlNode *xml)
Add XML attributes based on a list of name/value pairs.
#define crm_log_xml_trace(xml, text)
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define pcmk_err_bad_nvpair