Complete rewrite to support class trees. Makes the behaviour of the set
[become] / src / class.h
index 9abbe3f..6cf53a5 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: class.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
+ * $Id: class.h,v 1.3 1997/09/17 10:14:56 mdw Exp $
  *
  * Handling classes of things nicely
  *
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: class.h,v $
+ * Revision 1.3  1997/09/17 10:14:56  mdw
+ * Complete rewrite to support class trees.  Makes the behaviour of the set
+ * operators much more logical.
+ *
  * Revision 1.2  1997/08/04 10:24:21  mdw
  * Sources placed under CVS control.
  *
 /* --- Class types --- */
 
 enum {
-  clType_user = 1,                     /* Class of users */
-  clType_command = 2,                  /* Class of command strings */
-  clType_host = 4,                     /* Class of host names */
-  clType_all = 7,                      /* All of the above (maintain me) */
-  clType__limit                                /* First undefined class type */
+
+  /* --- Data types (user visible) --- *
+   *
+   * These bits encode what the user can think of as `types'.  They get used
+   * for typechecking and things.
+   */
+
+  clType_user = 0x01,                  /* Class of users */
+  clType_command = 0x02,               /* Class of command strings */
+  clType_host = 0x04,                  /* Class of host names */
+  clType_all = 0x0F,                   /* All of the above (maintain me) */
+  clType_mask = 0x0F,                  /* Mask for type flags */
+
+  /* --- Node types --- *
+   *
+   * A class actually looks suspiciously like a tree once things start
+   * getting complicated.  These bits encode the type of node we've got here.
+   */
+
+  clNode_any = 0x10,                   /* Magic type for the `all' class */
+  clNode_immed = 0x20,                 /* Immediate data item */
+  clNode_hash = 0x30,                  /* Hashtable of values */
+  clNode_union = 0x40,                 /* Union of two classes */
+  clNode_binop = 0x50,                 /* Binary operations start here */
+  clNode_diff = 0x50,                  /* Difference of two classes */
+  clNode_isect = 0x60,                 /* Intersection of two classes */
+  clNode_mask = 0xF0,                  /* Mask for picking these out */
+
+  /* --- Other useful flags --- */
+
+  clFlag_friendly = 0x100              /* Item can be hashed with others */
 };
 
 /* --- Class block --- */
 
-typedef struct classdef {
-  unsigned type;                       /* Type of this class */
+typedef struct class_node {
+  unsigned type;                       /* Class and node type, and flags */
   unsigned ref;                                /* Reference count */
-  sym_table *t;                                /* Symbol table for this class */
-} classdef;
+  union {
+    uid_t u;                           /* Immediate user id number */
+    char *s;                           /* Immediate string value */
+    sym_table t;                       /* Hash table for this class */
+    struct {
+      struct class_node *l, *r;                /* Left and right operands */
+    } c;                               /* Class operands for binops */
+  } v;                                 /* Value of this class node */
+} class_node;
 
 /*----- Global variables --------------------------------------------------*/
 
-extern classdef *class_all;            /* The match-everything class */
+extern class_node *class_all;          /* The match-everything class */
+extern class_node *class_none;         /* The match-nothing class */
 
 /*----- Functions provided ------------------------------------------------*/
 
-/* --- @class_create@ --- *
+/* --- @class_fromString@ --- *
  *
- * Arguments:  @unsigned type@ = type of the class to create
- *             @sym_table *t@ = pointer to symbol table which stores info
+ * Arguments:  @unsigned type@ = a type field
+ *             @const char *s@ = pointer to string to copy
  *
- * Returns:    Pointer to a @classdef@ which maintains the class's info.
+ * Returns:    A pointer to a class node containing that string, typed to
+ *             be the right thing.
  *
- * Use:                Creates a new class definition.  The new definition has one
- *             reference attached to it (which is the one you get returned).
+ * Use:                Given a string, wrap a class node around it.  The node has
+ *             one reference (the one you get returned).  The string is
+ *             copied, so you can get rid of your original one if you like.
  */
 
