X-Git-Url: https://git.distorted.org.uk/~mdw/become/blobdiff_plain/9df0c75da76d81285c5fca90bb8d538c68b38119..50a87c1f8ddb1abd3b80bbc99d99f7806cc40374:/src/class.h diff --git a/src/class.h b/src/class.h index 9abbe3f..6cf53a5 100644 --- a/src/class.h +++ b/src/class.h @@ -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 * @@ -29,6 +29,10 @@ /*----- 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. * @@ -60,112 +64,254 @@ /* --- 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 -------------------------------------------------*/