From: James Brister Date: Fri, 22 Jun 2001 16:47:20 +0000 (+0000) Subject: OMAPI class and subclass support. X-Git-Tag: HEAD-MERGE-V3-0-3B1~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=899d754f274d2946af76590e43925325b7eb3ce3;p=thirdparty%2Fdhcp.git OMAPI class and subclass support. --- diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 2c34629e7..d7c56a259 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -572,7 +572,7 @@ struct class { OMAPI_OBJECT_PREAMBLE; struct class *nic; /* Next in collection. */ struct class *superclass; /* Set for spawned classes only. */ - const char *name; /* Not set for spawned classes. */ + char *name; /* Not set for spawned classes. */ /* A class may be configured to permit a limited number of leases. */ int lease_limit; @@ -597,8 +597,16 @@ struct class { struct group *group; + /* Statements to execute if class matches. */ struct executable_statement *statements; + +#define CLASS_DECL_DELETED 1 +#define CLASS_DECL_DYNAMIC 2 +#define CLASS_DECL_STATIC 4 +#define CLASS_DECL_SUBCLASS 8 + + int flags; }; /* DHCP client lease structure... */ @@ -1340,6 +1348,7 @@ int write_group PROTO ((struct group_object *)); struct lease *new_leases PROTO ((unsigned, const char *, int)); OMAPI_OBJECT_ALLOC_DECL (lease, struct lease, dhcp_type_lease) OMAPI_OBJECT_ALLOC_DECL (class, struct class, dhcp_type_class) +OMAPI_OBJECT_ALLOC_DECL (subclass, struct class, dhcp_type_subclass) OMAPI_OBJECT_ALLOC_DECL (pool, struct pool, dhcp_type_pool) OMAPI_OBJECT_ALLOC_DECL (host, struct host_decl, dhcp_type_host) @@ -1985,6 +1994,7 @@ void classify_client PROTO ((struct packet *)); int check_collection PROTO ((struct packet *, struct lease *, struct collection *)); void classify PROTO ((struct packet *, struct class *)); +isc_result_t unlink_class PROTO((struct class **class)); isc_result_t find_class PROTO ((struct class **, const char *, const char *, int)); int unbill_class PROTO ((struct lease *, struct class *)); @@ -2086,6 +2096,7 @@ extern int (*dhcp_interface_shutdown_hook) (struct interface_info *); extern omapi_object_type_t *dhcp_type_lease; extern omapi_object_type_t *dhcp_type_pool; extern omapi_object_type_t *dhcp_type_class; +extern omapi_object_type_t *dhcp_type_subclass; #if defined (FAILOVER_PROTOCOL) extern omapi_object_type_t *dhcp_type_failover_state; @@ -2275,6 +2286,8 @@ extern struct hash_table *lease_hw_addr_hash; extern omapi_object_type_t *dhcp_type_host; +isc_result_t enter_class PROTO ((struct class *, int, int)); +isc_result_t delete_class PROTO ((struct class *, int)); isc_result_t enter_host PROTO ((struct host_decl *, int, int)); isc_result_t delete_host PROTO ((struct host_decl *, int)); int find_hosts_by_haddr PROTO ((struct host_decl **, int, diff --git a/server/class.c b/server/class.c index 5b89bcca8..251604836 100644 --- a/server/class.c +++ b/server/class.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: class.c,v 1.29 2001/04/20 20:39:26 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: class.c,v 1.30 2001/06/22 16:47:13 brister Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ @@ -227,6 +227,29 @@ void classify (packet, class) packet -> raw -> chaddr)); } + +isc_result_t unlink_class(struct class **class) { + struct collection *lp; + struct class *cp, *pp; + + for (lp = collections; lp; lp = lp -> next) { + for (pp = 0, cp = lp -> classes; cp; pp = cp, cp = cp -> nic) + if (cp == *class) { + if (pp == 0) { + lp->classes = cp->nic; + } else { + pp->nic = cp->nic; + } + cp->nic = 0; + class_dereference(class, MDL); + + return ISC_R_SUCCESS; + } + } + return ISC_R_NOTFOUND; +} + + isc_result_t find_class (struct class **class, const char *name, const char *file, int line) { diff --git a/server/confpars.c b/server/confpars.c index 41c916c74..970a96809 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: confpars.c,v 1.143 2001/05/02 07:05:52 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: confpars.c,v 1.144 2001/06/22 16:47:14 brister Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -274,6 +274,10 @@ isc_result_t lease_file_subparse (struct parse *cfile) } else parse_warn (cfile, "possibly corrupt lease file"); + } else if (token == CLASS) { + parse_class_declaration (0, cfile, root_group, 2); + } else if (token == SUBCLASS) { + parse_class_declaration (0, cfile, root_group, 3); } else if (token == HOST) { parse_host_declaration (cfile, root_group); } else if (token == GROUP) { @@ -1677,6 +1681,8 @@ int parse_class_declaration (cp, cfile, group, type) struct expression *expr; int new = 1; isc_result_t status; + int deleted = 0; + int dynamic = 0; token = next_token (&val, (unsigned *)0, cfile); if (token != STRING) { @@ -1824,7 +1830,7 @@ int parse_class_declaration (cp, cfile, group, type) } /* Save the name, if there is one. */ - class -> name = name; + class -> name = (char *)name; } if (type == 0 || type == 1 || type == 3) @@ -1862,6 +1868,18 @@ int parse_class_declaration (cp, cfile, group, type) token = next_token (&val, (unsigned *)0, cfile); parse_warn (cfile, "unexpected end of file"); break; + } else if (token == DYNAMIC) { + dynamic = 1; + token = next_token (&val, (unsigned *)0, cfile); + if (!parse_semi (cfile)) + break; + continue; + } else if (token == TOKEN_DELETED) { + deleted = 1; + token = next_token (&val, (unsigned *)0, cfile); + if (!parse_semi (cfile)) + break; + continue; } else if (token == MATCH) { if (pc) { parse_warn (cfile, @@ -1965,7 +1983,20 @@ int parse_class_declaration (cp, cfile, group, type) declaration); } } while (1); - if (type == 2 && new) { + + if (deleted) { + struct class *theclass = 0; + + status = find_class(&theclass, class->name, MDL); + if (status == ISC_R_SUCCESS) { + delete_class(theclass, 0); + class_dereference(&theclass, MDL); + } + } else if (type == 2 && new) { + if (dynamic) { + class->flags |= CLASS_DECL_DYNAMIC; + } + if (!collections -> classes) class_reference (&collections -> classes, class, MDL); else { @@ -1976,7 +2007,7 @@ int parse_class_declaration (cp, cfile, group, type) class_reference (&c -> nic, class, MDL); } } - if (cp) + if (cp) /* should always be 0??? */ status = class_reference (cp, class, MDL); class_dereference (&class, MDL); if (pc) diff --git a/server/db.c b/server/db.c index 725034282..474031afa 100644 --- a/server/db.c +++ b/server/db.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: db.c,v 1.64 2001/05/17 19:04:04 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: db.c,v 1.65 2001/06/22 16:47:16 brister Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -565,11 +565,102 @@ int db_printable_len (s, len) return 1; } +static int print_hash_string(FILE *fp, struct class *class) +{ + int i; + int errors; + + + for (i = 0; i < class -> hash_string.len; i++) + if (!isascii (class -> hash_string.data [i]) || + !isprint (class -> hash_string.data [i])) + break; + + if (i == class -> hash_string.len) { + errno = 0; + fprintf (fp, " \"%.*s\";", + (int)class -> hash_string.len, + class -> hash_string.data); + if (errno) + ++errors; + } else { + errno = 0; + fprintf (fp, " %2.2x", class -> hash_string.data [0]); + if (errno) + ++errors; + for (i = 1; i < class -> hash_string.len; i++) { + errno = 0; + fprintf (fp, ":%2.2x", + class -> hash_string.data [i]); + if (errno) + ++errors; + } + errno = 0; + if (errno) + ++errors; + } + + return !errors; +} + + + + +/* XXXJAB this needs to return non-zero on error. */ void write_named_billing_class (const char *name, unsigned len, struct class *class) { - /* XXX billing classes that are modified by OMAPI need - XXX to be detected and written out here. */ + if (class->superclass == 0) { + fprintf(db_file, "class \"%s\" {\n", name); + } else { + fprintf(db_file, "subclass \"%s\"", class->superclass->name); + print_hash_string(db_file, class); + fprintf(db_file, " {\n"); + } + + if ((class->flags & CLASS_DECL_DELETED) != 0) { + fprintf(db_file, " deleted;\n"); + } else { + fprintf(db_file, " dynamic;\n"); + } + + + if (class->lease_limit > 0) { + fprintf(db_file, " lease limit %d;\n", class->lease_limit); + } + + if (class->expr != 0) { + fprintf(db_file, " match if "); + write_expression(db_file, class->expr, 5, 5, 0); + } + + if (class->submatch != 0) { + if (class->spawning) { + fprintf(db_file, " spawn "); + } else { + fprintf(db_file, " match "); + } + + write_expression(db_file, class->submatch, 5, 5, 0); + } + + if (class->statements != 0) { + write_statements(db_file, class->statements, 8); + } + + /* XXXJAB this isn't right, but classes read in off the leases file + don't get the root group assigned to them (due to clone_group() + call). */ + if (class->group != 0 && class->group->authoritative != 0) { + write_statements (db_file, + class -> group -> statements, 8); + } + + fprintf(db_file, "}\n\n"); + + if (class -> hash != NULL) { /* yep. recursive. god help us. */ + class_hash_foreach (class -> hash, write_named_billing_class); + } } void write_billing_classes () @@ -608,6 +699,7 @@ int write_billing_class (class) if (errno) ++errors; +#if 0 for (i = 0; i < class -> hash_string.len; i++) if (!isascii (class -> hash_string.data [i]) || !isprint (class -> hash_string.data [i])) @@ -636,6 +728,10 @@ int write_billing_class (class) if (errno) ++errors; } +#else + print_hash_string(db_file, class); + fprintf(db_file, ";"); +#endif class -> dirty = 0; return !errors; diff --git a/server/mdb.c b/server/mdb.c index 0e704814c..a0e91924a 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: mdb.c,v 1.68 2001/05/17 19:04:08 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: mdb.c,v 1.69 2001/06/22 16:47:17 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -59,6 +59,43 @@ struct hash_table *host_name_hash; omapi_object_type_t *dhcp_type_host; +isc_result_t enter_class(cd, dynamicp, commit) + struct class *cd; + int dynamicp; + int commit; +{ + if (!collections -> classes) { + class_reference (&collections -> classes, cd, MDL); + } else if (cd->name != NULL) { /* regular class */ + struct class *c = 0; + + if (find_class(&c, cd->name, MDL) != ISC_R_NOTFOUND) { + class_dereference(&c, MDL); + return ISC_R_EXISTS; + } + + for (c = collections -> classes; + c -> nic; c = c -> nic) + /* nothing */ ; + class_reference (&c -> nic, cd, MDL); + } + + if (dynamicp && commit) { + const char *name = cd->name; + + if (name == NULL) { + name = cd->superclass->name; + } + + write_named_billing_class (name, 0, cd); + if (!commit_leases ()) + return ISC_R_IOERROR; + } + + return ISC_R_SUCCESS; +} + + isc_result_t enter_host (hd, dynamicp, commit) struct host_decl *hd; int dynamicp; @@ -218,6 +255,30 @@ isc_result_t enter_host (hd, dynamicp, commit) return ISC_R_SUCCESS; } + +isc_result_t delete_class (cp, commit) + struct class *cp; + int commit; +{ + cp->flags |= CLASS_DECL_DELETED; + + /* do the write first as we won't be leaving it in any data + structures, unlike the host objects */ + + if (commit) { + write_named_billing_class (cp->name, 0, cp); + if (!commit_leases ()) + return ISC_R_IOERROR; + } + + unlink_class(&cp); /* remove from collections */ + + class_dereference(&cp, MDL); + + return ISC_R_SUCCESS; +} + + isc_result_t delete_host (hd, commit) struct host_decl *hd; int commit; @@ -1712,10 +1773,28 @@ void write_leases () struct host_decl *hp; struct group_object *gp; struct hash_bucket *hb; + struct class *cp; + struct collection *colp; int i; int num_written; struct lease **lptr [5]; + /* write all the dynamically-created class declarations. */ + if (collections->classes) { + num_written = 0; + for (colp = collections ; colp ; colp = colp->next) { + for (cp = colp->classes ; cp ; cp = cp->nic) { + write_named_billing_class(cp->name, + 0, cp); + ++num_written; + } + } + + /* XXXJAB this number doesn't include subclasses... */ + log_info ("Wrote %d class decls to leases file.", num_written); + } + + /* Write all the dynamically-created group declarations. */ if (group_name_hash) { num_written = 0; diff --git a/server/omapi.c b/server/omapi.c index 991377c1c..00ac7d718 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -50,7 +50,7 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.47 2001/05/17 19:04:09 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.48 2001/06/22 16:47:18 brister Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -1196,7 +1196,7 @@ isc_result_t dhcp_host_stuff_values (omapi_object_t *c, } isc_result_t dhcp_host_lookup (omapi_object_t **lp, - omapi_object_t *id, omapi_object_t *ref) + omapi_object_t *id, omapi_object_t *ref) { omapi_value_t *tv = (omapi_value_t *)0; isc_result_t status; @@ -1571,20 +1571,132 @@ isc_result_t dhcp_pool_remove (omapi_object_t *lp, return ISC_R_NOTIMPLEMENTED; } -isc_result_t dhcp_class_set_value (omapi_object_t *h, - omapi_object_t *id, - omapi_data_string_t *name, - omapi_typed_data_t *value) +static isc_result_t +class_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) { struct class *class; + struct class *superclass = 0; isc_result_t status; - int foo; + int issubclass = (h -> type == dhcp_type_subclass); - if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; class = (struct class *)h; - /* No values to set yet. */ + if (!omapi_ds_strcmp (name, "name")) { + char *tname; + + if (class -> name) + return ISC_R_EXISTS; + + if ((tname = dmalloc (value -> u.buffer.len+1, MDL)) == NULL) { + return ISC_R_NOMEMORY; + } + + memcpy (tname, value -> u.buffer.value, value -> u.buffer.len); + + if (issubclass) { + status = find_class(&superclass, tname, MDL); + dfree(tname, MDL); + + if (status == ISC_R_NOTFOUND) + return status; + + if (class -> superclass != 0) { + class_dereference(&class -> superclass, MDL); + } + + class_reference(&class -> superclass, + superclass, MDL); + } else if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + class -> name = dmalloc (value -> u.buffer.len+1, + MDL); + if (!class -> name) + return ISC_R_NOMEMORY; + + memcpy (class -> name, + value -> u.buffer.value, + value -> u.buffer.len); + class -> name [value -> u.buffer.len] = 0; + } else { + return ISC_R_INVALIDARG; + } + + return ISC_R_SUCCESS; + } + + + if (issubclass && !omapi_ds_strcmp(name, "hashstring")) { + if (class -> hash_string.data) + return ISC_R_EXISTS; + + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + if (!buffer_allocate (&class -> hash_string.buffer, + value -> u.buffer.len, MDL)) + return ISC_R_NOMEMORY; + class->hash_string.data = + &class->hash_string.buffer -> data[0]; + memcpy (class -> hash_string.buffer -> data, + value -> u.buffer.value, + value -> u.buffer.len); + class -> hash_string.len = value -> u.buffer.len; + } else + return ISC_R_INVALIDARG; + return ISC_R_SUCCESS; + } + + + + if (!omapi_ds_strcmp (name, "group")) { + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + struct group_object *group; + group = (struct group_object *)0; + group_hash_lookup (&group, group_name_hash, + (char *)value -> u.buffer.value, + value -> u.buffer.len, MDL); + if (!group || (group -> flags & GROUP_OBJECT_DELETED)) + return ISC_R_NOTFOUND; + if (class -> group) + group_dereference (&class -> group, MDL); + group_reference (&class -> group, group -> group, MDL); + group_object_dereference (&group, MDL); + } else + return ISC_R_INVALIDARG; + return ISC_R_SUCCESS; + } + + + if (!omapi_ds_strcmp (name, "match")) { + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + /* XXXJAB support 'match hardware' here. */ + return ISC_R_INVALIDARG; /* XXX tmp */ + } else { + return ISC_R_INVALIDARG; + } + + return ISC_R_SUCCESS; + } + + + if (!omapi_ds_strcmp (name, "option")) { + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + /* XXXJAB support 'options' here. */ + /* XXXJAB specifically 'bootfile-name' */ + return ISC_R_INVALIDARG; /* XXX tmp */ + } else { + return ISC_R_INVALIDARG; + } + + return ISC_R_SUCCESS; + } + + /* Try to find some inner object that can take the value. */ if (h -> inner && h -> inner -> type -> set_value) { @@ -1598,6 +1710,24 @@ isc_result_t dhcp_class_set_value (omapi_object_t *h, } + + +isc_result_t dhcp_class_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + struct class *class; + struct class *superclass = 0; + isc_result_t status; + int foo; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + + return class_set_value(h, id, name, value); +} + isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value) @@ -1609,7 +1739,9 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, return ISC_R_INVALIDARG; class = (struct class *)h; - /* No values to get yet. */ + if (!omapi_ds_strcmp (name, "name")) + return omapi_make_string_value (value, name, class -> name, + MDL); /* Try to find some inner object that can provide the value. */ if (h -> inner && h -> inner -> type -> get_value) { @@ -1618,6 +1750,7 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } + return ISC_R_NOTFOUND; } @@ -1630,23 +1763,68 @@ isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line) return ISC_R_INVALIDARG; class = (struct class *)h; - /* Can't destroy classs yet. */ + /* Can't destroy class yet. */ return ISC_R_SUCCESS; } -isc_result_t dhcp_class_signal_handler (omapi_object_t *h, - const char *name, va_list ap) +static isc_result_t +class_signal_handler(omapi_object_t *h, + const char *name, va_list ap) { - struct class *class; + struct class *class = (struct class *)h; isc_result_t status; int updatep = 0; + int issubclass; - if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; - class = (struct class *)h; + issubclass = (h -> type == dhcp_type_subclass); + + if (!strcmp (name, "updated")) { + + if (!issubclass) { + if (class -> name == 0 || strlen(class -> name) == 0) { + return ISC_R_INVALIDARG; + } + } else { + if (class -> superclass == 0) { + return ISC_R_INVALIDARG; /* didn't give name */ + } - /* Can't write classs yet. */ + if (class -> hash_string.data == NULL) { + return ISC_R_INVALIDARG; + } + } + + + if (issubclass) { + if (!class -> superclass -> hash) { + class -> superclass -> hash = + new_hash ((hash_reference) + omapi_object_reference, + (hash_dereference) + omapi_object_dereference, 0); + } + add_hash (class -> superclass -> hash, + class -> hash_string.data, + class -> hash_string.len, + (void *)class, MDL); + } + + +#ifdef DEBUG_OMAPI + if (issubclass) { + log_debug ("OMAPI added subclass %s", + class -> superclass -> name); + } else { + log_debug ("OMAPI added class %s", class -> name); + } +#endif + + status = enter_class (class, 1, 1); + if (status != ISC_R_SUCCESS) + return status; + updatep = 1; + } /* Try to find some inner object that can take the value. */ if (h -> inner && h -> inner -> type -> signal_handler) { @@ -1655,11 +1833,23 @@ isc_result_t dhcp_class_signal_handler (omapi_object_t *h, if (status == ISC_R_SUCCESS) return status; } + if (updatep) return ISC_R_SUCCESS; + return ISC_R_NOTFOUND; } + +isc_result_t dhcp_class_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + + return class_signal_handler(h, name, ap); +} + isc_result_t dhcp_class_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) @@ -1684,32 +1874,124 @@ isc_result_t dhcp_class_stuff_values (omapi_object_t *c, return ISC_R_SUCCESS; } -isc_result_t dhcp_class_lookup (omapi_object_t **lp, - omapi_object_t *id, omapi_object_t *ref) +isc_result_t class_lookup (omapi_object_t **lp, + omapi_object_t *id, omapi_object_t *ref, + omapi_object_type_t *typewanted) { - omapi_value_t *tv = (omapi_value_t *)0; + omapi_value_t *nv = (omapi_value_t *)0; + omapi_value_t *hv = (omapi_value_t *)0; isc_result_t status; - struct class *class; + struct class *class = 0; + struct class *subclass = 0; - /* Can't look up classs yet. */ + *lp = NULL; + + /* see if we have a name */ + status = omapi_get_value_str (ref, id, "name", &nv); + if (status == ISC_R_SUCCESS) { + char *name = dmalloc(nv -> value -> u.buffer.len + 1, MDL); + memcpy (name, + nv -> value -> u.buffer.value, + nv -> value -> u.buffer.len); - /* If we get to here without finding a class, no valid key was - specified. */ - if (!*lp) - return ISC_R_NOKEYS; - return ISC_R_SUCCESS; + omapi_value_dereference (&nv, MDL); + + find_class(&class, name, MDL); + + dfree(name, MDL); + + if (class == NULL) { + return ISC_R_NOTFOUND; + } + + if (typewanted == dhcp_type_subclass) { + status = omapi_get_value_str (ref, id, + "hashstring", &hv); + if (status != ISC_R_SUCCESS) { + class_dereference(&class, MDL); + return ISC_R_NOKEYS; + } + + if (hv -> value -> type != omapi_datatype_data && + hv -> value -> type != omapi_datatype_string) { + class_dereference(&class, MDL); + omapi_value_dereference (&hv, MDL); + return ISC_R_NOKEYS; + } + + class_hash_lookup (&subclass, class -> hash, + (const char *)hv -> value -> u.buffer.value, + hv -> value -> u.buffer.len, MDL); + + omapi_value_dereference (&hv, MDL); + + class_dereference(&class, MDL); + + if (subclass == NULL) { + return ISC_R_NOTFOUND; + } + + class_reference(&class, subclass, MDL); + class_dereference(&subclass, MDL); + } + + + /* Don't return the object if the type is wrong. */ + if (class -> type != typewanted) { + class_dereference (&class, MDL); + return ISC_R_INVALIDARG; + } + + if (class -> flags & CLASS_DECL_DELETED) { + class_dereference (&class, MDL); + } + + omapi_object_reference(lp, (omapi_object_t *)class, MDL); + + return ISC_R_SUCCESS; + } + + return ISC_R_NOKEYS; +} + + +isc_result_t dhcp_class_lookup (omapi_object_t **lp, + omapi_object_t *id, omapi_object_t *ref) +{ + return class_lookup(lp, id, ref, dhcp_type_class); } isc_result_t dhcp_class_create (omapi_object_t **lp, omapi_object_t *id) { - return ISC_R_NOTIMPLEMENTED; + struct class *cp = 0; + isc_result_t status; + + status = class_allocate(&cp, MDL); + if (status != ISC_R_SUCCESS) + return status; + + group_reference (&cp -> group, root_group, MDL); + cp -> flags = CLASS_DECL_DYNAMIC; + status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL); + class_dereference (&cp, MDL); + return status; } isc_result_t dhcp_class_remove (omapi_object_t *lp, omapi_object_t *id) { - return ISC_R_NOTIMPLEMENTED; + struct class *cp; + if (lp -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + cp = (struct class *)lp; + +#ifdef DEBUG_OMAPI + log_debug ("OMAPI delete class %s", cp -> name); +#endif + + delete_class (cp, 1); + return ISC_R_SUCCESS; } isc_result_t dhcp_subclass_set_value (omapi_object_t *h, @@ -1717,25 +1999,15 @@ isc_result_t dhcp_subclass_set_value (omapi_object_t *h, omapi_data_string_t *name, omapi_typed_data_t *value) { - struct subclass *subclass; + struct class *subclass = 0; + struct class *superclass = 0; isc_result_t status; int foo; if (h -> type != dhcp_type_subclass) return ISC_R_INVALIDARG; - subclass = (struct subclass *)h; - - /* No values to set yet. */ - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> set_value) { - status = ((*(h -> inner -> type -> set_value)) - (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) - return status; - } - - return ISC_R_NOTFOUND; + return class_set_value(h, id, name, value); } @@ -1743,14 +2015,16 @@ isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value) { - struct subclass *subclass; + struct class *subclass; isc_result_t status; - if (h -> type != dhcp_type_subclass) + if (h -> type != dhcp_type_class) return ISC_R_INVALIDARG; - subclass = (struct subclass *)h; - - /* No values to get yet. */ + subclass = (struct class *)h; + if (subclass -> name != 0) + return ISC_R_INVALIDARG; + + /* XXXJAB No values to get yet. */ /* Try to find some inner object that can provide the value. */ if (h -> inner && h -> inner -> type -> get_value) { @@ -1759,20 +2033,24 @@ isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } + return ISC_R_NOTFOUND; } isc_result_t dhcp_subclass_destroy (omapi_object_t *h, const char *file, int line) { - struct subclass *subclass; + struct class *subclass; isc_result_t status; - if (h -> type != dhcp_type_subclass) + if (h -> type != dhcp_type_class) return ISC_R_INVALIDARG; - subclass = (struct subclass *)h; + subclass = (struct class *)h; + if (subclass -> name != 0) + return ISC_R_INVALIDARG; + - /* Can't destroy subclasss yet. */ + /* XXXJAB Can't destroy subclasss yet. */ return ISC_R_SUCCESS; } @@ -1780,38 +2058,26 @@ isc_result_t dhcp_subclass_destroy (omapi_object_t *h, isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - struct subclass *subclass; - isc_result_t status; - int updatep = 0; - if (h -> type != dhcp_type_subclass) return ISC_R_INVALIDARG; - subclass = (struct subclass *)h; - /* Can't write subclasss yet. */ - - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> signal_handler) { - status = ((*(h -> inner -> type -> signal_handler)) - (h -> inner, name, ap)); - if (status == ISC_R_SUCCESS) - return status; - } - if (updatep) - return ISC_R_SUCCESS; - return ISC_R_NOTFOUND; + return class_signal_handler(h, name, ap); } + isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { - struct subclass *subclass; + struct class *subclass; isc_result_t status; - if (h -> type != dhcp_type_subclass) + if (h -> type != dhcp_type_class) return ISC_R_INVALIDARG; - subclass = (struct subclass *)h; + subclass = (struct class *)h; + if (subclass -> name != 0) + return ISC_R_INVALIDARG; + /* Can't stuff subclass values yet. */ @@ -1829,29 +2095,67 @@ isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c, isc_result_t dhcp_subclass_lookup (omapi_object_t **lp, omapi_object_t *id, omapi_object_t *ref) { - omapi_value_t *tv = (omapi_value_t *)0; - isc_result_t status; - struct subclass *subclass; + return class_lookup(lp, id, ref, dhcp_type_subclass); +} + - /* Can't look up subclasss yet. */ - /* If we get to here without finding a subclass, no valid key was - specified. */ - if (!*lp) - return ISC_R_NOKEYS; - return ISC_R_SUCCESS; -} isc_result_t dhcp_subclass_create (omapi_object_t **lp, omapi_object_t *id) { - return ISC_R_NOTIMPLEMENTED; + struct class *cp = 0; + isc_result_t status; + +/* + * XXX + * NOTE: subclasses and classes have the same internal type, which makes it + * difficult to tell them apart. Specifically, in this function we need to + * create a class object (because there is no such thing as a subclass + * object), but one field of the class object is the type (which has the + * value dhcp_type_class), and it is from here that all the other omapi + * functions are accessed. So, even though there's a whole suite of + * subclass functions registered, they won't get used. Now we could change + * the type pointer after creating the class object, but I'm not certain + * that won't break something else. + */ + + status = subclass_allocate(&cp, MDL); + if (status != ISC_R_SUCCESS) + return status; + group_reference (&cp -> group, root_group, MDL); + + cp -> flags = CLASS_DECL_DYNAMIC; + + status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL); + subclass_dereference (&cp, MDL); + return status; } isc_result_t dhcp_subclass_remove (omapi_object_t *lp, omapi_object_t *id) { - return ISC_R_NOTIMPLEMENTED; +#if 1 + + log_fatal("calling dhcp_subclass_set_value"); + /* this should never be called see dhcp_subclass_create for why */ + +#else + + struct class *cp; + if (lp -> type != dhcp_type_subclass) + return ISC_R_INVALIDARG; + cp = (struct class *)lp; + +#ifdef DEBUG_OMAPI + log_debug ("OMAPI delete subclass %s", cp -> name); +#endif + + delete_class (cp, 1); + +#endif + + return ISC_R_SUCCESS; } /* vim: set tabstop=8: */ diff --git a/server/salloc.c b/server/salloc.c index d374d3cb5..d4460bed3 100644 --- a/server/salloc.c +++ b/server/salloc.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: salloc.c,v 1.2 2001/04/27 21:30:15 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: salloc.c,v 1.3 2001/06/22 16:47:20 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -60,6 +60,7 @@ struct lease *new_leases (n, file, line) OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease) OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class) +OMAPI_OBJECT_ALLOC (subclass, struct class, dhcp_type_subclass) OMAPI_OBJECT_ALLOC (pool, struct pool, dhcp_type_pool) #if !defined (NO_HOST_FREES) /* Scary debugging mode - don't enable! */