-extern classdef *class_create(unsigned /*type*/, sym_table */*t*/);
+extern class_node *class_fromString(unsigned /*type*/, const char */*s*/);
+
+/* --- @class_fromUser@ --- *
+ *
+ * Arguments:  @unsigned type@ = a type field
+ *             @uid_t u@ = a user-id number
+ *
+ * Returns:    A pointer to a class node containing the uid, typed to be
+ *             the thing you asked for.  Hopefully this will be
+ *             @clType_user@.
+ *
+ * Use:                Given a uid, wrap a class node around it.
+ */
+
+extern class_node *class_fromUser(unsigned /*type*/, uid_t /*u*/);
 
 /* --- @class_inc@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to a class block
+ * Arguments:  @class_node *c@ = pointer to a class block
  *
  * Returns:    ---
  *
  * Use:                Adds a reference to the class definition.
  */
 
-extern void class_inc(classdef */*c*/);
+extern void class_inc(class_node */*c*/);
 
 /* --- @class_dec@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to a class block
+ * Arguments:  @class_node *c@ = pointer to a class block
  *
  * Returns:    ---
  *
  * Use:                Removes a reference to a class block.
  */
 
-extern void class_dec(classdef */*c*/);
+extern void class_dec(class_node */*c*/);
+
+/* --- @class_mod@ --- *
+ *
+ * Arguments:  @class_node *c@ = pointer to a class node
+ *
+ * Returns:    A pointer to a class node, maybe the same one, maybe not,
+ *             with a reference count of 1, containing the same data.
+ *
+ * Use:                Gives you a node which you can modify.  Don't call this
+ *             for @class_all@ or @class_none@.
+ */
+
+extern class_node *class_mod(class_node */*c*/);
+
+/* --- @class_union@ --- *
+ *
+ * Arguments:  @class_node *l@ = left argument
+ *             @class_node *r@ = right argument
+ *
+ * Returns:    A class node representing the union of the two classes.
+ *
+ * Use:                Performs the union operation on classes.  If the types don't
+ *             match, then a null pointer is returned.  Both @l@ and @r@
+ *             may be modified, and will be decremented before they get
+ *             returned to you.  If you don't want that to happen, ensure
+ *             that you've claimed a reference to the original versions.
+ */
+
+extern class_node *class_union(class_node */*l*/, class_node */*r*/);
+
+/* --- @class_diff@ --- *
+ *
+ * Arguments:  @class_node *l@ = left argument
+ *             @class_node *r@ = right argument
+ *
+ * Returns:    A class node representing the difference of the two classes.
+ *
+ * Use:                Performs the set difference operation on classes.  If the
+ *             types don't match, then a null pointer is returned.  Both
+ *             @l@ and @r@ may be modified, and will be decremented before
+ *             they get returned to you.  If you don't want that to happen,
+ *             ensure that you've claimed a reference to the original
+ *             versions.
+ */
+
+extern class_node *class_diff(class_node */*l*/, class_node */*r*/);
+
+/* --- @class_isect@ --- *
+ *
+ * Arguments:  @class_node *l@ = left argument
+ *             @class_node *r@ = right argument
+ *
+ * Returns:    A class node representing the intersection of the two
+ *             classes.
+ *
+ * Use:                Performs the intersecion operation on classes.  If the types
+ *             don't match, then a null pointer is returned.  Both @l@ and
+ *             @r@ may be modified, and will be decremented before they get
+ *             returned to you.  If you don't want that to happen, ensure
+ *             that you've claimed a reference to the original versions.
+ */
+
+extern class_node *class_isect(class_node */*l*/, class_node */*r*/);
+
+/* --- @class_addUser@ --- *
+ *
+ * Arguments:  @class_node *c@ = pointer to a class node (may be null)
+ *             @uid_t u@ = user id number
+ *
+ * Returns:    Pointer to the combined node.
+ *
+ * Use:                Adds a user to a node, maybe hashifying it.
+ */
+
+extern class_node *class_addUser(class_node */*c*/, uid_t /*u*/);
+
+/* --- @class_addString@ --- *
+ *
+ * Arguments:  @class_node *c@ = pointer to a class node (may be null)
+ *             @const char *s@ = pointer to a string
+ *
+ * Returns:    Pointer to the combined node.
+ *
+ * Use:                Adds a user to a node, maybe hashifying it.
+ */
+
+extern class_node *class_addString(class_node */*c*/, const char */*s*/);
 
