Plan 9 from Bell Labs’s /usr/web/sources/contrib/de0u/root/sys/src/cmd/divergefs/logicalrule.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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");
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].