Release bumped to "gts4".
[tac_plus.git] / cfgeval.c
index c85122a..f0aed72 100644 (file)
--- a/cfgeval.c
+++ b/cfgeval.c
@@ -379,12 +379,14 @@ struct expr *parent;
        switch (expr->type) {
 
        case S_not:
-           expr_sink_internal(expr->u.not.child, membership, expr /* parent */);
+           if (expr_sink_internal(expr->u.not.child, membership, expr /* parent */))
+               return (1);
            break;
 
        case S_and:
        case S_or:
-           expr_sink_internal(expr->u.and_or.child_first, membership, expr /* parent */);
+           if (expr_sink_internal(expr->u.and_or.child_first, membership, expr /* parent */))
+               return (1);
            break;
 
        case S_user:
@@ -392,11 +394,18 @@ struct expr *parent;
        case S_group:
            tac_list_node_init(&expr->eval_scan.u.entity.notify_expr_node);
            expr->u.entity.entity = entity_lookup(expr->type, expr->u.entity.name);
+           if (!expr->u.entity.entity && expr->type == S_host) {
+               expr->u.entity.entity = new_entity(expr->type, (char *)expr->u.entity.name, expr->line);
+               if (!expr->u.entity.entity)
+                   return (1);
+               expr->u.entity.name = NULL;
+           }
            if (!expr->u.entity.entity) {
                report(LOG_ERR, "referenced entity %s %s not found on line %d",
                        entity_type_to_string(expr->type), expr->u.entity.name, expr->line);
                return (1);
-               }
+           }
+           /* already NULLed for not-yet-existing S_host */
            free((char *) expr->u.entity.name);
            expr->u.entity.name = NULL;
            break;
@@ -1067,8 +1076,15 @@ struct expr *expr;
        report(LOG_DEBUG, "expr_eval_notify_expr: REGISTERED notify " PF_EXPR " when " PF_ENTITY " is known",
                PA_EXPR(expr), PA_ENTITY(entity));
 
-    if (tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node))
+    if (tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node)) {
+#ifdef SCAN_PARANOIA
+       if (&entity->eval_scan.notify_expr_list
+        != tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node))
+           report(LOG_ERR, "Another " PF_ENTITY " already registered in notify node of " PF_EXPR,
+               PA_ENTITY(EXPR_ENTITY_TO_NOTIFYING_ENTITY(expr)), PA_EXPR(expr));
+#endif
        return;
+    }
 
     tac_list_addtail(&entity->eval_scan.notify_expr_list,
            &expr->eval_scan.u.entity.notify_expr_node);
@@ -1319,6 +1335,13 @@ top_down:
                    report(LOG_DEBUG, "expr_eval_immediate: bottom_up and_or: full scan: " PF_EXPR,
                            PA_EXPR(expr_single));
 
+               /* It would be nice to pretend that all 'veto' decisions already made in the child
+                * had to set our 'result' to the correct value. But 'consent' decisions don't set
+                * us and the behaviour of auto-set from the child in 'veto' case may get changed
+                * in the future versions.
+                * So we rather don't depend on it.
+                * This overhead doesn't change altgorithmic complexity anyway.
+                */
                result_parent = consent;
                for (expr_child = expr_parent->u.and_or.child_first; expr_child; expr_child = expr_child->next)
                {