21 #include <sys/types.h>
42 gboolean ruleset_default = TRUE;
47 ruleset_default = FALSE;
59 return ruleset_default;
71 return pe_test_rule(rule, node_hash, role, now, NULL, NULL);
82 return pe_test_rule(rule, node_hash, role, now, NULL, &match_data);
92 gboolean empty = TRUE;
93 gboolean passed = TRUE;
94 gboolean do_and = TRUE;
95 const char *value = NULL;
105 for (expr = __xml_first_child_element(rule); expr != NULL;
106 expr = __xml_next_element(expr)) {
112 if (test && do_and == FALSE) {
116 }
else if (test == FALSE && do_and) {
123 crm_err(
"Invalid Rule %s: rules must contain at least one expression",
ID(rule));
126 crm_trace(
"Rule %s %s",
ID(rule), passed ?
"passed" :
"failed");
134 return pe_test_rule(rule, node_hash, role, now, NULL, match_data);
175 gboolean accept = FALSE;
176 const char *
uname = NULL;
180 accept =
pe_test_rule(expr, node_hash, role, now, next_change,
188 if (node_hash != NULL) {
201 #if ENABLE_VERSIONED_ATTRS
203 if (node_hash && g_hash_table_lookup_extended(node_hash,
223 ID(expr), accept ?
"passed" :
"failed",
uname ?
uname :
"all nodes");
238 const char *tag = NULL;
239 const char *attr = NULL;
242 tag = crm_element_name(expr);
261 #if ENABLE_VERSIONED_ATTRS
273 gboolean accept = FALSE;
274 const char *op = NULL;
275 const char *value = NULL;
315 gboolean accept = FALSE;
316 gboolean attr_allocated = FALSE;
318 const char *h_val = NULL;
319 GHashTable *table = NULL;
321 const char *op = NULL;
322 const char *
type = NULL;
323 const char *attr = NULL;
324 const char *value = NULL;
325 const char *value_source = NULL;
333 if (attr == NULL || op == NULL) {
334 pe_err(
"Invalid attribute or operation in expression"
340 if (match_data->
re) {
344 attr = (
const char *) resolved_attr;
345 attr_allocated = TRUE;
350 table = match_data->
params;
352 table = match_data->
meta;
357 const char *param_name = value;
358 const char *param_value = NULL;
360 if (param_name && param_name[0]) {
361 if ((param_value = (
const char *)g_hash_table_lookup(table, param_name))) {
368 h_val = (
const char *)g_hash_table_lookup(hash, attr);
371 if (attr_allocated) {
376 if (value != NULL && h_val != NULL) {
387 crm_trace(
"Defaulting to %s based comparison for '%s' op",
type, op);
391 cmp = strcasecmp(h_val, value);
397 if (h_val_f < value_f) {
399 }
else if (h_val_f > value_f) {
410 }
else if (value == NULL && h_val == NULL) {
412 }
else if (value == NULL) {
429 if ((h_val == value) || cmp == 0) {
434 if ((h_val == NULL && value != NULL)
435 || (h_val != NULL && value == NULL)
440 }
else if (value == NULL || h_val == NULL) {
488 uint32_t epact, diy, goldn;
493 goldn = (y % 19) + 1;
494 epact = (11 * goldn + 18) % 30;
495 if ((epact == 25 && goldn > 11) || epact == 24)
498 return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
502 decodeNVpair(
const char *srcstring,
char separator,
char **name,
char **value)
504 const char *seploc = NULL;
510 crm_trace(
"Attempting to decode: [%s]", srcstring);
511 if (srcstring != NULL) {
512 seploc = strchr(srcstring, separator);
514 *name =
strndup(srcstring, seploc - srcstring);
516 *value = strdup(seploc + 1);
524 #define cron_check(xml_field, time_field) \
525 value = crm_element_value(cron_spec, xml_field); \
526 if(value != NULL) { \
527 gboolean pass = TRUE; \
528 decodeNVpair(value, '-', &value_low, &value_high); \
529 if(value_low == NULL) { \
530 value_low = strdup(value); \
532 value_low_i = crm_parse_int(value_low, "0"); \
533 value_high_i = crm_parse_int(value_high, "-1"); \
534 if(value_high_i < 0) { \
535 if(value_low_i != time_field) { \
538 } else if(value_low_i > time_field) { \
540 } else if(value_high_i < time_field) { \
545 if(pass == FALSE) { \
546 crm_debug("Condition '%s' in %s: failed", value, xml_field); \
549 crm_debug("Condition '%s' in %s: passed", value, xml_field); \
555 const char *value = NULL;
556 char *value_low = NULL;
557 char *value_high = NULL;
560 int value_high_i = 0;
562 uint32_t h, m, s, y, d, w;
593 #define update_field(xml_field, time_fn) \
594 value = crm_element_value(duration_spec, xml_field); \
595 if(value != NULL) { \
596 int value_i = crm_parse_int(value, "0"); \
597 time_fn(end, value_i); \
604 const char *value = NULL;
648 if ((next_change != NULL) && (t != NULL)) {
672 const char *value = NULL;
675 xmlNode *duration_spec = NULL;
676 xmlNode *date_spec = NULL;
695 if (start != NULL && end == NULL && duration_spec != NULL) {
700 if ((start == NULL) && (end == NULL)) {
704 crm_time_set_if_earlier(next_change, start);
709 if (end && next_change) {
712 crm_time_set_if_earlier(next_change, end);
731 crm_time_set_if_earlier(next_change, start);
739 crm_time_set_if_earlier(next_change, end);
751 typedef struct sorted_set_s {
754 const char *special_name;
759 sort_pairs(gconstpointer a, gconstpointer b)
764 if (a == NULL && b == NULL) {
766 }
else if (a == NULL) {
768 }
else if (b == NULL) {
772 if (
safe_str_eq(pair_a->name, pair_a->special_name)) {
775 }
else if (
safe_str_eq(pair_b->name, pair_a->special_name)) {
779 if (pair_a->score < pair_b->score) {
781 }
else if (pair_a->score > pair_b->score) {
788 populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlNode * top)
790 const char *name = NULL;
791 const char *value = NULL;
792 const char *old_value = NULL;
793 xmlNode *list = nvpair_list;
794 xmlNode *an_attr = NULL;
796 name = crm_element_name(list->children);
798 list = list->children;
801 for (an_attr = __xml_first_child_element(list); an_attr != NULL;
802 an_attr = __xml_next_element(an_attr)) {
812 crm_trace(
"Setting attribute: %s", name);
818 if (name == NULL || value == NULL) {
823 old_value = g_hash_table_lookup(hash, name);
827 crm_trace(
"Removing value for %s (%s)", name, value);
828 g_hash_table_remove(hash, name);
832 }
else if (old_value == NULL) {
833 g_hash_table_insert(hash, strdup(name), strdup(value));
835 }
else if (overwrite) {
836 crm_debug(
"Overwriting value of %s: %s -> %s", name, old_value, value);
837 g_hash_table_replace(hash, strdup(name), strdup(value));
843 #if ENABLE_VERSIONED_ATTRS
845 get_versioned_rule(xmlNode * attr_set)
847 xmlNode * rule = NULL;
848 xmlNode * expr = NULL;
850 for (rule = __xml_first_child_element(attr_set); rule != NULL;
851 rule = __xml_next_element(rule)) {
854 for (expr = __xml_first_child_element(rule); expr != NULL;
855 expr = __xml_next_element(expr)) {
868 add_versioned_attributes(xmlNode * attr_set, xmlNode * versioned_attrs)
870 xmlNode *attr_set_copy = NULL;
871 xmlNode *rule = NULL;
872 xmlNode *expr = NULL;
874 if (!attr_set || !versioned_attrs) {
880 rule = get_versioned_rule(attr_set_copy);
886 expr = __xml_first_child_element(rule);
887 while (expr != NULL) {
889 xmlNode *node = expr;
891 expr = __xml_next_element(expr);
894 expr = __xml_next_element(expr);
902 typedef struct unpack_data_s {
904 GHashTable *node_hash;
912 unpack_attr_set(gpointer
data, gpointer user_data)
918 unpack_data->now, unpack_data->next_change)) {
922 #if ENABLE_VERSIONED_ATTRS
923 if (get_versioned_rule(pair->attr_set) && !(unpack_data->node_hash &&
924 g_hash_table_lookup_extended(unpack_data->node_hash,
931 crm_trace(
"Adding attributes from %s", pair->name);
932 populate_hash(pair->attr_set, unpack_data->hash, unpack_data->overwrite, unpack_data->top);
935 #if ENABLE_VERSIONED_ATTRS
937 unpack_versioned_attr_set(gpointer
data, gpointer user_data)
943 unpack_data->now, unpack_data->next_change)) {
944 add_versioned_attributes(pair->attr_set, unpack_data->hash);
961 make_pairs(xmlNode *top, xmlNode *xml_obj,
const char *set_name,
962 const char *always_first)
965 const char *score = NULL;
967 xmlNode *attr_set = NULL;
969 if (xml_obj == NULL) {
975 for (attr_set = __xml_first_child_element(xml_obj); attr_set != NULL;
976 attr_set = __xml_next_element(attr_set)) {
979 if (set_name == NULL ||
crm_str_eq((
const char *)attr_set->name, set_name, TRUE)) {
982 if (attr_set == NULL) {
987 pair->name =
ID(attr_set);
988 pair->special_name = always_first;
989 pair->attr_set = attr_set;
994 unsorted = g_list_prepend(unsorted, pair);
997 return g_list_sort(unsorted, sort_pairs);
1016 unpack_nvpair_blocks(xmlNode *top, xmlNode *xml_obj,
const char *set_name,
1017 GHashTable *node_hash,
void *hash,
1018 const char *always_first, gboolean overwrite,
1022 GList *pairs = make_pairs(top, xml_obj, set_name, always_first);
1027 .node_hash = node_hash,
1029 .overwrite = overwrite,
1030 .next_change = next_change,
1034 g_list_foreach(pairs, unpack_func, &
data);
1035 g_list_free_full(pairs, free);
1054 GHashTable *node_hash, GHashTable *hash,
1055 const char *always_first, gboolean overwrite,
1058 unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, always_first,
1059 overwrite, now, next_change, unpack_attr_set);
1064 GHashTable *node_hash, GHashTable *hash,
1065 const char *always_first, gboolean overwrite,
1068 unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, always_first,
1069 overwrite, now, NULL, unpack_attr_set);
1072 #if ENABLE_VERSIONED_ATTRS
1074 pe_unpack_versioned_attributes(xmlNode *top, xmlNode *xml_obj,
1075 const char *set_name, GHashTable *node_hash,
1079 unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, NULL, FALSE,
1080 now, next_change, unpack_versioned_attr_set);
1089 const char *p, *last_match_index;
1090 char *p_dst, *result = NULL;
1092 if (!
string ||
string[0] ==
'\0' || !match_data) {
1096 p = last_match_index = string;
1099 if (*p ==
'%' && *(p + 1) && isdigit(*(p + 1))) {
1101 if (match_data->
nregs >= i && match_data->
pmatch[i].rm_so != -1 &&
1102 match_data->
pmatch[i].rm_eo > match_data->
pmatch[i].rm_so) {
1103 len += p - last_match_index + (match_data->
pmatch[i].rm_eo - match_data->
pmatch[i].rm_so);
1104 last_match_index = p + 2;
1110 len += p - last_match_index + 1;
1117 p_dst = result = calloc(1, len);
1121 if (*p ==
'%' && *(p + 1) && isdigit(*(p + 1))) {
1123 if (match_data->
nregs >= i && match_data->
pmatch[i].rm_so != -1 &&
1124 match_data->
pmatch[i].rm_eo > match_data->
pmatch[i].rm_so) {
1126 int match_len = match_data->
pmatch[i].rm_eo - match_data->
pmatch[i].rm_so;
1127 memcpy(p_dst, match_data->
string + match_data->
pmatch[i].rm_so, match_len);
1141 #if ENABLE_VERSIONED_ATTRS
1143 pe_unpack_versioned_parameters(xmlNode *versioned_params,
const char *ra_version)
1145 GHashTable *hash = crm_str_table_new();
1147 if (versioned_params && ra_version) {
1148 GHashTable *node_hash = crm_str_table_new();
1149 xmlNode *attr_set = __xml_first_child_element(versioned_params);
1153 strdup(ra_version));
1155 crm_element_name(attr_set), node_hash, hash, NULL,
1159 g_hash_table_destroy(node_hash);