29 #include <sys/types.h>
46 gboolean ruleset_default = TRUE;
49 for (rule = __xml_first_child(ruleset); rule != NULL; rule = __xml_next_element(rule)) {
51 ruleset_default = FALSE;
58 return ruleset_default;
83 gboolean empty = TRUE;
84 gboolean passed = TRUE;
85 gboolean do_and = TRUE;
86 const char *value = NULL;
96 for (expr = __xml_first_child(rule); expr != NULL; expr = __xml_next_element(expr)) {
100 if (test && do_and == FALSE) {
104 }
else if (test == FALSE && do_and) {
111 crm_err(
"Invalid Rule %s: rules must contain at least one expression",
ID(rule));
114 crm_trace(
"Rule %s %s",
ID(rule), passed ?
"passed" :
"failed");
138 gboolean accept = FALSE;
139 const char *
uname = NULL;
150 if (node_hash != NULL) {
163 #ifdef ENABLE_VERSIONED_ATTRS
165 if (node_hash && g_hash_table_lookup_extended(node_hash,
185 ID(expr), accept ?
"passed" :
"failed",
uname ?
uname :
"all nodes");
192 const char *tag = NULL;
193 const char *attr = NULL;
196 tag = crm_element_name(expr);
215 #ifdef ENABLE_VERSIONED_ATTRS
227 gboolean accept = FALSE;
228 const char *op = NULL;
229 const char *value = NULL;
274 gboolean accept = FALSE;
275 gboolean attr_allocated = FALSE;
277 const char *h_val = NULL;
278 GHashTable *table = NULL;
280 const char *op = NULL;
281 const char *
type = NULL;
282 const char *attr = NULL;
283 const char *value = NULL;
284 const char *value_source = NULL;
292 if (attr == NULL || op == NULL) {
293 pe_err(
"Invalid attribute or operation in expression"
299 if (match_data->
re) {
303 attr = (
const char *) resolved_attr;
304 attr_allocated = TRUE;
309 table = match_data->
params;
311 table = match_data->
meta;
316 const char *param_name = value;
317 const char *param_value = NULL;
319 if (param_name && param_name[0]) {
320 if ((param_value = (
const char *)g_hash_table_lookup(table, param_name))) {
327 h_val = (
const char *)g_hash_table_lookup(hash, attr);
330 if (attr_allocated) {
335 if (value != NULL && h_val != NULL) {
346 crm_trace(
"Defaulting to %s based comparison for '%s' op",
type, op);
350 cmp = strcasecmp(h_val, value);
356 if (h_val_f < value_f) {
358 }
else if (h_val_f > value_f) {
369 }
else if (value == NULL && h_val == NULL) {
371 }
else if (value == NULL) {
388 if ((h_val == value) || cmp == 0) {
393 if ((h_val == NULL && value != NULL)
394 || (h_val != NULL && value == NULL)
399 }
else if (value == NULL || h_val == NULL) {
452 goldn = (y % 19) + 1;
453 epact = (11 * goldn + 18) % 30;
454 if ((epact == 25 && goldn > 11) || epact == 24)
457 return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
461 decodeNVpair(
const char *srcstring,
char separator,
char **name,
char **value)
463 const char *seploc = NULL;
469 crm_trace(
"Attempting to decode: [%s]", srcstring);
470 if (srcstring != NULL) {
471 seploc = strchr(srcstring, separator);
473 *name =
strndup(srcstring, seploc - srcstring);
475 *value = strdup(seploc + 1);
483 #define cron_check(xml_field, time_field) \
484 value = crm_element_value(cron_spec, xml_field); \
485 if(value != NULL) { \
486 gboolean pass = TRUE; \
487 decodeNVpair(value, '-', &value_low, &value_high); \
488 if(value_low == NULL) { \
489 value_low = strdup(value); \
491 value_low_i = crm_parse_int(value_low, "0"); \
492 value_high_i = crm_parse_int(value_high, "-1"); \
493 if(value_high_i < 0) { \
494 if(value_low_i != time_field) { \
497 } else if(value_low_i > time_field) { \
499 } else if(value_high_i < time_field) { \
504 if(pass == FALSE) { \
505 crm_debug("Condition '%s' in %s: failed", value, xml_field); \
508 crm_debug("Condition '%s' in %s: passed", value, xml_field); \
514 const char *value = NULL;
515 char *value_low = NULL;
516 char *value_high = NULL;
519 int value_high_i = 0;
552 #define update_field(xml_field, time_fn) \
553 value = crm_element_value(duration_spec, xml_field); \
554 if(value != NULL) { \
555 int value_i = crm_parse_int(value, "0"); \
556 time_fn(end, value_i); \
563 const char *value = NULL;
584 const char *value = NULL;
587 xmlNode *duration_spec = NULL;
588 xmlNode *date_spec = NULL;
590 gboolean passed = FALSE;
606 if (start != NULL && end == NULL && duration_spec != NULL) {
642 typedef struct sorted_set_s {
645 const char *special_name;
650 sort_pairs(gconstpointer a, gconstpointer b)
655 if (a == NULL && b == NULL) {
657 }
else if (a == NULL) {
659 }
else if (b == NULL) {
663 if (
safe_str_eq(pair_a->name, pair_a->special_name)) {
666 }
else if (
safe_str_eq(pair_b->name, pair_a->special_name)) {
670 if (pair_a->score < pair_b->score) {
672 }
else if (pair_a->score > pair_b->score) {
679 populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlNode * top)
681 const char *name = NULL;
682 const char *value = NULL;
683 const char *old_value = NULL;
684 xmlNode *list = nvpair_list;
685 xmlNode *an_attr = NULL;
687 name = crm_element_name(list->children);
689 list = list->children;
692 for (an_attr = __xml_first_child(list); an_attr != NULL; an_attr = __xml_next_element(an_attr)) {
701 crm_trace(
"Setting attribute: %s", name);
707 if (name == NULL || value == NULL) {
712 old_value = g_hash_table_lookup(hash, name);
716 crm_trace(
"Removing value for %s (%s)", name, value);
717 g_hash_table_remove(hash, name);
721 }
else if (old_value == NULL) {
722 g_hash_table_insert(hash, strdup(name), strdup(value));
724 }
else if (overwrite) {
725 crm_debug(
"Overwriting value of %s: %s -> %s", name, old_value, value);
726 g_hash_table_replace(hash, strdup(name), strdup(value));
732 #ifdef ENABLE_VERSIONED_ATTRS
734 get_versioned_rule(xmlNode * attr_set)
736 xmlNode * rule = NULL;
737 xmlNode * expr = NULL;
739 for (rule = __xml_first_child(attr_set); rule != NULL; rule = __xml_next_element(rule)) {
741 for (expr = __xml_first_child(rule); expr != NULL; expr = __xml_next_element(expr)) {
753 add_versioned_attributes(xmlNode * attr_set, xmlNode * versioned_attrs)
755 xmlNode *attr_set_copy = NULL;
756 xmlNode *rule = NULL;
757 xmlNode *expr = NULL;
759 if (!attr_set || !versioned_attrs) {
765 rule = get_versioned_rule(attr_set_copy);
771 expr = __xml_first_child(rule);
772 while (expr != NULL) {
774 xmlNode *node = expr;
776 expr = __xml_next_element(expr);
779 expr = __xml_next_element(expr);
787 typedef struct unpack_data_s {
789 GHashTable *node_hash;
796 unpack_attr_set(gpointer
data, gpointer user_data)
801 if (
test_ruleset(pair->attr_set, unpack_data->node_hash, unpack_data->now) == FALSE) {
805 #ifdef ENABLE_VERSIONED_ATTRS
806 if (get_versioned_rule(pair->attr_set) && !(unpack_data->node_hash &&
807 g_hash_table_lookup_extended(unpack_data->node_hash,
814 crm_trace(
"Adding attributes from %s", pair->name);
815 populate_hash(pair->attr_set, unpack_data->hash, unpack_data->overwrite, unpack_data->top);
818 #ifdef ENABLE_VERSIONED_ATTRS
820 unpack_versioned_attr_set(gpointer
data, gpointer user_data)
825 if (
test_ruleset(pair->attr_set, unpack_data->node_hash, unpack_data->now) == FALSE) {
829 add_versioned_attributes(pair->attr_set, unpack_data->hash);
834 make_pairs_and_populate_data(xmlNode * top, xmlNode * xml_obj,
const char *set_name,
835 GHashTable * node_hash,
void * hash,
const char *always_first,
839 const char *score = NULL;
841 xmlNode *attr_set = NULL;
843 if (xml_obj == NULL) {
849 for (attr_set = __xml_first_child(xml_obj); attr_set != NULL; attr_set = __xml_next_element(attr_set)) {
851 if (set_name == NULL ||
crm_str_eq((
const char *)attr_set->name, set_name, TRUE)) {
854 if (attr_set == NULL) {
859 pair->name =
ID(attr_set);
860 pair->special_name = always_first;
861 pair->attr_set = attr_set;
866 unsorted = g_list_prepend(unsorted, pair);
872 data->node_hash = node_hash;
874 data->overwrite = overwrite;
879 return g_list_sort(unsorted, sort_pairs);
887 GHashTable * node_hash, GHashTable * hash,
const char *always_first,
891 GListPtr pairs = make_pairs_and_populate_data(top, xml_obj, set_name, node_hash, hash,
892 always_first, overwrite, now, &
data);
895 g_list_foreach(pairs, unpack_attr_set, &
data);
896 g_list_free_full(pairs, free);
900 #ifdef ENABLE_VERSIONED_ATTRS
902 pe_unpack_versioned_attributes(xmlNode * top, xmlNode * xml_obj,
const char *set_name,
903 GHashTable * node_hash, xmlNode * hash,
crm_time_t * now)
906 GListPtr pairs = make_pairs_and_populate_data(top, xml_obj, set_name, node_hash, hash,
907 NULL, FALSE, now, &
data);
910 g_list_foreach(pairs, unpack_versioned_attr_set, &
data);
911 g_list_free_full(pairs, free);
921 const char *p, *last_match_index;
922 char *p_dst, *result = NULL;
924 if (!
string ||
string[0] ==
'\0' || !match_data) {
928 p = last_match_index = string;
931 if (*p ==
'%' && *(p + 1) && isdigit(*(p + 1))) {
933 if (match_data->
nregs >= i && match_data->
pmatch[i].rm_so != -1 &&
934 match_data->
pmatch[i].rm_eo > match_data->
pmatch[i].rm_so) {
935 len += p - last_match_index + (match_data->
pmatch[i].rm_eo - match_data->
pmatch[i].rm_so);
936 last_match_index = p + 2;
942 len += p - last_match_index + 1;
949 p_dst = result = calloc(1, len);
953 if (*p ==
'%' && *(p + 1) && isdigit(*(p + 1))) {
955 if (match_data->
nregs >= i && match_data->
pmatch[i].rm_so != -1 &&
956 match_data->
pmatch[i].rm_eo > match_data->
pmatch[i].rm_so) {
958 int match_len = match_data->
pmatch[i].rm_eo - match_data->
pmatch[i].rm_so;
959 memcpy(p_dst, match_data->
string + match_data->
pmatch[i].rm_so, match_len);
973 #ifdef ENABLE_VERSIONED_ATTRS
975 pe_unpack_versioned_parameters(xmlNode *versioned_params,
const char *ra_version)
977 GHashTable *hash = crm_str_table_new();
979 if (versioned_params && ra_version) {
980 GHashTable *node_hash = crm_str_table_new();
981 xmlNode *attr_set = __xml_first_child(versioned_params);
987 node_hash, hash, NULL, FALSE, NULL);
990 g_hash_table_destroy(node_hash);