17 #include <sys/types.h>                      19 #include <libxml/tree.h>                    20 #include <libxml/valid.h>                   43                      const char *attr_n, 
const char *attr_v)
    45     xmlNode *child = NULL;
    46     const char *parent_name = 
"<null>";
    48     CRM_CHECK((attr_v == NULL) || (attr_n != NULL), 
return NULL);
    52         while ((child != NULL) && (child->type != XML_ELEMENT_NODE)) {
    56         parent_name = (
const char *) 
parent->name;
    60         const char *value = NULL;
    62         if ((node_name != NULL) && !pcmk__xe_is(child, node_name)) {
    73         if ((attr_v == NULL) && (value != NULL)) {
    77         if ((attr_v != NULL) && (pcmk__str_eq(value, attr_v, 
pcmk__str_none))) {
    83     if (node_name == NULL) {
    87         crm_trace(
"XML child node <%s %s=%s> not found in %s",
    88                   node_name, attr_n, attr_v, parent_name);
    90         crm_trace(
"XML child node <%s> not found in %s",
    91                   node_name, parent_name);
   108     for (xmlNode *next = (xml == NULL)? NULL : xml->next;
   109          next != NULL; next = next->next) {
   110         if ((next->type == XML_ELEMENT_NODE)
   111             && ((element_name == NULL) || pcmk__xe_is(next, element_name))) {
   135     const char *value = NULL;
   176     const char *old_value = NULL;
   188     if (old_value != NULL) {
   189         const char *n = 
name;
   190         const char *v = value;
   193         for (; (*n == *v) && (*n != 
'\0'); n++, v++);
   198             && ((*v == 
'+') || (*v == 
'='))) {
   205             if (old_value != value) {
   209                     crm_trace(
"Using 0 before incrementing %s because '%s' "   210                               "is not a score", 
name, old_value);
   221                     crm_trace(
"Not incrementing %s because '%s' does not have "   222                               "a valid increment", 
name, value);
   232     if (old_value != value) {
   256     for (xmlAttr *attr = pcmk__xe_first_attr(src); attr != NULL;
   259         const char *
name = (
const char *) attr->name;
   260         const char *value = pcmk__xml_attr_value(attr);
   291 compare_xml_attr(gconstpointer a, gconstpointer b)
   293     const xmlAttr *attr_a = a;
   294     const xmlAttr *attr_b = b;
   314     GSList *attr_list = NULL;
   316     for (xmlAttr *iter = pcmk__xe_first_attr(xml); iter != NULL;
   318         attr_list = g_slist_prepend(attr_list, iter);
   320     attr_list = g_slist_sort(attr_list, compare_xml_attr);
   322     for (GSList *iter = attr_list; iter != NULL; iter = iter->next) {
   323         xmlNode *attr = iter->data;
   326         xmlAddChild(xml, attr);
   328     g_slist_free(attr_list);
   363     const char *
name = user_data;
   380                                bool (*match)(xmlAttrPtr, 
void *),
   383     xmlAttrPtr next = NULL;
   385     for (xmlAttrPtr a = pcmk__xe_first_attr(element); a != NULL; a = next) {
   387         if ((match == NULL) || match(a, user_data)) {
   409     xmlNode *node = NULL;
   419         xmlDocSetRootElement(doc, node);
   446         const char *content = NULL;
   454                   || (node->children->type == XML_TEXT_NODE),
   457         if (strchr(format, 
'%') == NULL) {
   464             va_start(ap, format);
   468                 content = va_arg(ap, 
const char *);
   477         xmlNodeSetContent(node, (
pcmkXmlStr) content);
   506     va_start(ap, format);
   529     const char *
result = NULL;
   532                          pcmk__s(now_s, 
"Could not determine current time"));
   573     const char *update_name = NULL;
   574     const char *update_id_attr = NULL;
   575     const char *update_id_val = NULL;
   576     char *trace_s = NULL;
   583     if (update->type == XML_COMMENT_NODE) {
   588     update_name = (
const char *) update->name;
   590     CRM_CHECK(update_name != NULL, 
goto done);
   593     update_id_val = pcmk__xe_id(update);
   594     if (update_id_val != NULL) {
   599         if (update_id_val != NULL) {
   606             if (update_id_attr != NULL) {
   608                                             update_name, update_id_attr,
   626         crm_trace(
"Added %s", pcmk__s(trace_s, update_name));
   630         crm_trace(
"Found node %s to update", pcmk__s(trace_s, update_name));
   637     for (xmlNode *child = pcmk__xml_first_child(update); child != NULL;
   638          child = pcmk__xml_next(child)) {
   640         crm_trace(
"Updating child of %s", pcmk__s(trace_s, update_name));
   644     crm_trace(
"Finished with %s", pcmk__s(trace_s, update_name));
   669 delete_xe_if_matching(xmlNode *xml, 
void *user_data)
   671     xmlNode *search = user_data;
   673     if (!pcmk__xe_is(search, (
const char *) xml->name)) {
   678     for (
const xmlAttr *attr = pcmk__xe_first_attr(search); attr != NULL;
   681         const char *search_val = pcmk__xml_attr_value(attr);
   720     CRM_CHECK((xml != NULL) && (search != NULL), 
return EINVAL);
   747 replace_node(xmlNode *old, xmlNode *
new)
   751     old = xmlReplaceNode(old, 
new);
   785 replace_xe_if_matching(xmlNode *xml, 
void *user_data)
   787     xmlNode *replace = user_data;
   788     const char *xml_id = NULL;
   789     const char *replace_id = NULL;
   791     xml_id = pcmk__xe_id(xml);
   792     replace_id = pcmk__xe_id(replace);
   794     if (!pcmk__xe_is(replace, (
const char *) xml->name)) {
   799     if ((replace_id != NULL)
   808     replace_node(xml, replace);
   840     CRM_CHECK((xml != NULL) && (replace != NULL), 
return EINVAL);
   883 update_xe_if_matching(xmlNode *xml, 
void *user_data)
   885     struct update_data *
data = user_data;
   886     xmlNode *update = 
data->update;
   888     if (!pcmk__xe_is(update, (
const char *) xml->name)) {
   893     if (!pcmk__str_eq(pcmk__xe_id(xml), pcmk__xe_id(update), 
pcmk__str_none)) {
   900     update_xe(NULL, xml, update, 
data->flags);
   935     struct update_data 
data = {
   940     CRM_CHECK((xml != NULL) && (update != NULL), 
return EINVAL);
   955         const char *
name, *value;
   957         name = va_arg(pairs, 
const char *);
   962         value = va_arg(pairs, 
const char *);
   973     va_start(pairs, node);
   980                        int (*handler)(xmlNode *xml, 
void *userdata),
   983     xmlNode *children = (xml? xml->children : NULL);
   987     for (xmlNode *node = children; node != NULL; node = node->next) {
   988         if ((node->type == XML_ELEMENT_NODE)
   989             && ((child_element_name == NULL)
   990                 || pcmk__xe_is(node, child_element_name))) {
   991             int rc = handler(node, userdata);
  1019     xmlAttr *attr = NULL;
  1024     if (value == NULL) {
  1031         if (old == NULL || value == NULL || strcmp(old, value) != 0) {
  1037         crm_trace(
"Cannot add %s=%s to %s", 
name, value, node->name);
  1052     CRM_CHECK(attr && attr->children && attr->children->content, 
return NULL);
  1053     return (
char *)attr->children->content;
  1072     char *number = pcmk__itoa(value);
  1103 #define LLSTRSIZE 21  1145                     const struct timeval *value)
  1147     const char *added = NULL;
  1149     if (xml && name_sec && value) {
  1150         added = 
crm_xml_add_ll(xml, name_sec, (
long long) value->tv_sec);
  1151         if (added && name_usec) {
  1170     xmlAttr *attr = NULL;
  1177     } 
else if (
name == NULL) {
  1183     if (!attr || !attr->children) {
  1186     return (
const char *) attr->children->content;
  1203     const char *value = NULL;
  1214                      "because '%s' is not a valid integer: %s",
  1216         } 
else if ((value_ll < INT_MIN) || (value_ll > INT_MAX)) {
  1217             crm_warn(
"Using default for %s because '%s' is out of range",
  1220             *dest = (int) value_ll;
  1244                    uint32_t default_value)
  1246     const char *value = NULL;
  1247     long long value_ll = 0LL;
  1251         *dest = default_value;
  1261     if (value == NULL) {
  1266     if ((value_ll < 0) || (value_ll > UINT32_MAX)) {
  1267         value_ll = default_value;
  1274         *dest = (uint32_t) value_ll;
  1293     const char *value = NULL;
  1297     if (value != NULL) {
  1304                  "because '%s' is not a valid integer: %s",
  1324     const char *value = NULL;
  1334                  "because '%s' is not valid milliseconds: %s",
  1338     if ((value_ll < 0) || (value_ll > G_MAXUINT)) {
  1339         crm_warn(
"Using default for %s because '%s' is out of range",
  1343     *dest = (guint) value_ll;
  1361     long long value_ll = 0;
  1370     *dest = (time_t) value_ll;
  1389                           const char *name_usec, 
struct timeval *dest)
  1391     long long value_i = 0;
  1393     CRM_CHECK(dest != NULL, 
return -EINVAL);
  1412     dest->tv_sec = (time_t) value_i;
  1418     dest->tv_usec = (suseconds_t) value_i;
  1438     const char *value = NULL;
  1440     if ((t == NULL) || (*t != NULL) || (xml == NULL) || (attr == NULL)) {
  1445     if (value != NULL) {
  1503     const char *xml_value = NULL;
  1508     } 
else if (
name == NULL || value == NULL) {
  1514     if (xml_value == NULL) {
  1570     va_start(ap, format);
  1571     len = vasprintf(&
id, format, ap);
  1583     xmlNode *child = NULL;
  1584     GSList *nvpairs = NULL;
 int crm_element_value_ll(const xmlNode *data, const char *name, long long *dest)
Retrieve the long long integer value of an XML attribute. 
 
int pcmk__xe_delete_match(xmlNode *xml, xmlNode *search)
 
Deprecated Pacemaker XML element API. 
 
#define CRM_CHECK(expr, failure_action)
 
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
 
void pcmk__xe_set_props(xmlNodePtr node,...)
 
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
 
void pcmk__xe_remove_attr(xmlNode *element, const char *name)
 
G_GNUC_INTERNAL bool pcmk__xml_reset_node_flags(xmlNode *xml, void *user_data)
 
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute. 
 
#define pcmk__if_tracing(if_action, else_action)
 
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs. 
 
void pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
 
int pcmk__xe_get_bool_attr(const xmlNode *node, const char *name, bool *value)
 
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
 
struct crm_time_s crm_time_t
 
int pcmk__xe_get_datetime(const xmlNode *xml, const char *attr, crm_time_t **t)
 
void pcmk__xe_set_propv(xmlNodePtr node, va_list pairs)
 
G_GNUC_INTERNAL void pcmk__mark_xml_attr_dirty(xmlAttr *a)
 
GSList * pcmk_xml_attrs2nvpairs(const xmlNode *xml)
 
void pcmk__xe_set_id(xmlNode *node, const char *format,...)
 
int pcmk__xe_copy_attrs(xmlNode *target, const xmlNode *src, uint32_t flags)
 
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
 
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute. 
 
int pcmk__xe_get_score(const xmlNode *xml, const char *name, int *score, int default_score)
 
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. 
 
#define PCMK_XA_CIB_LAST_WRITTEN
 
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute. 
 
#define CRM_LOG_ASSERT(expr)
 
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code. 
 
void pcmk__xe_sort_attrs(xmlNode *xml)
 
Deprecated Pacemaker name-value pair API. 
 
void pcmk_nvpairs2xml_attrs(GSList *list, xmlNode *xml)
 
Deprecated Pacemaker XML API. 
 
void pcmk__xe_set_content(xmlNode *node, const char *format,...)
 
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
 
G_GNUC_INTERNAL xmlDoc * pcmk__xml_new_doc(void)
 
bool xml_tracking_changes(xmlNode *xml)
 
void pcmk__xml_free(xmlNode *xml)
 
const char * pcmk__xe_add_last_written(xmlNode *xe)
 
#define PCMK__PARSE_INT_DEFAULT
 
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
 
#define crm_warn(fmt, args...)
 
G_GNUC_INTERNAL void pcmk__xc_update(xmlNode *parent, xmlNode *target, xmlNode *update)
 
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value. 
 
void pcmk__xe_remove_matching_attrs(xmlNode *element, bool(*match)(xmlAttrPtr, void *), void *user_data)
 
void crm_xml_sanitize_id(char *id)
 
G_GNUC_INTERNAL void pcmk__xml_new_private_data(xmlNode *xml)
 
G_GNUC_INTERNAL void pcmk__xml_free_node(xmlNode *xml)
 
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
 
#define crm_trace(fmt, args...)
 
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value. 
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
Wrappers for and extensions to libxml2. 
 
int pcmk__xe_set_score(xmlNode *target, const char *name, const char *value)
 
xmlNode * pcmk__xe_next(const xmlNode *xml, const char *element_name)
 
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
 
int pcmk__add_scores(int score1, int score2)
 
#define pcmk__str_copy(str)
 
GSList * pcmk_sort_nvpairs(GSList *list)
 
Function and executable result codes. 
 
int pcmk__xe_replace_match(xmlNode *xml, xmlNode *replace)
 
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute. 
 
const xmlChar * pcmkXmlStr
 
Functionality for manipulating name/value pairs. 
 
#define pcmk__assert(expr)
 
const char * crm_xml_add_ll(xmlNode *xml, const char *name, long long value)
Create an XML attribute with specified name and long long int value. 
 
bool pcmk__xe_remove_attr_cb(xmlNode *xml, void *user_data)
 
pcmk__action_result_t result
 
#define crm_err(fmt, args...)
 
int pcmk__xe_update_match(xmlNode *xml, xmlNode *update, uint32_t flags)
 
char * pcmk__epoch2str(const time_t *source, uint32_t flags)
 
crm_time_t * crm_time_new(const char *string)
 
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
 
void pcmk__apply_acl(xmlNode *xml)
 
#define pcmk__mem_assert(ptr)
 
int pcmk__strcmp(const char *s1, const char *s2, uint32_t flags)
 
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string. 
 
void crm_xml_set_id(xmlNode *xml, const char *format,...)
 
bool pcmk__xml_tree_foreach(xmlNode *xml, bool(*fn)(xmlNode *, void *), void *user_data)
 
int crm_element_value_timeval(const xmlNode *xml, 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_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value. 
 
int crm_str_to_boolean(const char *s, int *ret)
 
#define crm_log_xml_trace(xml, text)
 
void pcmk__xml_sanitize_id(char *id)
 
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
 
int pcmk__xe_get_flags(const xmlNode *xml, const char *name, uint32_t *dest, uint32_t default_value)
 
int pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name, int(*handler)(xmlNode *xml, void *userdata), void *userdata)
 
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute. 
 
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
 
G_GNUC_INTERNAL int pcmk__xa_remove(xmlAttr *attr, bool force)
 
Don't overwrite existing values. 
 
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1