| File: | src/usr.sbin/ldapctl/../ldapd/schema.c |
| Warning: | line 53, column 9 Null pointer passed as 1st argument to string comparison function |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: schema.c,v 1.19 2019/10/24 12:39:26 tb Exp $ */ | |||
| 2 | ||||
| 3 | /* | |||
| 4 | * Copyright (c) 2010 Martin Hedenfalk <martinh@openbsd.org> | |||
| 5 | * | |||
| 6 | * Permission to use, copy, modify, and distribute this software for any | |||
| 7 | * purpose with or without fee is hereby granted, provided that the above | |||
| 8 | * copyright notice and this permission notice appear in all copies. | |||
| 9 | * | |||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| 17 | */ | |||
| 18 | ||||
| 19 | #include <sys/types.h> | |||
| 20 | ||||
| 21 | #include <ctype.h> | |||
| 22 | #include <stdlib.h> | |||
| 23 | #include <string.h> | |||
| 24 | #include <syslog.h> | |||
| 25 | ||||
| 26 | #include "ldapd.h" | |||
| 27 | #include "log.h" | |||
| 28 | ||||
| 29 | #define ERROR-1 -1 | |||
| 30 | #define STRING1 1 | |||
| 31 | ||||
| 32 | static int | |||
| 33 | attr_oid_cmp(struct attr_type *a, struct attr_type *b) | |||
| 34 | { | |||
| 35 | return strcasecmp(a->oid, b->oid); | |||
| 36 | } | |||
| 37 | ||||
| 38 | static int | |||
| 39 | obj_oid_cmp(struct object *a, struct object *b) | |||
| 40 | { | |||
| 41 | return strcasecmp(a->oid, b->oid); | |||
| 42 | } | |||
| 43 | ||||
| 44 | static int | |||
| 45 | oidname_cmp(struct oidname *a, struct oidname *b) | |||
| 46 | { | |||
| 47 | return strcasecmp(a->on_name, b->on_name); | |||
| 48 | } | |||
| 49 | ||||
| 50 | static int | |||
| 51 | symoid_cmp(struct symoid *a, struct symoid *b) | |||
| 52 | { | |||
| 53 | return strcasecmp(a->name, b->name); | |||
| ||||
| 54 | } | |||
| 55 | ||||
| 56 | RB_GENERATE(attr_type_tree, attr_type, link, attr_oid_cmp)void attr_type_tree_RB_INSERT_COLOR(struct attr_type_tree *head , struct attr_type *elm) { struct attr_type *parent, *gparent , *tmp; while ((parent = (elm)->link.rbe_parent) && (parent)->link.rbe_color == 1) { gparent = (parent)->link .rbe_parent; if (parent == (gparent)->link.rbe_left) { tmp = (gparent)->link.rbe_right; if (tmp && (tmp)-> link.rbe_color == 1) { (tmp)->link.rbe_color = 0; do { (parent )->link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->link. rbe_right == elm) { do { (tmp) = (parent)->link.rbe_right; if (((parent)->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)-> link.rbe_parent)) { if ((parent) == ((parent)->link.rbe_parent )->link.rbe_left) ((parent)->link.rbe_parent)->link. rbe_left = (tmp); else ((parent)->link.rbe_parent)->link .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do { } while (0); } while (0); tmp = parent; parent = elm; elm = tmp ; } do { (parent)->link.rbe_color = 0; (gparent)->link. rbe_color = 1; } while (0); do { (tmp) = (gparent)->link.rbe_left ; if (((gparent)->link.rbe_left = (tmp)->link.rbe_right )) { ((tmp)->link.rbe_right)->link.rbe_parent = (gparent ); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent )->link.rbe_parent)) { if ((gparent) == ((gparent)->link .rbe_parent)->link.rbe_left) ((gparent)->link.rbe_parent )->link.rbe_left = (tmp); else ((gparent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (gparent); (gparent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->link .rbe_left; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)->link.rbe_color = 0; do { (parent)->link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); elm = gparent ; continue; } if ((parent)->link.rbe_left == elm) { do { ( tmp) = (parent)->link.rbe_left; if (((parent)->link.rbe_left = (tmp)->link.rbe_right)) { ((tmp)->link.rbe_right)-> link.rbe_parent = (parent); } do {} while (0); if (((tmp)-> link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent ) == ((parent)->link.rbe_parent)->link.rbe_left) ((parent )->link.rbe_parent)->link.rbe_left = (tmp); else ((parent )->link.rbe_parent)->link.rbe_right = (tmp); } else (head )->rbh_root = (tmp); (tmp)->link.rbe_right = (parent); ( parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp )->link.rbe_parent)) do {} while (0); } while (0); tmp = parent ; parent = elm; elm = tmp; } do { (parent)->link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); do { (tmp ) = (gparent)->link.rbe_right; if (((gparent)->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)->link.rbe_left)-> link.rbe_parent = (gparent); } do {} while (0); if (((tmp)-> link.rbe_parent = (gparent)->link.rbe_parent)) { if ((gparent ) == ((gparent)->link.rbe_parent)->link.rbe_left) ((gparent )->link.rbe_parent)->link.rbe_left = (tmp); else ((gparent )->link.rbe_parent)->link.rbe_right = (tmp); } else (head )->rbh_root = (tmp); (tmp)->link.rbe_left = (gparent); ( gparent)->link.rbe_parent = (tmp); do {} while (0); if ((( tmp)->link.rbe_parent)) do {} while (0); } while (0); } } ( head->rbh_root)->link.rbe_color = 0; } void attr_type_tree_RB_REMOVE_COLOR (struct attr_type_tree *head, struct attr_type *parent, struct attr_type *elm) { struct attr_type *tmp; while ((elm == ((void *)0) || (elm)->link.rbe_color == 0) && elm != (head )->rbh_root) { if ((parent)->link.rbe_left == elm) { tmp = (parent)->link.rbe_right; if ((tmp)->link.rbe_color == 1) { do { (tmp)->link.rbe_color = 0; (parent)->link.rbe_color = 1; } while (0); do { (tmp) = (parent)->link.rbe_right; if (((parent)->link.rbe_right = (tmp)->link.rbe_left)) { ( (tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)-> link.rbe_parent)) { if ((parent) == ((parent)->link.rbe_parent )->link.rbe_left) ((parent)->link.rbe_parent)->link. rbe_left = (tmp); else ((parent)->link.rbe_parent)->link .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do { } while (0); } while (0); tmp = (parent)->link.rbe_right; } if (((tmp)->link.rbe_left == ((void*)0) || ((tmp)->link .rbe_left)->link.rbe_color == 0) && ((tmp)->link .rbe_right == ((void*)0) || ((tmp)->link.rbe_right)->link .rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent ; parent = (elm)->link.rbe_parent; } else { if ((tmp)-> link.rbe_right == ((void*)0) || ((tmp)->link.rbe_right)-> link.rbe_color == 0) { struct attr_type *oleft; if ((oleft = ( tmp)->link.rbe_left)) (oleft)->link.rbe_color = 0; (tmp )->link.rbe_color = 1; do { (oleft) = (tmp)->link.rbe_left ; if (((tmp)->link.rbe_left = (oleft)->link.rbe_right)) { ((oleft)->link.rbe_right)->link.rbe_parent = (tmp); } do {} while (0); if (((oleft)->link.rbe_parent = (tmp)-> link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent)-> link.rbe_left) ((tmp)->link.rbe_parent)->link.rbe_left = (oleft); else ((tmp)->link.rbe_parent)->link.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)-> link.rbe_right = (tmp); (tmp)->link.rbe_parent = (oleft); do {} while (0); if (((oleft)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_right; } (tmp) ->link.rbe_color = (parent)->link.rbe_color; (parent)-> link.rbe_color = 0; if ((tmp)->link.rbe_right) ((tmp)-> link.rbe_right)->link.rbe_color = 0; do { (tmp) = (parent) ->link.rbe_right; if (((parent)->link.rbe_right = (tmp) ->link.rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->link.rbe_left; if ((tmp)->link .rbe_color == 1) { do { (tmp)->link.rbe_color = 0; (parent )->link.rbe_color = 1; } while (0); do { (tmp) = (parent)-> link.rbe_left; if (((parent)->link.rbe_left = (tmp)->link .rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } if (((tmp)->link.rbe_left == ((void*)0) || ((tmp)->link .rbe_left)->link.rbe_color == 0) && ((tmp)->link .rbe_right == ((void*)0) || ((tmp)->link.rbe_right)->link .rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent ; parent = (elm)->link.rbe_parent; } else { if ((tmp)-> link.rbe_left == ((void*)0) || ((tmp)->link.rbe_left)-> link.rbe_color == 0) { struct attr_type *oright; if ((oright = (tmp)->link.rbe_right)) (oright)->link.rbe_color = 0; ( tmp)->link.rbe_color = 1; do { (oright) = (tmp)->link.rbe_right ; if (((tmp)->link.rbe_right = (oright)->link.rbe_left) ) { ((oright)->link.rbe_left)->link.rbe_parent = (tmp); } do {} while (0); if (((oright)->link.rbe_parent = (tmp) ->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent )->link.rbe_left) ((tmp)->link.rbe_parent)->link.rbe_left = (oright); else ((tmp)->link.rbe_parent)->link.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)-> link.rbe_left = (tmp); (tmp)->link.rbe_parent = (oright); do {} while (0); if (((oright)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } (tmp)-> link.rbe_color = (parent)->link.rbe_color; (parent)->link .rbe_color = 0; if ((tmp)->link.rbe_left) ((tmp)->link. rbe_left)->link.rbe_color = 0; do { (tmp) = (parent)->link .rbe_left; if (((parent)->link.rbe_left = (tmp)->link.rbe_right )) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent ); } do {} while (0); if (((tmp)->link.rbe_parent = (parent )->link.rbe_parent)) { if ((parent) == ((parent)->link. rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent) ->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->link.rbe_color = 0; } struct attr_type * attr_type_tree_RB_REMOVE(struct attr_type_tree *head, struct attr_type *elm) { struct attr_type *child, *parent, *old = elm ; int color; if ((elm)->link.rbe_left == ((void*)0)) child = (elm)->link.rbe_right; else if ((elm)->link.rbe_right == ((void*)0)) child = (elm)->link.rbe_left; else { struct attr_type *left; elm = (elm)->link.rbe_right; while ((left = (elm)->link.rbe_left)) elm = left; child = (elm)->link .rbe_right; parent = (elm)->link.rbe_parent; color = (elm) ->link.rbe_color; if (child) (child)->link.rbe_parent = parent; if (parent) { if ((parent)->link.rbe_left == elm) (parent)->link.rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child ; if ((elm)->link.rbe_parent == old) parent = elm; (elm)-> link = (old)->link; if ((old)->link.rbe_parent) { if (( (old)->link.rbe_parent)->link.rbe_left == old) ((old)-> link.rbe_parent)->link.rbe_left = elm; else ((old)->link .rbe_parent)->link.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; ((old)->link.rbe_left)->link .rbe_parent = elm; if ((old)->link.rbe_right) ((old)->link .rbe_right)->link.rbe_parent = elm; if (parent) { left = parent ; do { do {} while (0); } while ((left = (left)->link.rbe_parent )); } goto color; } parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color; if (child) (child)->link.rbe_parent = parent; if (parent) { if ((parent)->link.rbe_left == elm ) (parent)->link.rbe_left = child; else (parent)->link. rbe_right = child; do {} while (0); } else (head)->rbh_root = child; color: if (color == 0) attr_type_tree_RB_REMOVE_COLOR (head, parent, child); return (old); } struct attr_type * attr_type_tree_RB_INSERT (struct attr_type_tree *head, struct attr_type *elm) { struct attr_type *tmp; struct attr_type *parent = ((void*)0); int comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp; comp = (attr_oid_cmp)(elm, parent); if (comp < 0) tmp = (tmp)-> link.rbe_left; else if (comp > 0) tmp = (tmp)->link.rbe_right ; else return (tmp); } do { (elm)->link.rbe_parent = parent ; (elm)->link.rbe_left = (elm)->link.rbe_right = ((void *)0); (elm)->link.rbe_color = 1; } while (0); if (parent != ((void*)0)) { if (comp < 0) (parent)->link.rbe_left = elm ; else (parent)->link.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; attr_type_tree_RB_INSERT_COLOR(head , elm); return (((void*)0)); } struct attr_type * attr_type_tree_RB_FIND (struct attr_type_tree *head, struct attr_type *elm) { struct attr_type *tmp = (head)->rbh_root; int comp; while (tmp) { comp = attr_oid_cmp(elm, tmp); if (comp < 0) tmp = (tmp)-> link.rbe_left; else if (comp > 0) tmp = (tmp)->link.rbe_right ; else return (tmp); } return (((void*)0)); } struct attr_type * attr_type_tree_RB_NFIND(struct attr_type_tree *head, struct attr_type *elm) { struct attr_type *tmp = (head)->rbh_root ; struct attr_type *res = ((void*)0); int comp; while (tmp) { comp = attr_oid_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->link.rbe_left; } else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } return (res); } struct attr_type * attr_type_tree_RB_NEXT(struct attr_type *elm) { if ((elm)->link.rbe_right) { elm = (elm)->link .rbe_right; while ((elm)->link.rbe_left) elm = (elm)->link .rbe_left; } else { if ((elm)->link.rbe_parent && ( elm == ((elm)->link.rbe_parent)->link.rbe_left)) elm = ( elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct attr_type * attr_type_tree_RB_PREV (struct attr_type *elm) { if ((elm)->link.rbe_left) { elm = (elm)->link.rbe_left; while ((elm)->link.rbe_right) elm = (elm)->link.rbe_right; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right )) elm = (elm)->link.rbe_parent; else { while ((elm)->link .rbe_parent && (elm == ((elm)->link.rbe_parent)-> link.rbe_left)) elm = (elm)->link.rbe_parent; elm = (elm)-> link.rbe_parent; } } return (elm); } struct attr_type * attr_type_tree_RB_MINMAX (struct attr_type_tree *head, int val) { struct attr_type *tmp = (head)->rbh_root; struct attr_type *parent = ((void*)0) ; while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)-> link.rbe_left; else tmp = (tmp)->link.rbe_right; } return ( parent); }; | |||
| 57 | RB_GENERATE(object_tree, object, link, obj_oid_cmp)void object_tree_RB_INSERT_COLOR(struct object_tree *head, struct object *elm) { struct object *parent, *gparent, *tmp; while ( (parent = (elm)->link.rbe_parent) && (parent)-> link.rbe_color == 1) { gparent = (parent)->link.rbe_parent ; if (parent == (gparent)->link.rbe_left) { tmp = (gparent )->link.rbe_right; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)->link.rbe_color = 0; do { (parent)->link .rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0) ; elm = gparent; continue; } if ((parent)->link.rbe_right == elm) { do { (tmp) = (parent)->link.rbe_right; if (((parent )->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); do { (tmp) = (gparent)->link.rbe_left; if (((gparent )->link.rbe_left = (tmp)->link.rbe_right)) { ((tmp)-> link.rbe_right)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent )) { if ((gparent) == ((gparent)->link.rbe_parent)->link .rbe_left) ((gparent)->link.rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link. rbe_right = (gparent); (gparent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->link.rbe_left ; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)-> link.rbe_color = 0; do { (parent)->link.rbe_color = 0; (gparent )->link.rbe_color = 1; } while (0); elm = gparent; continue ; } if ((parent)->link.rbe_left == elm) { do { (tmp) = (parent )->link.rbe_left; if (((parent)->link.rbe_left = (tmp)-> link.rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->link.rbe_color = 0; (gparent)->link .rbe_color = 1; } while (0); do { (tmp) = (gparent)->link. rbe_right; if (((gparent)->link.rbe_right = (tmp)->link .rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent)) { if ((gparent) == ((gparent )->link.rbe_parent)->link.rbe_left) ((gparent)->link .rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link .rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (gparent); (gparent)-> link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link .rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root )->link.rbe_color = 0; } void object_tree_RB_REMOVE_COLOR( struct object_tree *head, struct object *parent, struct object *elm) { struct object *tmp; while ((elm == ((void*)0) || (elm )->link.rbe_color == 0) && elm != (head)->rbh_root ) { if ((parent)->link.rbe_left == elm) { tmp = (parent)-> link.rbe_right; if ((tmp)->link.rbe_color == 1) { do { (tmp )->link.rbe_color = 0; (parent)->link.rbe_color = 1; } while (0); do { (tmp) = (parent)->link.rbe_right; if (((parent) ->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_right; } if (((tmp)->link .rbe_left == ((void*)0) || ((tmp)->link.rbe_left)->link .rbe_color == 0) && ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent; parent = (elm)-> link.rbe_parent; } else { if ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0) { struct object *oleft; if ((oleft = (tmp)->link.rbe_left)) (oleft)->link.rbe_color = 0; (tmp)->link.rbe_color = 1 ; do { (oleft) = (tmp)->link.rbe_left; if (((tmp)->link .rbe_left = (oleft)->link.rbe_right)) { ((oleft)->link. rbe_right)->link.rbe_parent = (tmp); } do {} while (0); if (((oleft)->link.rbe_parent = (tmp)->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent)->link.rbe_left) ( (tmp)->link.rbe_parent)->link.rbe_left = (oleft); else ( (tmp)->link.rbe_parent)->link.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->link.rbe_right = ( tmp); (tmp)->link.rbe_parent = (oleft); do {} while (0); if (((oleft)->link.rbe_parent)) do {} while (0); } while (0) ; tmp = (parent)->link.rbe_right; } (tmp)->link.rbe_color = (parent)->link.rbe_color; (parent)->link.rbe_color = 0; if ((tmp)->link.rbe_right) ((tmp)->link.rbe_right)-> link.rbe_color = 0; do { (tmp) = (parent)->link.rbe_right; if (((parent)->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)-> link.rbe_parent)) { if ((parent) == ((parent)->link.rbe_parent )->link.rbe_left) ((parent)->link.rbe_parent)->link. rbe_left = (tmp); else ((parent)->link.rbe_parent)->link .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do { } while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->link.rbe_left; if ((tmp)->link .rbe_color == 1) { do { (tmp)->link.rbe_color = 0; (parent )->link.rbe_color = 1; } while (0); do { (tmp) = (parent)-> link.rbe_left; if (((parent)->link.rbe_left = (tmp)->link .rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } if (((tmp)->link.rbe_left == ((void*)0) || ((tmp)->link .rbe_left)->link.rbe_color == 0) && ((tmp)->link .rbe_right == ((void*)0) || ((tmp)->link.rbe_right)->link .rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent ; parent = (elm)->link.rbe_parent; } else { if ((tmp)-> link.rbe_left == ((void*)0) || ((tmp)->link.rbe_left)-> link.rbe_color == 0) { struct object *oright; if ((oright = ( tmp)->link.rbe_right)) (oright)->link.rbe_color = 0; (tmp )->link.rbe_color = 1; do { (oright) = (tmp)->link.rbe_right ; if (((tmp)->link.rbe_right = (oright)->link.rbe_left) ) { ((oright)->link.rbe_left)->link.rbe_parent = (tmp); } do {} while (0); if (((oright)->link.rbe_parent = (tmp) ->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent )->link.rbe_left) ((tmp)->link.rbe_parent)->link.rbe_left = (oright); else ((tmp)->link.rbe_parent)->link.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)-> link.rbe_left = (tmp); (tmp)->link.rbe_parent = (oright); do {} while (0); if (((oright)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } (tmp)-> link.rbe_color = (parent)->link.rbe_color; (parent)->link .rbe_color = 0; if ((tmp)->link.rbe_left) ((tmp)->link. rbe_left)->link.rbe_color = 0; do { (tmp) = (parent)->link .rbe_left; if (((parent)->link.rbe_left = (tmp)->link.rbe_right )) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent ); } do {} while (0); if (((tmp)->link.rbe_parent = (parent )->link.rbe_parent)) { if ((parent) == ((parent)->link. rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent) ->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->link.rbe_color = 0; } struct object * object_tree_RB_REMOVE(struct object_tree *head, struct object *elm) { struct object *child, *parent, *old = elm; int color ; if ((elm)->link.rbe_left == ((void*)0)) child = (elm)-> link.rbe_right; else if ((elm)->link.rbe_right == ((void*) 0)) child = (elm)->link.rbe_left; else { struct object *left ; elm = (elm)->link.rbe_right; while ((left = (elm)->link .rbe_left)) elm = left; child = (elm)->link.rbe_right; parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; if ((elm)-> link.rbe_parent == old) parent = elm; (elm)->link = (old)-> link; if ((old)->link.rbe_parent) { if (((old)->link.rbe_parent )->link.rbe_left == old) ((old)->link.rbe_parent)->link .rbe_left = elm; else ((old)->link.rbe_parent)->link.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; (( old)->link.rbe_left)->link.rbe_parent = elm; if ((old)-> link.rbe_right) ((old)->link.rbe_right)->link.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)->link.rbe_parent)); } goto color; } parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; color: if ( color == 0) object_tree_RB_REMOVE_COLOR(head, parent, child); return (old); } struct object * object_tree_RB_INSERT(struct object_tree *head, struct object *elm) { struct object *tmp; struct object *parent = ((void*)0); int comp = 0; tmp = (head )->rbh_root; while (tmp) { parent = tmp; comp = (obj_oid_cmp )(elm, parent); if (comp < 0) tmp = (tmp)->link.rbe_left ; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } do { (elm)->link.rbe_parent = parent; (elm)-> link.rbe_left = (elm)->link.rbe_right = ((void*)0); (elm)-> link.rbe_color = 1; } while (0); if (parent != ((void*)0)) { if (comp < 0) (parent)->link.rbe_left = elm; else (parent )->link.rbe_right = elm; do {} while (0); } else (head)-> rbh_root = elm; object_tree_RB_INSERT_COLOR(head, elm); return (((void*)0)); } struct object * object_tree_RB_FIND(struct object_tree *head, struct object *elm) { struct object *tmp = (head)-> rbh_root; int comp; while (tmp) { comp = obj_oid_cmp(elm, tmp ); if (comp < 0) tmp = (tmp)->link.rbe_left; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } return (((void*)0)); } struct object * object_tree_RB_NFIND( struct object_tree *head, struct object *elm) { struct object *tmp = (head)->rbh_root; struct object *res = ((void*)0); int comp; while (tmp) { comp = obj_oid_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->link.rbe_left; } else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp ); } return (res); } struct object * object_tree_RB_NEXT(struct object *elm) { if ((elm)->link.rbe_right) { elm = (elm)-> link.rbe_right; while ((elm)->link.rbe_left) elm = (elm)-> link.rbe_left; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct object * object_tree_RB_PREV(struct object *elm) { if ((elm)->link.rbe_left) { elm = (elm)-> link.rbe_left; while ((elm)->link.rbe_right) elm = (elm)-> link.rbe_right; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct object * object_tree_RB_MINMAX(struct object_tree *head, int val) { struct object *tmp = (head)-> rbh_root; struct object *parent = ((void*)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->link.rbe_left; else tmp = (tmp)->link.rbe_right; } return (parent); }; | |||
| 58 | RB_GENERATE(oidname_tree, oidname, link, oidname_cmp)void oidname_tree_RB_INSERT_COLOR(struct oidname_tree *head, struct oidname *elm) { struct oidname *parent, *gparent, *tmp; while ((parent = (elm)->link.rbe_parent) && (parent)-> link.rbe_color == 1) { gparent = (parent)->link.rbe_parent ; if (parent == (gparent)->link.rbe_left) { tmp = (gparent )->link.rbe_right; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)->link.rbe_color = 0; do { (parent)->link .rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0) ; elm = gparent; continue; } if ((parent)->link.rbe_right == elm) { do { (tmp) = (parent)->link.rbe_right; if (((parent )->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); do { (tmp) = (gparent)->link.rbe_left; if (((gparent )->link.rbe_left = (tmp)->link.rbe_right)) { ((tmp)-> link.rbe_right)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent )) { if ((gparent) == ((gparent)->link.rbe_parent)->link .rbe_left) ((gparent)->link.rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link. rbe_right = (gparent); (gparent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->link.rbe_left ; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)-> link.rbe_color = 0; do { (parent)->link.rbe_color = 0; (gparent )->link.rbe_color = 1; } while (0); elm = gparent; continue ; } if ((parent)->link.rbe_left == elm) { do { (tmp) = (parent )->link.rbe_left; if (((parent)->link.rbe_left = (tmp)-> link.rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->link.rbe_color = 0; (gparent)->link .rbe_color = 1; } while (0); do { (tmp) = (gparent)->link. rbe_right; if (((gparent)->link.rbe_right = (tmp)->link .rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent)) { if ((gparent) == ((gparent )->link.rbe_parent)->link.rbe_left) ((gparent)->link .rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link .rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (gparent); (gparent)-> link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link .rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root )->link.rbe_color = 0; } void oidname_tree_RB_REMOVE_COLOR (struct oidname_tree *head, struct oidname *parent, struct oidname *elm) { struct oidname *tmp; while ((elm == ((void*)0) || (elm )->link.rbe_color == 0) && elm != (head)->rbh_root ) { if ((parent)->link.rbe_left == elm) { tmp = (parent)-> link.rbe_right; if ((tmp)->link.rbe_color == 1) { do { (tmp )->link.rbe_color = 0; (parent)->link.rbe_color = 1; } while (0); do { (tmp) = (parent)->link.rbe_right; if (((parent) ->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_right; } if (((tmp)->link .rbe_left == ((void*)0) || ((tmp)->link.rbe_left)->link .rbe_color == 0) && ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent; parent = (elm)-> link.rbe_parent; } else { if ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0) { struct oidname *oleft; if ((oleft = (tmp)->link.rbe_left) ) (oleft)->link.rbe_color = 0; (tmp)->link.rbe_color = 1 ; do { (oleft) = (tmp)->link.rbe_left; if (((tmp)->link .rbe_left = (oleft)->link.rbe_right)) { ((oleft)->link. rbe_right)->link.rbe_parent = (tmp); } do {} while (0); if (((oleft)->link.rbe_parent = (tmp)->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent)->link.rbe_left) ( (tmp)->link.rbe_parent)->link.rbe_left = (oleft); else ( (tmp)->link.rbe_parent)->link.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->link.rbe_right = ( tmp); (tmp)->link.rbe_parent = (oleft); do {} while (0); if (((oleft)->link.rbe_parent)) do {} while (0); } while (0) ; tmp = (parent)->link.rbe_right; } (tmp)->link.rbe_color = (parent)->link.rbe_color; (parent)->link.rbe_color = 0; if ((tmp)->link.rbe_right) ((tmp)->link.rbe_right)-> link.rbe_color = 0; do { (tmp) = (parent)->link.rbe_right; if (((parent)->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)-> link.rbe_parent)) { if ((parent) == ((parent)->link.rbe_parent )->link.rbe_left) ((parent)->link.rbe_parent)->link. rbe_left = (tmp); else ((parent)->link.rbe_parent)->link .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do { } while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->link.rbe_left; if ((tmp)->link .rbe_color == 1) { do { (tmp)->link.rbe_color = 0; (parent )->link.rbe_color = 1; } while (0); do { (tmp) = (parent)-> link.rbe_left; if (((parent)->link.rbe_left = (tmp)->link .rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } if (((tmp)->link.rbe_left == ((void*)0) || ((tmp)->link .rbe_left)->link.rbe_color == 0) && ((tmp)->link .rbe_right == ((void*)0) || ((tmp)->link.rbe_right)->link .rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent ; parent = (elm)->link.rbe_parent; } else { if ((tmp)-> link.rbe_left == ((void*)0) || ((tmp)->link.rbe_left)-> link.rbe_color == 0) { struct oidname *oright; if ((oright = ( tmp)->link.rbe_right)) (oright)->link.rbe_color = 0; (tmp )->link.rbe_color = 1; do { (oright) = (tmp)->link.rbe_right ; if (((tmp)->link.rbe_right = (oright)->link.rbe_left) ) { ((oright)->link.rbe_left)->link.rbe_parent = (tmp); } do {} while (0); if (((oright)->link.rbe_parent = (tmp) ->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent )->link.rbe_left) ((tmp)->link.rbe_parent)->link.rbe_left = (oright); else ((tmp)->link.rbe_parent)->link.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)-> link.rbe_left = (tmp); (tmp)->link.rbe_parent = (oright); do {} while (0); if (((oright)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } (tmp)-> link.rbe_color = (parent)->link.rbe_color; (parent)->link .rbe_color = 0; if ((tmp)->link.rbe_left) ((tmp)->link. rbe_left)->link.rbe_color = 0; do { (tmp) = (parent)->link .rbe_left; if (((parent)->link.rbe_left = (tmp)->link.rbe_right )) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent ); } do {} while (0); if (((tmp)->link.rbe_parent = (parent )->link.rbe_parent)) { if ((parent) == ((parent)->link. rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent) ->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->link.rbe_color = 0; } struct oidname * oidname_tree_RB_REMOVE(struct oidname_tree *head, struct oidname *elm) { struct oidname *child, *parent, *old = elm; int color ; if ((elm)->link.rbe_left == ((void*)0)) child = (elm)-> link.rbe_right; else if ((elm)->link.rbe_right == ((void*) 0)) child = (elm)->link.rbe_left; else { struct oidname *left ; elm = (elm)->link.rbe_right; while ((left = (elm)->link .rbe_left)) elm = left; child = (elm)->link.rbe_right; parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; if ((elm)-> link.rbe_parent == old) parent = elm; (elm)->link = (old)-> link; if ((old)->link.rbe_parent) { if (((old)->link.rbe_parent )->link.rbe_left == old) ((old)->link.rbe_parent)->link .rbe_left = elm; else ((old)->link.rbe_parent)->link.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; (( old)->link.rbe_left)->link.rbe_parent = elm; if ((old)-> link.rbe_right) ((old)->link.rbe_right)->link.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)->link.rbe_parent)); } goto color; } parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; color: if ( color == 0) oidname_tree_RB_REMOVE_COLOR(head, parent, child) ; return (old); } struct oidname * oidname_tree_RB_INSERT(struct oidname_tree *head, struct oidname *elm) { struct oidname *tmp ; struct oidname *parent = ((void*)0); int comp = 0; tmp = (head )->rbh_root; while (tmp) { parent = tmp; comp = (oidname_cmp )(elm, parent); if (comp < 0) tmp = (tmp)->link.rbe_left ; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } do { (elm)->link.rbe_parent = parent; (elm)-> link.rbe_left = (elm)->link.rbe_right = ((void*)0); (elm)-> link.rbe_color = 1; } while (0); if (parent != ((void*)0)) { if (comp < 0) (parent)->link.rbe_left = elm; else (parent )->link.rbe_right = elm; do {} while (0); } else (head)-> rbh_root = elm; oidname_tree_RB_INSERT_COLOR(head, elm); return (((void*)0)); } struct oidname * oidname_tree_RB_FIND(struct oidname_tree *head, struct oidname *elm) { struct oidname *tmp = (head)->rbh_root; int comp; while (tmp) { comp = oidname_cmp (elm, tmp); if (comp < 0) tmp = (tmp)->link.rbe_left; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } return (((void*)0)); } struct oidname * oidname_tree_RB_NFIND (struct oidname_tree *head, struct oidname *elm) { struct oidname *tmp = (head)->rbh_root; struct oidname *res = ((void*)0) ; int comp; while (tmp) { comp = oidname_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->link.rbe_left; } else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp ); } return (res); } struct oidname * oidname_tree_RB_NEXT(struct oidname *elm) { if ((elm)->link.rbe_right) { elm = (elm)-> link.rbe_right; while ((elm)->link.rbe_left) elm = (elm)-> link.rbe_left; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct oidname * oidname_tree_RB_PREV(struct oidname *elm) { if ((elm)->link.rbe_left) { elm = (elm)-> link.rbe_left; while ((elm)->link.rbe_right) elm = (elm)-> link.rbe_right; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct oidname * oidname_tree_RB_MINMAX (struct oidname_tree *head, int val) { struct oidname *tmp = ( head)->rbh_root; struct oidname *parent = ((void*)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->link.rbe_left ; else tmp = (tmp)->link.rbe_right; } return (parent); }; | |||
| 59 | RB_GENERATE(symoid_tree, symoid, link, symoid_cmp)void symoid_tree_RB_INSERT_COLOR(struct symoid_tree *head, struct symoid *elm) { struct symoid *parent, *gparent, *tmp; while ( (parent = (elm)->link.rbe_parent) && (parent)-> link.rbe_color == 1) { gparent = (parent)->link.rbe_parent ; if (parent == (gparent)->link.rbe_left) { tmp = (gparent )->link.rbe_right; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)->link.rbe_color = 0; do { (parent)->link .rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0) ; elm = gparent; continue; } if ((parent)->link.rbe_right == elm) { do { (tmp) = (parent)->link.rbe_right; if (((parent )->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> link.rbe_color = 0; (gparent)->link.rbe_color = 1; } while (0); do { (tmp) = (gparent)->link.rbe_left; if (((gparent )->link.rbe_left = (tmp)->link.rbe_right)) { ((tmp)-> link.rbe_right)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent )) { if ((gparent) == ((gparent)->link.rbe_parent)->link .rbe_left) ((gparent)->link.rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link. rbe_right = (gparent); (gparent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->link.rbe_left ; if (tmp && (tmp)->link.rbe_color == 1) { (tmp)-> link.rbe_color = 0; do { (parent)->link.rbe_color = 0; (gparent )->link.rbe_color = 1; } while (0); elm = gparent; continue ; } if ((parent)->link.rbe_left == elm) { do { (tmp) = (parent )->link.rbe_left; if (((parent)->link.rbe_left = (tmp)-> link.rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->link.rbe_color = 0; (gparent)->link .rbe_color = 1; } while (0); do { (tmp) = (gparent)->link. rbe_right; if (((gparent)->link.rbe_right = (tmp)->link .rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (gparent); } do {} while (0); if (((tmp)->link.rbe_parent = (gparent)->link.rbe_parent)) { if ((gparent) == ((gparent )->link.rbe_parent)->link.rbe_left) ((gparent)->link .rbe_parent)->link.rbe_left = (tmp); else ((gparent)->link .rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (gparent); (gparent)-> link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link .rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root )->link.rbe_color = 0; } void symoid_tree_RB_REMOVE_COLOR( struct symoid_tree *head, struct symoid *parent, struct symoid *elm) { struct symoid *tmp; while ((elm == ((void*)0) || (elm )->link.rbe_color == 0) && elm != (head)->rbh_root ) { if ((parent)->link.rbe_left == elm) { tmp = (parent)-> link.rbe_right; if ((tmp)->link.rbe_color == 1) { do { (tmp )->link.rbe_color = 0; (parent)->link.rbe_color = 1; } while (0); do { (tmp) = (parent)->link.rbe_right; if (((parent) ->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)-> link.rbe_left)->link.rbe_parent = (parent); } do {} while ( 0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent )) { if ((parent) == ((parent)->link.rbe_parent)->link. rbe_left) ((parent)->link.rbe_parent)->link.rbe_left = ( tmp); else ((parent)->link.rbe_parent)->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_right; } if (((tmp)->link .rbe_left == ((void*)0) || ((tmp)->link.rbe_left)->link .rbe_color == 0) && ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent; parent = (elm)-> link.rbe_parent; } else { if ((tmp)->link.rbe_right == ((void *)0) || ((tmp)->link.rbe_right)->link.rbe_color == 0) { struct symoid *oleft; if ((oleft = (tmp)->link.rbe_left)) (oleft)->link.rbe_color = 0; (tmp)->link.rbe_color = 1 ; do { (oleft) = (tmp)->link.rbe_left; if (((tmp)->link .rbe_left = (oleft)->link.rbe_right)) { ((oleft)->link. rbe_right)->link.rbe_parent = (tmp); } do {} while (0); if (((oleft)->link.rbe_parent = (tmp)->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent)->link.rbe_left) ( (tmp)->link.rbe_parent)->link.rbe_left = (oleft); else ( (tmp)->link.rbe_parent)->link.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->link.rbe_right = ( tmp); (tmp)->link.rbe_parent = (oleft); do {} while (0); if (((oleft)->link.rbe_parent)) do {} while (0); } while (0) ; tmp = (parent)->link.rbe_right; } (tmp)->link.rbe_color = (parent)->link.rbe_color; (parent)->link.rbe_color = 0; if ((tmp)->link.rbe_right) ((tmp)->link.rbe_right)-> link.rbe_color = 0; do { (tmp) = (parent)->link.rbe_right; if (((parent)->link.rbe_right = (tmp)->link.rbe_left)) { ((tmp)->link.rbe_left)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)-> link.rbe_parent)) { if ((parent) == ((parent)->link.rbe_parent )->link.rbe_left) ((parent)->link.rbe_parent)->link. rbe_left = (tmp); else ((parent)->link.rbe_parent)->link .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->link.rbe_left = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do { } while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->link.rbe_left; if ((tmp)->link .rbe_color == 1) { do { (tmp)->link.rbe_color = 0; (parent )->link.rbe_color = 1; } while (0); do { (tmp) = (parent)-> link.rbe_left; if (((parent)->link.rbe_left = (tmp)->link .rbe_right)) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent); } do {} while (0); if (((tmp)->link.rbe_parent = (parent)->link.rbe_parent)) { if ((parent) == ((parent) ->link.rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent )->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } if (((tmp)->link.rbe_left == ((void*)0) || ((tmp)->link .rbe_left)->link.rbe_color == 0) && ((tmp)->link .rbe_right == ((void*)0) || ((tmp)->link.rbe_right)->link .rbe_color == 0)) { (tmp)->link.rbe_color = 1; elm = parent ; parent = (elm)->link.rbe_parent; } else { if ((tmp)-> link.rbe_left == ((void*)0) || ((tmp)->link.rbe_left)-> link.rbe_color == 0) { struct symoid *oright; if ((oright = ( tmp)->link.rbe_right)) (oright)->link.rbe_color = 0; (tmp )->link.rbe_color = 1; do { (oright) = (tmp)->link.rbe_right ; if (((tmp)->link.rbe_right = (oright)->link.rbe_left) ) { ((oright)->link.rbe_left)->link.rbe_parent = (tmp); } do {} while (0); if (((oright)->link.rbe_parent = (tmp) ->link.rbe_parent)) { if ((tmp) == ((tmp)->link.rbe_parent )->link.rbe_left) ((tmp)->link.rbe_parent)->link.rbe_left = (oright); else ((tmp)->link.rbe_parent)->link.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)-> link.rbe_left = (tmp); (tmp)->link.rbe_parent = (oright); do {} while (0); if (((oright)->link.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->link.rbe_left; } (tmp)-> link.rbe_color = (parent)->link.rbe_color; (parent)->link .rbe_color = 0; if ((tmp)->link.rbe_left) ((tmp)->link. rbe_left)->link.rbe_color = 0; do { (tmp) = (parent)->link .rbe_left; if (((parent)->link.rbe_left = (tmp)->link.rbe_right )) { ((tmp)->link.rbe_right)->link.rbe_parent = (parent ); } do {} while (0); if (((tmp)->link.rbe_parent = (parent )->link.rbe_parent)) { if ((parent) == ((parent)->link. rbe_parent)->link.rbe_left) ((parent)->link.rbe_parent) ->link.rbe_left = (tmp); else ((parent)->link.rbe_parent )->link.rbe_right = (tmp); } else (head)->rbh_root = (tmp ); (tmp)->link.rbe_right = (parent); (parent)->link.rbe_parent = (tmp); do {} while (0); if (((tmp)->link.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->link.rbe_color = 0; } struct symoid * symoid_tree_RB_REMOVE(struct symoid_tree *head, struct symoid *elm) { struct symoid *child, *parent, *old = elm; int color ; if ((elm)->link.rbe_left == ((void*)0)) child = (elm)-> link.rbe_right; else if ((elm)->link.rbe_right == ((void*) 0)) child = (elm)->link.rbe_left; else { struct symoid *left ; elm = (elm)->link.rbe_right; while ((left = (elm)->link .rbe_left)) elm = left; child = (elm)->link.rbe_right; parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; if ((elm)-> link.rbe_parent == old) parent = elm; (elm)->link = (old)-> link; if ((old)->link.rbe_parent) { if (((old)->link.rbe_parent )->link.rbe_left == old) ((old)->link.rbe_parent)->link .rbe_left = elm; else ((old)->link.rbe_parent)->link.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; (( old)->link.rbe_left)->link.rbe_parent = elm; if ((old)-> link.rbe_right) ((old)->link.rbe_right)->link.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)->link.rbe_parent)); } goto color; } parent = (elm)->link.rbe_parent; color = (elm)->link.rbe_color ; if (child) (child)->link.rbe_parent = parent; if (parent ) { if ((parent)->link.rbe_left == elm) (parent)->link. rbe_left = child; else (parent)->link.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; color: if ( color == 0) symoid_tree_RB_REMOVE_COLOR(head, parent, child); return (old); } struct symoid * symoid_tree_RB_INSERT(struct symoid_tree *head, struct symoid *elm) { struct symoid *tmp; struct symoid *parent = ((void*)0); int comp = 0; tmp = (head )->rbh_root; while (tmp) { parent = tmp; comp = (symoid_cmp )(elm, parent); if (comp < 0) tmp = (tmp)->link.rbe_left ; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } do { (elm)->link.rbe_parent = parent; (elm)-> link.rbe_left = (elm)->link.rbe_right = ((void*)0); (elm)-> link.rbe_color = 1; } while (0); if (parent != ((void*)0)) { if (comp < 0) (parent)->link.rbe_left = elm; else (parent )->link.rbe_right = elm; do {} while (0); } else (head)-> rbh_root = elm; symoid_tree_RB_INSERT_COLOR(head, elm); return (((void*)0)); } struct symoid * symoid_tree_RB_FIND(struct symoid_tree *head, struct symoid *elm) { struct symoid *tmp = (head)-> rbh_root; int comp; while (tmp) { comp = symoid_cmp(elm, tmp) ; if (comp < 0) tmp = (tmp)->link.rbe_left; else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp); } return (((void*)0)); } struct symoid * symoid_tree_RB_NFIND( struct symoid_tree *head, struct symoid *elm) { struct symoid *tmp = (head)->rbh_root; struct symoid *res = ((void*)0); int comp; while (tmp) { comp = symoid_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->link.rbe_left; } else if (comp > 0) tmp = (tmp)->link.rbe_right; else return (tmp ); } return (res); } struct symoid * symoid_tree_RB_NEXT(struct symoid *elm) { if ((elm)->link.rbe_right) { elm = (elm)-> link.rbe_right; while ((elm)->link.rbe_left) elm = (elm)-> link.rbe_left; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct symoid * symoid_tree_RB_PREV(struct symoid *elm) { if ((elm)->link.rbe_left) { elm = (elm)-> link.rbe_left; while ((elm)->link.rbe_right) elm = (elm)-> link.rbe_right; } else { if ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_right)) elm = (elm)->link.rbe_parent; else { while ((elm)->link.rbe_parent && (elm == ((elm)->link.rbe_parent)->link.rbe_left )) elm = (elm)->link.rbe_parent; elm = (elm)->link.rbe_parent ; } } return (elm); } struct symoid * symoid_tree_RB_MINMAX(struct symoid_tree *head, int val) { struct symoid *tmp = (head)-> rbh_root; struct symoid *parent = ((void*)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->link.rbe_left; else tmp = (tmp)->link.rbe_right; } return (parent); }; | |||
| 60 | ||||
| 61 | static struct attr_list *push_attr(struct attr_list *alist, struct attr_type *a); | |||
| 62 | static struct obj_list *push_obj(struct obj_list *olist, struct object *obj); | |||
| 63 | static struct name_list *push_name(struct name_list *nl, char *name); | |||
| 64 | int is_oidstr(const char *oidstr); | |||
| 65 | ||||
| 66 | struct attr_type * | |||
| 67 | lookup_attribute_by_name(struct schema *schema, char *name) | |||
| 68 | { | |||
| 69 | struct oidname *on, find; | |||
| 70 | ||||
| 71 | find.on_name = name; | |||
| 72 | on = RB_FIND(oidname_tree, &schema->attr_names, &find)oidname_tree_RB_FIND(&schema->attr_names, &find); | |||
| 73 | ||||
| 74 | if (on) | |||
| 75 | return on->on_attr_typeon_ptr.ou_attr_type; | |||
| 76 | return NULL((void*)0); | |||
| 77 | } | |||
| 78 | ||||
| 79 | struct attr_type * | |||
| 80 | lookup_attribute_by_oid(struct schema *schema, char *oid) | |||
| 81 | { | |||
| 82 | struct attr_type find; | |||
| 83 | ||||
| 84 | find.oid = oid; | |||
| 85 | return RB_FIND(attr_type_tree, &schema->attr_types, &find)attr_type_tree_RB_FIND(&schema->attr_types, &find); | |||
| 86 | } | |||
| 87 | ||||
| 88 | struct attr_type * | |||
| 89 | lookup_attribute(struct schema *schema, char *oid_or_name) | |||
| 90 | { | |||
| 91 | if (is_oidstr(oid_or_name)) | |||
| 92 | return lookup_attribute_by_oid(schema, oid_or_name); | |||
| 93 | return lookup_attribute_by_name(schema, oid_or_name); | |||
| 94 | } | |||
| 95 | ||||
| 96 | struct object * | |||
| 97 | lookup_object_by_oid(struct schema *schema, char *oid) | |||
| 98 | { | |||
| 99 | struct object find; | |||
| 100 | ||||
| 101 | find.oid = oid; | |||
| 102 | return RB_FIND(object_tree, &schema->objects, &find)object_tree_RB_FIND(&schema->objects, &find); | |||
| 103 | } | |||
| 104 | ||||
| 105 | struct object * | |||
| 106 | lookup_object_by_name(struct schema *schema, char *name) | |||
| 107 | { | |||
| 108 | struct oidname *on, find; | |||
| 109 | ||||
| 110 | find.on_name = name; | |||
| 111 | on = RB_FIND(oidname_tree, &schema->object_names, &find)oidname_tree_RB_FIND(&schema->object_names, &find); | |||
| 112 | ||||
| 113 | if (on) | |||
| 114 | return on->on_objecton_ptr.ou_object; | |||
| 115 | return NULL((void*)0); | |||
| 116 | } | |||
| 117 | ||||
| 118 | struct object * | |||
| 119 | lookup_object(struct schema *schema, char *oid_or_name) | |||
| 120 | { | |||
| 121 | if (is_oidstr(oid_or_name)) | |||
| 122 | return lookup_object_by_oid(schema, oid_or_name); | |||
| 123 | return lookup_object_by_name(schema, oid_or_name); | |||
| 124 | } | |||
| 125 | ||||
| 126 | /* | |||
| 127 | * Looks up a symbolic OID, optionally with a suffix OID, so if | |||
| 128 | * SYMBOL = 1.2.3.4 | |||
| 129 | * then | |||
| 130 | * SYMBOL:5.6 = 1.2.3.4.5.6 | |||
| 131 | * | |||
| 132 | * Returned string must be freed by the caller. | |||
| 133 | * Modifies the name argument. | |||
| 134 | */ | |||
| 135 | char * | |||
| 136 | lookup_symbolic_oid(struct schema *schema, char *name) | |||
| 137 | { | |||
| 138 | struct symoid *symoid, find; | |||
| 139 | char *colon, *oid; | |||
| 140 | size_t sz; | |||
| 141 | ||||
| 142 | colon = strchr(name, ':'); | |||
| 143 | if (colon != NULL((void*)0)) { | |||
| 144 | if (!is_oidstr(colon + 1)) { | |||
| 145 | log_warnx("invalid OID after colon: %s", colon + 1); | |||
| 146 | return NULL((void*)0); | |||
| 147 | } | |||
| 148 | *colon = '\0'; | |||
| 149 | } | |||
| 150 | ||||
| 151 | find.name = name; | |||
| 152 | symoid = RB_FIND(symoid_tree, &schema->symbolic_oids, &find)symoid_tree_RB_FIND(&schema->symbolic_oids, &find); | |||
| 153 | if (symoid == NULL((void*)0)) | |||
| 154 | return NULL((void*)0); | |||
| 155 | ||||
| 156 | if (colon == NULL((void*)0)) | |||
| 157 | return strdup(symoid->oid); | |||
| 158 | ||||
| 159 | /* Expand SYMBOL:OID. */ | |||
| 160 | sz = strlen(symoid->oid) + 1 + strlen(colon + 1) + 1; | |||
| 161 | if ((oid = malloc(sz)) == NULL((void*)0)) { | |||
| 162 | log_warnx("malloc"); | |||
| 163 | return NULL((void*)0); | |||
| 164 | } | |||
| 165 | ||||
| 166 | strlcpy(oid, symoid->oid, sz); | |||
| 167 | strlcat(oid, ".", sz); | |||
| 168 | strlcat(oid, colon + 1, sz); | |||
| 169 | ||||
| 170 | return oid; | |||
| 171 | } | |||
| 172 | ||||
| 173 | /* | |||
| 174 | * Push a symbol-OID pair on the tree. Name and OID must be valid pointers | |||
| 175 | * during the lifetime of the tree. | |||
| 176 | */ | |||
| 177 | static struct symoid * | |||
| 178 | push_symbolic_oid(struct schema *schema, char *name, char *oid) | |||
| 179 | { | |||
| 180 | struct symoid *symoid, find; | |||
| 181 | ||||
| 182 | find.name = name; | |||
| 183 | symoid = RB_FIND(symoid_tree, &schema->symbolic_oids, &find)symoid_tree_RB_FIND(&schema->symbolic_oids, &find); | |||
| 184 | ||||
| 185 | if (symoid == NULL((void*)0)) { | |||
| 186 | symoid = calloc(1, sizeof(*symoid)); | |||
| 187 | if (symoid == NULL((void*)0)) { | |||
| 188 | log_warnx("calloc"); | |||
| 189 | return NULL((void*)0); | |||
| 190 | } | |||
| 191 | ||||
| 192 | symoid->name = name; | |||
| 193 | RB_INSERT(symoid_tree, &schema->symbolic_oids, symoid)symoid_tree_RB_INSERT(&schema->symbolic_oids, symoid); | |||
| 194 | } | |||
| 195 | ||||
| 196 | free(symoid->oid); | |||
| 197 | symoid->oid = oid; | |||
| 198 | ||||
| 199 | return symoid; | |||
| 200 | } | |||
| 201 | ||||
| 202 | static struct attr_list * | |||
| 203 | push_attr(struct attr_list *alist, struct attr_type *a) | |||
| 204 | { | |||
| 205 | struct attr_ptr *aptr; | |||
| 206 | ||||
| 207 | if (alist == NULL((void*)0)) { | |||
| 208 | if ((alist = calloc(1, sizeof(*alist))) == NULL((void*)0)) { | |||
| 209 | log_warn("calloc"); | |||
| 210 | return NULL((void*)0); | |||
| 211 | } | |||
| 212 | SLIST_INIT(alist){ ((alist)->slh_first) = ((void*)0); }; | |||
| 213 | } | |||
| 214 | ||||
| 215 | if ((aptr = calloc(1, sizeof(*aptr))) == NULL((void*)0)) { | |||
| 216 | log_warn("calloc"); | |||
| 217 | free(alist); | |||
| 218 | return NULL((void*)0); | |||
| 219 | } | |||
| 220 | aptr->attr_type = a; | |||
| 221 | SLIST_INSERT_HEAD(alist, aptr, next)do { (aptr)->next.sle_next = (alist)->slh_first; (alist )->slh_first = (aptr); } while (0); | |||
| 222 | ||||
| 223 | return alist; | |||
| 224 | } | |||
| 225 | ||||
| 226 | static struct obj_list * | |||
| 227 | push_obj(struct obj_list *olist, struct object *obj) | |||
| 228 | { | |||
| 229 | struct obj_ptr *optr; | |||
| 230 | ||||
| 231 | if (olist == NULL((void*)0)) { | |||
| 232 | if ((olist = calloc(1, sizeof(*olist))) == NULL((void*)0)) { | |||
| 233 | log_warn("calloc"); | |||
| 234 | return NULL((void*)0); | |||
| 235 | } | |||
| 236 | SLIST_INIT(olist){ ((olist)->slh_first) = ((void*)0); }; | |||
| 237 | } | |||
| 238 | ||||
| 239 | if ((optr = calloc(1, sizeof(*optr))) == NULL((void*)0)) { | |||
| 240 | log_warn("calloc"); | |||
| 241 | free(olist); | |||
| 242 | return NULL((void*)0); | |||
| 243 | } | |||
| 244 | optr->object = obj; | |||
| 245 | SLIST_INSERT_HEAD(olist, optr, next)do { (optr)->next.sle_next = (olist)->slh_first; (olist )->slh_first = (optr); } while (0); | |||
| 246 | ||||
| 247 | return olist; | |||
| 248 | } | |||
| 249 | ||||
| 250 | int | |||
| 251 | is_oidstr(const char *oidstr) | |||
| 252 | { | |||
| 253 | struct ber_oid oid; | |||
| 254 | return (ober_string2oid(oidstr, &oid) == 0); | |||
| 255 | } | |||
| 256 | ||||
| 257 | static struct name_list * | |||
| 258 | push_name(struct name_list *nl, char *name) | |||
| 259 | { | |||
| 260 | struct name *n; | |||
| 261 | ||||
| 262 | if (nl == NULL((void*)0)) { | |||
| 263 | if ((nl = calloc(1, sizeof(*nl))) == NULL((void*)0)) { | |||
| 264 | log_warn("calloc"); | |||
| 265 | return NULL((void*)0); | |||
| 266 | } | |||
| 267 | SLIST_INIT(nl){ ((nl)->slh_first) = ((void*)0); }; | |||
| 268 | } | |||
| 269 | if ((n = calloc(1, sizeof(*n))) == NULL((void*)0)) { | |||
| 270 | log_warn("calloc"); | |||
| 271 | free(nl); | |||
| 272 | return NULL((void*)0); | |||
| 273 | } | |||
| 274 | n->name = name; | |||
| 275 | SLIST_INSERT_HEAD(nl, n, next)do { (n)->next.sle_next = (nl)->slh_first; (nl)->slh_first = (n); } while (0); | |||
| 276 | ||||
| 277 | return nl; | |||
| 278 | } | |||
| 279 | ||||
| 280 | static int | |||
| 281 | schema_getc(struct schema *schema, int quotec) | |||
| 282 | { | |||
| 283 | int c, next; | |||
| 284 | ||||
| 285 | if (schema->pushback_index) | |||
| 286 | return (schema->pushback_buffer[--schema->pushback_index]); | |||
| 287 | ||||
| 288 | if (quotec) { | |||
| 289 | if ((c = getc(schema->fp)(!__isthreaded ? (--(schema->fp)->_r < 0 ? __srget(schema ->fp) : (int)(*(schema->fp)->_p++)) : (getc)(schema-> fp))) == EOF(-1)) { | |||
| 290 | log_warnx("reached end of file while parsing " | |||
| 291 | "quoted string"); | |||
| 292 | return EOF(-1); | |||
| 293 | } | |||
| 294 | return (c); | |||
| 295 | } | |||
| 296 | ||||
| 297 | while ((c = getc(schema->fp)(!__isthreaded ? (--(schema->fp)->_r < 0 ? __srget(schema ->fp) : (int)(*(schema->fp)->_p++)) : (getc)(schema-> fp))) == '\\') { | |||
| 298 | next = getc(schema->fp)(!__isthreaded ? (--(schema->fp)->_r < 0 ? __srget(schema ->fp) : (int)(*(schema->fp)->_p++)) : (getc)(schema-> fp)); | |||
| 299 | if (next != '\n') { | |||
| 300 | c = next; | |||
| 301 | break; | |||
| 302 | } | |||
| 303 | schema->lineno++; | |||
| 304 | } | |||
| 305 | ||||
| 306 | return (c); | |||
| 307 | } | |||
| 308 | ||||
| 309 | static int | |||
| 310 | schema_ungetc(struct schema *schema, int c) | |||
| 311 | { | |||
| 312 | if (c == EOF(-1)) | |||
| 313 | return EOF(-1); | |||
| 314 | ||||
| 315 | if (schema->pushback_index < SCHEMA_MAXPUSHBACK128-1) | |||
| 316 | return (schema->pushback_buffer[schema->pushback_index++] = c); | |||
| 317 | else | |||
| 318 | return (EOF(-1)); | |||
| 319 | } | |||
| 320 | ||||
| 321 | static int | |||
| 322 | findeol(struct schema *schema) | |||
| 323 | { | |||
| 324 | int c; | |||
| 325 | ||||
| 326 | /* skip to either EOF or the first real EOL */ | |||
| 327 | while (1) { | |||
| 328 | if (schema->pushback_index) | |||
| 329 | c = schema->pushback_buffer[--schema->pushback_index]; | |||
| 330 | else | |||
| 331 | c = schema_getc(schema, 0); | |||
| 332 | if (c == '\n') { | |||
| 333 | schema->lineno++; | |||
| 334 | break; | |||
| 335 | } | |||
| 336 | if (c == EOF(-1)) | |||
| 337 | break; | |||
| 338 | } | |||
| 339 | return (ERROR-1); | |||
| 340 | } | |||
| 341 | ||||
| 342 | static int | |||
| 343 | schema_lex(struct schema *schema, char **kw) | |||
| 344 | { | |||
| 345 | char buf[8096]; | |||
| 346 | char *p; | |||
| 347 | int quotec, next, c; | |||
| 348 | ||||
| 349 | if (kw
| |||
| 350 | *kw = NULL((void*)0); | |||
| 351 | ||||
| 352 | top: | |||
| 353 | p = buf; | |||
| 354 | while ((c = schema_getc(schema, 0)) == ' ' || c == '\t') | |||
| 355 | ; /* nothing */ | |||
| 356 | ||||
| 357 | if (c == '#') | |||
| 358 | while ((c = schema_getc(schema, 0)) != '\n' && c != EOF(-1)) | |||
| 359 | ; /* nothing */ | |||
| 360 | ||||
| 361 | switch (c) { | |||
| 362 | case '\'': | |||
| 363 | case '"': | |||
| 364 | quotec = c; | |||
| 365 | while (1) { | |||
| 366 | if ((c = schema_getc(schema, quotec)) == EOF(-1)) | |||
| 367 | return (0); | |||
| 368 | if (c == '\n') { | |||
| 369 | schema->lineno++; | |||
| 370 | continue; | |||
| 371 | } else if (c == '\\') { | |||
| 372 | if ((next = schema_getc(schema, quotec)) == EOF(-1)) | |||
| 373 | return (0); | |||
| 374 | if (next == quotec || c == ' ' || c == '\t') | |||
| 375 | c = next; | |||
| 376 | else if (next == '\n') | |||
| 377 | continue; | |||
| 378 | else | |||
| 379 | schema_ungetc(schema, next); | |||
| 380 | } else if (c == quotec) { | |||
| 381 | *p = '\0'; | |||
| 382 | break; | |||
| 383 | } | |||
| 384 | if (p + 1 >= buf + sizeof(buf) - 1) { | |||
| 385 | log_warnx("string too long"); | |||
| 386 | return (findeol(schema)); | |||
| 387 | } | |||
| 388 | *p++ = (char)c; | |||
| 389 | } | |||
| 390 | if (kw != NULL((void*)0) && (*kw = strdup(buf)) == NULL((void*)0)) | |||
| 391 | fatal("schema_lex: strdup"); | |||
| 392 | return (STRING1); | |||
| 393 | } | |||
| 394 | ||||
| 395 | #define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && x != '{' && x != '}' && x != '<' && x != '>' && x != '!' && x != '=' && x != '/' && x != '#' && x != ',') ) \ | |||
| 396 | (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ | |||
| 397 | x != '{' && x != '}' && x != '<' && x != '>' && \ | |||
| 398 | x != '!' && x != '=' && x != '/' && x != '#' && \ | |||
| 399 | x != ',')) | |||
| 400 | ||||
| 401 | if (isalnum(c) || c == ':' || c == '_' || c == '*') { | |||
| 402 | do { | |||
| 403 | *p++ = c; | |||
| 404 | if ((size_t)(p-buf) >= sizeof(buf)) { | |||
| 405 | log_warnx("string too long"); | |||
| 406 | return (findeol(schema)); | |||
| 407 | } | |||
| 408 | } while ((c = schema_getc(schema, 0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c != ')' && c != '{' && c != '}' && c != '<' && c != '>' && c != '!' && c != '=' && c != '/' && c != '#' && c != ',') ))); | |||
| 409 | schema_ungetc(schema, c); | |||
| 410 | *p = '\0'; | |||
| 411 | if (kw != NULL((void*)0) && (*kw = strdup(buf)) == NULL((void*)0)) | |||
| 412 | fatal("schema_lex: strdup"); | |||
| 413 | return STRING1; | |||
| 414 | } | |||
| 415 | if (c == '\n') { | |||
| 416 | schema->lineno++; | |||
| 417 | goto top; | |||
| 418 | } | |||
| 419 | if (c == EOF(-1)) | |||
| 420 | return (0); | |||
| 421 | return (c); | |||
| 422 | } | |||
| 423 | ||||
| 424 | struct schema * | |||
| 425 | schema_new(void) | |||
| 426 | { | |||
| 427 | struct schema *schema; | |||
| 428 | ||||
| 429 | if ((schema = calloc(1, sizeof(*schema))) == NULL((void*)0)) | |||
| 430 | return NULL((void*)0); | |||
| 431 | ||||
| 432 | RB_INIT(&schema->attr_types)do { (&schema->attr_types)->rbh_root = ((void*)0); } while (0); | |||
| 433 | RB_INIT(&schema->attr_names)do { (&schema->attr_names)->rbh_root = ((void*)0); } while (0); | |||
| 434 | RB_INIT(&schema->objects)do { (&schema->objects)->rbh_root = ((void*)0); } while (0); | |||
| 435 | RB_INIT(&schema->object_names)do { (&schema->object_names)->rbh_root = ((void*)0) ; } while (0); | |||
| 436 | RB_INIT(&schema->symbolic_oids)do { (&schema->symbolic_oids)->rbh_root = ((void*)0 ); } while (0); | |||
| 437 | ||||
| 438 | return schema; | |||
| 439 | } | |||
| 440 | ||||
| 441 | static void | |||
| 442 | schema_err(struct schema *schema, const char *fmt, ...) | |||
| 443 | { | |||
| 444 | va_list ap; | |||
| 445 | char *msg; | |||
| 446 | ||||
| 447 | va_start(ap, fmt)__builtin_va_start(ap, fmt); | |||
| 448 | if (vasprintf(&msg, fmt, ap) == -1) | |||
| 449 | fatal("vasprintf"); | |||
| 450 | va_end(ap)__builtin_va_end(ap); | |||
| 451 | logit(LOG_CRIT2, "%s:%d: %s", schema->filename, schema->lineno, msg); | |||
| 452 | free(msg); | |||
| 453 | ||||
| 454 | schema->error++; | |||
| 455 | } | |||
| 456 | ||||
| 457 | static int | |||
| 458 | schema_link_attr_name(struct schema *schema, const char *name, struct attr_type *attr) | |||
| 459 | { | |||
| 460 | struct oidname *oidname, *prev; | |||
| 461 | ||||
| 462 | if ((oidname = calloc(1, sizeof(*oidname))) == NULL((void*)0)) { | |||
| 463 | log_warn("calloc"); | |||
| 464 | return -1; | |||
| 465 | } | |||
| 466 | ||||
| 467 | oidname->on_name = name; | |||
| 468 | oidname->on_attr_typeon_ptr.ou_attr_type = attr; | |||
| 469 | prev = RB_INSERT(oidname_tree, &schema->attr_names, oidname)oidname_tree_RB_INSERT(&schema->attr_names, oidname); | |||
| 470 | if (prev != NULL((void*)0)) { | |||
| 471 | schema_err(schema, "attribute type name '%s'" | |||
| 472 | " already defined for oid %s", | |||
| 473 | name, prev->on_attr_typeon_ptr.ou_attr_type->oid); | |||
| 474 | free(oidname); | |||
| 475 | return -1; | |||
| 476 | } | |||
| 477 | ||||
| 478 | return 0; | |||
| 479 | } | |||
| 480 | ||||
| 481 | static int | |||
| 482 | schema_link_attr_names(struct schema *schema, struct attr_type *attr) | |||
| 483 | { | |||
| 484 | struct name *name; | |||
| 485 | ||||
| 486 | SLIST_FOREACH(name, attr->names, next)for((name) = ((attr->names)->slh_first); (name) != ((void *)0); (name) = ((name)->next.sle_next)) { | |||
| 487 | if (schema_link_attr_name(schema, name->name, attr) != 0) | |||
| 488 | return -1; | |||
| 489 | } | |||
| 490 | return 0; | |||
| 491 | } | |||
| 492 | ||||
| 493 | static int | |||
| 494 | schema_link_obj_name(struct schema *schema, const char *name, struct object *obj) | |||
| 495 | { | |||
| 496 | struct oidname *oidname, *prev; | |||
| 497 | ||||
| 498 | if ((oidname = calloc(1, sizeof(*oidname))) == NULL((void*)0)) { | |||
| 499 | log_warn("calloc"); | |||
| 500 | return -1; | |||
| 501 | } | |||
| 502 | ||||
| 503 | oidname->on_name = name; | |||
| 504 | oidname->on_objecton_ptr.ou_object = obj; | |||
| 505 | prev = RB_INSERT(oidname_tree, &schema->object_names, oidname)oidname_tree_RB_INSERT(&schema->object_names, oidname); | |||
| 506 | if (prev != NULL((void*)0)) { | |||
| 507 | schema_err(schema, "object class name '%s'" | |||
| 508 | " already defined for oid %s", | |||
| 509 | name, prev->on_objecton_ptr.ou_object->oid); | |||
| 510 | free(oidname); | |||
| 511 | return -1; | |||
| 512 | } | |||
| 513 | ||||
| 514 | return 0; | |||
| 515 | } | |||
| 516 | ||||
| 517 | static int | |||
| 518 | schema_link_obj_names(struct schema *schema, struct object *obj) | |||
| 519 | { | |||
| 520 | struct name *name; | |||
| 521 | ||||
| 522 | SLIST_FOREACH(name, obj->names, next)for((name) = ((obj->names)->slh_first); (name) != ((void *)0); (name) = ((name)->next.sle_next)) { | |||
| 523 | if (schema_link_obj_name(schema, name->name, obj) != 0) | |||
| 524 | return -1; | |||
| 525 | } | |||
| 526 | return 0; | |||
| 527 | } | |||
| 528 | ||||
| 529 | static struct name_list * | |||
| 530 | schema_parse_names(struct schema *schema) | |||
| 531 | { | |||
| 532 | struct name_list *nlist = NULL((void*)0); | |||
| 533 | char *kw; | |||
| 534 | int token; | |||
| 535 | ||||
| 536 | token = schema_lex(schema, &kw); | |||
| 537 | if (token == STRING1) | |||
| 538 | return push_name(NULL((void*)0), kw); | |||
| 539 | ||||
| 540 | if (token != '(') | |||
| 541 | goto fail; | |||
| 542 | ||||
| 543 | for (;;) { | |||
| 544 | token = schema_lex(schema, &kw); | |||
| 545 | if (token == ')') | |||
| 546 | break; | |||
| 547 | if (token != STRING1) | |||
| 548 | goto fail; | |||
| 549 | nlist = push_name(nlist, kw); | |||
| 550 | } | |||
| 551 | ||||
| 552 | return nlist; | |||
| 553 | ||||
| 554 | fail: | |||
| 555 | free(kw); | |||
| 556 | /* FIXME: leaks nlist here */ | |||
| 557 | return NULL((void*)0); | |||
| 558 | } | |||
| 559 | ||||
| 560 | static void | |||
| 561 | schema_free_name_list(struct name_list *nlist) | |||
| 562 | { | |||
| 563 | struct name *name; | |||
| 564 | ||||
| 565 | while ((name = SLIST_FIRST(nlist)((nlist)->slh_first)) != NULL((void*)0)) { | |||
| 566 | SLIST_REMOVE_HEAD(nlist, next)do { (nlist)->slh_first = (nlist)->slh_first->next.sle_next ; } while (0); | |||
| 567 | free(name->name); | |||
| 568 | free(name); | |||
| 569 | } | |||
| 570 | free(nlist); | |||
| 571 | } | |||
| 572 | ||||
| 573 | static struct attr_list * | |||
| 574 | schema_parse_attrlist(struct schema *schema) | |||
| 575 | { | |||
| 576 | struct attr_list *alist = NULL((void*)0); | |||
| 577 | struct attr_type *attr; | |||
| 578 | char *kw; | |||
| 579 | int token, want_dollar = 0; | |||
| 580 | ||||
| 581 | token = schema_lex(schema, &kw); | |||
| 582 | if (token == STRING1) { | |||
| 583 | if ((attr = lookup_attribute(schema, kw)) == NULL((void*)0)) { | |||
| 584 | schema_err(schema, "undeclared attribute type '%s'", kw); | |||
| 585 | goto fail; | |||
| 586 | } | |||
| 587 | free(kw); | |||
| 588 | return push_attr(NULL((void*)0), attr); | |||
| 589 | } | |||
| 590 | ||||
| 591 | if (token != '(') | |||
| 592 | goto fail; | |||
| 593 | ||||
| 594 | for (;;) { | |||
| 595 | token = schema_lex(schema, &kw); | |||
| 596 | if (token == ')') | |||
| 597 | break; | |||
| 598 | if (token == '$') { | |||
| 599 | if (!want_dollar) | |||
| 600 | goto fail; | |||
| 601 | want_dollar = 0; | |||
| 602 | continue; | |||
| 603 | } | |||
| 604 | if (token != STRING1) | |||
| 605 | goto fail; | |||
| 606 | if ((attr = lookup_attribute(schema, kw)) == NULL((void*)0)) { | |||
| 607 | schema_err(schema, "%s: no such attribute", kw); | |||
| 608 | goto fail; | |||
| 609 | } | |||
| 610 | alist = push_attr(alist, attr); | |||
| 611 | free(kw); | |||
| 612 | want_dollar = 1; | |||
| 613 | } | |||
| 614 | ||||
| 615 | return alist; | |||
| 616 | ||||
| 617 | fail: | |||
| 618 | free(kw); | |||
| 619 | /* FIXME: leaks alist here */ | |||
| 620 | return NULL((void*)0); | |||
| 621 | } | |||
| 622 | ||||
| 623 | static struct obj_list * | |||
| 624 | schema_parse_objlist(struct schema *schema) | |||
| 625 | { | |||
| 626 | struct obj_list *olist = NULL((void*)0); | |||
| 627 | struct object *obj; | |||
| 628 | char *kw; | |||
| 629 | int token, want_dollar = 0; | |||
| 630 | ||||
| 631 | token = schema_lex(schema, &kw); | |||
| 632 | if (token == STRING1) { | |||
| 633 | if ((obj = lookup_object(schema, kw)) == NULL((void*)0)) { | |||
| 634 | schema_err(schema, "undeclared object class '%s'", kw); | |||
| 635 | goto fail; | |||
| 636 | } | |||
| 637 | free(kw); | |||
| 638 | return push_obj(NULL((void*)0), obj); | |||
| 639 | } | |||
| 640 | ||||
| 641 | if (token != '(') | |||
| 642 | goto fail; | |||
| 643 | ||||
| 644 | for (;;) { | |||
| 645 | token = schema_lex(schema, &kw); | |||
| 646 | if (token == ')') | |||
| 647 | break; | |||
| 648 | if (token == '$') { | |||
| 649 | if (!want_dollar) | |||
| 650 | goto fail; | |||
| 651 | want_dollar = 0; | |||
| 652 | continue; | |||
| 653 | } | |||
| 654 | if (token != STRING1) | |||
| 655 | goto fail; | |||
| 656 | if ((obj = lookup_object(schema, kw)) == NULL((void*)0)) | |||
| 657 | goto fail; | |||
| 658 | olist = push_obj(olist, obj); | |||
| 659 | want_dollar = 1; | |||
| 660 | } | |||
| 661 | ||||
| 662 | return olist; | |||
| 663 | ||||
| 664 | fail: | |||
| 665 | free(kw); | |||
| 666 | /* FIXME: leaks olist here */ | |||
| 667 | return NULL((void*)0); | |||
| 668 | } | |||
| 669 | ||||
| 670 | static int | |||
| 671 | schema_validate_match_rule(struct schema *schema, struct attr_type *at, | |||
| 672 | const struct match_rule *mrule, enum match_rule_type type) | |||
| 673 | { | |||
| 674 | int i; | |||
| 675 | ||||
| 676 | if (mrule == NULL((void*)0)) | |||
| 677 | return 0; | |||
| 678 | ||||
| 679 | if ((mrule->type & type) != type) { | |||
| 680 | schema_err(schema, "%s: bad matching rule '%s'", | |||
| 681 | ATTR_NAME(at)((at)->names ? (((at)->names)->slh_first)->name : (at)->oid), mrule->name); | |||
| 682 | return -1; | |||
| 683 | } | |||
| 684 | ||||
| 685 | /* Is this matching rule compatible with the attribute syntax? */ | |||
| 686 | if (strcmp(mrule->syntax_oid, at->syntax->oid) == 0) | |||
| 687 | return 0; | |||
| 688 | ||||
| 689 | /* Check any alternative syntaxes for compatibility. */ | |||
| 690 | for (i = 0; mrule->alt_syntax_oids && mrule->alt_syntax_oids[i]; i++) | |||
| 691 | if (strcmp(mrule->alt_syntax_oids[i], at->syntax->oid) == 0) | |||
| 692 | return 0; | |||
| 693 | ||||
| 694 | schema_err(schema, "%s: inappropriate matching rule '%s' for syntax [%s]", | |||
| 695 | ATTR_NAME(at)((at)->names ? (((at)->names)->slh_first)->name : (at)->oid), mrule->name, at->syntax->oid); | |||
| 696 | return -1; | |||
| 697 | } | |||
| 698 | ||||
| 699 | static int | |||
| 700 | schema_parse_attributetype(struct schema *schema) | |||
| 701 | { | |||
| 702 | struct attr_type *attr = NULL((void*)0), *prev, *sup; | |||
| 703 | struct name_list *xnames; | |||
| 704 | char *kw = NULL((void*)0), *arg = NULL((void*)0); | |||
| 705 | int token, ret = 0, c; | |||
| 706 | ||||
| 707 | if (schema_lex(schema, NULL((void*)0)) != '(') | |||
| 708 | goto fail; | |||
| 709 | ||||
| 710 | if (schema_lex(schema, &kw) != STRING1) | |||
| 711 | goto fail; | |||
| 712 | ||||
| 713 | if ((attr = calloc(1, sizeof(*attr))) == NULL((void*)0)) { | |||
| 714 | log_warn("calloc"); | |||
| 715 | goto fail; | |||
| 716 | } | |||
| 717 | attr->usage = USAGE_USER_APP; | |||
| 718 | ||||
| 719 | if (is_oidstr(kw)) | |||
| 720 | attr->oid = kw; | |||
| 721 | else { | |||
| 722 | attr->oid = lookup_symbolic_oid(schema, kw); | |||
| 723 | if (attr->oid == NULL((void*)0)) | |||
| 724 | goto fail; | |||
| 725 | free(kw); | |||
| 726 | } | |||
| 727 | kw = NULL((void*)0); | |||
| 728 | ||||
| 729 | prev = RB_INSERT(attr_type_tree, &schema->attr_types, attr)attr_type_tree_RB_INSERT(&schema->attr_types, attr); | |||
| 730 | if (prev != NULL((void*)0)) { | |||
| 731 | schema_err(schema, "attribute type %s already defined", attr->oid); | |||
| 732 | goto fail; | |||
| 733 | } | |||
| 734 | ||||
| 735 | while (ret == 0) { | |||
| 736 | token = schema_lex(schema, &kw); | |||
| 737 | if (token == ')') | |||
| 738 | break; | |||
| 739 | else if (token != STRING1) | |||
| 740 | goto fail; | |||
| 741 | if (strcasecmp(kw, "NAME") == 0) { | |||
| 742 | attr->names = schema_parse_names(schema); | |||
| 743 | if (attr->names == NULL((void*)0)) | |||
| 744 | goto fail; | |||
| 745 | schema_link_attr_names(schema, attr); | |||
| 746 | } else if (strcasecmp(kw, "DESC") == 0) { | |||
| 747 | if (schema_lex(schema, &attr->desc) != STRING1) | |||
| 748 | goto fail; | |||
| 749 | } else if (strcasecmp(kw, "OBSOLETE") == 0) { | |||
| 750 | attr->obsolete = 1; | |||
| 751 | } else if (strcasecmp(kw, "SUP") == 0) { | |||
| 752 | if (schema_lex(schema, &arg) != STRING1) | |||
| 753 | goto fail; | |||
| 754 | if ((attr->sup = lookup_attribute(schema, arg)) == NULL((void*)0)) { | |||
| 755 | schema_err(schema, "%s: no such attribute", arg); | |||
| 756 | goto fail; | |||
| 757 | } | |||
| 758 | free(arg); | |||
| 759 | } else if (strcasecmp(kw, "EQUALITY") == 0) { | |||
| 760 | if (schema_lex(schema, &arg) != STRING1) | |||
| 761 | goto fail; | |||
| 762 | if ((attr->equality = match_rule_lookup(arg)) == NULL((void*)0)) { | |||
| 763 | schema_err(schema, "%s: unknown matching rule", | |||
| 764 | arg); | |||
| 765 | goto fail; | |||
| 766 | } | |||
| 767 | free(arg); | |||
| 768 | } else if (strcasecmp(kw, "ORDERING") == 0) { | |||
| 769 | if (schema_lex(schema, &arg) != STRING1) | |||
| 770 | goto fail; | |||
| 771 | if ((attr->ordering = match_rule_lookup(arg)) == NULL((void*)0)) { | |||
| 772 | schema_err(schema, "%s: unknown matching rule", | |||
| 773 | arg); | |||
| 774 | goto fail; | |||
| 775 | } | |||
| 776 | free(arg); | |||
| 777 | } else if (strcasecmp(kw, "SUBSTR") == 0) { | |||
| 778 | if (schema_lex(schema, &arg) != STRING1) | |||
| 779 | goto fail; | |||
| 780 | if ((attr->substr = match_rule_lookup(arg)) == NULL((void*)0)) { | |||
| 781 | schema_err(schema, "%s: unknown matching rule", | |||
| 782 | arg); | |||
| 783 | goto fail; | |||
| 784 | } | |||
| 785 | free(arg); | |||
| 786 | } else if (strcasecmp(kw, "SYNTAX") == 0) { | |||
| 787 | if (schema_lex(schema, &arg) != STRING1 || | |||
| 788 | !is_oidstr(arg)) | |||
| 789 | goto fail; | |||
| 790 | ||||
| 791 | if ((attr->syntax = syntax_lookup(arg)) == NULL((void*)0)) { | |||
| 792 | schema_err(schema, "syntax not supported: %s", | |||
| 793 | arg); | |||
| 794 | goto fail; | |||
| 795 | } | |||
| 796 | ||||
| 797 | if ((c = schema_getc(schema, 0)) == '{') { | |||
| 798 | if (schema_lex(schema, NULL((void*)0)) != STRING1 || | |||
| 799 | schema_lex(schema, NULL((void*)0)) != '}') | |||
| 800 | goto fail; | |||
| 801 | } else | |||
| 802 | schema_ungetc(schema, c); | |||
| 803 | free(arg); | |||
| 804 | } else if (strcasecmp(kw, "SINGLE-VALUE") == 0) { | |||
| 805 | attr->single = 1; | |||
| 806 | } else if (strcasecmp(kw, "COLLECTIVE") == 0) { | |||
| 807 | attr->collective = 1; | |||
| 808 | } else if (strcasecmp(kw, "NO-USER-MODIFICATION") == 0) { | |||
| 809 | attr->immutable = 1; | |||
| 810 | } else if (strcasecmp(kw, "USAGE") == 0) { | |||
| 811 | if (schema_lex(schema, &arg) != STRING1) | |||
| 812 | goto fail; | |||
| 813 | if (strcasecmp(arg, "dSAOperation") == 0) | |||
| 814 | attr->usage = USAGE_DSA_OP; | |||
| 815 | else if (strcasecmp(arg, "directoryOperation") == 0) | |||
| 816 | attr->usage = USAGE_DIR_OP; | |||
| 817 | else if (strcasecmp(arg, "distributedOperation") == 0) | |||
| 818 | attr->usage = USAGE_DIST_OP; | |||
| 819 | else if (strcasecmp(arg, "userApplications") == 0) | |||
| 820 | attr->usage = USAGE_USER_APP; | |||
| 821 | else { | |||
| 822 | schema_err(schema, "invalid usage '%s'", arg); | |||
| 823 | goto fail; | |||
| 824 | } | |||
| 825 | free(arg); | |||
| 826 | } else if (strncmp(kw, "X-", 2) == 0) { | |||
| 827 | /* unknown extension, eat argument(s) */ | |||
| 828 | xnames = schema_parse_names(schema); | |||
| 829 | if (xnames == NULL((void*)0)) | |||
| 830 | goto fail; | |||
| 831 | schema_free_name_list(xnames); | |||
| 832 | } else { | |||
| 833 | schema_err(schema, "syntax error at token '%s'", kw); | |||
| 834 | goto fail; | |||
| 835 | } | |||
| 836 | free(kw); | |||
| 837 | } | |||
| 838 | ||||
| 839 | /* Check that a syntax is defined, either directly or | |||
| 840 | * indirectly via a superior attribute type. | |||
| 841 | */ | |||
| 842 | sup = attr->sup; | |||
| 843 | while (attr->syntax == NULL((void*)0) && sup != NULL((void*)0)) { | |||
| 844 | attr->syntax = sup->syntax; | |||
| 845 | sup = sup->sup; | |||
| 846 | } | |||
| 847 | if (attr->syntax == NULL((void*)0)) { | |||
| 848 | schema_err(schema, "%s: no syntax defined", ATTR_NAME(attr)((attr)->names ? (((attr)->names)->slh_first)->name : (attr)->oid)); | |||
| 849 | goto fail; | |||
| 850 | } | |||
| 851 | ||||
| 852 | /* If the attribute type doesn't explicitly define equality, check | |||
| 853 | * if any superior attribute type does. | |||
| 854 | */ | |||
| 855 | sup = attr->sup; | |||
| 856 | while (attr->equality == NULL((void*)0) && sup != NULL((void*)0)) { | |||
| 857 | attr->equality = sup->equality; | |||
| 858 | sup = sup->sup; | |||
| 859 | } | |||
| 860 | /* Same thing with ordering matching rule. */ | |||
| 861 | sup = attr->sup; | |||
| 862 | while (attr->ordering == NULL((void*)0) && sup != NULL((void*)0)) { | |||
| 863 | attr->ordering = sup->ordering; | |||
| 864 | sup = sup->sup; | |||
| 865 | } | |||
| 866 | /* ...and substring matching rule. */ | |||
| 867 | sup = attr->sup; | |||
| 868 | while (attr->substr == NULL((void*)0) && sup != NULL((void*)0)) { | |||
| 869 | attr->substr = sup->substr; | |||
| 870 | sup = sup->sup; | |||
| 871 | } | |||
| 872 | ||||
| 873 | if (schema_validate_match_rule(schema, attr, attr->equality, MATCH_EQUALITY) != 0 || | |||
| 874 | schema_validate_match_rule(schema, attr, attr->ordering, MATCH_ORDERING) != 0 || | |||
| 875 | schema_validate_match_rule(schema, attr, attr->substr, MATCH_SUBSTR) != 0) | |||
| 876 | goto fail; | |||
| 877 | ||||
| 878 | return 0; | |||
| 879 | ||||
| 880 | fail: | |||
| 881 | free(kw); | |||
| 882 | if (attr != NULL((void*)0)) { | |||
| 883 | if (attr->oid != NULL((void*)0)) { | |||
| 884 | RB_REMOVE(attr_type_tree, &schema->attr_types, attr)attr_type_tree_RB_REMOVE(&schema->attr_types, attr); | |||
| 885 | free(attr->oid); | |||
| 886 | } | |||
| 887 | free(attr->desc); | |||
| 888 | free(attr); | |||
| 889 | } | |||
| 890 | return -1; | |||
| 891 | } | |||
| 892 | ||||
| 893 | static int | |||
| 894 | schema_parse_objectclass(struct schema *schema) | |||
| 895 | { | |||
| 896 | struct object *obj = NULL((void*)0), *prev; | |||
| 897 | struct obj_ptr *optr; | |||
| 898 | struct name_list *xnames; | |||
| 899 | char *kw = NULL((void*)0); | |||
| 900 | int token, ret = 0; | |||
| 901 | ||||
| 902 | if (schema_lex(schema, NULL((void*)0)) != '(') | |||
| 903 | goto fail; | |||
| 904 | ||||
| 905 | if (schema_lex(schema, &kw) != STRING1) | |||
| 906 | goto fail; | |||
| 907 | ||||
| 908 | if ((obj = calloc(1, sizeof(*obj))) == NULL((void*)0)) { | |||
| 909 | log_warn("calloc"); | |||
| 910 | goto fail; | |||
| 911 | } | |||
| 912 | obj->kind = KIND_STRUCTURAL; | |||
| 913 | ||||
| 914 | if (is_oidstr(kw)) | |||
| 915 | obj->oid = kw; | |||
| 916 | else { | |||
| 917 | obj->oid = lookup_symbolic_oid(schema, kw); | |||
| 918 | if (obj->oid == NULL((void*)0)) | |||
| 919 | goto fail; | |||
| 920 | free(kw); | |||
| 921 | } | |||
| 922 | kw = NULL((void*)0); | |||
| 923 | ||||
| 924 | prev = RB_INSERT(object_tree, &schema->objects, obj)object_tree_RB_INSERT(&schema->objects, obj); | |||
| 925 | if (prev != NULL((void*)0)) { | |||
| 926 | schema_err(schema, "object class %s already defined", obj->oid); | |||
| 927 | goto fail; | |||
| 928 | } | |||
| 929 | ||||
| 930 | while (ret == 0) { | |||
| 931 | token = schema_lex(schema, &kw); | |||
| 932 | if (token == ')') | |||
| 933 | break; | |||
| 934 | else if (token != STRING1) | |||
| 935 | goto fail; | |||
| 936 | if (strcasecmp(kw, "NAME") == 0) { | |||
| 937 | obj->names = schema_parse_names(schema); | |||
| 938 | if (obj->names == NULL((void*)0)) | |||
| 939 | goto fail; | |||
| 940 | schema_link_obj_names(schema, obj); | |||
| 941 | } else if (strcasecmp(kw, "DESC") == 0) { | |||
| 942 | if (schema_lex(schema, &obj->desc) != STRING1) | |||
| 943 | goto fail; | |||
| 944 | } else if (strcasecmp(kw, "OBSOLETE") == 0) { | |||
| 945 | obj->obsolete = 1; | |||
| 946 | } else if (strcasecmp(kw, "SUP") == 0) { | |||
| 947 | obj->sup = schema_parse_objlist(schema); | |||
| 948 | if (obj->sup == NULL((void*)0)) | |||
| 949 | goto fail; | |||
| 950 | } else if (strcasecmp(kw, "ABSTRACT") == 0) { | |||
| 951 | obj->kind = KIND_ABSTRACT; | |||
| 952 | } else if (strcasecmp(kw, "STRUCTURAL") == 0) { | |||
| 953 | obj->kind = KIND_STRUCTURAL; | |||
| 954 | } else if (strcasecmp(kw, "AUXILIARY") == 0) { | |||
| 955 | obj->kind = KIND_AUXILIARY; | |||
| 956 | } else if (strcasecmp(kw, "MUST") == 0) { | |||
| 957 | obj->must = schema_parse_attrlist(schema); | |||
| 958 | if (obj->must == NULL((void*)0)) | |||
| 959 | goto fail; | |||
| 960 | } else if (strcasecmp(kw, "MAY") == 0) { | |||
| 961 | obj->may = schema_parse_attrlist(schema); | |||
| 962 | if (obj->may == NULL((void*)0)) | |||
| 963 | goto fail; | |||
| 964 | } else if (strncasecmp(kw, "X-", 2) == 0) { | |||
| 965 | /* unknown extension, eat argument(s) */ | |||
| 966 | xnames = schema_parse_names(schema); | |||
| 967 | if (xnames == NULL((void*)0)) | |||
| 968 | goto fail; | |||
| 969 | schema_free_name_list(xnames); | |||
| 970 | } else { | |||
| 971 | schema_err(schema, "syntax error at token '%s'", kw); | |||
| 972 | goto fail; | |||
| 973 | } | |||
| 974 | free(kw); | |||
| 975 | } | |||
| 976 | ||||
| 977 | /* Verify the subclassing is allowed. | |||
| 978 | * | |||
| 979 | * Structural object classes cannot subclass auxiliary object classes. | |||
| 980 | * Auxiliary object classes cannot subclass structural object classes. | |||
| 981 | * Abstract object classes cannot derive from structural or auxiliary | |||
| 982 | * object classes. | |||
| 983 | */ | |||
| 984 | if (obj->sup != NULL((void*)0)) { | |||
| 985 | SLIST_FOREACH(optr, obj->sup, next)for((optr) = ((obj->sup)->slh_first); (optr) != ((void* )0); (optr) = ((optr)->next.sle_next)) { | |||
| 986 | if (obj->kind == KIND_STRUCTURAL && | |||
| 987 | optr->object->kind == KIND_AUXILIARY) { | |||
| 988 | log_warnx("structural object class '%s' cannot" | |||
| 989 | " subclass auxiliary object class '%s'", | |||
| 990 | OBJ_NAME(obj)((obj)->names ? (((obj)->names)->slh_first)->name : (obj)->oid), OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names) ->slh_first)->name : (optr->object)->oid)); | |||
| 991 | goto fail; | |||
| 992 | } | |||
| 993 | ||||
| 994 | if (obj->kind == KIND_AUXILIARY && | |||
| 995 | optr->object->kind == KIND_STRUCTURAL) { | |||
| 996 | log_warnx("auxiliary object class '%s' cannot" | |||
| 997 | " subclass structural object class '%s'", | |||
| 998 | OBJ_NAME(obj)((obj)->names ? (((obj)->names)->slh_first)->name : (obj)->oid), OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names) ->slh_first)->name : (optr->object)->oid)); | |||
| 999 | goto fail; | |||
| 1000 | } | |||
| 1001 | ||||
| 1002 | if (obj->kind == KIND_ABSTRACT && | |||
| 1003 | optr->object->kind != KIND_ABSTRACT) { | |||
| 1004 | log_warnx("abstract object class '%s' cannot" | |||
| 1005 | " subclass non-abstract object class '%s'", | |||
| 1006 | OBJ_NAME(obj)((obj)->names ? (((obj)->names)->slh_first)->name : (obj)->oid), OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names) ->slh_first)->name : (optr->object)->oid)); | |||
| 1007 | goto fail; | |||
| 1008 | } | |||
| 1009 | } | |||
| 1010 | } | |||
| 1011 | ||||
| 1012 | return 0; | |||
| 1013 | ||||
| 1014 | fail: | |||
| 1015 | free(kw); | |||
| 1016 | if (obj != NULL((void*)0)) { | |||
| 1017 | if (obj->oid != NULL((void*)0)) { | |||
| 1018 | RB_REMOVE(object_tree, &schema->objects, obj)object_tree_RB_REMOVE(&schema->objects, obj); | |||
| 1019 | free(obj->oid); | |||
| 1020 | } | |||
| 1021 | free(obj->desc); | |||
| 1022 | free(obj); | |||
| 1023 | } | |||
| 1024 | return -1; | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | static int | |||
| 1028 | schema_parse_objectidentifier(struct schema *schema) | |||
| 1029 | { | |||
| 1030 | char *symname = NULL((void*)0), *symoid = NULL((void*)0); | |||
| 1031 | char *oid = NULL((void*)0); | |||
| 1032 | ||||
| 1033 | if (schema_lex(schema, &symname) != STRING1) | |||
| 1034 | goto fail; | |||
| 1035 | if (schema_lex(schema, &symoid) != STRING1) | |||
| 1036 | goto fail; | |||
| 1037 | ||||
| 1038 | if (is_oidstr(symoid)) { | |||
| 1039 | oid = symoid; | |||
| 1040 | symoid = NULL((void*)0); | |||
| 1041 | } else if ((oid = lookup_symbolic_oid(schema, symoid)) == NULL((void*)0)) | |||
| 1042 | goto fail; | |||
| 1043 | ||||
| 1044 | if (push_symbolic_oid(schema, symname, oid) == NULL((void*)0)) | |||
| 1045 | goto fail; | |||
| 1046 | ||||
| 1047 | free(symoid); | |||
| 1048 | return 0; | |||
| 1049 | ||||
| 1050 | fail: | |||
| 1051 | free(symname); | |||
| 1052 | free(symoid); | |||
| 1053 | free(oid); | |||
| 1054 | return -1; | |||
| 1055 | } | |||
| 1056 | ||||
| 1057 | int | |||
| 1058 | schema_parse(struct schema *schema, const char *filename) | |||
| 1059 | { | |||
| 1060 | char *kw; | |||
| 1061 | int token, ret = 0; | |||
| 1062 | ||||
| 1063 | log_debug("parsing schema file '%s'", filename); | |||
| 1064 | ||||
| 1065 | if ((schema->fp = fopen(filename, "r")) == NULL((void*)0)) { | |||
| ||||
| 1066 | log_warn("%s", filename); | |||
| 1067 | return -1; | |||
| 1068 | } | |||
| 1069 | schema->filename = filename; | |||
| 1070 | schema->lineno = 1; | |||
| 1071 | ||||
| 1072 | while (ret == 0) { | |||
| 1073 | token = schema_lex(schema, &kw); | |||
| 1074 | if (token
| |||
| 1075 | if (strcasecmp(kw, "attributetype") == 0) | |||
| 1076 | ret = schema_parse_attributetype(schema); | |||
| 1077 | else if (strcasecmp(kw, "objectclass") == 0) | |||
| 1078 | ret = schema_parse_objectclass(schema); | |||
| 1079 | else if (strcasecmp(kw, "objectidentifier") == 0) | |||
| 1080 | ret = schema_parse_objectidentifier(schema); | |||
| 1081 | else { | |||
| 1082 | schema_err(schema, "syntax error at '%s'", kw); | |||
| 1083 | ret = -1; | |||
| 1084 | } | |||
| 1085 | if (ret == -1 && schema->error == 0) | |||
| 1086 | schema_err(schema, "syntax error"); | |||
| 1087 | free(kw); | |||
| 1088 | } else if (token == 0) { /* EOF */ | |||
| 1089 | break; | |||
| 1090 | } else { | |||
| 1091 | schema_err(schema, "syntax error"); | |||
| 1092 | ret = -1; | |||
| 1093 | } | |||
| 1094 | } | |||
| 1095 | ||||
| 1096 | fclose(schema->fp); | |||
| 1097 | schema->fp = NULL((void*)0); | |||
| 1098 | schema->filename = NULL((void*)0); | |||
| 1099 | ||||
| 1100 | return ret; | |||
| 1101 | } | |||
| 1102 | ||||
| 1103 | static int | |||
| 1104 | schema_dump_names(const char *desc, struct name_list *nlist, | |||
| 1105 | char *buf, size_t size) | |||
| 1106 | { | |||
| 1107 | struct name *name; | |||
| 1108 | ||||
| 1109 | if (nlist == NULL((void*)0) || SLIST_EMPTY(nlist)(((nlist)->slh_first) == ((void*)0))) | |||
| 1110 | return 0; | |||
| 1111 | ||||
| 1112 | if (strlcat(buf, " ", size) >= size || | |||
| 1113 | strlcat(buf, desc, size) >= size) | |||
| 1114 | return -1; | |||
| 1115 | ||||
| 1116 | name = SLIST_FIRST(nlist)((nlist)->slh_first); | |||
| 1117 | if (SLIST_NEXT(name, next)((name)->next.sle_next) == NULL((void*)0)) { | |||
| 1118 | /* single name, no parenthesis */ | |||
| 1119 | if (strlcat(buf, " '", size) >= size || | |||
| 1120 | strlcat(buf, name->name, size) >= size || | |||
| 1121 | strlcat(buf, "'", size) >= size) | |||
| 1122 | return -1; | |||
| 1123 | } else { | |||
| 1124 | if (strlcat(buf, " ( ", size) >= size) | |||
| 1125 | return -1; | |||
| 1126 | SLIST_FOREACH(name, nlist, next)for((name) = ((nlist)->slh_first); (name) != ((void*)0); ( name) = ((name)->next.sle_next)) | |||
| 1127 | if (strlcat(buf, "'", size) >= size || | |||
| 1128 | strlcat(buf, name->name, size) >= size || | |||
| 1129 | strlcat(buf, "' ", size) >= size) | |||
| 1130 | return -1; | |||
| 1131 | if (strlcat(buf, ")", size) >= size) | |||
| 1132 | return -1; | |||
| 1133 | } | |||
| 1134 | ||||
| 1135 | return 0; | |||
| 1136 | } | |||
| 1137 | ||||
| 1138 | static int | |||
| 1139 | schema_dump_attrlist(const char *desc, struct attr_list *alist, | |||
| 1140 | char *buf, size_t size) | |||
| 1141 | { | |||
| 1142 | struct attr_ptr *aptr; | |||
| 1143 | ||||
| 1144 | if (alist == NULL((void*)0) || SLIST_EMPTY(alist)(((alist)->slh_first) == ((void*)0))) | |||
| 1145 | return 0; | |||
| 1146 | ||||
| 1147 | if (strlcat(buf, " ", size) >= size || | |||
| 1148 | strlcat(buf, desc, size) >= size) | |||
| 1149 | return -1; | |||
| 1150 | ||||
| 1151 | aptr = SLIST_FIRST(alist)((alist)->slh_first); | |||
| 1152 | if (SLIST_NEXT(aptr, next)((aptr)->next.sle_next) == NULL((void*)0)) { | |||
| 1153 | /* single attribute, no parenthesis */ | |||
| 1154 | if (strlcat(buf, " ", size) >= size || | |||
| 1155 | strlcat(buf, ATTR_NAME(aptr->attr_type)((aptr->attr_type)->names ? (((aptr->attr_type)-> names)->slh_first)->name : (aptr->attr_type)->oid ), size) >= size) | |||
| 1156 | return -1; | |||
| 1157 | } else { | |||
| 1158 | if (strlcat(buf, " ( ", size) >= size) | |||
| 1159 | return -1; | |||
| 1160 | SLIST_FOREACH(aptr, alist, next)for((aptr) = ((alist)->slh_first); (aptr) != ((void*)0); ( aptr) = ((aptr)->next.sle_next)) { | |||
| 1161 | if (strlcat(buf, ATTR_NAME(aptr->attr_type)((aptr->attr_type)->names ? (((aptr->attr_type)-> names)->slh_first)->name : (aptr->attr_type)->oid ), | |||
| 1162 | size) >= size || | |||
| 1163 | strlcat(buf, " ", size) >= size) | |||
| 1164 | return -1; | |||
| 1165 | if (SLIST_NEXT(aptr, next)((aptr)->next.sle_next) != NULL((void*)0) && | |||
| 1166 | strlcat(buf, "$ ", size) >= size) | |||
| 1167 | return -1; | |||
| 1168 | } | |||
| 1169 | if (strlcat(buf, ")", size) >= size) | |||
| 1170 | return -1; | |||
| 1171 | } | |||
| 1172 | ||||
| 1173 | return 0; | |||
| 1174 | } | |||
| 1175 | ||||
| 1176 | static int | |||
| 1177 | schema_dump_objlist(const char *desc, struct obj_list *olist, | |||
| 1178 | char *buf, size_t size) | |||
| 1179 | { | |||
| 1180 | struct obj_ptr *optr; | |||
| 1181 | ||||
| 1182 | if (olist == NULL((void*)0) || SLIST_EMPTY(olist)(((olist)->slh_first) == ((void*)0))) | |||
| 1183 | return 0; | |||
| 1184 | ||||
| 1185 | if (strlcat(buf, " ", size) >= size || | |||
| 1186 | strlcat(buf, desc, size) >= size) | |||
| 1187 | return -1; | |||
| 1188 | ||||
| 1189 | optr = SLIST_FIRST(olist)((olist)->slh_first); | |||
| 1190 | if (SLIST_NEXT(optr, next)((optr)->next.sle_next) == NULL((void*)0)) { | |||
| 1191 | /* single attribute, no parenthesis */ | |||
| 1192 | if (strlcat(buf, " ", size) >= size || | |||
| 1193 | strlcat(buf, OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names) ->slh_first)->name : (optr->object)->oid), size) >= size) | |||
| 1194 | return -1; | |||
| 1195 | } else { | |||
| 1196 | if (strlcat(buf, " ( ", size) >= size) | |||
| 1197 | return -1; | |||
| 1198 | SLIST_FOREACH(optr, olist, next)for((optr) = ((olist)->slh_first); (optr) != ((void*)0); ( optr) = ((optr)->next.sle_next)) { | |||
| 1199 | if (strlcat(buf, OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names) ->slh_first)->name : (optr->object)->oid), size) >= size || | |||
| 1200 | strlcat(buf, " ", size) >= size) | |||
| 1201 | return -1; | |||
| 1202 | if (SLIST_NEXT(optr, next)((optr)->next.sle_next) != NULL((void*)0) && | |||
| 1203 | strlcat(buf, "$ ", size) >= size) | |||
| 1204 | return -1; | |||
| 1205 | } | |||
| 1206 | if (strlcat(buf, ")", size) >= size) | |||
| 1207 | return -1; | |||
| 1208 | } | |||
| 1209 | ||||
| 1210 | return 0; | |||
| 1211 | } | |||
| 1212 | ||||
| 1213 | int | |||
| 1214 | schema_dump_object(struct object *obj, char *buf, size_t size) | |||
| 1215 | { | |||
| 1216 | if (strlcpy(buf, "( ", size) >= size || | |||
| 1217 | strlcat(buf, obj->oid, size) >= size) | |||
| 1218 | return -1; | |||
| 1219 | ||||
| 1220 | if (schema_dump_names("NAME", obj->names, buf, size) != 0) | |||
| 1221 | return -1; | |||
| 1222 | ||||
| 1223 | if (obj->desc != NULL((void*)0)) | |||
| 1224 | if (strlcat(buf, " DESC '", size) >= size || | |||
| 1225 | strlcat(buf, obj->desc, size) >= size || | |||
| 1226 | strlcat(buf, "'", size) >= size) | |||
| 1227 | return -1; | |||
| 1228 | ||||
| 1229 | switch (obj->kind) { | |||
| 1230 | case KIND_STRUCTURAL: | |||
| 1231 | if (strlcat(buf, " STRUCTURAL", size) >= size) | |||
| 1232 | return -1; | |||
| 1233 | break; | |||
| 1234 | case KIND_ABSTRACT: | |||
| 1235 | if (strlcat(buf, " ABSTRACT", size) >= size) | |||
| 1236 | return -1; | |||
| 1237 | break; | |||
| 1238 | case KIND_AUXILIARY: | |||
| 1239 | if (strlcat(buf, " AUXILIARY", size) >= size) | |||
| 1240 | return -1; | |||
| 1241 | break; | |||
| 1242 | } | |||
| 1243 | ||||
| 1244 | if (schema_dump_objlist("SUP", obj->sup, buf, size) != 0) | |||
| 1245 | return -1; | |||
| 1246 | ||||
| 1247 | if (obj->obsolete && strlcat(buf, " OBSOLETE", size) >= size) | |||
| 1248 | return -1; | |||
| 1249 | ||||
| 1250 | if (schema_dump_attrlist("MUST", obj->must, buf, size) != 0) | |||
| 1251 | return -1; | |||
| 1252 | ||||
| 1253 | if (schema_dump_attrlist("MAY", obj->may, buf, size) != 0) | |||
| 1254 | return -1; | |||
| 1255 | ||||
| 1256 | if (strlcat(buf, " )", size) >= size) | |||
| 1257 | return -1; | |||
| 1258 | ||||
| 1259 | return 0; | |||
| 1260 | } | |||
| 1261 | ||||
| 1262 | int | |||
| 1263 | schema_dump_attribute(struct attr_type *at, char *buf, size_t size) | |||
| 1264 | { | |||
| 1265 | if (strlcpy(buf, "( ", size) >= size || | |||
| 1266 | strlcat(buf, at->oid, size) >= size) | |||
| 1267 | return -1; | |||
| 1268 | ||||
| 1269 | if (schema_dump_names("NAME", at->names, buf, size) != 0) | |||
| 1270 | return -1; | |||
| 1271 | ||||
| 1272 | if (at->desc != NULL((void*)0)) | |||
| 1273 | if (strlcat(buf, " DESC '", size) >= size || | |||
| 1274 | strlcat(buf, at->desc, size) >= size || | |||
| 1275 | strlcat(buf, "'", size) >= size) | |||
| 1276 | return -1; | |||
| 1277 | ||||
| 1278 | if (at->obsolete && strlcat(buf, " OBSOLETE", size) >= size) | |||
| 1279 | return -1; | |||
| 1280 | ||||
| 1281 | if (at->sup != NULL((void*)0)) | |||
| 1282 | if (strlcat(buf, " SUP ", size) >= size || | |||
| 1283 | strlcat(buf, ATTR_NAME(at->sup)((at->sup)->names ? (((at->sup)->names)->slh_first )->name : (at->sup)->oid), size) >= size) | |||
| 1284 | return -1; | |||
| 1285 | ||||
| 1286 | if (at->equality != NULL((void*)0)) | |||
| 1287 | if (strlcat(buf, " EQUALITY ", size) >= size || | |||
| 1288 | strlcat(buf, at->equality->name, size) >= size) | |||
| 1289 | return -1; | |||
| 1290 | ||||
| 1291 | if (at->ordering != NULL((void*)0)) | |||
| 1292 | if (strlcat(buf, " ORDERING ", size) >= size || | |||
| 1293 | strlcat(buf, at->ordering->name, size) >= size) | |||
| 1294 | return -1; | |||
| 1295 | ||||
| 1296 | if (at->substr != NULL((void*)0)) | |||
| 1297 | if (strlcat(buf, " SUBSTR ", size) >= size || | |||
| 1298 | strlcat(buf, at->substr->name, size) >= size) | |||
| 1299 | return -1; | |||
| 1300 | ||||
| 1301 | if (at->syntax != NULL((void*)0)) | |||
| 1302 | if (strlcat(buf, " SYNTAX ", size) >= size || | |||
| 1303 | strlcat(buf, at->syntax->oid, size) >= size) | |||
| 1304 | return -1; | |||
| 1305 | ||||
| 1306 | if (at->single && strlcat(buf, " SINGLE-VALUE", size) >= size) | |||
| 1307 | return -1; | |||
| 1308 | ||||
| 1309 | if (at->collective && strlcat(buf, " COLLECTIVE", size) >= size) | |||
| 1310 | return -1; | |||
| 1311 | ||||
| 1312 | if (at->immutable && strlcat(buf, " NO-USER-MODIFICATION", size) >= size) | |||
| 1313 | return -1; | |||
| 1314 | ||||
| 1315 | switch (at->usage) { | |||
| 1316 | case USAGE_USER_APP: | |||
| 1317 | /* User application usage is the default. */ | |||
| 1318 | break; | |||
| 1319 | case USAGE_DIR_OP: | |||
| 1320 | if (strlcat(buf, " USAGE directoryOperation", size) >= size) | |||
| 1321 | return -1; | |||
| 1322 | break; | |||
| 1323 | case USAGE_DIST_OP: | |||
| 1324 | if (strlcat(buf, " USAGE distributedOperation", size) >= size) | |||
| 1325 | return -1; | |||
| 1326 | break; | |||
| 1327 | case USAGE_DSA_OP: | |||
| 1328 | if (strlcat(buf, " USAGE dSAOperation", size) >= size) | |||
| 1329 | return -1; | |||
| 1330 | break; | |||
| 1331 | } | |||
| 1332 | ||||
| 1333 | if (strlcat(buf, " )", size) >= size) | |||
| 1334 | return -1; | |||
| 1335 | ||||
| 1336 | return 0; | |||
| 1337 | } | |||
| 1338 | ||||
| 1339 | int | |||
| 1340 | schema_dump_match_rule(struct match_rule *mr, char *buf, size_t size) | |||
| 1341 | { | |||
| 1342 | if (strlcpy(buf, "( ", size) >= size || | |||
| 1343 | strlcat(buf, mr->oid, size) >= size || | |||
| 1344 | strlcat(buf, " NAME '", size) >= size || | |||
| 1345 | strlcat(buf, mr->name, size) >= size || | |||
| 1346 | strlcat(buf, "' SYNTAX ", size) >= size || | |||
| 1347 | strlcat(buf, mr->syntax_oid, size) >= size || | |||
| 1348 | strlcat(buf, " )", size) >= size) | |||
| 1349 | return -1; | |||
| 1350 | ||||
| 1351 | return 0; | |||
| 1352 | } | |||
| 1353 |