#include <u.h>
#include <libc.h>
#include <String.h>
#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");
}
|