-/* --- @class_userMatch@ --- *
+/* --- @class_matchUser@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to a class block
- *             @int u@ = uid number to check against
+ * Arguments:  @class_node *c@ = pointer to root class node
+ *             @uid_t u@ = user id number
  *
- * Returns:    Zero if no match, nonzero if it matched.
+ * Returns:    Nonzero if it matches, zero if it doesn't.
  *
- * Use:                Looks to see if a user is in a group.
+ * Use:                Determines whether a user is matched by a class.  Assumes
+ *             that the types are correct.
  */
 
-extern int class_userMatch(classdef */*c*/, int /*u*/);
+extern int class_matchUser(class_node */*c*/, uid_t /*u*/);
 
-/* --- @class_commandMatch@ --- *
+/* --- @class_matchCommand@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to a class block
- *             @const char *p@ = pointer to command string to match
+ * Arguments:  @class_node *c@ = pointer to root class node
+ *             @const char *s@ = pointer to a string
  *
- * Returns:    Zero for no match, nonzero if it matched.
+ * Returns:    Nonzero if it matches, zero if it doesn't.
  *
- * Use:                Tries to match a string against the wildcard patterns in the
- *             given class.  Note that this involves examining all the
- *             items, so it's not too quick.  Then again, you don't have
- *             big command classes, do you...?
+ * Use:                Determines whether a string is matched by a class.  Assumes
+ *             that the types are correct.
  */
 
-extern int class_commandMatch(classdef */*c*/, const char */*p*/);
+extern int class_matchCommand(class_node */*c*/, const char */*s*/);
 
-/* --- @class_hostMatch@ --- *
+/* --- @class_matchHost@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to class block
- *             @struct in_addr addr@ = IP address to match
+ * Arguments:  @class_node *c@ = pointer to root class node
+ *             @struct in_addr a@ = IP address to match
  *
- * Returns:    Zero for no match, nonzero if it matched.
+ * Returns:    Nonzero if it matches, zero if it doesn't.
  *
- * Use:                Tries to match an IP address against the patterns and masks
- *             in the given class.
+ * Use:                Determines whether a host matches a host class.  Assumes
+ *             that the types are correct.  The actual mechanism is a bit
+ *             odd here, but I think this is the Right Thing.  At each stage
+ *             I try to match %%@/all/%% of the possible names for the host.
+ *             Thus host `splat' with address 1.2.3.4 would fail to match
+ *             the class "1.2.*" - "splat".  This seems to be what the
+ *             author intuitively expects.  It's just a bit weird.
  */
 
-extern int class_hostMatch(classdef */*c*/, struct in_addr /*addr*/);
+extern int class_matchHost(class_node */*c*/, struct in_addr /*a*/);
 
 /* --- @class_dump@ --- *
  *
- * Arguments:  @classdef *c@ = pointer to a class block
+ * Argumemnts: @class_node *c@ = pointer to root node
+ *             @int indent@ = indent depth
  *
  * Returns:    ---
  *
- * Use:                Dumps the contents of a class to a stream.
+ * Use:                Dumps a class to the trace output.
  */
 
-extern void class_dump(classdef */*c*/);
+extern void class_dump(class_node */*c*/, int /*indent*/);
 
 /*----- That's all, folks -------------------------------------------------*/