#include #include #include #include "common.h" #include "debug.h" #include "rule.h" #include "logicalrule.h" enum { DEBUG_BINARYRULE = false, DEBUG_ANDRULE = false, DEBUG_ORRULE = false, }; typedef struct BinaryRule { Rule; Rule *first; Rule *second; } BinaryRule; static Rule *binaryrule_new( Rule *first, Rule *second, char *path, RuleOperations *ops, char *name) { BinaryRule *result; char buf[RULE_MAXNAMELEN]; assert_valid(first); assert_valid(second); assert_valid(path); assert_valid(ops); assert_valid(name); result = (BinaryRule *)emalloc_fs(sizeof(*result)); result->ops = ops; result->root = estrdup_fs(path); result->first = first; result->second = second; snprint(buf, sizeof(buf), "(%s %s %s)", first->name, name, second->name); result->name = estrdup_fs(buf); return result; } static void binaryrule_free(Rule *rule) { BinaryRule *self = (BinaryRule *)rule; rule_free(self->first); rule_free(self->second); free(self->name); self->name = nil; free(self); } static bool andrule_issatisfy(Rule *rule, char *path, Dir *d); static bool andrule_contains(Rule *rule, char *path, int omode, ulong perm); static RuleOperations andops = { .free = binaryrule_free, .issatisfy = andrule_issatisfy, .contains = andrule_contains }; static bool andrule_issatisfy(Rule *rule, char *path, Dir *d) { BinaryRule *self = (BinaryRule *)rule; NOISE(DEBUG_BINARYRULE || DEBUG_ANDRULE, "entering andrule_issatisfy %s with path: %s", self->name, path); if(!rule_issatisfy(self->first, path, d)) { return false; } NOISE(DEBUG_BINARYRULE || DEBUG_ANDRULE, "andrule_issatisfy first rule failed"); return rule_issatisfy(self->second, path, d); } static bool andrule_contains(Rule *rule, char *path, int omode, ulong perm) { BinaryRule *self = (BinaryRule *)rule; NOISE(DEBUG_BINARYRULE || DEBUG_ANDRULE, "entering andrule_contains %s with path: %s", self->name, path); if(!rule_contains(self->first, path, omode, perm)) { return false; } NOISE(DEBUG_BINARYRULE || DEBUG_ANDRULE, "andrule_contains first rule failed"); return rule_contains(self->second, path, omode, perm); } Rule *andrule_new(Rule *first, Rule *second, char *path) { assert_valid(first); assert_valid(second); INFO(DEBUG_BINARYRULE || DEBUG_ANDRULE, "parsed && rule with path: %s", path); return binaryrule_new(first, second, path, &andops, "and"); } static bool orrule_issatisfy(Rule *rule, char *path, Dir *d); static bool orrule_contains(Rule *rule, char *path, int omode, ulong perm); static RuleOperations orops = { .free = binaryrule_free, .issatisfy = orrule_issatisfy, .contains = orrule_contains }; static bool orrule_issatisfy(Rule *rule, char *path, Dir *d) { BinaryRule *self = (BinaryRule *)rule; NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "entering orrule_issatisfy with path: %s", path); if(rule_issatisfy(self->first, path, d)) { NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_issatisfy first rule succeeded"); return true; } NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_issatisfy first rule failed"); if(rule_issatisfy(self->second, path, d)) { NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_issatisfy second rule succeeded"); return true; } NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_issatisfy second rule failed"); return false; } static bool orrule_contains(Rule *rule, char *path, int omode, ulong perm) { BinaryRule *self = (BinaryRule *)rule; NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "entering orrule_contains %s path: %s", self->name, path); if(rule_contains(self->first, path, omode, perm)) { NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_contains first rule succeeded"); return true; } NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_contains_file first rule failed"); if(rule_contains(self->second, path, omode, perm)) { NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_contains second rule succeeded"); return true; } NOISE(DEBUG_BINARYRULE || DEBUG_ORRULE, "orrule_contains second rule failed"); return false; } Rule *orrule_new(Rule *first, Rule *second, char *path) { assert_valid(first); assert_valid(second); INFO(DEBUG_BINARYRULE || DEBUG_ORRULE, "parsed || rule with path: %s", path); return binaryrule_new(first, second, path, &orops, "or"); }