/* -*-c-*-
*
- * $Id: class.h,v 1.2 1997/08/04 10:24:21 mdw Exp $
+ * $Id: class.h,v 1.5 1998/04/23 13:22:44 mdw Exp $
*
* Handling classes of things nicely
*
- * (c) 1997 EBI
+ * (c) 1998 EBI
*/
/*----- Licensing notice --------------------------------------------------*
/*----- Revision history --------------------------------------------------*
*
* $Log: class.h,v $
+ * Revision 1.5 1998/04/23 13:22:44 mdw
+ * Fix value of clNode_binop, required for bcquery.
+ *
+ * Revision 1.4 1998/01/12 16:45:53 mdw
+ * Fix copyright date.
+ *
+ * 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_binop = 0x40, /* Binary operations start here */
+ clNode_union = 0x40, /* Union of two classes */
+ 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@ = a type field
+ * @const char *s@ = pointer to string to copy
+ *
+ * Returns: A pointer to a class node containing that string, typed to
+ * be the right thing.
+ *
+ * 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 class_node *class_fromString(unsigned /*type*/, const char */*s*/);
+
+/* --- @class_fromUser@ --- *
*
- * 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
+ * @uid_t u@ = a user-id number
*
- * Returns: Pointer to a @classdef@ which maintains the class's info.
+ * 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: Creates a new class definition. The new definition has one
- * reference attached to it (which is the one you get returned).
+ * Use: Given a uid, wrap a class node around it.
*/
-extern classdef *class_create(unsigned /*type*/, sym_table */*t*/);
+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 -------------------------------------------------*/